"""simple docstring"""
from collections import deque
from math import floor
from random import random
from time import time



class 					lowerCAmelCase_      :



				"""simple docstring"""

				def __init__(			self      ):






										"""simple docstring"""

										snake_case        =     {}

				def 						snake_case	(			self						,      lowerCAmelCase						,      lowerCAmelCase						,      lowerCAmelCase=1      ):






										"""simple docstring"""

										if self.graph.get(lowerCAmelCase      ):
																if self.graph[u].count([w, v]      ) == 0:
																						self.graph[u].append([w, v]      )
										else:
																snake_case        =     [[w, v]]
										if not self.graph.get(lowerCAmelCase      ):
																snake_case        =     []

				def 						snake_case	(			self      ):






										"""simple docstring"""

										return list(self.graph      )

				def 						snake_case	(			self						,      lowerCAmelCase						,      lowerCAmelCase      ):






										"""simple docstring"""

										if self.graph.get(lowerCAmelCase      ):
																for _ in self.graph[u]:
																						if _[1] == v:
																												self.graph[u].remove(lowerCAmelCase      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										if s == d:
																return []
										snake_case        =     []
										snake_case        =     []
										if s == -2:
																snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     s

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if visited.count(node[1]      ) < 1:
																																		if node[1] == d:
																																								visited.append(lowerCAmelCase      )
																																								return visited
																																		else:
																																								stack.append(node[1]      )
																																								visited.append(node[1]      )
																																								snake_case        =     node[1]
																																								break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return visited

				def 						snake_case	(			self						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										if c == -1:
																snake_case        =     floor(random() * 1_00_00      ) + 10
										for i in range(lowerCAmelCase      ):
																# every vertex has max 100 edges
																for _ in range(floor(random() * 1_02      ) + 1      ):
																						snake_case        =     floor(random() * c      ) + 1
																						if n != i:
																												self.add_pair(lowerCAmelCase						,      lowerCAmelCase						,      1      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2      ):






										"""simple docstring"""

										snake_case        =     deque()
										snake_case        =     []
										if s == -2:
																snake_case        =     list(self.graph      )[0]
										d.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										while d:
																snake_case        =     d.popleft()
																if len(self.graph[s]      ) != 0:
																						for node in self.graph[s]:
																												if visited.count(node[1]      ) < 1:
																																		d.append(node[1]      )
																																		visited.append(node[1]      )
										return visited

				def 						snake_case	(			self						,      lowerCAmelCase      ):






										"""simple docstring"""

										snake_case        =     0
										for x in self.graph:
																for y in self.graph[x]:
																						if y[1] == u:
																												count += 1
										return count

				def 						snake_case	(			self						,      lowerCAmelCase      ):






										"""simple docstring"""

										return len(self.graph[u]      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2      ):






										"""simple docstring"""

										snake_case        =     []
										snake_case        =     []
										if s == -2:
																snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     s
										snake_case        =     []

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if visited.count(node[1]      ) < 1:
																																		stack.append(node[1]      )
																																		visited.append(node[1]      )
																																		snake_case        =     node[1]
																																		break

            # check if all the children are visited
																if s == ss:
																						sorted_nodes.append(stack.pop()      )
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return sorted_nodes

				def 						snake_case	(			self      ):






										"""simple docstring"""

										snake_case        =     []
										snake_case        =     []
										snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     -2
										snake_case        =     []
										snake_case        =     s
										snake_case        =     False
										snake_case        =     set()

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if (
																												    visited.count(node[1]      ) > 0
																												    and node[1] != parent
																												    and indirect_parents.count(node[1]      ) > 0
																												    and not on_the_way_back
																												):
																																		snake_case        =     len(lowerCAmelCase      ) - 1
																																		while len_stack >= 0:
																																								if stack[len_stack] == node[1]:
																																														anticipating_nodes.add(node[1]      )
																																														break
																																								else:
																																														anticipating_nodes.add(stack[len_stack]      )
																																														len_stack -= 1
																												if visited.count(node[1]      ) < 1:
																																		stack.append(node[1]      )
																																		visited.append(node[1]      )
																																		snake_case        =     node[1]
																																		break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						snake_case        =     True
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     False
																						indirect_parents.append(lowerCAmelCase      )
																						snake_case        =     s
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return list(lowerCAmelCase      )

				def 						snake_case	(			self      ):






										"""simple docstring"""

										snake_case        =     []
										snake_case        =     []
										snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     -2
										snake_case        =     []
										snake_case        =     s
										snake_case        =     False
										snake_case        =     set()

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if (
																												    visited.count(node[1]      ) > 0
																												    and node[1] != parent
																												    and indirect_parents.count(node[1]      ) > 0
																												    and not on_the_way_back
																												):
																																		snake_case        =     len(lowerCAmelCase      ) - 1
																																		while len_stack_minus_one >= 0:
																																								if stack[len_stack_minus_one] == node[1]:
																																														anticipating_nodes.add(node[1]      )
																																														break
																																								else:
																																														return True
																												if visited.count(node[1]      ) < 1:
																																		stack.append(node[1]      )
																																		visited.append(node[1]      )
																																		snake_case        =     node[1]
																																		break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						snake_case        =     True
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     False
																						indirect_parents.append(lowerCAmelCase      )
																						snake_case        =     s
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return False

				def 						snake_case	(			self						,      lowerCAmelCase=-2						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										snake_case        =     time()
										self.dfs(lowerCAmelCase						,      lowerCAmelCase      )
										snake_case        =     time()
										return end - begin

				def 						snake_case	(			self						,      lowerCAmelCase=-2      ):






										"""simple docstring"""

										snake_case        =     time()
										self.bfs(lowerCAmelCase      )
										snake_case        =     time()
										return end - begin





class 					lowerCAmelCase_      :



				"""simple docstring"""

				def __init__(			self      ):






										"""simple docstring"""

										snake_case        =     {}

				def 						snake_case	(			self						,      lowerCAmelCase						,      lowerCAmelCase						,      lowerCAmelCase=1      ):






										"""simple docstring"""

										if self.graph.get(lowerCAmelCase      ):
																# if there already is a edge
																if self.graph[u].count([w, v]      ) == 0:
																						self.graph[u].append([w, v]      )
										else:
																# if u does not exist
																snake_case        =     [[w, v]]
										# add the other way
										if self.graph.get(lowerCAmelCase      ):
																# if there already is a edge
																if self.graph[v].count([w, u]      ) == 0:
																						self.graph[v].append([w, u]      )
										else:
																# if u does not exist
																snake_case        =     [[w, u]]

				def 						snake_case	(			self						,      lowerCAmelCase						,      lowerCAmelCase      ):






										"""simple docstring"""

										if self.graph.get(lowerCAmelCase      ):
																for _ in self.graph[u]:
																						if _[1] == v:
																												self.graph[u].remove(lowerCAmelCase      )
        # the other way round
										if self.graph.get(lowerCAmelCase      ):
																for _ in self.graph[v]:
																						if _[1] == u:
																												self.graph[v].remove(lowerCAmelCase      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										if s == d:
																return []
										snake_case        =     []
										snake_case        =     []
										if s == -2:
																snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     s

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if visited.count(node[1]      ) < 1:
																																		if node[1] == d:
																																								visited.append(lowerCAmelCase      )
																																								return visited
																																		else:
																																								stack.append(node[1]      )
																																								visited.append(node[1]      )
																																								snake_case        =     node[1]
																																								break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return visited

				def 						snake_case	(			self						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										if c == -1:
																snake_case        =     floor(random() * 1_00_00      ) + 10
										for i in range(lowerCAmelCase      ):
																# every vertex has max 100 edges
																for _ in range(floor(random() * 1_02      ) + 1      ):
																						snake_case        =     floor(random() * c      ) + 1
																						if n != i:
																												self.add_pair(lowerCAmelCase						,      lowerCAmelCase						,      1      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2      ):






										"""simple docstring"""

										snake_case        =     deque()
										snake_case        =     []
										if s == -2:
																snake_case        =     list(self.graph      )[0]
										d.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										while d:
																snake_case        =     d.popleft()
																if len(self.graph[s]      ) != 0:
																						for node in self.graph[s]:
																												if visited.count(node[1]      ) < 1:
																																		d.append(node[1]      )
																																		visited.append(node[1]      )
										return visited

				def 						snake_case	(			self						,      lowerCAmelCase      ):






										"""simple docstring"""

										return len(self.graph[u]      )

				def 						snake_case	(			self      ):






										"""simple docstring"""

										snake_case        =     []
										snake_case        =     []
										snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     -2
										snake_case        =     []
										snake_case        =     s
										snake_case        =     False
										snake_case        =     set()

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if (
																												    visited.count(node[1]      ) > 0
																												    and node[1] != parent
																												    and indirect_parents.count(node[1]      ) > 0
																												    and not on_the_way_back
																												):
																																		snake_case        =     len(lowerCAmelCase      ) - 1
																																		while len_stack >= 0:
																																								if stack[len_stack] == node[1]:
																																														anticipating_nodes.add(node[1]      )
																																														break
																																								else:
																																														anticipating_nodes.add(stack[len_stack]      )
																																														len_stack -= 1
																												if visited.count(node[1]      ) < 1:
																																		stack.append(node[1]      )
																																		visited.append(node[1]      )
																																		snake_case        =     node[1]
																																		break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						snake_case        =     True
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     False
																						indirect_parents.append(lowerCAmelCase      )
																						snake_case        =     s
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return list(lowerCAmelCase      )

				def 						snake_case	(			self      ):






										"""simple docstring"""

										snake_case        =     []
										snake_case        =     []
										snake_case        =     list(self.graph      )[0]
										stack.append(lowerCAmelCase      )
										visited.append(lowerCAmelCase      )
										snake_case        =     -2
										snake_case        =     []
										snake_case        =     s
										snake_case        =     False
										snake_case        =     set()

										while True:
																# check if there is any non isolated nodes
																if len(self.graph[s]      ) != 0:
																						snake_case        =     s
																						for node in self.graph[s]:
																												if (
																												    visited.count(node[1]      ) > 0
																												    and node[1] != parent
																												    and indirect_parents.count(node[1]      ) > 0
																												    and not on_the_way_back
																												):
																																		snake_case        =     len(lowerCAmelCase      ) - 1
																																		while len_stack_minus_one >= 0:
																																								if stack[len_stack_minus_one] == node[1]:
																																														anticipating_nodes.add(node[1]      )
																																														break
																																								else:
																																														return True
																												if visited.count(node[1]      ) < 1:
																																		stack.append(node[1]      )
																																		visited.append(node[1]      )
																																		snake_case        =     node[1]
																																		break

            # check if all the children are visited
																if s == ss:
																						stack.pop()
																						snake_case        =     True
																						if len(lowerCAmelCase      ) != 0:
																												snake_case        =     stack[len(lowerCAmelCase      ) - 1]
																else:
																						snake_case        =     False
																						indirect_parents.append(lowerCAmelCase      )
																						snake_case        =     s
																						snake_case        =     ss

																# check if se have reached the starting point
																if len(lowerCAmelCase      ) == 0:
																						return False

				def 						snake_case	(			self      ):






										"""simple docstring"""

										return list(self.graph      )

				def 						snake_case	(			self						,      lowerCAmelCase=-2						,      lowerCAmelCase=-1      ):






										"""simple docstring"""

										snake_case        =     time()
										self.dfs(lowerCAmelCase						,      lowerCAmelCase      )
										snake_case        =     time()
										return end - begin

				def 						snake_case	(			self						,      lowerCAmelCase=-2      ):






										"""simple docstring"""

										snake_case        =     time()
										self.bfs(lowerCAmelCase      )
										snake_case        =     time()
										return end - begin



"""simple docstring"""
import argparse
import math
import traceback

import dateutil.parser as date_parser
import requests





def 				lowerCAmelCase__      (     _UpperCamelCase    :			Any   )   ->			int:





						"""simple docstring"""






						snake_case        =     {}

						snake_case        =     job['started_at']
						snake_case        =     job['completed_at']

						snake_case        =     date_parser.parse(_UpperCamelCase   )
						snake_case        =     date_parser.parse(_UpperCamelCase   )

						snake_case        =     round((end_datetime - start_datetime).total_seconds() / 60.0   )

						snake_case        =     start
						snake_case        =     end
						snake_case        =     duration_in_min

						return job_info





def 				lowerCAmelCase__      (     _UpperCamelCase    :			Dict	,     _UpperCamelCase    :			Any=None   )   ->			Union[str, Any]:





						"""simple docstring"""






						snake_case        =     None
						if token is not None:
												snake_case        =     {'Accept': 'application/vnd.github+json', 'Authorization': f"""Bearer {token}"""}

						snake_case        =     f"""https://api.github.com/repos/huggingface/transformers/actions/runs/{workflow_run_id}/jobs?per_page=100"""
						snake_case        =     requests.get(_UpperCamelCase	,     headers=_UpperCamelCase   ).json()
						snake_case        =     {}

						try:
												job_time.update({job['name']: extract_time_from_single_job(_UpperCamelCase   ) for job in result['jobs']}   )
												snake_case        =     math.ceil((result['total_count'] - 1_0_0) / 1_0_0   )

												for i in range(_UpperCamelCase   ):
																		snake_case        =     requests.get(url + f"""&page={i + 2}"""	,     headers=_UpperCamelCase   ).json()
																		job_time.update({job['name']: extract_time_from_single_job(_UpperCamelCase   ) for job in result['jobs']}   )

												return job_time
						except Exception:
												print(f"""Unknown error, could not fetch links:\n{traceback.format_exc()}"""   )

						return {}


if __name__ == "__main__":
					SCREAMING_SNAKE_CASE__   =					argparse.ArgumentParser()
					# Required parameters
					parser.add_argument("--workflow_run_id", type=str, required=True, help="A GitHub Actions workflow run id.")
					SCREAMING_SNAKE_CASE__   =					parser.parse_args()

					SCREAMING_SNAKE_CASE__   =					get_job_time(args.workflow_run_id)
					SCREAMING_SNAKE_CASE__   =					dict(sorted(job_time.items(), key=lambda item: item[1]["duration"], reverse=True))

					for k, v in job_time.items():
										print(f"""{k}: {v['duration']}""")


