q2rad 0.1.208__py3-none-any.whl → 0.1.210__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 q2rad might be problematic. Click here for more details.

q2rad/q2appmanager.py CHANGED
@@ -40,6 +40,7 @@ app_tables = [
40
40
  class AppManager(Q2Form):
41
41
  def __init__(self, title=""):
42
42
  super().__init__("Manage q2Application")
43
+ self.selected_tables = []
43
44
 
44
45
  def on_init(self):
45
46
  app_data = q2app.q2_app.selected_application
@@ -332,7 +333,68 @@ class AppManager(Q2Form):
332
333
  rez[x].append(row)
333
334
  return rez
334
335
 
336
+ def tables_selector(self, mode="export"):
337
+ st = Q2Form(f"Select tables for {mode}")
338
+ st.ok_button = 1
339
+ st.cancel_button = 1
340
+
341
+ def get_widgets(st=st):
342
+ return [x for x in st.widgets() if x.startswith("c_")]
343
+
344
+ tables = [
345
+ x
346
+ for x in q2app.q2_app.db_data.get_tables()
347
+ if not x.startswith("log_") and x != "sqlite_sequence"
348
+ ]
349
+ if st.add_control("/v"):
350
+ if st.add_control("/vr"):
351
+ tables.sort()
352
+ for index, table in enumerate(tables):
353
+ if self.selected_tables == []:
354
+ check_data = 1
355
+ else:
356
+ check_data = table in self.selected_tables
357
+
358
+ label = get("forms", f"form_table='{table}'", "title", self.q2_app.db_logic)
359
+ st.add_control(
360
+ f"c_{index}", pic=f"{table} ({label})", control="check", data=check_data, stretch=99
361
+ )
362
+ st.add_control("/")
363
+ st.add_control("/")
364
+ st.add_control("/h")
365
+ st.add_control(
366
+ "all",
367
+ "Check all",
368
+ control="button",
369
+ datalen=10,
370
+ valid=lambda: [st.s.__setattr__(x, 1) for x in get_widgets()],
371
+ )
372
+ st.add_control(
373
+ "nothing",
374
+ "Uncheck all",
375
+ control="button",
376
+ datalen=10,
377
+ valid=lambda: [st.s.__setattr__(x, 0) for x in get_widgets()],
378
+ )
379
+ st.add_control(
380
+ "invert",
381
+ "Invert",
382
+ control="button",
383
+ datalen=10,
384
+ valid=lambda: [st.s.__setattr__(x, 0 if st.s.__getattr__(x) else 1) for x in get_widgets()],
385
+ )
386
+ st.add_control("/")
387
+ st.run()
388
+
389
+ if st.ok_pressed:
390
+ self.selected_tables = [
391
+ table for index, table in enumerate(tables) if st.s.__getattr__(f"c_{index}")
392
+ ]
393
+ return True
394
+
335
395
  def export_data(self, file=""):
396
+ if not self.tables_selector("export"):
397
+ return
336
398
  filetype = "JSON(*.json)"
337
399
  if not file:
338
400
  file, filetype = q2app.q2_app.get_save_file_dialoq("Export Database", filter=filetype)
@@ -349,14 +411,16 @@ class AppManager(Q2Form):
349
411
  def get_data_json(self):
350
412
  db: Q2Db = q2app.q2_app.db_data
351
413
  rez = {}
352
- for x in db.get_tables():
353
- if x in app_tables:
414
+ for table in db.get_tables():
415
+ if table in app_tables:
354
416
  continue
355
- if x.startswith("log_") or x == "sqlite_sequence":
417
+ if table.startswith("log_") or table == "sqlite_sequence":
356
418
  continue
357
- rez[x] = []
358
- for row in db.table(x).records():
359
- rez[x].append(row)
419
+ if table not in self.selected_tables:
420
+ continue
421
+ rez[table] = []
422
+ for row in db.table(table).records():
423
+ rez[table].append(row)
360
424
  return rez
361
425
 
362
426
  def import_q2market(self):
@@ -410,6 +474,8 @@ class AppManager(Q2Form):
410
474
  q2Mess("<br>".join(errors))
411
475
 
412
476
  def import_data(self, file=""):
477
+ if not self.tables_selector("import"):
478
+ return
413
479
  filetype = "JSON(*.json)"
414
480
  if not file:
415
481
  file, filetype = q2app.q2_app.get_open_file_dialoq("Import Data", filter=filetype)
@@ -418,10 +484,10 @@ class AppManager(Q2Form):
418
484
  return
419
485
 
420
486
  data = json.load(open(file))
421
- self.import_json_data(data)
487
+ self.import_json_data(data, self.selected_tables)
422
488
 
423
489
  @staticmethod
424
- def import_json_data(data):
490
+ def import_json_data(data, selected_tables=[]):
425
491
  db: Q2Db = q2app.q2_app.db_data
426
492
  db_tables = db.get_tables()
427
493
  wait_table = Q2WaitShow(len(data))
@@ -430,6 +496,8 @@ class AppManager(Q2Form):
430
496
  wait_table.step(table)
431
497
  if table not in db_tables:
432
498
  continue
499
+ if selected_tables and table not in selected_tables:
500
+ continue
433
501
  wait_row = Q2WaitShow(len(data[table]))
434
502
  db.cursor(f"delete from {table}")
435
503
  for row in data[table]:
q2rad/q2appselector.py CHANGED
@@ -102,13 +102,14 @@ class Q2AppSelect(Q2Form):
102
102
  self.add_control(
103
103
  "select_data_storage_file",
104
104
  _("?"),
105
+ datalen=3,
105
106
  mess=_("Open Data Storage sqlite database file"),
106
107
  control="button",
107
108
  valid=self.openSqliteDataFile,
108
109
  )
109
110
  self.add_control("/")
110
111
  if self.add_control("/h"):
111
- self.add_control("host_data", _("Host"), gridlabel=_("Data host"), datalen=100)
112
+ self.add_control("host_data", _("Host"), gridlabel=_("Data host"), datalen=100, stretch=90)
112
113
  self.add_control("port_data", _("Port"), gridlabel=_("Data port"), datatype="int")
113
114
  self.add_control(
114
115
  "guest_mode",
@@ -118,6 +119,7 @@ class Q2AppSelect(Q2Form):
118
119
  datalen=1,
119
120
  mess=_("No database schema changes"),
120
121
  )
122
+ self.add_control("/s", stretch=0)
121
123
  self.add_control("/")
122
124
 
123
125
  self.add_control("/")
@@ -145,13 +147,14 @@ class Q2AppSelect(Q2Form):
145
147
  self.add_control(
146
148
  "select_app_storage_file",
147
149
  _("?"),
150
+ datalen=3,
148
151
  mess=_("Open App Storage sqlite database file"),
149
152
  control="button",
150
153
  valid=self.openSqliteDataFile,
151
154
  )
152
155
  self.add_control("/")
153
156
  if self.add_control("/h"):
154
- self.add_control("host_logic", _("Host"), gridlabel=_("Logic host"), datalen=100)
157
+ self.add_control("host_logic", _("Host"), gridlabel=_("Logic host"), datalen=100, stretch=90)
155
158
  self.add_control("port_logic", _("Port"), gridlabel=_("Logic port"), datatype="int")
156
159
  self.add_control(
157
160
  "dev_mode",
@@ -161,6 +164,7 @@ class Q2AppSelect(Q2Form):
161
164
  datalen=1,
162
165
  mess=_("Allow to change App"),
163
166
  )
167
+ self.add_control("/s", stretch=0)
164
168
  self.add_control("/")
165
169
  self.add_control("/")
166
170
 
@@ -307,7 +311,9 @@ class Q2AppSelect(Q2Form):
307
311
  pinform.add_control("/h")
308
312
  pinform.add_control("/s")
309
313
  pinform.add_control("", "Application:", control="label")
310
- pinform.add_control("appname", app_name, control="label", style="color:green;font-weight:bold;background:white")
314
+ pinform.add_control(
315
+ "appname", app_name, control="label", style="color:green;font-weight:bold;background:white"
316
+ )
311
317
  pinform.add_control("/s")
312
318
  pinform.add_control("/")
313
319
  pinform.add_control("/f")
q2rad/q2forms.py CHANGED
@@ -262,7 +262,7 @@ class Q2Forms(Q2Form, Q2_save_and_run):
262
262
  def select_data_storage_table(self):
263
263
  choice = choice_table()
264
264
  if choice:
265
- self.s.form_table = choice['table']
265
+ self.s.form_table = choice["table"]
266
266
  if self.s.name == "":
267
267
  self.s.name = self.s.form_table
268
268
  if self.s.title == "":
@@ -272,7 +272,7 @@ class Q2Forms(Q2Form, Q2_save_and_run):
272
272
  choice = choice_column(self.s.form_table)
273
273
  if choice:
274
274
  self.s.form_table_sort += ", " if self.s.form_table_sort else ""
275
- self.s.form_table_sort += choice['col']
275
+ self.s.form_table_sort += choice["col"]
276
276
 
277
277
  def form_runner(self):
278
278
  name = self.r.name
@@ -283,3 +283,29 @@ class Q2Forms(Q2Form, Q2_save_and_run):
283
283
  q2mess(_("Give me some NAME!!!"))
284
284
  self.w.name.set_focus()
285
285
  return False
286
+
287
+ def after_crud_save(self):
288
+ super().after_crud_save()
289
+ if self.crud_mode != "EDIT":
290
+ if self.s.form_table:
291
+ self.db.insert(
292
+ "lines",
293
+ {
294
+ "name": self.s.name,
295
+ "column": "id",
296
+ "noform": "*",
297
+ "nogrid": "*",
298
+ "datatype": "int",
299
+ "migrate": "*",
300
+ "pk": "*",
301
+ "ai": "*",
302
+ },
303
+ )
304
+ self.db.insert(
305
+ "actions",
306
+ {
307
+ "name": self.s.name,
308
+ "action_mode": "1",
309
+ },
310
+ )
311
+ self.refresh()
q2rad/q2lines.py CHANGED
@@ -22,7 +22,7 @@ from q2rad.q2raddb import last_error
22
22
  from q2rad.q2utils import Q2Form, int_
23
23
 
24
24
  from q2gui import q2app
25
-
25
+ import csv
26
26
 
27
27
  import gettext
28
28
 
@@ -91,7 +91,8 @@ class Q2Lines(Q2Form, Q2_save_and_run):
91
91
  # self.add_seq_actions()
92
92
 
93
93
  self.add_action("Run", self.form_runner, hotkey="F4")
94
- self.add_action("Fill", self.filler)
94
+ self.add_action("Fill from DB", self.filler)
95
+ self.add_action("Fill from CSV", self.csv_filler)
95
96
  self.add_action("-")
96
97
  self.add_action("Select panel", icon="⭥", worker=self.select_panel, hotkey="F3")
97
98
  self.add_action("Copy to", icon="❖", worker=self.copy_to)
@@ -103,6 +104,7 @@ class Q2Lines(Q2Form, Q2_save_and_run):
103
104
 
104
105
  def create_form(self):
105
106
  from q2rad.q2forms import Q2Forms
107
+
106
108
  self.add_control("id", "", datatype="int", pk="*", ai="*", noform=1, nogrid=1)
107
109
  self.add_control("column", _("Column name"), datalen=50)
108
110
  self.add_control("/")
@@ -303,15 +305,7 @@ class Q2Lines(Q2Form, Q2_save_and_run):
303
305
  rows = self.get_grid_selected_rows()
304
306
  choice = choice_form()
305
307
  if choice:
306
- seq = (
307
- int_(
308
- q2cursor(
309
- f"select max(seq) as maxseq from lines where name='{choice['name']}'",
310
- q2app.q2_app.db_logic,
311
- ).r.maxseq
312
- )
313
- + 1
314
- )
308
+ seq = self.get_next_sequence(choice["name"])
315
309
  for x in rows:
316
310
  rec = self.model.get_record(x)
317
311
  rec["seq"] = seq
@@ -321,6 +315,18 @@ class Q2Lines(Q2Form, Q2_save_and_run):
321
315
  print(last_error(q2app.q2_app.db_logic))
322
316
  self.refresh()
323
317
 
318
+ def get_next_sequence(self, form_name):
319
+ seq = (
320
+ int_(
321
+ q2cursor(
322
+ f"select max(seq) as maxseq from lines where name='{form_name}'",
323
+ q2app.q2_app.db_logic,
324
+ ).r.maxseq
325
+ )
326
+ + 1
327
+ )
328
+ return seq
329
+
324
330
  def add_layout(self, layout_type):
325
331
  selected_row = sorted(self.get_grid_selected_rows())
326
332
  if len(selected_row) == 0:
@@ -401,6 +407,7 @@ class Q2Lines(Q2Form, Q2_save_and_run):
401
407
  return
402
408
 
403
409
  cols = self.q2_app.db_data.db_schema.get_schema_columns(self.prev_form.r.form_table)
410
+ seq = self.get_next_sequence(self.prev_form.r.name)
404
411
  for x in cols:
405
412
  if self.db.get("lines", f"name = '{self.prev_form.r.name}' and `column` = '{x}'") == {}:
406
413
  insert(
@@ -414,9 +421,46 @@ class Q2Lines(Q2Form, Q2_save_and_run):
414
421
  "pk": cols[x]["pk"],
415
422
  "ai": cols[x]["ai"],
416
423
  "migrate": "*",
424
+ "seq": seq,
417
425
  },
418
426
  self.db,
419
427
  )
428
+ seq += 1
429
+ self.refresh()
430
+
431
+ def csv_filler(self):
432
+ if self.model.row_count() > 0:
433
+ if q2AskYN("Lines list is not empty! Are you sure") != 2:
434
+ return
435
+
436
+ csv_file_name = q2app.q2_app.get_open_file_dialoq("Open CSV file", filter="CSV (*.csv)")[0]
437
+ if not csv_file_name:
438
+ return
439
+
440
+ with open(csv_file_name) as csv_file:
441
+ reader = csv.DictReader(csv_file, dialect="excel", delimiter=";")
442
+ cols = {x: 0 for x in reader.fieldnames}
443
+ for x in reader:
444
+ for key, value in x.items():
445
+ cols[key] = max(cols[key], len(value))
446
+ cols
447
+ seq = self.get_next_sequence(self.prev_form.r.name)
448
+ for x in cols:
449
+ if self.db.get("lines", f"name = '{self.prev_form.r.name}' and `column` = '{x}'") == {}:
450
+ insert(
451
+ "lines",
452
+ {
453
+ "name": self.prev_form.r.name,
454
+ "column": x,
455
+ "label": x,
456
+ "datatype": "char",
457
+ "datalen": cols[x],
458
+ "migrate": "*",
459
+ "seq": seq,
460
+ },
461
+ self.db,
462
+ )
463
+ seq += 1
420
464
  self.refresh()
421
465
 
422
466
  def before_crud_save(self):
@@ -431,7 +475,6 @@ class Q2Lines(Q2Form, Q2_save_and_run):
431
475
  self.datatype_valid()
432
476
  self.control_valid()
433
477
  self.database_valid()
434
- # self.next_sequense()
435
478
 
436
479
  def datatype_valid(self):
437
480
  self.w.datalen.set_enabled(self.s.datatype in ";".join(HAS_DATALEN))
q2rad/q2rad.py CHANGED
@@ -523,11 +523,11 @@ class Q2RadApp(Q2App):
523
523
  # self.dev_mode = False
524
524
 
525
525
  if self.dev_mode:
526
- self.add_menu("Dev|Forms", self.run_forms, toolbar=self.dev_mode)
527
- self.add_menu("Dev|Modules", self.run_modules, toolbar=self.dev_mode)
528
- self.add_menu("Dev|Querys", self.run_queries, toolbar=self.dev_mode)
529
- self.add_menu("Dev|Reports", self.run_reports, toolbar=self.dev_mode)
530
- self.add_menu("Dev|Packages", self.run_packages, toolbar=self.dev_mode)
526
+ self.add_menu("Dev|Forms", self.run_forms)
527
+ self.add_menu("Dev|Modules", self.run_modules)
528
+ self.add_menu("Dev|Querys", self.run_queries)
529
+ self.add_menu("Dev|Reports", self.run_reports)
530
+ self.add_menu("Dev|Packages", self.run_packages)
531
531
  if not self.frozen:
532
532
  self.add_menu("Dev|-")
533
533
  self.add_menu("Dev|Make binary", self.make_binary)
@@ -731,6 +731,12 @@ class Q2RadApp(Q2App):
731
731
 
732
732
  return latest_version, current_version
733
733
 
734
+ def get_git_package_version(git_package):
735
+ package_name = os.path.basename(git_package)
736
+ package_path = git_package.replace("github.com", "githubusercontent.com")
737
+ version_url = f"https://raw.{package_path}/main/{package_name}/version.py"
738
+ return read_url(version_url).decode().split("=")[-1].strip()
739
+
734
740
  def update_packages(self, packages_list=q2_modules, force=False):
735
741
  if self.frozen:
736
742
  return
@@ -786,7 +792,6 @@ class Q2RadApp(Q2App):
786
792
  mess = ("Upgrading complete!<p>" "The program will be restarted!" "<p><p>") + "<p>".join(upgraded)
787
793
  else:
788
794
  mess = "Updates not found!<p>"
789
- q2Mess(mess)
790
795
  if upgraded:
791
796
  self.restart()
792
797
 
@@ -836,12 +841,6 @@ class Q2RadApp(Q2App):
836
841
  if self.frozen:
837
842
  return
838
843
 
839
- q2mess(
840
- f'"{sys.executable.replace("w.exe", ".exe")}" -m pip install '
841
- f"--upgrade --no-cache-dir {package if isinstance(package, str) else package[1]} "
842
- f"=={latest_version}"
843
- )
844
-
845
844
  def pip_runner():
846
845
  trm = Q2Terminal(callback=print)
847
846
  trm.run(
@@ -919,7 +918,12 @@ class Q2RadApp(Q2App):
919
918
  for package in rez:
920
919
  latest_version, current_version = rez[package]
921
920
  if self.db_logic is not None and package not in q2_modules:
922
- pkg_ver = get("packages", f"package_name='{package}'", "package_version", q2_db=self.db_logic)
921
+ pkg_ver = get(
922
+ "packages",
923
+ f"package_name='{package if isinstance(package, str) else package[0]}'",
924
+ "package_version",
925
+ q2_db=self.db_logic,
926
+ )
923
927
  pkg_ver = pkg_ver if pkg_ver else "99999"
924
928
  if pkg_ver != "":
925
929
  try:
q2rad/q2utils.py CHANGED
@@ -357,7 +357,7 @@ def q2choice(records=[], title="Make your choice", column_title=["Column"]):
357
357
 
358
358
  def choice_table():
359
359
  return q2choice(
360
- [{"table": x} for x in q2app.q2_app.db_data.db_schema.get_schema_tables()],
360
+ [{"table": x} for x in q2app.q2_app.db_data.db_schema.get_schema_tables() if not x.startswith("log_")],
361
361
  title="Select table",
362
362
  column_title="Table",
363
363
  )
q2rad/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.208"
1
+ __version__ = "0.1.210"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: q2rad
3
- Version: 0.1.208
3
+ Version: 0.1.210
4
4
  Summary: RAD - database, GUI, reports
5
5
  Author: Andrei Puchko
6
6
  Author-email: andrei.puchko@gmx.de
@@ -1,24 +1,24 @@
1
1
  q2rad/__init__.py,sha256=Y0Up-UTXOmCYC9llNmTF10CpDDgF2kv10pyHT3-YwmQ,183
2
2
  q2rad/__main__.py,sha256=zP4JARM-FzFHM-vWLehx7c5N4v4m_F-TuMobCdFzr4Q,824
3
3
  q2rad/q2actions.py,sha256=eExRvOSyLhT_v1XCR-DmLEhQ9g_LRkrlyXnwDCjT0LM,8258
4
- q2rad/q2appmanager.py,sha256=pdEdyTXWr9zjdZgVmfNXJrjDmQ_Ntq21udhD1b4vA2I,15975
5
- q2rad/q2appselector.py,sha256=PZWSXaiUswinB_Zj1Q8fyRhzqK9ViB8lUHlNVUr85rI,18597
4
+ q2rad/q2appmanager.py,sha256=RXcR35NDtoyhtWOlPOPt5Ml17JVHgnFy9POCYtJ9dT8,18451
5
+ q2rad/q2appselector.py,sha256=wS945hPfugCcxoEuRWm8nP1849Slw90CrRYgMhBB4nI,18811
6
6
  q2rad/q2constants.py,sha256=dQtN4OMvZw0FATDAFYjolI7eGMVUnNnbTl6qM-ggZ4I,3416
7
- q2rad/q2forms.py,sha256=A5VeBK8OdE3zn0L1TgvCk4OjpB1nLibJqBFfpVZr_Uc,10181
8
- q2rad/q2lines.py,sha256=vMwYCxL8wQmYXWYm_qjJUWcq9xfmY_E7NInmDYtQfws,17537
7
+ q2rad/q2forms.py,sha256=z8YO2uLXf1QxmlDe099IenfWtUl0olW3a1U4uay8kgc,11030
8
+ q2rad/q2lines.py,sha256=KQslxn06vypKSFahCDAa7oFPoo_BhvABTKy5iDEOFbc,19133
9
9
  q2rad/q2make.py,sha256=wXoyBUwf2zaAl9JjWDCbjAteUElRq0O7ippyaMY9eug,6476
10
10
  q2rad/q2market.py,sha256=nyIBhZYqxNSlBXpcxdBRQ1vGSzWV8jI4cQoVa9JdRhE,2589
11
11
  q2rad/q2modules.py,sha256=N3OkUKfiwVZtmDyAtnJcs2Rprd7uIHd0HhjHTyFoN_s,4294
12
12
  q2rad/q2packages.py,sha256=bP-QfNx0-IZ_rNTJ88jeYmNL09Pryjf4V803Yam34Tk,3742
13
13
  q2rad/q2queries.py,sha256=EXcau1UCdPrvTvsYr0857NoXldmrkhdrkmbUTk5LrMQ,12536
14
- q2rad/q2rad.py,sha256=3KvhToAWxxpKL2U8rC60N8r-vgVMKdHtlwqB1uOm8-I,47245
14
+ q2rad/q2rad.py,sha256=oaJ7P9L1vd-w8kKLku4gcIH5y-lC_IxLKOlRtPhr3mQ,47359
15
15
  q2rad/q2raddb.py,sha256=ISqT5EBFO7eaXcQRNpA0hMiRU84kbd-FcfckwKMlGfs,4506
16
16
  q2rad/q2reports.py,sha256=Q-bZONOSDDQPrLziHTpW_L6FS82CkWzxITkv5EX5x98,84439
17
17
  q2rad/q2stylesettings.py,sha256=rEJLyLzsffJEXnMbg9bPB3KHLjYfw-49QgrtcYOfGV0,4769
18
- q2rad/q2utils.py,sha256=QInWNqLaDDvmd0PKDZHrsp3Jx6Nqm_klzUinDCwgJJM,19619
19
- q2rad/version.py,sha256=r6S9Z5bC-KqcliwYKywxzs7SdUqUkWvy19eoa_KcTgY,23
20
- q2rad-0.1.208.dist-info/entry_points.txt,sha256=DmsJQE6f3wYuhdN2h6ARYxSe8_d03paeepfGpdVj5rs,42
21
- q2rad-0.1.208.dist-info/LICENSE,sha256=JRR3LlR18ghhYXT4G2cWgXmnxRvcuVcKlqncWWK4MRY,10347
22
- q2rad-0.1.208.dist-info/METADATA,sha256=gCwzQdDxtmcEdL9Xk_KNEqrIf4ps6q6rdVYp8Yzz62E,3369
23
- q2rad-0.1.208.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
24
- q2rad-0.1.208.dist-info/RECORD,,
18
+ q2rad/q2utils.py,sha256=qpyw0V92DI8LcrUkWrtPlFoD9G2SGLXMfGwLGBLn3EU,19647
19
+ q2rad/version.py,sha256=FiJHVGUWIUbI3cvPHtojUuqMLuCH8j90dVwrKzHcfB0,23
20
+ q2rad-0.1.210.dist-info/entry_points.txt,sha256=DmsJQE6f3wYuhdN2h6ARYxSe8_d03paeepfGpdVj5rs,42
21
+ q2rad-0.1.210.dist-info/LICENSE,sha256=JRR3LlR18ghhYXT4G2cWgXmnxRvcuVcKlqncWWK4MRY,10347
22
+ q2rad-0.1.210.dist-info/METADATA,sha256=HDfXUh-laM24a7KeH568_aiuyoSkkldq6At1oQokVsk,3369
23
+ q2rad-0.1.210.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
24
+ q2rad-0.1.210.dist-info/RECORD,,