ivoryos 1.3.5__py3-none-any.whl → 1.3.6__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.

Potentially problematic release.


This version of ivoryos might be problematic. Click here for more details.

@@ -30,7 +30,7 @@ class AxOptimizer(OptimizerBase):
30
30
  @staticmethod
31
31
  def _create_generator_mapping():
32
32
  """Create a mapping from string values to Generator enum members."""
33
- from ax.modelbridge import Generators
33
+ from ax.adapter import Generators
34
34
  return {member.value: member for member in Generators}
35
35
 
36
36
  def _convert_parameter_to_ax_format(self, parameter_space):
@@ -96,8 +96,8 @@ class AxOptimizer(OptimizerBase):
96
96
  step_2 = optimizer_config.get("step_2", {})
97
97
  step_1_generator = step_1.get("model", "Sobol")
98
98
  step_2_generator = step_2.get("model", "BOTorch")
99
- generator_1 = GenerationStep(model=generators.get(step_1_generator), num_trials=step_1.get("num_samples", 5))
100
- generator_2 = GenerationStep(model=generators.get(step_2_generator), num_trials=step_2.get("num_samples", -1))
99
+ generator_1 = GenerationStep(generator=generators.get(step_1_generator), num_trials=step_1.get("num_samples", 5))
100
+ generator_2 = GenerationStep(generator=generators.get(step_2_generator), num_trials=step_2.get("num_samples", -1))
101
101
  return GenerationStrategy(steps=[generator_1, generator_2])
102
102
 
103
103
  def suggest(self, n=1):
@@ -5,7 +5,7 @@ from abc import ABC, abstractmethod
5
5
 
6
6
 
7
7
  class OptimizerBase(ABC):
8
- def __init__(self, experiment_name:str, parameter_space: list, objective_config: dict, optimizer_config: dict):
8
+ def __init__(self, experiment_name:str, parameter_space: list, objective_config: dict, optimizer_config: dict, datapath:str=None):
9
9
  """
10
10
  :param experiment_name: arbitrary name
11
11
  :param parameter_space: list of parameter names
@@ -29,6 +29,7 @@ class OptimizerBase(ABC):
29
29
  self.parameter_space = parameter_space
30
30
  self.objective_config = objective_config
31
31
  self.optimizer_config = optimizer_config
32
+ self.datapath = datapath
32
33
 
33
34
  @abstractmethod
34
35
  def suggest(self, n=1):
@@ -2,8 +2,10 @@
2
2
 
3
3
  from ivoryos.optimizer.ax_optimizer import AxOptimizer
4
4
  from ivoryos.optimizer.baybe_optimizer import BaybeOptimizer
5
+ from ivoryos.optimizer.nimo_optimizer import NIMOOptimizer
5
6
 
6
7
  OPTIMIZER_REGISTRY = {
7
8
  "ax": AxOptimizer,
8
- "baybe": BaybeOptimizer
9
+ "baybe": BaybeOptimizer,
10
+ "nimo": NIMOOptimizer,
9
11
  }
@@ -385,7 +385,13 @@ def methods_handler(instrument: str = ''):
385
385
  success = False
386
386
  msg = [f"{field}: {', '.join(messages)}" for field, messages in form.errors.items()]
387
387
  utils.post_script_file(script)
388
- exec_string = script.compile(current_app.config['SCRIPT_FOLDER'])
388
+ #TODO
389
+ try:
390
+ exec_string = script.compile(current_app.config['SCRIPT_FOLDER'])
391
+ except Exception as e:
392
+ exec_string = {}
393
+ msg = f"Compilation failed: {str(e)}"
394
+ # exec_string = script.compile(current_app.config['SCRIPT_FOLDER'])
389
395
  session['python_code'] = exec_string
390
396
  design_buttons = {stype: create_action_button(script, stype) for stype in script.stypes}
391
397
  html = render_template("components/canvas_main.html", script=script, buttons_dict=design_buttons)
@@ -23,12 +23,16 @@ def get_step(uuid: int):
23
23
  """
24
24
  script = utils.get_script_file()
25
25
  action = script.find_by_uuid(uuid)
26
- if request.method == 'GET':
27
- # forms = create_form_from_action(action, script=script)
26
+ if action is None:
27
+ return jsonify({"warning": "Step not found, please refresh the page."}), 404
28
+
29
+ elif request.method == 'GET':
30
+ forms = create_form_from_action(action, script=script)
28
31
  # session['edit_action'] = action
29
32
  return render_template("components/edit_action_form.html",
30
33
  action=action,
31
- forms=create_form_from_action(action, script=script))
34
+ forms=forms)
35
+
32
36
 
33
37
 
34
38
  @steps.post("/draft/steps/<int:uuid>")
@@ -6,6 +6,7 @@
6
6
  <i class="bi bi-arrow-return-left"></i>
7
7
  </a>
8
8
  </div>
9
+ {% if action %}
9
10
  <h5> {{ action['action'] | format_name }} </h5>
10
11
  <form role="form" method='POST' name="{{instrument}}"
11
12
  action="{{ url_for('design.design_steps.get_step', uuid=action['uuid']) }}"
@@ -36,3 +37,4 @@
36
37
  <button type="submit" class="btn btn-primary">Save</button>
37
38
  <button type="button" class="btn btn-primary" id="back">Back</button>
38
39
  </form>
40
+ {% endif %}
ivoryos/server.py CHANGED
@@ -50,6 +50,7 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
50
50
  blueprint_plugins: Union[list, Blueprint] = [],
51
51
  exclude_names: list = [],
52
52
  notification_handler=None,
53
+ optimizer_registry: dict = None,
53
54
  ):
54
55
  """
55
56
  Start ivoryOS app server.
@@ -91,7 +92,10 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
91
92
  app.config["LOGGERS_PATH"] = logger_output_name or app.config["LOGGERS_PATH"] # default.log
92
93
  logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
93
94
  dummy_deck_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["DUMMY_DECK"])
94
- global_config.optimizers = OPTIMIZER_REGISTRY
95
+ if optimizer_registry:
96
+ global_config.optimizers = optimizer_registry
97
+ else:
98
+ global_config.optimizers = OPTIMIZER_REGISTRY
95
99
  if module:
96
100
  app.config["MODULE"] = module
97
101
  app.config["OFF_LINE"] = False
@@ -172,33 +172,50 @@ function editAction(uuid) {
172
172
  return;
173
173
  }
174
174
 
175
- // Save current state before fetching new content
176
175
  previousHtmlState = document.getElementById('instrument-panel').innerHTML;
177
176
 
178
177
  fetch(scriptStepUrl.replace('0', uuid), {
179
- method: 'GET',
178
+ method: 'GET', // no need for Content-Type on GET
180
179
  headers: {
181
180
  'Content-Type': 'application/json'
182
181
  }
183
182
  })
184
- .then(response => response.text())
183
+ .then(response => {
184
+ if (!response.ok) {
185
+ return response.json().then(err => {
186
+ if (err.warning) {
187
+ alert(err.warning); // <-- should fire now
188
+ }
189
+ // restore panel so user isn't stuck
190
+ if (previousHtmlState) {
191
+ document.getElementById('instrument-panel').innerHTML = previousHtmlState;
192
+ previousHtmlState = null;
193
+ }
194
+ throw new Error("Step fetch failed: " + response.status);
195
+ });
196
+ }
197
+ return response.text();
198
+ })
185
199
  .then(html => {
186
200
  document.getElementById('instrument-panel').innerHTML = html;
187
201
 
188
- // Add click handler for back button
189
- document.getElementById('back').addEventListener('click', function(e) {
190
- e.preventDefault();
191
- if (previousHtmlState) {
192
- document.getElementById('instrument-panel').innerHTML = previousHtmlState;
193
- previousHtmlState = null; // Clear the stored state
194
- }
195
- });
202
+ const backButton = document.getElementById('back');
203
+ if (backButton) {
204
+ backButton.addEventListener('click', function(e) {
205
+ e.preventDefault();
206
+ if (previousHtmlState) {
207
+ document.getElementById('instrument-panel').innerHTML = previousHtmlState;
208
+ previousHtmlState = null;
209
+ }
210
+ });
211
+ }
196
212
  })
197
213
  .catch(error => console.error('Error:', error));
198
214
  }
199
215
 
200
216
 
201
217
 
218
+
202
219
  function deleteAction(uuid) {
203
220
  if (!uuid) {
204
221
  console.error('Invalid UUID');
@@ -209,7 +209,7 @@ def parse_optimization_form(form_data: Dict[str, str]):
209
209
  parameter["bounds"] = bounds
210
210
 
211
211
  elif value == "choice":
212
- choices_field = f"{param_name}_choices"
212
+ choices_field = f"{param_name}_value"
213
213
  if choices_field in form_data and form_data[choices_field]:
214
214
  # Split choices by comma and clean whitespace
215
215
  choices = [choice.strip() for choice in form_data[choices_field].split(',')]
@@ -644,12 +644,21 @@ class Script(db.Model):
644
644
  args_str = args_str.replace(f"'#{args[arg][1:]}'", args[arg][1:])
645
645
  elif isinstance(args[arg], dict):
646
646
  # print(args[arg])
647
- variables = self.get_variables()
647
+ if not args[arg]:
648
+ continue
649
+ # Extract the variable name (first key in the dict)
648
650
  value = next(iter(args[arg]))
649
- if value not in variables:
650
- raise ValueError(f"Variable ({value}) is not defined.")
651
- args_str = args_str.replace(f"{args[arg]}", next(iter(args[arg])))
652
- # elif self._is_variable(arg):
651
+ var_type = args[arg].get(value)
652
+
653
+ # Only process if it's a function_output variable reference
654
+ if var_type == "function_output":
655
+ variables = self.get_variables()
656
+ if value not in variables:
657
+ raise ValueError(f"Variable ({value}) is not defined.")
658
+ # Replace the dict string representation with just the variable name
659
+ args_str = args_str.replace(f"{args[arg]}", value)
660
+
661
+ # elif self._is_variable(arg):
653
662
  # print("is variable")
654
663
  # args_str = args_str.replace(f"'{args[arg]}'", args[arg])
655
664
  return args_str
ivoryos/utils/form.py CHANGED
@@ -405,7 +405,7 @@ def create_form_from_action(action: dict, script=None, design=True):
405
405
  for name, param_type in arg_types.items():
406
406
  # formatted_param_name = format_name(name)
407
407
  value = args.get(name, "")
408
- if type(value) is dict:
408
+ if type(value) is dict and value:
409
409
  value = next(iter(value))
410
410
  field_kwargs = {
411
411
  "label": name,
@@ -556,9 +556,13 @@ def _action_button(action: dict, variables: dict):
556
556
  arg_list = []
557
557
  for k, v in action['args'].items():
558
558
  if isinstance(v, dict):
559
- value = next(iter(v)) # Extract the first key if it's a dict
560
- # show warning color for variable calling when there is no definition
561
- style = "background-color: khaki" if value not in variables.keys() else ""
559
+ if not v:
560
+ value = v # Keep the original value if not a dict
561
+ else:
562
+ value = next(iter(v)) # Extract the first key if it's a dict
563
+ # show warning color for variable calling when there is no definition
564
+
565
+ style = "background-color: khaki" if v.get(value) == "function_output" and value not in variables.keys() else ""
562
566
  else:
563
567
  value = v # Keep the original value if not a dict
564
568
  arg_list.append(f"{k} = {value}") # Format the key-value pair
@@ -198,7 +198,7 @@ class ScriptRunner:
198
198
 
199
199
 
200
200
  else:
201
- print("just exec synchronously")
201
+ # print("just exec synchronously")
202
202
  exec(line, exec_globals, exec_locals)
203
203
  exec_globals.update(exec_locals)
204
204
  # return locals_dict
ivoryos/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.3.5"
1
+ __version__ = "1.3.6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.5
3
+ Version: 1.3.6
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -9,6 +9,7 @@ Requires-Python: >=3.7
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: bcrypt
12
+ Requires-Dist: Flask[async]
12
13
  Requires-Dist: Flask-Login
13
14
  Requires-Dist: Flask-Session
14
15
  Requires-Dist: Flask-SocketIO
@@ -21,8 +22,10 @@ Provides-Extra: optimizer-ax
21
22
  Requires-Dist: ax-platform; extra == "optimizer-ax"
22
23
  Provides-Extra: optimizer-baybe
23
24
  Requires-Dist: baybe; extra == "optimizer-baybe"
25
+ Provides-Extra: optimizer-nimo
26
+ Requires-Dist: nimo; extra == "optimizer-nimo"
24
27
  Provides-Extra: optimizer
25
- Requires-Dist: ax-platform; extra == "optimizer"
28
+ Requires-Dist: ax-platform>=1.1.2; extra == "optimizer"
26
29
  Requires-Dist: baybe; extra == "optimizer"
27
30
  Provides-Extra: doc
28
31
  Requires-Dist: sphinx; extra == "doc"
@@ -1,13 +1,13 @@
1
1
  ivoryos/__init__.py,sha256=gEvBO2y5TRq06Itjjej3iAcq73UsihqKPWcb2HykPwM,463
2
2
  ivoryos/app.py,sha256=G6kzEOVzCduj7Fc2r1rMbMFHgDzZQV0lC20Oxps7RSM,4839
3
3
  ivoryos/config.py,sha256=y3RxNjiIola9tK7jg-mHM8EzLMwiLwOzoisXkDvj0gA,2174
4
- ivoryos/server.py,sha256=5tXrgG16lm6Fl-Q-ZHxiGQQoyZQFxRhdDf6idNYqhNg,6985
4
+ ivoryos/server.py,sha256=Idr41Boa8rPsh3bVJ8xy2Flwfxa1Xu6f2T0oMp4qBEk,7121
5
5
  ivoryos/socket_handlers.py,sha256=VWVWiIdm4jYAutwGu6R0t1nK5MuMyOCL0xAnFn06jWQ,1302
6
- ivoryos/version.py,sha256=tdqvkGH0OryRjjXzO3HS5DyYol-VTO9fC8m43nB2PgI,22
7
- ivoryos/optimizer/ax_optimizer.py,sha256=PoSu8hrDFFpqyhRBnaSMswIUsDfEX6sPWt8NEZ_sobs,7112
8
- ivoryos/optimizer/base_optimizer.py,sha256=JTbUharZKn0t8_BDbAFuwZIbT1VOnX1Xuog1pJuU8hY,1992
6
+ ivoryos/version.py,sha256=5ZbAQtod5QalTI1C2N07edlxplzG_Q2XvGOSyOok4uA,22
7
+ ivoryos/optimizer/ax_optimizer.py,sha256=k7RzhNMjh3MseOE-_FADVX72lYLDyXz-XE3juSBRWTk,7116
8
+ ivoryos/optimizer/base_optimizer.py,sha256=gNBX9m3RxoYklwEBkqeDGZlU7c6e9e5kN0ZeTtnxnCE,2044
9
9
  ivoryos/optimizer/baybe_optimizer.py,sha256=EdrrRiYO-IOx610cPXiQhH4qG8knUP0uiZ0YoyaGIU8,7954
10
- ivoryos/optimizer/registry.py,sha256=lr0cqdI2iEjw227ZPRpVkvsdYdddjeJJRzawDv77cEc,219
10
+ ivoryos/optimizer/registry.py,sha256=dLMo5cszcwa06hfBxdINQIGpkHtRe5-J3J7t76Jq6X0,306
11
11
  ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  ivoryos/routes/api/api.py,sha256=97Y7pqTwOaWgZgI5ovEPxEBm6Asrt0Iy0VhBkVp2xqA,2304
13
13
  ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,9 +27,9 @@ ivoryos/routes/data/templates/workflow_database.html,sha256=ofvHcovpwmJXo1SFiSrL
27
27
  ivoryos/routes/data/templates/workflow_view.html,sha256=Ti17kzlPlYTmzx5MkdsPlXJ1_k6QgMYQBM6FHjG50go,12491
28
28
  ivoryos/routes/data/templates/components/step_card.html,sha256=XWsr7qxAY76RCuQHETubWjWBlPgs2HkviH4ju6qfBKo,1923
29
29
  ivoryos/routes/design/__init__.py,sha256=zS3HXKaw0ALL5n6t_W1rUz5Uj5_tTQ-Y1VMXyzewvR0,113
30
- ivoryos/routes/design/design.py,sha256=8xWsJxs-jg3r1yszzvHWK0mccYoYlgzhO_dTV7aEA_w,18567
30
+ ivoryos/routes/design/design.py,sha256=HPjjoGH9mzSP6TxVNUYWgwhfzkpRt5BF38agL_tJvXk,18760
31
31
  ivoryos/routes/design/design_file.py,sha256=MVIc5uGSaGxZhs86hfPjX2n0iy1OcXeLq7b9Ucdg4VQ,2115
32
- ivoryos/routes/design/design_step.py,sha256=maDaR-CFK6UY_ajbQeYJ_onwYW0e9nMD-HgrhsSU6JY,5874
32
+ ivoryos/routes/design/design_step.py,sha256=M3l37kP1kU4_bolLBU1MWJgEW0LUXojo9UdQgysZyXs,5943
33
33
  ivoryos/routes/design/templates/experiment_builder.html,sha256=hh-d2tOc_40gww5WfUYIf8sM3qBaALZnR8Sx7Ja4tpU,1623
34
34
  ivoryos/routes/design/templates/components/action_form.html,sha256=kXJOrJLbFsMHHWVSuMQHpt1xFrUMnwgzTG8e6Qfn0Cg,3042
35
35
  ivoryos/routes/design/templates/components/actions_panel.html,sha256=jHTR58saTUIZInBdC-vLc1ZTbStLiULeWbupjB4hQzo,977
@@ -39,7 +39,7 @@ ivoryos/routes/design/templates/components/canvas_footer.html,sha256=5VRRacMZbzx
39
39
  ivoryos/routes/design/templates/components/canvas_header.html,sha256=7iIzLDGHX7MnmBbf98nWtLDprbeIgoNV4dJUO1zE4Tc,3598
40
40
  ivoryos/routes/design/templates/components/canvas_main.html,sha256=nLEtp3U2YtfJwob1kR8ua8-UVdu9hwc6z1L5UMNVz8c,1524
41
41
  ivoryos/routes/design/templates/components/deck_selector.html,sha256=ryTRpljYezo0AzGLCJu_qOMokjjnft3GIxddmNGtBA0,657
42
- ivoryos/routes/design/templates/components/edit_action_form.html,sha256=Dz7FnnOK4PYptAHNy9_WFCU1RZTSV61-1lNHHOSRJNs,1876
42
+ ivoryos/routes/design/templates/components/edit_action_form.html,sha256=idhUKOqewIxgqMKYKLutqOjopKQVLvddB6uufoBA3Lo,1912
43
43
  ivoryos/routes/design/templates/components/instruments_panel.html,sha256=tRKd-wOqKjaMJCLuGgRmHtxIgSjklhBkuX8arm5aTCU,4268
44
44
  ivoryos/routes/design/templates/components/modals.html,sha256=6Dl8I8oD4ln7kK8C5e92pFVVH5KDte-vVTL0U_6NSTg,306
45
45
  ivoryos/routes/design/templates/components/python_code_overlay.html,sha256=GUHgsmUWQf0P1Fbg5W0OJC34TXCUIMQVUkS7KDoauyI,1264
@@ -74,7 +74,7 @@ ivoryos/static/logo.webp,sha256=lXgfQR-4mHTH83k7VV9iB54-oC2ipe6uZvbwdOnLETc,1497
74
74
  ivoryos/static/style.css,sha256=zQVx35A5g6JMJ-K84-6fSKtzXGjp_p5ZVG6KLHPM2IE,4021
75
75
  ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
76
76
  ivoryos/static/gui_annotation/Slide2.PNG,sha256=z3wQ9oVgg4JTWVLQGKK_KhtepRHUYP1e05XUWGT2A0I,118761
77
- ivoryos/static/js/action_handlers.js,sha256=DnNYV5mITADKp14I6NaByNRzHco0dDPP2fuSM43x2hY,6119
77
+ ivoryos/static/js/action_handlers.js,sha256=MdYfXLRNSMAkfO_lkDb8Mr--MlZA7SluEQ5AB3Jqw7k,6704
78
78
  ivoryos/static/js/db_delete.js,sha256=l67fqUaN_FVDaL7v91Hd7LyRbxnqXx9nyjF34-7aewY,561
79
79
  ivoryos/static/js/overlay.js,sha256=dPxop19es0E0ZUSY3d_4exIk7CJuQEnlW5uTt5fZfzI,483
80
80
  ivoryos/static/js/script_metadata.js,sha256=m8VYZ8OGT2oTx1kXMXq60bKQI9WCbJNkzcFDzLvRuGc,1188
@@ -84,20 +84,20 @@ ivoryos/static/js/sortable_design.js,sha256=ASc9P6_423Mczeg6QH6LVtyxLyWhpxWJP2nE
84
84
  ivoryos/static/js/ui_state.js,sha256=XYsOcfGlduqLlqHySvPrRrR50CiAsml51duqneigsRY,3368
85
85
  ivoryos/templates/base.html,sha256=cl5w6E8yskbUzdiJFal6fZjnPuFNKEzc7BrrbRd6bMI,8581
86
86
  ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- ivoryos/utils/bo_campaign.py,sha256=Fil-zT7JexL_p9XqyWByjAk42XB1R9XUKN8CdV5bi6c,9714
87
+ ivoryos/utils/bo_campaign.py,sha256=AqTE4aIUWL26P0-o1qvL2ms4MjYzNQABNxZFisxBsyg,9712
88
88
  ivoryos/utils/client_proxy.py,sha256=74G3HAuq50iEHkSvlMZFmQaukm613FbRgOdzO_T3dMg,10191
89
- ivoryos/utils/db_models.py,sha256=i1fLiWFnese2xqAfWipN9eUDHeuy6eIYE9_cY6YZ6NU,31553
89
+ ivoryos/utils/db_models.py,sha256=TbOydX7rC1jGfei2mVYaexlE3lyq1Igb1VQuHJlMRKQ,31945
90
90
  ivoryos/utils/decorators.py,sha256=p1Bdl3dCeaHNv6-cCCUOZMiFu9kRaqqQnkFJUkzPoJE,991
91
- ivoryos/utils/form.py,sha256=Ej9tx06KZZ5fPQm1ho1byotNocF3u24aatc2ZyI0rK4,22301
91
+ ivoryos/utils/form.py,sha256=f1yXHlOQX1YnJ2j_UW6iHmh4pTAGAs9sAlhyQB8yBIo,22505
92
92
  ivoryos/utils/global_config.py,sha256=leYoEXvAS0AH4xQpYsqu4HI9CJ9-wiLM-pIh_bEG4Ak,3087
93
93
  ivoryos/utils/llm_agent.py,sha256=-lVCkjPlpLues9sNTmaT7bT4sdhWvV2DiojNwzB2Lcw,6422
94
94
  ivoryos/utils/py_to_json.py,sha256=ZtejHgwdEAUCVVMYeVNR8G7ceLINue294q6WpiJ6jn0,9734
95
- ivoryos/utils/script_runner.py,sha256=qozSrlpnsk5rZzui8WT59cMaw41ZfsYKvofAXdDiC5A,20747
95
+ ivoryos/utils/script_runner.py,sha256=gIYdTEFNWZFmPf9cf31y3wAUKUeJk_qnjohYDKevWNw,20749
96
96
  ivoryos/utils/serilize.py,sha256=lkBhkz8r2bLmz2_xOb0c4ptSSOqjIu6krj5YYK4Nvj8,6784
97
97
  ivoryos/utils/task_runner.py,sha256=xiMzK8gQ0mHsg0A1Ah8fmXe3azpaJh4hJiQJLHA11ZQ,3682
98
98
  ivoryos/utils/utils.py,sha256=dIc4BO55eS3lCA0nhbIncS5d7sLaKZy5hJS1I_Sm45o,14949
99
- ivoryos-1.3.5.dist-info/licenses/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
100
- ivoryos-1.3.5.dist-info/METADATA,sha256=z3rNHhq2GaCBN6bWwi6JtUXn8fWzkigMR-_PuKHgFtc,8403
101
- ivoryos-1.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
- ivoryos-1.3.5.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
103
- ivoryos-1.3.5.dist-info/RECORD,,
99
+ ivoryos-1.3.6.dist-info/licenses/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
100
+ ivoryos-1.3.6.dist-info/METADATA,sha256=wUfp7SCz5Vtw7CrpuoKeirxfuf71F6deGzjBlx2Zuj8,8516
101
+ ivoryos-1.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
+ ivoryos-1.3.6.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
103
+ ivoryos-1.3.6.dist-info/RECORD,,