math-spec-mapping 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- Classes/Block.py +17 -0
- Classes/BoundaryAction.py +4 -14
- Classes/ControlAction.py +7 -14
- Classes/MathSpec.py +13 -0
- Classes/Mechanism.py +4 -12
- Classes/Policy.py +7 -19
- Classes/Space.py +7 -0
- Classes/__init__.py +2 -1
- Load/action_transmission_channel.py +7 -5
- Load/boundary_actions.py +7 -3
- Load/control_actions.py +4 -1
- Load/general.py +2 -0
- Load/load.py +1 -1
- Load/mechanism.py +4 -2
- Load/policy.py +5 -2
- Load/spaces.py +17 -1
- Load/state_update_transmission_channels.py +11 -7
- Reports/html.py +2 -2
- Reports/mechanisms.py +4 -4
- Reports/node_map.py +12 -18
- Reports/policies.py +6 -6
- Reports/spaces.py +6 -4
- Reports/state.py +9 -5
- {math_spec_mapping-0.1.1.dist-info → math_spec_mapping-0.1.3.dist-info}/METADATA +2 -2
- math_spec_mapping-0.1.3.dist-info/RECORD +48 -0
- math_spec_mapping-0.1.1.dist-info/RECORD +0 -46
- {math_spec_mapping-0.1.1.dist-info → math_spec_mapping-0.1.3.dist-info}/LICENSE +0 -0
- {math_spec_mapping-0.1.1.dist-info → math_spec_mapping-0.1.3.dist-info}/WHEEL +0 -0
- {math_spec_mapping-0.1.1.dist-info → math_spec_mapping-0.1.3.dist-info}/top_level.txt +0 -0
Classes/Block.py
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
|
3
|
+
|
4
|
+
class Block:
|
5
|
+
def __init__(self, data: Dict):
|
6
|
+
self.name = data["name"]
|
7
|
+
self.description = data["description"]
|
8
|
+
self.constraints = data["constraints"]
|
9
|
+
self.domain = data["domain"]
|
10
|
+
self.codomain = data["codomain"]
|
11
|
+
self.parameters_used = data["parameters_used"]
|
12
|
+
if "label" in data:
|
13
|
+
self.label = data["label"]
|
14
|
+
else:
|
15
|
+
self.label = self.name
|
16
|
+
self.called_by = []
|
17
|
+
self.calls = []
|
Classes/BoundaryAction.py
CHANGED
@@ -1,25 +1,15 @@
|
|
1
1
|
from typing import Dict
|
2
|
+
from .Block import Block
|
2
3
|
|
3
4
|
|
4
|
-
class BoundaryAction:
|
5
|
-
|
5
|
+
class BoundaryAction(Block):
|
6
6
|
def __init__(self, data: Dict):
|
7
|
-
|
8
|
-
|
9
|
-
self.constraints = data["constraints"]
|
7
|
+
data["domain"] = None
|
8
|
+
super().__init__(data)
|
10
9
|
self.boundary_action_options = data["boundary_action_options"]
|
11
|
-
self.called_by = data["called_by"]
|
12
|
-
self.codomain = data["codomain"]
|
13
|
-
self.parameters_used = data["parameters_used"]
|
14
|
-
if "label" in data:
|
15
|
-
self.label = data["label"]
|
16
|
-
else:
|
17
|
-
self.label = self.name
|
18
|
-
self.calls = []
|
19
10
|
|
20
11
|
|
21
12
|
class BoundaryActionOption:
|
22
|
-
|
23
13
|
def __init__(self, data: Dict):
|
24
14
|
self.name = data["name"]
|
25
15
|
self.description = data["description"]
|
Classes/ControlAction.py
CHANGED
@@ -1,23 +1,16 @@
|
|
1
1
|
from typing import Dict
|
2
|
+
from .Block import Block
|
2
3
|
|
3
4
|
|
4
|
-
class ControlAction:
|
5
|
-
|
5
|
+
class ControlAction(Block):
|
6
6
|
def __init__(self, data: Dict):
|
7
|
-
|
8
|
-
|
9
|
-
self.constraints = data["constraints"]
|
7
|
+
data["domain"] = None
|
8
|
+
super().__init__(data)
|
10
9
|
self.control_action_options = data["control_action_options"]
|
11
|
-
self.codomain = data["codomain"]
|
12
|
-
self.parameters_used = data["parameters_used"]
|
13
|
-
if "label" in data:
|
14
|
-
self.label = data["label"]
|
15
|
-
else:
|
16
|
-
self.label = self.name
|
17
|
-
self.calls = []
|
18
10
|
|
19
11
|
|
20
12
|
class ControlActionOption:
|
21
|
-
|
22
13
|
def __init__(self, data: Dict):
|
23
|
-
|
14
|
+
self.name = data["name"]
|
15
|
+
self.description = data["description"]
|
16
|
+
self.logic = data["logic"]
|
Classes/MathSpec.py
CHANGED
@@ -28,6 +28,19 @@ class MathSpec:
|
|
28
28
|
self._check_parameters()
|
29
29
|
self._crawl_parameters()
|
30
30
|
self._crawl_parameters_exploded()
|
31
|
+
self._check_dictionary_names()
|
32
|
+
|
33
|
+
def _check_dictionary_names(self):
|
34
|
+
for key in self.boundary_actions:
|
35
|
+
assert key == self.boundary_actions[key].name
|
36
|
+
for key in self.control_actions:
|
37
|
+
assert key == self.control_actions[key].name
|
38
|
+
for key in self.entities:
|
39
|
+
assert key == self.entities[key].name
|
40
|
+
for key in self.mechanisms:
|
41
|
+
assert key == self.mechanisms[key].name
|
42
|
+
for key in self.policies:
|
43
|
+
assert key == self.policies[key].name
|
31
44
|
|
32
45
|
def _check_parameters(self):
|
33
46
|
for ba in self.boundary_actions.values():
|
Classes/Mechanism.py
CHANGED
@@ -1,18 +1,10 @@
|
|
1
1
|
from typing import Dict
|
2
|
+
from .Block import Block
|
2
3
|
|
3
4
|
|
4
|
-
class Mechanism:
|
5
|
-
|
5
|
+
class Mechanism(Block):
|
6
6
|
def __init__(self, data: Dict):
|
7
|
-
|
8
|
-
|
9
|
-
self.constraints = data["constraints"]
|
7
|
+
data["codomain"] = None
|
8
|
+
super().__init__(data)
|
10
9
|
self.logic = data["logic"]
|
11
|
-
self.domain = data["domain"]
|
12
|
-
self.parameters_used = data["parameters_used"]
|
13
|
-
if "label" in data:
|
14
|
-
self.label = data["label"]
|
15
|
-
else:
|
16
|
-
self.label = self.name
|
17
|
-
self.called_by = []
|
18
10
|
self.updates = []
|
Classes/Policy.py
CHANGED
@@ -1,27 +1,15 @@
|
|
1
|
-
from typing import Dict
|
1
|
+
from typing import Dict, List
|
2
|
+
from .Block import Block
|
2
3
|
|
3
4
|
|
4
|
-
class
|
5
|
-
|
5
|
+
class PolicyOption:
|
6
6
|
def __init__(self, data: Dict):
|
7
7
|
self.name = data["name"]
|
8
8
|
self.description = data["description"]
|
9
|
-
self.
|
10
|
-
self.policy_options = data["policy_options"]
|
11
|
-
self.domain = data["domain"]
|
12
|
-
self.codomain = data["codomain"]
|
13
|
-
self.parameters_used = data["parameters_used"]
|
14
|
-
if "label" in data:
|
15
|
-
self.label = data["label"]
|
16
|
-
else:
|
17
|
-
self.label = self.name
|
18
|
-
self.called_by = []
|
19
|
-
self.calls = []
|
20
|
-
|
9
|
+
self.logic = data["logic"]
|
21
10
|
|
22
|
-
class PolicyOption:
|
23
11
|
|
12
|
+
class Policy(Block):
|
24
13
|
def __init__(self, data: Dict):
|
25
|
-
|
26
|
-
self.
|
27
|
-
self.logic = data["logic"]
|
14
|
+
super().__init__(data)
|
15
|
+
self.policy_options: List[PolicyOption] = data["policy_options"]
|
Classes/Space.py
ADDED
Classes/__init__.py
CHANGED
@@ -8,4 +8,5 @@ from .Parameter import Parameter, ParameterSet, ParameterContainer
|
|
8
8
|
from .Policy import Policy, PolicyOption
|
9
9
|
from .StateUpdateTransmissionChannel import StateUpdateTransmissionChannel
|
10
10
|
from .StatefulMetric import StatefulMetric, StatefulMetricSet
|
11
|
-
from .ControlAction import ControlAction, ControlActionOption
|
11
|
+
from .ControlAction import ControlAction, ControlActionOption
|
12
|
+
from .Space import Space
|
@@ -3,7 +3,9 @@ from ..Classes import ActionTransmissionChannel
|
|
3
3
|
from .general import check_json_keys
|
4
4
|
|
5
5
|
|
6
|
-
def convert_action_transmission_channel(
|
6
|
+
def convert_action_transmission_channel(
|
7
|
+
data: Dict, ms: Dict
|
8
|
+
) -> ActionTransmissionChannel:
|
7
9
|
"""Function to convert dictionary to action transmission channel
|
8
10
|
|
9
11
|
Args:
|
@@ -20,6 +22,8 @@ def convert_action_transmission_channel(data: Dict, ms: Dict) -> ActionTransmiss
|
|
20
22
|
# Copy
|
21
23
|
data = data.copy()
|
22
24
|
|
25
|
+
data["space"] = ms["Spaces"][data["space"]]
|
26
|
+
|
23
27
|
# Assert that the origin is in the math spec and only once then convert
|
24
28
|
origin = data["origin"]
|
25
29
|
is_boundary = origin in ms["Boundary Actions"]
|
@@ -46,10 +50,8 @@ def convert_action_transmission_channel(data: Dict, ms: Dict) -> ActionTransmiss
|
|
46
50
|
data["target"] = ms["Mechanisms"][target]
|
47
51
|
|
48
52
|
# Add in called by and called here with origin and target
|
49
|
-
data["origin"].calls.append(
|
50
|
-
|
51
|
-
data["target"].called_by.append(
|
52
|
-
(data["origin"], data["optional"], data["space"]))
|
53
|
+
data["origin"].calls.append((data["target"], data["optional"], data["space"]))
|
54
|
+
data["target"].called_by.append((data["origin"], data["optional"], data["space"]))
|
53
55
|
|
54
56
|
# Build the action transmission channel object
|
55
57
|
return ActionTransmissionChannel(data)
|
Load/boundary_actions.py
CHANGED
@@ -30,10 +30,13 @@ def convert_boundary_action(data: Dict, ms: Dict) -> BoundaryAction:
|
|
30
30
|
# Assert that the entities in called_by are in math spec
|
31
31
|
if data["called_by"]:
|
32
32
|
for name in data["called_by"]:
|
33
|
-
assert
|
34
|
-
name
|
33
|
+
assert (
|
34
|
+
name in ms["Entities"]
|
35
|
+
), "{} entity not in entities dictionary".format(name)
|
35
36
|
data["called_by"] = [ms["Entities"][x] for x in data["called_by"]]
|
36
37
|
|
38
|
+
data["codomain"] = (ms["Spaces"][x] for x in data["codomain"])
|
39
|
+
|
37
40
|
# Build the boundary action object
|
38
41
|
return BoundaryAction(data)
|
39
42
|
|
@@ -49,6 +52,7 @@ def load_boundary_actions(ms: Dict, json: Dict) -> None:
|
|
49
52
|
ms["Boundary Actions"] = {}
|
50
53
|
for key in json["Boundary Actions"]:
|
51
54
|
ms["Boundary Actions"][key] = convert_boundary_action(
|
52
|
-
json["Boundary Actions"][key], ms
|
55
|
+
json["Boundary Actions"][key], ms
|
56
|
+
)
|
53
57
|
for entity in ms["Boundary Actions"][key].called_by:
|
54
58
|
entity.add_boundary_action(ms["Boundary Actions"][key])
|
Load/control_actions.py
CHANGED
@@ -27,6 +27,8 @@ def convert_control_action(data: Dict, ms: Dict) -> ControlAction:
|
|
27
27
|
new_cao.append(ControlActionOption(ca))
|
28
28
|
data["control_action_options"] = new_cao
|
29
29
|
|
30
|
+
data["codomain"] = (ms["Spaces"][x] for x in data["codomain"])
|
31
|
+
|
30
32
|
# Build the control action object
|
31
33
|
return ControlAction(data)
|
32
34
|
|
@@ -42,4 +44,5 @@ def load_control_actions(ms: Dict, json: Dict) -> None:
|
|
42
44
|
ms["Control Actions"] = {}
|
43
45
|
for key in json["Control Actions"]:
|
44
46
|
ms["Control Actions"][key] = convert_control_action(
|
45
|
-
json["Control Actions"][key], ms
|
47
|
+
json["Control Actions"][key], ms
|
48
|
+
)
|
Load/general.py
CHANGED
@@ -87,6 +87,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
|
|
87
87
|
"codomain",
|
88
88
|
"parameters_used",
|
89
89
|
],
|
90
|
+
"Control Action Option": ["name", "description", "logic"],
|
90
91
|
"Boundary Action Option": ["name", "description", "logic"],
|
91
92
|
"Parameter Set": ["name", "notes", "parameters"],
|
92
93
|
"Parameter": [
|
@@ -97,6 +98,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
|
|
97
98
|
"domain",
|
98
99
|
"parameter_class",
|
99
100
|
],
|
101
|
+
"Space": ["name", "schema"],
|
100
102
|
}
|
101
103
|
|
102
104
|
check_set = check_sets[check_set_key]
|
Load/load.py
CHANGED
@@ -30,6 +30,7 @@ def load_from_json(json: Dict) -> MathSpec:
|
|
30
30
|
ms = {}
|
31
31
|
|
32
32
|
# Do loading one by one to transfer the json
|
33
|
+
load_spaces(ms, json)
|
33
34
|
load_states(ms, json)
|
34
35
|
load_entities(ms, json)
|
35
36
|
load_boundary_actions(ms, json)
|
@@ -37,7 +38,6 @@ def load_from_json(json: Dict) -> MathSpec:
|
|
37
38
|
load_mechanisms(ms, json)
|
38
39
|
load_parameters(ms, json)
|
39
40
|
load_policies(ms, json)
|
40
|
-
load_spaces(ms, json)
|
41
41
|
load_stateful_metrics(ms, json)
|
42
42
|
load_action_transmission_channels(ms, json)
|
43
43
|
load_state_update_transmission_channels(ms, json)
|
Load/mechanism.py
CHANGED
@@ -3,7 +3,7 @@ from ..Classes import Mechanism
|
|
3
3
|
from .general import check_json_keys
|
4
4
|
|
5
5
|
|
6
|
-
def convert_mechanism(data: Dict) -> Mechanism:
|
6
|
+
def convert_mechanism(data: Dict, ms: Dict) -> Mechanism:
|
7
7
|
"""Function to convert dictionary to mechanism object
|
8
8
|
|
9
9
|
Args:
|
@@ -19,6 +19,8 @@ def convert_mechanism(data: Dict) -> Mechanism:
|
|
19
19
|
# Copy
|
20
20
|
data = data.copy()
|
21
21
|
|
22
|
+
data["domain"] = (ms["Spaces"][x] for x in data["domain"])
|
23
|
+
|
22
24
|
# Build the action transmission channel object
|
23
25
|
return Mechanism(data)
|
24
26
|
|
@@ -33,4 +35,4 @@ def load_mechanisms(ms: Dict, json: Dict) -> None:
|
|
33
35
|
|
34
36
|
ms["Mechanisms"] = {}
|
35
37
|
for key in json["Mechanisms"]:
|
36
|
-
ms["Mechanisms"][key] = convert_mechanism(json["Mechanisms"][key])
|
38
|
+
ms["Mechanisms"][key] = convert_mechanism(json["Mechanisms"][key], ms)
|
Load/policy.py
CHANGED
@@ -25,7 +25,7 @@ def convert_policy_options(data: Dict) -> PolicyOption:
|
|
25
25
|
return PolicyOption(data)
|
26
26
|
|
27
27
|
|
28
|
-
def convert_policy(data: Dict) -> Policy:
|
28
|
+
def convert_policy(data: Dict, ms: Dict) -> Policy:
|
29
29
|
"""Function to convert dictionary to policy object
|
30
30
|
|
31
31
|
Args:
|
@@ -47,6 +47,9 @@ def convert_policy(data: Dict) -> Policy:
|
|
47
47
|
policy_options.append(convert_policy_options(po))
|
48
48
|
data["policy_options"] = policy_options
|
49
49
|
|
50
|
+
data["codomain"] = (ms["Spaces"][x] for x in data["codomain"])
|
51
|
+
data["domain"] = (ms["Spaces"][x] for x in data["domain"])
|
52
|
+
|
50
53
|
# Build the policy object
|
51
54
|
return Policy(data)
|
52
55
|
|
@@ -61,4 +64,4 @@ def load_policies(ms: Dict, json: Dict) -> None:
|
|
61
64
|
|
62
65
|
ms["Policies"] = {}
|
63
66
|
for key in json["Policies"]:
|
64
|
-
ms["Policies"][key] = convert_policy(json["Policies"][key])
|
67
|
+
ms["Policies"][key] = convert_policy(json["Policies"][key], ms)
|
Load/spaces.py
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
from typing import Dict
|
2
|
+
from ..Classes import Space
|
3
|
+
from .general import check_json_keys
|
4
|
+
|
5
|
+
|
6
|
+
def convert_space(data: Dict) -> Space:
|
7
|
+
# Check the keys are correct
|
8
|
+
check_json_keys(data, "Space")
|
9
|
+
|
10
|
+
# Copy
|
11
|
+
data = data.copy()
|
12
|
+
|
13
|
+
# Build the space object
|
14
|
+
return Space(data)
|
2
15
|
|
3
16
|
|
4
17
|
def load_spaces(ms: Dict, json: Dict) -> None:
|
@@ -10,4 +23,7 @@ def load_spaces(ms: Dict, json: Dict) -> None:
|
|
10
23
|
"""
|
11
24
|
|
12
25
|
# Placeholder for now
|
13
|
-
ms["Spaces"] =
|
26
|
+
ms["Spaces"] = {}
|
27
|
+
|
28
|
+
for space in json["Spaces"]:
|
29
|
+
ms["Spaces"][space["name"]] = convert_space(space)
|
@@ -3,7 +3,9 @@ from ..Classes import StateUpdateTransmissionChannel
|
|
3
3
|
from .general import check_json_keys
|
4
4
|
|
5
5
|
|
6
|
-
def convert_state_update_transmission_channel(
|
6
|
+
def convert_state_update_transmission_channel(
|
7
|
+
data: Dict, ms: Dict
|
8
|
+
) -> StateUpdateTransmissionChannel:
|
7
9
|
"""Function to convert dictionary to state update transmission channel
|
8
10
|
|
9
11
|
Args:
|
@@ -19,24 +21,25 @@ def convert_state_update_transmission_channel(data: Dict, ms: Dict) -> StateUpda
|
|
19
21
|
|
20
22
|
# Assert the origin is in mechanisms then map
|
21
23
|
origin = data["origin"]
|
22
|
-
assert origin in ms["Mechanisms"]
|
24
|
+
assert origin in ms["Mechanisms"], "{} not found in mechanisms".format(origin)
|
23
25
|
data["origin"] = ms["Mechanisms"][origin]
|
24
26
|
|
25
27
|
# Assert entity is in entities then map
|
26
28
|
entity = data["entity"]
|
27
|
-
assert entity in ms["Entities"]
|
29
|
+
assert entity in ms["Entities"], "{} not found in entities".format(entity)
|
28
30
|
data["entity"] = ms["Entities"][entity]
|
29
31
|
|
30
32
|
# Assert variable is in entity state then map
|
31
33
|
entity = data["entity"]
|
32
34
|
variable = data["variable"]
|
33
35
|
|
34
|
-
assert variable in entity.state.variable_map
|
36
|
+
assert variable in entity.state.variable_map, "{} variable not in {} state".format(
|
37
|
+
variable, entity.name
|
38
|
+
)
|
35
39
|
data["variable"] = entity.state.variable_map[variable]
|
36
40
|
|
37
41
|
# Add in the updates logic
|
38
|
-
data["origin"].updates.append((data["entity"],
|
39
|
-
data["variable"]))
|
42
|
+
data["origin"].updates.append((data["entity"], data["variable"]))
|
40
43
|
data["entity"].state.updated_by.append(data["origin"])
|
41
44
|
data["entity"].add_impacted_by_mechanism(data["origin"])
|
42
45
|
data["variable"].updated_by.append(data["origin"])
|
@@ -59,4 +62,5 @@ def load_state_update_transmission_channels(ms: Dict, json: Dict) -> None:
|
|
59
62
|
ms["State Update Transmission Channels"] = []
|
60
63
|
for sutc in json["State Update Transmission Channels"]:
|
61
64
|
ms["State Update Transmission Channels"].append(
|
62
|
-
convert_state_update_transmission_channel(sutc, ms)
|
65
|
+
convert_state_update_transmission_channel(sutc, ms)
|
66
|
+
)
|
Reports/html.py
CHANGED
@@ -54,7 +54,7 @@ def write_action_chain_reports(
|
|
54
54
|
out += "<h2>State</h2>"
|
55
55
|
out += write_local_state_variable_tables(all_nodes["State"])
|
56
56
|
|
57
|
-
out += write_out_spaces(ms, [x.
|
57
|
+
out += write_out_spaces(ms, [x.name for x in all_nodes["Spaces"]])
|
58
58
|
out += write_out_boundary_actions(
|
59
59
|
ms, [x.name for x in all_nodes["Boundary Actions"]]
|
60
60
|
)
|
@@ -93,7 +93,7 @@ def write_entity_reports(ms: MathSpec, directory: str, entities: List[str]) -> N
|
|
93
93
|
out += "<h2>State</h2>"
|
94
94
|
out += write_local_state_variable_tables(all_nodes["State"])
|
95
95
|
|
96
|
-
out += write_out_spaces(ms, [x.
|
96
|
+
out += write_out_spaces(ms, [x.name for x in all_nodes["Spaces"]])
|
97
97
|
out += write_out_boundary_actions(
|
98
98
|
ms, [x.name for x in all_nodes["Boundary Actions"]]
|
99
99
|
)
|
Reports/mechanisms.py
CHANGED
@@ -15,25 +15,25 @@ def write_out_mechanism(mechanism: Mechanism) -> str:
|
|
15
15
|
for i, x in enumerate(mechanism.called_by):
|
16
16
|
x = x[0]
|
17
17
|
out += "<p>"
|
18
|
-
out += "{}. {}".format(i+1, x.name)
|
18
|
+
out += "{}. {}".format(i + 1, x.name)
|
19
19
|
out += "</p>"
|
20
20
|
|
21
21
|
out += "<h4>Domain Spaces:</h4>\n"
|
22
22
|
for i, x in enumerate(mechanism.domain):
|
23
23
|
out += "<p>"
|
24
|
-
out += "{}. {}".format(i+1, x.
|
24
|
+
out += "{}. {}".format(i + 1, x.name)
|
25
25
|
out += "</p>"
|
26
26
|
|
27
27
|
out += "<h4>State Updates:</h4>\n"
|
28
28
|
for i, x in enumerate(mechanism.updates):
|
29
29
|
out += "<p>"
|
30
|
-
out += "{}. {}.{}".format(i+1, x[0].name, x[1].name)
|
30
|
+
out += "{}. {}.{}".format(i + 1, x[0].name, x[1].name)
|
31
31
|
out += "</p>"
|
32
32
|
|
33
33
|
out += "<h4>Constraints:</h4>\n"
|
34
34
|
for i, x in enumerate(mechanism.constraints):
|
35
35
|
out += "<p>"
|
36
|
-
out += "{}. {}\n".format(i+1, x)
|
36
|
+
out += "{}. {}\n".format(i + 1, x)
|
37
37
|
out += "</p>"
|
38
38
|
|
39
39
|
out += "<h4>Logic:</h4>\n"
|
Reports/node_map.py
CHANGED
@@ -12,24 +12,19 @@ def create_action_chains_graph(ms, action_keys, name):
|
|
12
12
|
graph.node(entity.name, entity.label, shape="cylinder", color="black")
|
13
13
|
|
14
14
|
for ba in all_nodes["Boundary Actions"]:
|
15
|
-
graph.node(ba.name, ba.label, shape="diamond",
|
16
|
-
|
17
|
-
|
15
|
+
graph.node(ba.name, ba.label, shape="diamond", color="orange", style="filled")
|
16
|
+
|
18
17
|
for ca in all_nodes["Control Actions"]:
|
19
|
-
graph.node(ca.name, ca.label, shape="diamond",
|
20
|
-
color="yellow", style='filled')
|
18
|
+
graph.node(ca.name, ca.label, shape="diamond", color="yellow", style="filled")
|
21
19
|
|
22
20
|
for p in all_nodes["Policies"]:
|
23
|
-
graph.node(p.name, p.label, shape="rectangle",
|
24
|
-
color="red", style='filled')
|
21
|
+
graph.node(p.name, p.label, shape="rectangle", color="red", style="filled")
|
25
22
|
|
26
23
|
for m in all_nodes["Mechanisms"]:
|
27
|
-
graph.node(m.name, m.label, shape="oval",
|
28
|
-
color="azure2", style='filled')
|
24
|
+
graph.node(m.name, m.label, shape="oval", color="azure2", style="filled")
|
29
25
|
|
30
26
|
for entity in all_nodes["Entities2"]:
|
31
|
-
graph.node(entity.name+"_2", entity.label,
|
32
|
-
shape="cylinder", color="black")
|
27
|
+
graph.node(entity.name + "_2", entity.label, shape="cylinder", color="black")
|
33
28
|
|
34
29
|
for su in all_nodes["State Updates"]:
|
35
30
|
label = "{}.{}".format(su[0].name, su[1].name)
|
@@ -41,7 +36,7 @@ def create_action_chains_graph(ms, action_keys, name):
|
|
41
36
|
graph.edge(entity.name, ba.name)
|
42
37
|
for call in ba.calls:
|
43
38
|
optional_flag = call[1]
|
44
|
-
space = call[2].
|
39
|
+
space = call[2].name
|
45
40
|
space = wrap(space, 12)
|
46
41
|
space = "\n".join(space)
|
47
42
|
call = call[0]
|
@@ -50,7 +45,7 @@ def create_action_chains_graph(ms, action_keys, name):
|
|
50
45
|
for ca in all_nodes["Control Actions"]:
|
51
46
|
for call in ca.calls:
|
52
47
|
optional_flag = call[1]
|
53
|
-
space = call[2].
|
48
|
+
space = call[2].name
|
54
49
|
space = wrap(space, 12)
|
55
50
|
space = "\n".join(space)
|
56
51
|
call = call[0]
|
@@ -58,15 +53,14 @@ def create_action_chains_graph(ms, action_keys, name):
|
|
58
53
|
|
59
54
|
for p in all_nodes["Policies"]:
|
60
55
|
for call in p.calls:
|
61
|
-
space = call[2].
|
56
|
+
space = call[2].name
|
62
57
|
space = wrap(space, 12)
|
63
58
|
space = "\n".join(space)
|
64
|
-
#space = "\n".join(space.split(" "))
|
59
|
+
# space = "\n".join(space.split(" "))
|
65
60
|
optional_flag = call[1]
|
66
61
|
call = call[0]
|
67
62
|
if optional_flag:
|
68
|
-
graph.edge(p.name, call.name, style="dashed",
|
69
|
-
label=space)
|
63
|
+
graph.edge(p.name, call.name, style="dashed", label=space)
|
70
64
|
else:
|
71
65
|
graph.edge(p.name, call.name, label=space)
|
72
66
|
|
@@ -78,7 +72,7 @@ def create_action_chains_graph(ms, action_keys, name):
|
|
78
72
|
|
79
73
|
for su in all_nodes["State Updates"]:
|
80
74
|
label1 = "{}.{}".format(su[0].name, su[1].name)
|
81
|
-
label2 = su[0].name+"_2"
|
75
|
+
label2 = su[0].name + "_2"
|
82
76
|
graph.edge(label1, label2)
|
83
77
|
|
84
78
|
return graph
|
Reports/policies.py
CHANGED
@@ -15,39 +15,39 @@ def write_out_policy(policy: Policy) -> str:
|
|
15
15
|
for i, x in enumerate(policy.called_by):
|
16
16
|
x = x[0]
|
17
17
|
out += "<p>"
|
18
|
-
out += "{}. {}".format(i+1, x.name)
|
18
|
+
out += "{}. {}".format(i + 1, x.name)
|
19
19
|
out += "</p>"
|
20
20
|
|
21
21
|
out += "<h4>Domain Spaces:</h4>\n"
|
22
22
|
for i, x in enumerate(policy.domain):
|
23
23
|
out += "<p>"
|
24
|
-
out += "{}. {}".format(i+1, x.
|
24
|
+
out += "{}. {}".format(i + 1, x.name)
|
25
25
|
out += "</p>"
|
26
26
|
|
27
27
|
out += "<h4>Followed By:</h4>\n"
|
28
28
|
for i, x in enumerate(policy.calls):
|
29
29
|
x = x[0]
|
30
30
|
out += "<p>"
|
31
|
-
out += "{}. {}".format(i+1, x.name)
|
31
|
+
out += "{}. {}".format(i + 1, x.name)
|
32
32
|
out += "</p>"
|
33
33
|
|
34
34
|
out += "<h4>Codomain Spaces:</h4>\n"
|
35
35
|
for i, x in enumerate(policy.codomain):
|
36
36
|
out += "<p>"
|
37
|
-
out += "{}. {}".format(i+1, x.
|
37
|
+
out += "{}. {}".format(i + 1, x.name)
|
38
38
|
out += "</p>"
|
39
39
|
|
40
40
|
out += "<h4>Constraints:</h4>\n"
|
41
41
|
for i, x in enumerate(policy.constraints):
|
42
42
|
out += "<p>"
|
43
|
-
out += "{}. {}\n".format(i+1, x)
|
43
|
+
out += "{}. {}\n".format(i + 1, x)
|
44
44
|
out += "</p>"
|
45
45
|
|
46
46
|
if policy.policy_options:
|
47
47
|
out += "<h4>Policy Options:</h4>\n"
|
48
48
|
for i, x in enumerate(policy.policy_options):
|
49
49
|
out += "<details>"
|
50
|
-
out += "<summary><b>{}. {}</b></summary>".format(i+1, x.name)
|
50
|
+
out += "<summary><b>{}. {}</b></summary>".format(i + 1, x.name)
|
51
51
|
out += "<p>"
|
52
52
|
out += x.description
|
53
53
|
out += "</p>"
|
Reports/spaces.py
CHANGED
@@ -5,11 +5,13 @@ from typing import List, TypedDict
|
|
5
5
|
def write_out_space(space: TypedDict) -> str:
|
6
6
|
out = ""
|
7
7
|
out += "<h3>"
|
8
|
-
out += space.
|
8
|
+
out += space.name
|
9
9
|
out += "</h3>"
|
10
10
|
|
11
|
-
d = space.
|
12
|
-
d = ",<br/>".join(
|
11
|
+
d = space.schema
|
12
|
+
d = ",<br/>".join(
|
13
|
+
["{}: {}".format(a, b.__name__) for a, b in zip(d.keys(), d.values())]
|
14
|
+
)
|
13
15
|
d = "{" + d + "}"
|
14
16
|
|
15
17
|
out += "<p>"
|
@@ -24,4 +26,4 @@ def write_out_spaces(ms: MathSpec, spaces: List[str]) -> str:
|
|
24
26
|
for name in spaces:
|
25
27
|
out += write_out_space(ms.spaces[name])
|
26
28
|
|
27
|
-
return out
|
29
|
+
return out
|
Reports/state.py
CHANGED
@@ -9,14 +9,18 @@ def write_state_variable_table(target_state):
|
|
9
9
|
</tr>"""
|
10
10
|
|
11
11
|
for var in target_state.variables:
|
12
|
-
table_vars = [
|
13
|
-
|
12
|
+
table_vars = [
|
13
|
+
var.name,
|
14
|
+
var.description,
|
15
|
+
var.type.__name__,
|
16
|
+
var.symbol,
|
17
|
+
var.domain,
|
18
|
+
]
|
14
19
|
table += "<tr>"
|
15
20
|
for tv in table_vars:
|
16
21
|
table += "<td>"
|
17
22
|
if tv:
|
18
|
-
table += "{}".format(tv).replace("<",
|
19
|
-
"<").replace(">", ">")
|
23
|
+
table += "{}".format(tv).replace("<", "<").replace(">", ">")
|
20
24
|
table += "</td>"
|
21
25
|
|
22
26
|
table += "</tr>"
|
@@ -31,4 +35,4 @@ def write_local_state_variable_tables(states):
|
|
31
35
|
for state in states:
|
32
36
|
out += "<h4>{}</h4>".format(state.name)
|
33
37
|
out += write_state_variable_table(state)
|
34
|
-
return out
|
38
|
+
return out
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: math_spec_mapping
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: A library for easy mapping of mathematical specifications.
|
5
5
|
Author-email: Sean McOwen <Sean@Block.Science>
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -36,7 +36,7 @@ As well, there are times when you want a fully zoomed out view, and other times
|
|
36
36
|
|
37
37
|
|
38
38
|
```mermaid
|
39
|
-
graph
|
39
|
+
graph TD
|
40
40
|
A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file and parsed, with validations and mappings along the way \n Can show different views on the fly]
|
41
41
|
B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
|
42
42
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
__init__.py,sha256=lsyvmC37lNTZbIK_b0O4WQpYt129kB0-fhj14UXje80,339
|
2
|
+
Classes/ActionTransmissionChannel.py,sha256=zWMo5QsgPh5WGIWXl-xOrZNMXYJXmK6Vejw1dQvi0og,246
|
3
|
+
Classes/Block.py,sha256=ZZ7nJOSLUzwpWlz3TnbF6RnCSN1Mg3S8lKldMu5PKkM,503
|
4
|
+
Classes/BoundaryAction.py,sha256=DQkfRLc4fFB0lmkAcZn7SPpCBObi9rRfPkclFDcjoHI,429
|
5
|
+
Classes/ControlAction.py,sha256=Y1jmm3pNDuauhhuGLpdVIWhuArwk7_7MFNRl_fZGElY,425
|
6
|
+
Classes/Entity.py,sha256=wCckyg7880oenwj503Wi4_HbVRZab9zl13Q51Dc2OtA,1197
|
7
|
+
Classes/MathSpec.py,sha256=Wpq20x76SeA8Z5uBhEhFc7-BcJ7qba49vTnH29gl5e8,9913
|
8
|
+
Classes/Mechanism.py,sha256=-rmnOHNcxsRNS4pH9eMkRiZomx0ZcXI-Yednw6_JJfE,235
|
9
|
+
Classes/Parameter.py,sha256=ZWHgXP1MyxjFH943ZU3tWkhw6YGqcBY4xTmnQDJ1cJo,1052
|
10
|
+
Classes/Policy.py,sha256=7Mz0QmsEdZcgK9_wlMaeEoCEgtKC5E8koDGmdXHHyi4,391
|
11
|
+
Classes/Space.py,sha256=-8e__ZkCvksoUD3QDEysJQnQSdl6cv8jGIUmO096A0s,145
|
12
|
+
Classes/State.py,sha256=2JsI63lG_4K-f6QXMqFFoiu_0oFF0rbNQp-0ivb3uGE,1369
|
13
|
+
Classes/StateUpdateTransmissionChannel.py,sha256=3hBLvD1lE64PkwqksBXAfFWv7foOZzGQLAFQWy42tOA,257
|
14
|
+
Classes/StatefulMetric.py,sha256=r0d7mEE4yPJNQ-aQybLAiywcXo-K9AiwPvq2ILgmT-Y,667
|
15
|
+
Classes/__init__.py,sha256=JirG2bLL_-yTac5Gd7lfazdVdgGSmEfs_zGILJorTDU,593
|
16
|
+
Convenience/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
Convenience/starter.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
Load/__init__.py,sha256=_ga5nHi7U5rY5lCF36_XI9Qmybq4P8R4m5I5mmjLBk8,33
|
19
|
+
Load/action_transmission_channel.py,sha256=E_EPWJ44H5GKNDl0fwJhC9LksI7z6AAaV9dttjQcQD4,2511
|
20
|
+
Load/boundary_actions.py,sha256=HokALnMEJd_upSZW_tTjqArHzwlbxR1_TYbwdJrYmus,1781
|
21
|
+
Load/control_actions.py,sha256=xFJrC4kQw0mbYw9YwoVnj3fFhr2kEC5GefE8MCzEV9Y,1302
|
22
|
+
Load/entities.py,sha256=mz1zx1KQZjGPI6KvDnA0HbMRT3ijmeYGpvF8MH6R118,1104
|
23
|
+
Load/general.py,sha256=UBBzgeMehgJU8tRovdJuW2H38OmVoY0GZsGXVUlKM6c,3361
|
24
|
+
Load/load.py,sha256=ZPWrztKBZ9P4vBogKSchi5KXnO6JKPecWvGUJTyAjIw,1487
|
25
|
+
Load/mechanism.py,sha256=4QqpZ-DPOMJ9N03OSBUbgwJGVcU_YZZn8UyevLNWc8k,933
|
26
|
+
Load/parameters.py,sha256=7QvNXvI2e5dEnW2KvwqtX_Pr-cnvz51WFa3aEbnqMLg,1060
|
27
|
+
Load/policy.py,sha256=J1w2GlOYUk4tsfZPexraHce2Op4tucJBI3Fhw7bXluU,1547
|
28
|
+
Load/spaces.py,sha256=H93XwDjaXHjQQXnJLQ49sZMo2GgONdOSKJ5TtA3u1MA,645
|
29
|
+
Load/state_update_transmission_channels.py,sha256=l6KnF_4eQwmhvpcuBjEIveNqeZVBQK861SUiOBAWHqA,2216
|
30
|
+
Load/stateful_metrics.py,sha256=85zRqK2AuOmxgH9b7Lgha2v44ei3RVClnZ0I17WZ_hg,1160
|
31
|
+
Load/states.py,sha256=A_4rBPFAnkuXzzMlv5wnGB5wsFVA-0RghqNp7XCgK8E,966
|
32
|
+
Reports/__init__.py,sha256=we5Qb7FIG4iSdkejnTw1H5vj_EdiCx7zMD9K3Xti888,389
|
33
|
+
Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-YdcI2ZZ19_Qv_K7Qk,1410
|
34
|
+
Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
|
35
|
+
Reports/general.py,sha256=WOOn6Wlb8M4fsdN49FlKLwOka6vJPQ9aCUy88TL2ki0,1610
|
36
|
+
Reports/html.py,sha256=l13C03Jvl955vxtwoDtd9fuW2CEuNqNMO6H1PIuw7pA,5976
|
37
|
+
Reports/mechanisms.py,sha256=d2Rxt3JBYvqAOAYUynl0buYVoXEHrO8EGq7GK6hK8NA,1322
|
38
|
+
Reports/node_map.py,sha256=FdSMDQG16NX6n9sZcH-T5xwsvgjrV9OqBHc9J_VlNK0,3129
|
39
|
+
Reports/parameters.py,sha256=kI0Nu-8i0P6eaQjpivC1WORzSjGnz2CqW7R0SKmf0ME,231
|
40
|
+
Reports/policies.py,sha256=EuBzBsTM6QSS_GHFcAyhGgWvDDZwRuKe7Eos9nX13ho,1814
|
41
|
+
Reports/spaces.py,sha256=hyy0TAM8vz986nexGtDKUrEksd9jPTZx47NQWiTfriY,583
|
42
|
+
Reports/state.py,sha256=5jPrulJ2MIBto6qIWlapYG4c7YnOlYovV0_pYe2hCKg,932
|
43
|
+
Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
|
44
|
+
math_spec_mapping-0.1.3.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
|
45
|
+
math_spec_mapping-0.1.3.dist-info/METADATA,sha256=p4kqmwfp-Inz9XCUG9p_3dVsu0bhgpovewCckam5SQA,2484
|
46
|
+
math_spec_mapping-0.1.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
47
|
+
math_spec_mapping-0.1.3.dist-info/top_level.txt,sha256=VPXI_45FlWgal53yjpbpWhksTVaFU3h8Soro9cmmcxc,42
|
48
|
+
math_spec_mapping-0.1.3.dist-info/RECORD,,
|
@@ -1,46 +0,0 @@
|
|
1
|
-
__init__.py,sha256=lsyvmC37lNTZbIK_b0O4WQpYt129kB0-fhj14UXje80,339
|
2
|
-
Classes/ActionTransmissionChannel.py,sha256=zWMo5QsgPh5WGIWXl-xOrZNMXYJXmK6Vejw1dQvi0og,246
|
3
|
-
Classes/BoundaryAction.py,sha256=oFJhCFsBmlfzSZroakmVLWYEyRG97F8OOnRi7zsnCek,744
|
4
|
-
Classes/ControlAction.py,sha256=5dGB39qkWvp_HSYYIZIPFnOyga-he_15AMtNX_y46cg,595
|
5
|
-
Classes/Entity.py,sha256=wCckyg7880oenwj503Wi4_HbVRZab9zl13Q51Dc2OtA,1197
|
6
|
-
Classes/MathSpec.py,sha256=f-pFLRI3a4ENy1ieTZ8pAelHjn1Mw4u7XwkaBMeaRyA,9380
|
7
|
-
Classes/Mechanism.py,sha256=q32IZkQv7L2oF2BDO9mgU9ZhOqkY-BuAvN8BRGuJRwI,504
|
8
|
-
Classes/Parameter.py,sha256=ZWHgXP1MyxjFH943ZU3tWkhw6YGqcBY4xTmnQDJ1cJo,1052
|
9
|
-
Classes/Policy.py,sha256=Q60dU7Auj5OP4cBZUMBu5pm19LTlJOktwr6d6mrrhFQ,732
|
10
|
-
Classes/State.py,sha256=2JsI63lG_4K-f6QXMqFFoiu_0oFF0rbNQp-0ivb3uGE,1369
|
11
|
-
Classes/StateUpdateTransmissionChannel.py,sha256=3hBLvD1lE64PkwqksBXAfFWv7foOZzGQLAFQWy42tOA,257
|
12
|
-
Classes/StatefulMetric.py,sha256=r0d7mEE4yPJNQ-aQybLAiywcXo-K9AiwPvq2ILgmT-Y,667
|
13
|
-
Classes/__init__.py,sha256=5OVPJospxxiUnDtjAosvpZPIJgTUhaypH1dPevi51Pk,567
|
14
|
-
Convenience/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
Convenience/starter.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
Load/__init__.py,sha256=_ga5nHi7U5rY5lCF36_XI9Qmybq4P8R4m5I5mmjLBk8,33
|
17
|
-
Load/action_transmission_channel.py,sha256=GlfKKDUwUOZkDilD-pYskdixlEdWuLYyHivPTBTwJyE,2475
|
18
|
-
Load/boundary_actions.py,sha256=z60bgdNKH93YsKXv79EC7L3uZvDEFeKZ6fAD4Q06TWE,1689
|
19
|
-
Load/control_actions.py,sha256=rd1vTMQDVwn89z5Rj7-O_R18i-RPK376CCzwt7WdOq0,1225
|
20
|
-
Load/entities.py,sha256=mz1zx1KQZjGPI6KvDnA0HbMRT3ijmeYGpvF8MH6R118,1104
|
21
|
-
Load/general.py,sha256=p2Voa2VvesdoLzX-A5FNjt6tVx4tG-tJ6jjsGb6YhYs,3257
|
22
|
-
Load/load.py,sha256=RvtEfsswF7PGqN7qAdODz7Cu8P_Oo5T8idgPd_J8GGE,1487
|
23
|
-
Load/mechanism.py,sha256=kJvhyXbmG8k1gNGfrC49_NHJs8xL3ZAa0dyYv4HH8zo,855
|
24
|
-
Load/parameters.py,sha256=7QvNXvI2e5dEnW2KvwqtX_Pr-cnvz51WFa3aEbnqMLg,1060
|
25
|
-
Load/policy.py,sha256=kMOniaavIKI_N2Jb8Oc5F9kKjSOHqSaFjDSqrpwpDMQ,1402
|
26
|
-
Load/spaces.py,sha256=G1AJoHEPtWZpsLptnOx3zaV3CfG2xYrlalAy4s9Ev80,301
|
27
|
-
Load/state_update_transmission_channels.py,sha256=eLxdyxAIdvSrQ3cqb5ce2TczsgHL1GcvZGh1NcsRgy0,2073
|
28
|
-
Load/stateful_metrics.py,sha256=85zRqK2AuOmxgH9b7Lgha2v44ei3RVClnZ0I17WZ_hg,1160
|
29
|
-
Load/states.py,sha256=A_4rBPFAnkuXzzMlv5wnGB5wsFVA-0RghqNp7XCgK8E,966
|
30
|
-
Reports/__init__.py,sha256=we5Qb7FIG4iSdkejnTw1H5vj_EdiCx7zMD9K3Xti888,389
|
31
|
-
Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-YdcI2ZZ19_Qv_K7Qk,1410
|
32
|
-
Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
|
33
|
-
Reports/general.py,sha256=WOOn6Wlb8M4fsdN49FlKLwOka6vJPQ9aCUy88TL2ki0,1610
|
34
|
-
Reports/html.py,sha256=UkGS57pMPELwwjbUdPaZgy61qR7J25gNtD4ku0BL0HE,5984
|
35
|
-
Reports/mechanisms.py,sha256=YhxeCp4vfJVizncxPwkXe8SoZ7UYqm3AaO5WQdXD0gE,1318
|
36
|
-
Reports/node_map.py,sha256=8OtmAUgERCIxYDeHT_ieku7HQsDSvJwB1__vrPqkSCs,3262
|
37
|
-
Reports/parameters.py,sha256=kI0Nu-8i0P6eaQjpivC1WORzSjGnz2CqW7R0SKmf0ME,231
|
38
|
-
Reports/policies.py,sha256=xE59j79HWjr0S7eIYkhJSdKVAqmQFcj5vD0UTWaKILc,1810
|
39
|
-
Reports/spaces.py,sha256=iqmW4ONhq1XrFgstKvZ0XMa9f_hP-k2-1w00Sl6kLb8,580
|
40
|
-
Reports/state.py,sha256=tMLOXE1rN2oBRdAhL0kFgd6sVNck4GK4qK64-uJWo6o,931
|
41
|
-
Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
|
42
|
-
math_spec_mapping-0.1.1.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
|
43
|
-
math_spec_mapping-0.1.1.dist-info/METADATA,sha256=ApCZfAiQNpCpmL2mhPEMDBOkgXh2CF_8HCqVOF-hNWw,2484
|
44
|
-
math_spec_mapping-0.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
45
|
-
math_spec_mapping-0.1.1.dist-info/top_level.txt,sha256=VPXI_45FlWgal53yjpbpWhksTVaFU3h8Soro9cmmcxc,42
|
46
|
-
math_spec_mapping-0.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|