graph-games-proto 0.3.2078__py3-none-any.whl → 0.3.2095__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
graph_games_proto/fns.py CHANGED
@@ -982,6 +982,38 @@ class GameConfig(PClass):
982
982
  fig=Fig.__fromdict__(d["fig"]),
983
983
  seed=d["seed"]
984
984
  )
985
+
986
+
987
+ class PublicGameConfig(PClass):
988
+ uuid = field(type=str)
989
+ started_at = field(type=str)
990
+ num_players = field(type=int)
991
+ fig = field(type=Fig)
992
+ def __todict__(self):
993
+ return {
994
+ "uuid": self.uuid,
995
+ "started_at": self.started_at,
996
+ "num_players": self.num_players,
997
+ "fig": self.fig.__todict__(),
998
+ }
999
+ @staticmethod
1000
+ def __fromdict__(d):
1001
+ return PublicGameConfig(
1002
+ uuid=d["uuid"],
1003
+ started_at=d["started_at"],
1004
+ num_players=d["num_players"],
1005
+ fig=Fig.__fromdict__(d["fig"]),
1006
+ )
1007
+
1008
+
1009
+ @dispatch(GameConfig)
1010
+ def getpublicgameconfig(game_config):
1011
+ return PublicGameConfig(
1012
+ uuid=game_config.uuid,
1013
+ started_at=game_config.started_at,
1014
+ num_players=game_config.num_players,
1015
+ fig=game_config.fig,
1016
+ )
985
1017
 
986
1018
 
987
1019
  class ActionDrawUnit:
@@ -1195,7 +1227,7 @@ class LegalActionKeep(PClass):
1195
1227
  num_cards = len(card_uuids_matching_deck)
1196
1228
  actual_min = 0 if legal_action.keep.min is None else legal_action.keep.min
1197
1229
  actual_max = num_cards if legal_action.keep.max is None else min(legal_action.keep.max, num_cards)
1198
- rand_num_chosen = state.rng.randint(actual_min, actual_max)
1230
+ rand_num_chosen = state.kernel.rng.randint(actual_min, actual_max)
1199
1231
  card_uuids = card_uuids_matching_deck[0:rand_num_chosen]
1200
1232
  return Action2(
1201
1233
  submitted_at=submitted_at,
@@ -1236,7 +1268,7 @@ class LegalActionDiscard(PClass):
1236
1268
  num_cards = len(card_uuids_matching_deck)
1237
1269
  actual_min = 0 if legal_action.discard.min is None else legal_action.discard.min
1238
1270
  actual_max = num_cards if legal_action.discard.max is None else min(legal_action.discard.max, num_cards)
1239
- rand_num_chosen = state.rng.randint(actual_min, actual_max)
1271
+ rand_num_chosen = state.kernel.rng.randint(actual_min, actual_max)
1240
1272
  card_uuids = card_uuids_matching_deck[0:rand_num_chosen]
1241
1273
  return Action2(
1242
1274
  submitted_at=submitted_at,
@@ -1809,13 +1841,11 @@ def init_segment_record(segment: Segment2) -> SegmentRecord:
1809
1841
 
1810
1842
 
1811
1843
  class Path2(PClass):
1812
- uuid = field(type=str)
1813
1844
  idx = field(type=int)
1814
1845
  edge_uuid = field(type=str)
1815
1846
  segments = field(type=list) # List[Segment]
1816
1847
  def __todict__(self):
1817
1848
  return {
1818
- "uuid": self.uuid,
1819
1849
  "idx": self.idx,
1820
1850
  "edge_uuid": self.edge_uuid,
1821
1851
  "segments": [segment.__todict__() for segment in self.segments],
@@ -1823,7 +1853,6 @@ class Path2(PClass):
1823
1853
  @staticmethod
1824
1854
  def __fromdict__(d):
1825
1855
  return Path2(
1826
- uuid=d["uuid"],
1827
1856
  idx=d["idx"],
1828
1857
  edge_uuid=d["edge_uuid"],
1829
1858
  segments=[Segment2.__fromdict__(segment) for segment in d["segments"]],
@@ -1831,13 +1860,11 @@ class Path2(PClass):
1831
1860
 
1832
1861
 
1833
1862
  class PathRecord(PClass):
1834
- uuid = field(type=str)
1835
1863
  idx = field(type=int)
1836
1864
  edge_uuid = field(type=str)
1837
1865
  segment_uuids = field(type=list) # List[str]
1838
1866
  def __todict__(self):
1839
1867
  return {
1840
- "uuid": self.uuid,
1841
1868
  "idx": self.idx,
1842
1869
  "edge_uuid": self.edge_uuid,
1843
1870
  "segment_uuids": self.segment_uuids,
@@ -1845,7 +1872,6 @@ class PathRecord(PClass):
1845
1872
  @staticmethod
1846
1873
  def __fromdict__(d):
1847
1874
  return PathRecord(
1848
- uuid=d["uuid"],
1849
1875
  idx=d["idx"],
1850
1876
  edge_uuid=d["edge_uuid"],
1851
1877
  segment_uuids=d["segment_uuids"],
@@ -1854,7 +1880,6 @@ class PathRecord(PClass):
1854
1880
 
1855
1881
  def init_path_record(path: Path2) -> PathRecord:
1856
1882
  return PathRecord(
1857
- uuid=path.uuid,
1858
1883
  idx=path.idx,
1859
1884
  edge_uuid=path.edge_uuid,
1860
1885
  segment_uuids=[segment.uuid for segment in path.segments],
@@ -2052,8 +2077,8 @@ class BonusStatus(PClass):
2052
2077
 
2053
2078
 
2054
2079
  class StateKernel(PClass):
2055
- rng = field(type=random.Random)
2056
2080
  game_config = field(type=GameConfig)
2081
+ rng = field(type=random.Random)
2057
2082
 
2058
2083
  uuid2edgerecord = field(type=dict) # Dict[str, BiEdgeRecord]
2059
2084
  uuid2segmentrecord = field(type=dict) # Dict[str, SegmentRecord]
@@ -2081,8 +2106,8 @@ class StateKernel(PClass):
2081
2106
  player_graphs_3 = field(type=list) # List[PlayerGraph]
2082
2107
  def __todict__(self):
2083
2108
  return {
2084
- "rng": rng2json(self.rng),
2085
2109
  "game_config": self.game_config.__todict__(),
2110
+ "rng": rng2json(self.rng),
2086
2111
  "edges": [edge.__todict__() for edge in self.edges],
2087
2112
  "nodes": [node.__todict__() for node in self.nodes],
2088
2113
  "regions": [region.__todict__() for region in self.regions],
@@ -2110,8 +2135,8 @@ class StateKernel(PClass):
2110
2135
  @staticmethod
2111
2136
  def __fromdict__(d):
2112
2137
  return StateKernel(
2113
- rng=json2rng(d["rng"]),
2114
2138
  game_config=GameConfig.__fromdict__(d["game_config"]),
2139
+ rng=json2rng(d["rng"]),
2115
2140
  edges=[BiEdge.__fromdict__(edge) for edge in d["edges"]],
2116
2141
  nodes=[Node.__fromdict__(n) for n in d["nodes"]],
2117
2142
  regions=[Region.__fromdict__(r) for r in d["regions"]],
@@ -2138,13 +2163,15 @@ class StateKernel(PClass):
2138
2163
  )
2139
2164
 
2140
2165
 
2141
- def init_state_kernel(**kwargs):
2142
- rng = kwargs.get('rng')
2143
- game_config = kwargs.get('game_config')
2144
- fig = game_config.fig
2145
- board_config = fig.board_config
2146
- nodes = kwargs.get('nodes', [])
2147
- edges = kwargs.get('edges', [])
2166
+ def init_state_kernel(game_config, **kwargs):
2167
+ board_config = game_config.fig.board_config
2168
+ nodes = kwargs.get('nodes', get_nodes(board_config))
2169
+ nodeuuid2idx = {node.uuid: idx for idx, node in enumerate(nodes)}
2170
+ edges = get_edges(board_config, nodeuuid2idx)
2171
+ segments = kwargs.get('segments', get_segments(board_config))
2172
+ goals = board_config.goals
2173
+ regions = kwargs.get('regions', [])
2174
+
2148
2175
  idx2pathrecord = []
2149
2176
  edgeuuid2idx = {edge.uuid: idx for idx, edge in enumerate(edges)}
2150
2177
  for edge in edges:
@@ -2166,8 +2193,18 @@ def init_state_kernel(**kwargs):
2166
2193
  carduuid2card[card.uuid] = card
2167
2194
  carduuid2deckidx[card.uuid] = dek.idx
2168
2195
 
2169
- nodeuuid2idx = {node.uuid: idx for idx, node in enumerate(board_config.points)}
2170
- edges = get_edges(rng, board_config, nodeuuid2idx)
2196
+ starting_piles = []
2197
+ for piece_template in board_config.piece_templates:
2198
+ if piece_template.has_player:
2199
+ for player_idx in range(game_config.num_players):
2200
+ pieces = generate_pieces(piece_template, player_idx)
2201
+ pile = Pile(
2202
+ player_idx=player_idx,
2203
+ num_pieces=piece_template.quantity,
2204
+ pieces=[piece.uuid for piece in pieces],
2205
+ )
2206
+ starting_piles.append(pile)
2207
+
2171
2208
  edgetuple2uuid = {}
2172
2209
  for edge in edges:
2173
2210
  node_1_idx = nodeuuid2idx[edge.node_1_uuid]
@@ -2175,27 +2212,42 @@ def init_state_kernel(**kwargs):
2175
2212
  edge_tuple = (min(node_1_idx, node_2_idx), max(node_1_idx, node_2_idx))
2176
2213
  edgetuple2uuid[edge_tuple] = edge.uuid
2177
2214
 
2178
- bonuses = game_config.fig.board_config.bonuses
2215
+ bonuses = board_config.bonuses
2179
2216
  bonusuuid2bonusidx = {bonus.uuid: idx for idx, bonus in enumerate(bonuses)}
2180
2217
 
2181
- player_graphs_3 = calc_player_graphs3(nodes, edges, pieceuuid2piece, game_config)
2218
+ player_graphs_3 = calc_player_graphs3(nodes, edges, pieceuuid2piece, game_config.num_players)
2182
2219
 
2183
- segments = kwargs.get('segments', [])
2184
-
2185
2220
  uuid2segmentrecord = {segment.uuid: init_segment_record(segment) for segment in segments}
2186
2221
  uuid2edgerecord = {edge.uuid: init_biedge_record(edge) for edge in edges}
2187
2222
 
2223
+ starting_decks = []
2224
+ for dek in board_config.deks:
2225
+ cards = generate_cards(dek)
2226
+ deck_obj = Deck(
2227
+ uuid=dek.uuid,
2228
+ idx=dek.idx,
2229
+ units=[],
2230
+ faceup_spots=[],
2231
+ discard=[],
2232
+ facedown_stack=[card.uuid for card in cards],
2233
+ )
2234
+ starting_decks.append(deck_obj)
2235
+
2236
+ default_players = [
2237
+ Player(idx=idx, pieces=[], cards=[], discard_tray=[]) for idx in range(game_config.num_players)
2238
+ ]
2239
+
2188
2240
  return StateKernel(
2189
- rng=rng,
2190
2241
  game_config=game_config,
2191
- edges=edges,
2192
- nodes=kwargs.get('nodes', []),
2193
- regions=kwargs.get('regions', []),
2194
- decks=kwargs.get('decks', []),
2195
- piles=kwargs.get('piles', []),
2196
- players=kwargs.get('players'),
2197
- player_idxs=kwargs.get('player_idxs'),
2242
+ rng=getrng(game_config.seed),
2243
+ decks=kwargs.get('decks', starting_decks),
2244
+ piles=kwargs.get('piles', starting_piles),
2245
+ players=kwargs.get('players', default_players),
2246
+ player_idxs=kwargs.get('player_idxs', list(range(game_config.num_players))),
2198
2247
  history=kwargs.get('history', []),
2248
+ edges=edges,
2249
+ nodes=nodes,
2250
+ regions=regions,
2199
2251
  uuid2edgerecord=uuid2edgerecord,
2200
2252
  uuid2segmentrecord=uuid2segmentrecord,
2201
2253
  idx2pathrecord=idx2pathrecord,
@@ -2206,9 +2258,9 @@ def init_state_kernel(**kwargs):
2206
2258
  nodeuuid2idx=nodeuuid2idx,
2207
2259
  carduuid2deckidx=carduuid2deckidx,
2208
2260
  bonusuuid2bonusidx=bonusuuid2bonusidx,
2209
- starting_decks=kwargs.get('starting_decks', []),
2210
- starting_piles=kwargs.get('starting_piles', []),
2211
- goals=kwargs.get('goals', []),
2261
+ starting_decks=starting_decks,
2262
+ starting_piles=starting_piles,
2263
+ goals=goals,
2212
2264
  player_graphs_3=player_graphs_3,
2213
2265
  )
2214
2266
 
@@ -2474,6 +2526,7 @@ class RemainingAllottedTime(PClass):
2474
2526
 
2475
2527
 
2476
2528
  class PublicState(PClass):
2529
+ game_config = field(type=PublicGameConfig)
2477
2530
  deadlines = field(type=list) # List[RemainingAllottedTime|None]
2478
2531
  game_started_at = field(type=str)
2479
2532
  allotted_times = field(type=list)
@@ -2614,7 +2667,7 @@ def get_segments(board_config):
2614
2667
  return segments
2615
2668
 
2616
2669
 
2617
- def get_edges(rng, board_config, nodeuuid2idx):
2670
+ def get_edges(board_config, nodeuuid2idx):
2618
2671
  edges = []
2619
2672
 
2620
2673
 
@@ -2630,7 +2683,6 @@ def get_edges(rng, board_config, nodeuuid2idx):
2630
2683
  Segment2(uuid=s.uuid, unit_uuid=s.unit_uuid, pieces=[]) for s in matching_board_path.path.segments
2631
2684
  ]
2632
2685
  path = Path2(
2633
- uuid=str(generate_uuid_with_rng(rng)),
2634
2686
  idx=path_idx,
2635
2687
  edge_uuid=link.uuid,
2636
2688
  segments=segments,
@@ -2707,97 +2759,8 @@ def getsettingvalue(s, setting_name):
2707
2759
 
2708
2760
  @dispatch(GameConfig)
2709
2761
  def getinitialstate(game_config):
2710
- rng = getrng(game_config.seed)
2711
- board_config = game_config.fig.board_config
2712
- nodes = get_nodes(board_config)
2713
-
2714
- piles = []
2715
- for piece_template in board_config.piece_templates:
2716
- if piece_template.has_player:
2717
- for player_idx in range(game_config.num_players):
2718
- pieces = generate_pieces(piece_template, player_idx)
2719
- pile = Pile(
2720
- player_idx=player_idx,
2721
- num_pieces=piece_template.quantity,
2722
- pieces=[piece.uuid for piece in pieces],
2723
- )
2724
- piles.append(pile)
2725
-
2726
- decks = []
2727
- for dek in board_config.deks:
2728
- cards = generate_cards(dek)
2729
- deck_obj = Deck(
2730
- uuid=dek.uuid,
2731
- idx=dek.idx,
2732
- units=[],
2733
- faceup_spots=[],
2734
- discard=[],
2735
- facedown_stack=[card.uuid for card in cards],
2736
- )
2737
- decks.append(deck_obj)
2738
-
2739
- # bonuses = game_config.fig.board_config.bonuses
2740
- # bonus_statuses = [
2741
- # BonusStatus(
2742
- # bonus_uuid=bonus.uuid,
2743
- # winners=[],
2744
- # player_statuses=[
2745
- # BonusPlayerStatus(
2746
- # player_idx=player_idx,
2747
- # score=0,
2748
- # longest_trail=None,
2749
- # )
2750
- # for player_idx in range(game_config.num_players)
2751
- # ]
2752
- # )
2753
- # for bonus in bonuses
2754
- # ]
2755
-
2756
- # state = State(
2757
- # bonus_statuses=bonus_statuses,
2758
- # history=[],
2759
- # player_scores=[PlayerScore2(public_items=[], private_items=[]) for _ in range(game_config.num_players)],
2760
- # player_graphs=[
2761
- # PlayerGraph(
2762
- # player_idx=player_idx,
2763
- # neighbors=[[] for _ in range(len(nodes))]
2764
- # ) for player_idx in range(game_config.num_players)
2765
- # ],
2766
- # nodes = nodes,
2767
- # edges = edges,
2768
- # regions = get_regions(board_config),
2769
- # legal_actions_3=[],
2770
- # piles=piles,
2771
- # players=[Player(idx=idx, pieces=[], cards=[], discard_tray=[]) for idx in range(game_config.num_players)],
2772
- # player_idxs=list(range(game_config.num_players)),
2773
- # decks=decks,
2774
- # rng=rng,
2775
- # last_to_play=None,
2776
- # winners=[],
2777
- # )
2778
-
2779
- nodeuuid2idx = {node.uuid: idx for idx, node in enumerate(board_config.points)}
2780
- edges = get_edges(rng, board_config, nodeuuid2idx)
2781
-
2782
- kernel = init_state_kernel(
2783
- rng=rng,
2784
- game_config=game_config,
2785
- segments=get_segments(board_config),
2786
- edges=edges,
2787
- nodes=nodes,
2788
- decks=decks,
2789
- piles=piles,
2790
- players=[Player(idx=idx, pieces=[], cards=[], discard_tray=[]) for idx in range(game_config.num_players)],
2791
- player_idxs=list(range(game_config.num_players)),
2792
- history=[],
2793
- player_scores=[PlayerScore2(public_items=[], private_items=[]) for _ in range(game_config.num_players)],
2794
- starting_decks=[Deck.__fromdict__(x.__todict__()) for x in decks],
2795
- starting_piles=[Pile.__fromdict__(x.__todict__()) for x in piles],
2796
- goals=board_config.goals,
2797
- )
2798
-
2762
+ kernel = init_state_kernel(game_config)
2799
2763
  kernel = run_kernel_hooks(kernel, INITIALIZATION_HOOKS, True)
2800
-
2801
2764
  return init_memoized_state(kernel)
2802
2765
 
2803
2766
 
@@ -3749,18 +3712,17 @@ def calc_player_graph3(nodes, edges, pieceuuid2piece, player_idx):
3749
3712
 
3750
3713
 
3751
3714
  def calc_player_graphs(state):
3752
- game_config = state.kernel.game_config
3753
3715
  return [
3754
3716
  calc_player_graph(state, player_idx)
3755
- for player_idx in range(game_config.num_players)
3717
+ for player_idx in range(state.kernel.game_config.num_players)
3756
3718
  ]
3757
3719
 
3758
3720
 
3759
- @dispatch(list, list, dict, GameConfig)
3760
- def calc_player_graphs3(nodes, edges, pieceuuid2piece, game_config):
3721
+ @dispatch(list, list, dict, int)
3722
+ def calc_player_graphs3(nodes, edges, pieceuuid2piece, num_players):
3761
3723
  return [
3762
3724
  calc_player_graph3(nodes, edges, pieceuuid2piece, player_idx)
3763
- for player_idx in range(game_config.num_players)
3725
+ for player_idx in range(num_players)
3764
3726
  ]
3765
3727
 
3766
3728
 
@@ -4595,7 +4557,7 @@ def get_deadline(s, max_allotted_time):
4595
4557
  since_action_idx = max_allotted_time.since_action_idx
4596
4558
  if since_action_idx == -1:
4597
4559
  allotted_since = datetime.strptime(
4598
- s.kernel.game_config.started_at,
4560
+ s.kernel.started_at,
4599
4561
  "%Y-%m-%d %H:%M:%S"
4600
4562
  )
4601
4563
  else:
@@ -4676,21 +4638,23 @@ def imagine_decks(public_state, private_state):
4676
4638
 
4677
4639
 
4678
4640
  def imagine_state(public_state, private_state):
4679
- game_config = public_state.game_config
4641
+ public_game_config = public_state.game_config
4642
+
4680
4643
  imagined_kernel = init_state_kernel(
4681
- rng=random.Random(),
4682
- game_config=game_config,
4644
+ GameConfig(
4645
+ seed=random.randint(0, 2**31 - 1),
4646
+ uuid=public_game_config.uuid,
4647
+ num_players=public_game_config.num_players,
4648
+ fig=public_game_config.fig,
4649
+ started_at=public_game_config.started_at,
4650
+ ),
4683
4651
  edges=public_state.edges,
4684
4652
  nodes=public_state.nodes,
4685
4653
  piles=public_state.piles,
4654
+ player_idxs=public_state.player_idxs,
4686
4655
  decks=imagine_decks(public_state, private_state),
4687
4656
  players=imagine_players(public_state, private_state),
4688
- player_idxs=public_state.player_idxs,
4689
4657
  history=imagine_history(public_state, private_state),
4690
- player_scores=imagine_player_scores(public_state, private_state),
4691
- starting_decks=[Deck.__fromdict__(x.__todict__()) for x in decks],
4692
- starting_piles=[Pile.__fromdict__(x.__todict__()) for x in public_state.piles],
4693
- goals=game_config.fig.board_config.goals,
4694
4658
  )
4695
4659
  return init_memoized_state(imagined_kernel)
4696
4660
 
@@ -4723,7 +4687,6 @@ def getpublicstate(s):
4723
4687
  )
4724
4688
  paths.append(
4725
4689
  Path2(
4726
- uuid=path_record.uuid,
4727
4690
  edge_uuid=path_record.edge_uuid,
4728
4691
  segments=segments,
4729
4692
  idx=path_record.idx
@@ -4748,8 +4711,9 @@ def getpublicstate(s):
4748
4711
 
4749
4712
 
4750
4713
  return PublicState(
4714
+ game_config=getpublicgameconfig(s.kernel.game_config),
4751
4715
  deadlines=get_deadlines(s),
4752
- game_started_at=s.kernel.game_config.started_at,
4716
+ game_started_at=s.kernel.started_at,
4753
4717
  allotted_times=get_max_allotted_times(s),
4754
4718
  all_pieces=list(s.kernel.pieceuuid2piece.values()),
4755
4719
  to_play_2=getpublictoplay(s),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graph_games_proto
3
- Version: 0.3.2078
3
+ Version: 0.3.2095
4
4
  Requires-Dist: multipledispatch==1.0.0
5
5
  Requires-Dist: pyrsistent==0.20.0
6
6
  Requires-Dist: numpy==2.2.4
@@ -1,9 +1,9 @@
1
1
  graph_games_proto/__init__.py,sha256=_EVQR-51XehfH45XZlba1WPdx3omS3Gm1nTwrgGyn2Q,667
2
2
  graph_games_proto/all_types.py,sha256=IpbwftEcHS5Ewz-saFNk0lO9FvcbuHG36odRTayCXUk,54911
3
- graph_games_proto/fns.py,sha256=_1ih4jhg9LtO2OTx5Bo3Xa5G7o43XWEa1jFty_f1lF0,201156
3
+ graph_games_proto/fns.py,sha256=aq2Vxkuz1J4LGAPlO8OZtW1Tns81gL68UICMfsZzeHY,199556
4
4
  graph_games_proto/main.py,sha256=fj2U7KcwrpZtuUhjOX5yVxY18LZvvsxDFYZ_S5mxe04,145
5
5
  graph_games_proto/state.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- graph_games_proto-0.3.2078.dist-info/METADATA,sha256=45PxNh56O2ygcfAq64cbl5dlm4if0pHZURIMCkBCPfU,188
7
- graph_games_proto-0.3.2078.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
- graph_games_proto-0.3.2078.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
- graph_games_proto-0.3.2078.dist-info/RECORD,,
6
+ graph_games_proto-0.3.2095.dist-info/METADATA,sha256=3B4hZJi4LhHbTKGGFf-y7t0nTc0sQ-w_1rPTCZ0-jyA,188
7
+ graph_games_proto-0.3.2095.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
+ graph_games_proto-0.3.2095.dist-info/top_level.txt,sha256=-4QSrBMf_MM4BGsr2QXBpqDx8c8k_OPnzGyFjqjakes,18
9
+ graph_games_proto-0.3.2095.dist-info/RECORD,,