anywidget-graph 0.2.6__tar.gz → 0.2.7__tar.gz

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.
Files changed (41) hide show
  1. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/PKG-INFO +1 -1
  2. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/pyproject.toml +1 -1
  3. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/__init__.py +1 -1
  4. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/icons.js +1 -0
  5. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/index.js +62 -2
  6. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/styles.css +48 -1
  7. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/toolbar.js +33 -1
  8. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/uv.lock +29 -29
  9. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/.github/workflows/ci.yml +0 -0
  10. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/.github/workflows/pypi.yml +0 -0
  11. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/.gitignore +0 -0
  12. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/.python-version +0 -0
  13. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/LICENSE +0 -0
  14. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/README.md +0 -0
  15. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/examples/demo.py +0 -0
  16. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/__init__.py +0 -0
  17. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/arango.py +0 -0
  18. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/cosmosdb.py +0 -0
  19. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/grafeo.py +0 -0
  20. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/ladybug.py +0 -0
  21. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/backends/neo4j.py +0 -0
  22. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/__init__.py +0 -0
  23. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/base.py +0 -0
  24. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/common.py +0 -0
  25. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/cypher.py +0 -0
  26. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/gql.py +0 -0
  27. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/graphql.py +0 -0
  28. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/gremlin.py +0 -0
  29. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/converters/sparql.py +0 -0
  30. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/demo.py +0 -0
  31. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/py.typed +0 -0
  32. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/__init__.py +0 -0
  33. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/grafeo-embed.js +0 -0
  34. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/grafeo.js +0 -0
  35. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/neo4j.js +0 -0
  36. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/properties.js +0 -0
  37. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/schema.js +0 -0
  38. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/ui/settings.js +0 -0
  39. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/src/anywidget_graph/widget.py +0 -0
  40. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/tests/__init__.py +0 -0
  41. {anywidget_graph-0.2.6 → anywidget_graph-0.2.7}/tests/test_graph.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anywidget-graph
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Interactive graph visualization for Python notebooks using anywidget
5
5
  Project-URL: Homepage, https://grafeo.dev/
6
6
  Project-URL: Repository, https://github.com/GrafeoDB/anywidget-graph
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "anywidget-graph"
3
- version = "0.2.6"
3
+ version = "0.2.7"
4
4
  description = "Interactive graph visualization for Python notebooks using anywidget"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -3,4 +3,4 @@
3
3
  from anywidget_graph.widget import Graph
4
4
 
5
5
  __all__ = ["Graph"]
6
- __version__ = "0.2.5"
6
+ __version__ = "0.2.7"
@@ -15,4 +15,5 @@ export const ICONS = {
15
15
  zoomIn: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>`,
16
16
  zoomOut: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="8" y1="11" x2="14" y2="11"/></svg>`,
17
17
  zoomFit: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg>`,
18
+ search: `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`,
18
19
  };
@@ -236,9 +236,28 @@ function render({ model, el }) {
236
236
  // Panel references for mutual exclusion
237
237
  const panels = { schema, settings, properties };
238
238
 
239
+ // Search state (shared with nodeReducer)
240
+ let searchTerm = "";
241
+ let searchMatches = new Set();
242
+
243
+ function onSearch(term) {
244
+ searchTerm = (term || "").toLowerCase().trim();
245
+ searchMatches.clear();
246
+ if (searchTerm) {
247
+ graph.forEachNode((id, attrs) => {
248
+ const label = (attrs.label || "").toLowerCase();
249
+ const nodeId = String(id).toLowerCase();
250
+ if (label.includes(searchTerm) || nodeId.includes(searchTerm)) {
251
+ searchMatches.add(id);
252
+ }
253
+ });
254
+ }
255
+ renderer.refresh();
256
+ }
257
+
239
258
  // Create toolbar if enabled
240
259
  if (model.get("show_toolbar")) {
241
- const toolbar = createToolbar(model, onExecuteQuery, panels);
260
+ const toolbar = createToolbar(model, onExecuteQuery, panels, onSearch);
242
261
  wrapper.appendChild(toolbar);
243
262
  }
244
263
 
@@ -351,7 +370,7 @@ function render({ model, el }) {
351
370
  labelWeight: "500",
352
371
  });
353
372
 
354
- // Node reducer for selection highlighting + pinned indicator
373
+ // Node reducer for selection highlighting, search filtering, and pinned indicator
355
374
  renderer.setSetting("nodeReducer", (node, data) => {
356
375
  const selectedNodes = model.get("selected_nodes") || [];
357
376
  const pinnedNodes = model.get("pinned_nodes") || {};
@@ -363,6 +382,12 @@ function render({ model, el }) {
363
382
  res.label = "";
364
383
  }
365
384
 
385
+ // Dim non-matching nodes when search is active
386
+ if (searchTerm && !searchMatches.has(node)) {
387
+ res.color = data.color + "20";
388
+ res.label = "";
389
+ }
390
+
366
391
  // Show ring on pinned nodes
367
392
  if (pinnedNodes[node]) {
368
393
  res.borderColor = "#f59e0b";
@@ -676,6 +701,41 @@ function render({ model, el }) {
676
701
  model.save_changes();
677
702
  });
678
703
 
704
+ // Keyboard shortcuts
705
+ wrapper.tabIndex = 0;
706
+ wrapper.style.outline = "none";
707
+ wrapper.addEventListener("keydown", (e) => {
708
+ const tag = e.target.tagName;
709
+ if (tag === "INPUT" || tag === "SELECT" || tag === "TEXTAREA") return;
710
+
711
+ if (e.key === "f" || e.key === "F") {
712
+ e.preventDefault();
713
+ renderer.getCamera().animatedReset({ duration: 200 });
714
+ } else if (e.key === "Escape") {
715
+ model.set("selected_node", null);
716
+ model.set("selected_edge", null);
717
+ model.set("selected_nodes", []);
718
+ model.set("selected_edges", []);
719
+ model.save_changes();
720
+ } else if (e.key === "Delete" || e.key === "Backspace") {
721
+ const selected = model.get("selected_nodes") || [];
722
+ if (selected.length === 0) return;
723
+ e.preventDefault();
724
+ const removeSet = new Set(selected);
725
+ const nodes = (model.get("nodes") || []).filter(n => !removeSet.has(n.id));
726
+ const edges = (model.get("edges") || []).filter(
727
+ edge => !removeSet.has(edge.source) && !removeSet.has(edge.target)
728
+ );
729
+ model.set("nodes", nodes);
730
+ model.set("edges", edges);
731
+ model.set("selected_node", null);
732
+ model.set("selected_edge", null);
733
+ model.set("selected_nodes", []);
734
+ model.set("selected_edges", []);
735
+ model.save_changes();
736
+ }
737
+ });
738
+
679
739
  // Double-click node: unpin if pinned, otherwise expand (fetch neighbors)
680
740
  renderer.on("doubleClickNode", ({ node }) => {
681
741
  const pinned = { ...(model.get("pinned_nodes") || {}) };
@@ -90,6 +90,53 @@
90
90
  color: var(--awg-text-muted);
91
91
  }
92
92
 
93
+ /* === SEARCH INPUT === */
94
+ .awg-search-wrap {
95
+ display: flex;
96
+ align-items: center;
97
+ position: relative;
98
+ flex-shrink: 0;
99
+ }
100
+
101
+ .awg-search-icon {
102
+ position: absolute;
103
+ left: 8px;
104
+ color: var(--awg-text-muted);
105
+ display: flex;
106
+ pointer-events: none;
107
+ }
108
+
109
+ .awg-search-input {
110
+ width: 140px;
111
+ padding: 6px 8px 6px 28px;
112
+ border: 1px solid var(--awg-input-border);
113
+ border-radius: 6px;
114
+ font-size: 12px;
115
+ background: var(--awg-input-bg);
116
+ color: var(--awg-text);
117
+ transition: border-color 0.15s, box-shadow 0.15s, width 0.2s;
118
+ }
119
+
120
+ .awg-search-input:focus {
121
+ outline: none;
122
+ border-color: var(--awg-accent);
123
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.15);
124
+ width: 180px;
125
+ }
126
+
127
+ .awg-search-input::placeholder {
128
+ color: var(--awg-text-muted);
129
+ }
130
+
131
+ /* === COUNT BADGE === */
132
+ .awg-count-badge {
133
+ font-size: 11px;
134
+ color: var(--awg-text-muted);
135
+ white-space: nowrap;
136
+ flex-shrink: 0;
137
+ font-variant-numeric: tabular-nums;
138
+ }
139
+
93
140
  /* === BUTTONS === */
94
141
  .awg-btn {
95
142
  display: inline-flex;
@@ -218,7 +265,7 @@
218
265
  display: flex;
219
266
  flex-direction: column;
220
267
  gap: 2px;
221
- z-index: 10;
268
+ z-index: 25;
222
269
  }
223
270
 
224
271
  .awg-zoom-btn {
@@ -7,8 +7,9 @@ import { updateStatusDot } from "./settings.js";
7
7
  /**
8
8
  * Create the toolbar component.
9
9
  * @param {object} panels - { schema, settings, properties } panel objects with toggle/close/isOpen
10
+ * @param {function} onSearch - callback(term) for search filtering
10
11
  */
11
- export function createToolbar(model, onExecuteQuery, panels) {
12
+ export function createToolbar(model, onExecuteQuery, panels, onSearch) {
12
13
  const toolbar = document.createElement("div");
13
14
  toolbar.className = "awg-toolbar";
14
15
 
@@ -71,6 +72,37 @@ export function createToolbar(model, onExecuteQuery, panels) {
71
72
  toolbar.appendChild(queryContainer);
72
73
  }
73
74
 
75
+ // Search input (compact filter for nodes)
76
+ const searchWrap = document.createElement("div");
77
+ searchWrap.className = "awg-search-wrap";
78
+ const searchIcon = document.createElement("span");
79
+ searchIcon.className = "awg-search-icon";
80
+ searchIcon.innerHTML = ICONS.search;
81
+ searchWrap.appendChild(searchIcon);
82
+
83
+ const searchInput = document.createElement("input");
84
+ searchInput.type = "text";
85
+ searchInput.className = "awg-search-input";
86
+ searchInput.placeholder = "Filter nodes...";
87
+ searchInput.addEventListener("input", () => {
88
+ onSearch?.(searchInput.value);
89
+ });
90
+ searchWrap.appendChild(searchInput);
91
+ toolbar.appendChild(searchWrap);
92
+
93
+ // Count badge
94
+ const countBadge = document.createElement("span");
95
+ countBadge.className = "awg-count-badge";
96
+ function updateCount() {
97
+ const nodes = model.get("nodes") || [];
98
+ const edges = model.get("edges") || [];
99
+ countBadge.textContent = `${nodes.length} nodes \u00b7 ${edges.length} edges`;
100
+ }
101
+ updateCount();
102
+ model.on("change:nodes", updateCount);
103
+ model.on("change:edges", updateCount);
104
+ toolbar.appendChild(countBadge);
105
+
74
106
  // Settings button (mutual exclusion with properties)
75
107
  if (model.get("show_settings")) {
76
108
  const settingsBtn = document.createElement("button");
@@ -154,7 +154,7 @@ wheels = [
154
154
 
155
155
  [[package]]
156
156
  name = "anywidget-graph"
157
- version = "0.2.6"
157
+ version = "0.2.7"
158
158
  source = { editable = "." }
159
159
  dependencies = [
160
160
  { name = "anywidget" },
@@ -191,16 +191,16 @@ dev = [
191
191
  [package.metadata]
192
192
  requires-dist = [
193
193
  { name = "anywidget", specifier = ">=0.9.21" },
194
- { name = "grafeo", marker = "extra == 'grafeo'", specifier = ">=0.5.0" },
194
+ { name = "grafeo", marker = "extra == 'grafeo'", specifier = ">=0.5" },
195
195
  { name = "gremlinpython", marker = "extra == 'cosmosdb'", specifier = ">=3.7" },
196
196
  { name = "marimo", specifier = ">=0.19.9" },
197
- { name = "marimo", marker = "extra == 'dev'", specifier = ">=0.19.9" },
197
+ { name = "marimo", marker = "extra == 'dev'", specifier = ">=0.20" },
198
198
  { name = "networkx", marker = "extra == 'networkx'", specifier = ">=3.0" },
199
199
  { name = "pandas", marker = "extra == 'pandas'", specifier = ">=2.0" },
200
- { name = "prek", marker = "extra == 'dev'", specifier = ">=0.3.2" },
200
+ { name = "prek", marker = "extra == 'dev'", specifier = ">=0.3" },
201
201
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" },
202
- { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.0" },
203
- { name = "ty", marker = "extra == 'dev'", specifier = ">=0.0.16" },
202
+ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15" },
203
+ { name = "ty", marker = "extra == 'dev'", specifier = ">=0.0.20" },
204
204
  ]
205
205
 
206
206
  [package.metadata.requires-dev]
@@ -614,7 +614,7 @@ wheels = [
614
614
 
615
615
  [[package]]
616
616
  name = "marimo"
617
- version = "0.19.10"
617
+ version = "0.20.4"
618
618
  source = { registry = "https://pypi.org/simple" }
619
619
  dependencies = [
620
620
  { name = "click" },
@@ -635,9 +635,9 @@ dependencies = [
635
635
  { name = "uvicorn" },
636
636
  { name = "websockets" },
637
637
  ]
638
- sdist = { url = "https://files.pythonhosted.org/packages/2b/1f/da120728d93960e7db35840800af9216cd300ef02fa2831b085186614c82/marimo-0.19.10.tar.gz", hash = "sha256:a4fad325b8c5e7aef77c21d62764c20899c352dfa1afbc44c30760ae081d2b27", size = 38202668 }
638
+ sdist = { url = "https://files.pythonhosted.org/packages/9c/eb/3c19ce54be3440cece96bffbb2027c57d618ab336d53ef6a962f570ce468/marimo-0.20.4.tar.gz", hash = "sha256:7f46ce837953717504673e33e47fb42a619bf5f9d2000d1a3a3b1663a47c5498", size = 38336283 }
639
639
  wheels = [
640
- { url = "https://files.pythonhosted.org/packages/f5/cd/b1c382afc8f00c05bb52202fdfdd8db2ffbd0c13a96e6d1eb93fd5d72516/marimo-0.19.10-py3-none-any.whl", hash = "sha256:c87541222cbf34ab864e91c88d72d6a8abf3a6db8a9bc93968e21bd58390a944", size = 38608642 },
640
+ { url = "https://files.pythonhosted.org/packages/56/62/bf2c92cc7aab69edfb3907e9bf102c37c1e16b8f4bc6ddd4258ae4c8063c/marimo-0.20.4-py3-none-any.whl", hash = "sha256:3200edd7209f470821b58deb4a45e0577889fab1052748d77088f18bef7d9dd8", size = 38752562 },
641
641
  ]
642
642
 
643
643
  [[package]]
@@ -1381,26 +1381,26 @@ wheels = [
1381
1381
 
1382
1382
  [[package]]
1383
1383
  name = "ty"
1384
- version = "0.0.16"
1385
- source = { registry = "https://pypi.org/simple" }
1386
- sdist = { url = "https://files.pythonhosted.org/packages/ee/18/77f84d89db54ea0d1d1b09fa2f630ac4c240c8e270761cb908c06b6e735c/ty-0.0.16.tar.gz", hash = "sha256:a999b0db6aed7d6294d036ebe43301105681e0c821a19989be7c145805d7351c", size = 5129637 }
1387
- wheels = [
1388
- { url = "https://files.pythonhosted.org/packages/67/b9/909ebcc7f59eaf8a2c18fb54bfcf1c106f99afb3e5460058d4b46dec7b20/ty-0.0.16-py3-none-linux_armv6l.whl", hash = "sha256:6d8833b86396ed742f2b34028f51c0e98dbf010b13ae4b79d1126749dc9dab15", size = 10113870 },
1389
- { url = "https://files.pythonhosted.org/packages/c3/2c/b963204f3df2fdbf46a4a1ea4a060af9bb676e065d59c70ad0f5ae0dbae8/ty-0.0.16-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:934c0055d3b7f1cf3c8eab78c6c127ef7f347ff00443cef69614bda6f1502377", size = 9936286 },
1390
- { url = "https://files.pythonhosted.org/packages/ef/4d/3d78294f2ddfdded231e94453dea0e0adef212b2bd6536296039164c2a3e/ty-0.0.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b55e8e8733b416d914003cd22e831e139f034681b05afed7e951cc1a5ea1b8d4", size = 9442660 },
1391
- { url = "https://files.pythonhosted.org/packages/15/40/ce48c0541e3b5749b0890725870769904e6b043e077d4710e5325d5cf807/ty-0.0.16-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feccae8f4abd6657de111353bd604f36e164844466346eb81ffee2c2b06ea0f0", size = 9934506 },
1392
- { url = "https://files.pythonhosted.org/packages/84/16/3b29de57e1ec6e56f50a4bb625ee0923edb058c5f53e29014873573a00cd/ty-0.0.16-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1cad5e29d8765b92db5fa284940ac57149561f3f89470b363b9aab8a6ce553b0", size = 9933099 },
1393
- { url = "https://files.pythonhosted.org/packages/f7/a1/e546995c25563d318c502b2f42af0fdbed91e1fc343708241e2076373644/ty-0.0.16-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86f28797c7dc06f081238270b533bf4fc8e93852f34df49fb660e0b58a5cda9a", size = 10438370 },
1394
- { url = "https://files.pythonhosted.org/packages/11/c1/22d301a4b2cce0f75ae84d07a495f87da193bcb68e096d43695a815c4708/ty-0.0.16-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be971a3b42bcae44d0e5787f88156ed2102ad07558c05a5ae4bfd32a99118e66", size = 10992160 },
1395
- { url = "https://files.pythonhosted.org/packages/6f/40/f1892b8c890db3f39a1bab8ec459b572de2df49e76d3cad2a9a239adcde9/ty-0.0.16-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c9f982b7c4250eb91af66933f436b3a2363c24b6353e94992eab6551166c8b7", size = 10717892 },
1396
- { url = "https://files.pythonhosted.org/packages/2f/1b/caf9be8d0c738983845f503f2e92ea64b8d5fae1dd5ca98c3fca4aa7dadc/ty-0.0.16-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d122edf85ce7bdf6f85d19158c991d858fc835677bd31ca46319c4913043dc84", size = 10510916 },
1397
- { url = "https://files.pythonhosted.org/packages/60/ea/28980f5c7e1f4c9c44995811ea6a36f2fcb205232a6ae0f5b60b11504621/ty-0.0.16-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:497ebdddbb0e35c7758ded5aa4c6245e8696a69d531d5c9b0c1a28a075374241", size = 9908506 },
1398
- { url = "https://files.pythonhosted.org/packages/f7/80/8672306596349463c21644554f935ff8720679a14fd658fef658f66da944/ty-0.0.16-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e1e0ac0837bde634b030243aeba8499383c0487e08f22e80f5abdacb5b0bd8ce", size = 9949486 },
1399
- { url = "https://files.pythonhosted.org/packages/8b/8a/d8747d36f30bd82ea157835f5b70d084c9bb5d52dd9491dba8a149792d6a/ty-0.0.16-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1216c9bcca551d9f89f47a817ebc80e88ac37683d71504e5509a6445f24fd024", size = 10145269 },
1400
- { url = "https://files.pythonhosted.org/packages/6f/4c/753535acc7243570c259158b7df67e9c9dd7dab9a21ee110baa4cdcec45d/ty-0.0.16-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:221bbdd2c6ee558452c96916ab67fcc465b86967cf0482e19571d18f9c831828", size = 10608644 },
1401
- { url = "https://files.pythonhosted.org/packages/3e/05/8e8db64cf45a8b16757e907f7a3bfde8d6203e4769b11b64e28d5bdcd79a/ty-0.0.16-py3-none-win32.whl", hash = "sha256:d52c4eb786be878e7514cab637200af607216fcc5539a06d26573ea496b26512", size = 9582579 },
1402
- { url = "https://files.pythonhosted.org/packages/25/bc/45759faea132cd1b2a9ff8374e42ba03d39d076594fbb94f3e0e2c226c62/ty-0.0.16-py3-none-win_amd64.whl", hash = "sha256:f572c216aa8ecf79e86589c6e6d4bebc01f1f3cb3be765c0febd942013e1e73a", size = 10436043 },
1403
- { url = "https://files.pythonhosted.org/packages/7f/02/70a491802e7593e444137ed4e41a04c34d186eb2856f452dd76b60f2e325/ty-0.0.16-py3-none-win_arm64.whl", hash = "sha256:430eadeb1c0de0c31ef7bef9d002bdbb5f25a31e3aad546f1714d76cd8da0a87", size = 9915122 },
1384
+ version = "0.0.20"
1385
+ source = { registry = "https://pypi.org/simple" }
1386
+ sdist = { url = "https://files.pythonhosted.org/packages/56/95/8de69bb98417227b01f1b1d743c819d6456c9fd140255b6124b05b17dfd6/ty-0.0.20.tar.gz", hash = "sha256:ebba6be7974c14efbb2a9adda6ac59848f880d7259f089dfa72a093039f1dcc6", size = 5262529 }
1387
+ wheels = [
1388
+ { url = "https://files.pythonhosted.org/packages/0b/2c/718abe48393e521bf852cd6b0f984766869b09c258d6e38a118768a91731/ty-0.0.20-py3-none-linux_armv6l.whl", hash = "sha256:7cc12769c169c9709a829c2248ee2826b7aae82e92caeac813d856f07c021eae", size = 10333656 },
1389
+ { url = "https://files.pythonhosted.org/packages/41/0e/eb1c4cc4a12862e2327b72657bcebb10b7d9f17046f1bdcd6457a0211615/ty-0.0.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b777c1bf13bc0a95985ebb8a324b8668a4a9b2e514dde5ccf09e4d55d2ff232", size = 10168505 },
1390
+ { url = "https://files.pythonhosted.org/packages/89/7f/10230798e673f0dd3094dfd16e43bfd90e9494e7af6e8e7db516fb431ddf/ty-0.0.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b2a4a7db48bf8cba30365001bc2cad7fd13c1a5aacdd704cc4b7925de8ca5eb3", size = 9678510 },
1391
+ { url = "https://files.pythonhosted.org/packages/7a/3d/59d9159577494edd1728f7db77b51bb07884bd21384f517963114e3ab5f6/ty-0.0.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6846427b8b353a43483e9c19936dc6a25612573b44c8f7d983dfa317e7f00d4c", size = 10162926 },
1392
+ { url = "https://files.pythonhosted.org/packages/9c/a8/b7273eec3e802f78eb913fbe0ce0c16ef263723173e06a5776a8359b2c66/ty-0.0.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:245ceef5bd88df366869385cf96411cb14696334f8daa75597cf7e41c3012eb8", size = 10171702 },
1393
+ { url = "https://files.pythonhosted.org/packages/9f/32/5f1144f2f04a275109db06e3498450c4721554215b80ae73652ef412eeab/ty-0.0.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4d21d1cdf67a444d3c37583c17291ddba9382a9871021f3f5d5735e09e85efe", size = 10682552 },
1394
+ { url = "https://files.pythonhosted.org/packages/6a/db/9f1f637310792f12bd6ed37d5fc8ab39ba1a9b0c6c55a33865e9f1cad840/ty-0.0.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd4ffd907d1bd70e46af9e9a2f88622f215e1bf44658ea43b32c2c0b357299e4", size = 11242605 },
1395
+ { url = "https://files.pythonhosted.org/packages/1a/68/cc9cae2e732fcfd20ccdffc508407905a023fc8493b8771c392d915528dc/ty-0.0.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6594b58d8b0e9d16a22b3045fc1305db4b132c8d70c17784ab8c7a7cc986807", size = 10974655 },
1396
+ { url = "https://files.pythonhosted.org/packages/1c/c1/b9e3e3f28fe63486331e653f6aeb4184af8b1fe80542fcf74d2dda40a93d/ty-0.0.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3662f890518ce6cf4d7568f57d03906912d2afbf948a01089a28e325b1ef198c", size = 10761325 },
1397
+ { url = "https://files.pythonhosted.org/packages/39/9e/67db935bdedf219a00fb69ec5437ba24dab66e0f2e706dd54a4eca234b84/ty-0.0.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0e3ffbae58f9f0d17cdc4ac6d175ceae560b7ed7d54f9ddfb1c9f31054bcdc2c", size = 10145793 },
1398
+ { url = "https://files.pythonhosted.org/packages/c7/de/b0eb815d4dc5a819c7e4faddc2a79058611169f7eef07ccc006531ce228c/ty-0.0.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:176e52bc8bb00b0e84efd34583962878a447a3a0e34ecc45fd7097a37554261b", size = 10189640 },
1399
+ { url = "https://files.pythonhosted.org/packages/b8/71/63734923965cbb70df1da3e93e4b8875434e326b89e9f850611122f279bf/ty-0.0.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b2bc73025418e976ca4143dde71fb9025a90754a08ac03e6aa9b80d4bed1294b", size = 10370568 },
1400
+ { url = "https://files.pythonhosted.org/packages/32/a0/a532c2048533347dff48e9ca98bd86d2c224356e101688a8edaf8d6973fb/ty-0.0.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d52f7c9ec6e363e094b3c389c344d5a140401f14a77f0625e3f28c21918552f5", size = 10853999 },
1401
+ { url = "https://files.pythonhosted.org/packages/48/88/36c652c658fe96658043e4abc8ea97801de6fb6e63ab50aaa82807bff1d8/ty-0.0.20-py3-none-win32.whl", hash = "sha256:c7d32bfe93f8fcaa52b6eef3f1b930fd7da410c2c94e96f7412c30cfbabf1d17", size = 9744206 },
1402
+ { url = "https://files.pythonhosted.org/packages/ff/a7/a4a13bed1d7fd9d97aaa3c5bb5e6d3e9a689e6984806cbca2ab4c9233cac/ty-0.0.20-py3-none-win_amd64.whl", hash = "sha256:a5e10f40fc4a0a1cbcb740a4aad5c7ce35d79f030836ea3183b7a28f43170248", size = 10711999 },
1403
+ { url = "https://files.pythonhosted.org/packages/8d/7e/6bfd748a9f4ff9267ed3329b86a0f02cdf6ab49f87bc36c8a164852f99fc/ty-0.0.20-py3-none-win_arm64.whl", hash = "sha256:53f7a5c12c960e71f160b734f328eff9a35d578af4b67a36b0bb5990ac5cdc27", size = 10150143 },
1404
1404
  ]
1405
1405
 
1406
1406
  [[package]]
File without changes