code-node-graph 0.1.0__py3-none-any.whl → 0.3.0__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.
- code_node/__init__.py +1 -1
- code_node/report/graph.py +153 -4
- code_node/report/style.py +62 -14
- code_node/report/walk.py +42 -7
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.3.0.dist-info}/METADATA +1 -1
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.3.0.dist-info}/RECORD +9 -9
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.3.0.dist-info}/WHEEL +0 -0
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.3.0.dist-info}/entry_points.txt +0 -0
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.3.0.dist-info}/licenses/LICENSE +0 -0
code_node/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ from .libraries import Library, register_library
|
|
|
13
13
|
from .platforms import Platform, get_platform, register_platform
|
|
14
14
|
from .project import EntryPoint, Project, entry_points, read_project
|
|
15
15
|
|
|
16
|
-
__version__ = "0.
|
|
16
|
+
__version__ = "0.3.0"
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
"CodeGraph",
|
code_node/report/graph.py
CHANGED
|
@@ -13,8 +13,8 @@ from typing import Any, Callable
|
|
|
13
13
|
|
|
14
14
|
from ..kit.blocks import _Report, _draws
|
|
15
15
|
from ..kit.fmt import _plural
|
|
16
|
-
from ..kit.highlight import _python_lines
|
|
17
|
-
from ..kit.render import _prose
|
|
16
|
+
from ..kit.highlight import _python_html, _python_lines
|
|
17
|
+
from ..kit.render import _CALL_RE, _prose
|
|
18
18
|
from ..kit.text import _esc
|
|
19
19
|
|
|
20
20
|
from ..analysis.graph import CodeGraph, GraphEdge, GraphNode
|
|
@@ -1081,7 +1081,7 @@ def _node_svg(
|
|
|
1081
1081
|
)
|
|
1082
1082
|
classes = " ".join(["cn", f"k-{n.kind}", f"n-{n.id}", *(f"a-{m}" for m in neighbours)]) + (" warn" if warn else "")
|
|
1083
1083
|
return (
|
|
1084
|
-
f'<g class="{_esc(classes)}" transform="translate({x:.1f},{y:.1f})"
|
|
1084
|
+
f'<g class="{_esc(classes)}" transform="translate({x:.1f},{y:.1f})">'
|
|
1085
1085
|
f'<rect class="bg" width="{w:.0f}" height="{h:.0f}" rx="11"/>'
|
|
1086
1086
|
f'<rect class="fg" x=".5" y=".5" width="{w - 1:.0f}" height="{h - 1:.0f}" rx="10.5"/>{"".join(parts)}</g>'
|
|
1087
1087
|
)
|
|
@@ -1175,6 +1175,153 @@ def _g_panel(n: GraphNode, lines_of: Callable[[str], list[str]], editor: str = "
|
|
|
1175
1175
|
)
|
|
1176
1176
|
|
|
1177
1177
|
|
|
1178
|
+
_G_TIP_W = 420 # a box's hover card, wide
|
|
1179
|
+
|
|
1180
|
+
_G_TIP_SIGNATURE = 6 # lines of a def its hover card shows, at most
|
|
1181
|
+
|
|
1182
|
+
_G_TIP_WARNING = "A warning is about it: "
|
|
1183
|
+
|
|
1184
|
+
# a name in the card's sentences worth setting as code: a dotted or keyed path (Records[].s3.bucket.name,
|
|
1185
|
+
# book:{book_id}, s3:GetObject, orders/handler.py) or a variable in capitals (DB_HOST)
|
|
1186
|
+
_G_CODE_RE = re.compile(
|
|
1187
|
+
r"(?<![\w.\-/])([A-Za-z_][\w\-]*(?:[.:/]+[\w{}\-]+|\[\]|\{\w*\})+|[A-Z][A-Z0-9]*_[A-Z0-9_]*[A-Z0-9])(?![\w{])"
|
|
1188
|
+
)
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
def _g_tip_text(text: str) -> str:
|
|
1192
|
+
"""
|
|
1193
|
+
One of the card's sentences as HTML, its calls coloured as Python and its names set as code, every piece escaped.
|
|
1194
|
+
"""
|
|
1195
|
+
out = []
|
|
1196
|
+
for i, piece in enumerate(_CALL_RE.split(text)):
|
|
1197
|
+
if i % 2:
|
|
1198
|
+
out.append(f'<code class="ctk">{_python_html(piece)}</code>')
|
|
1199
|
+
continue
|
|
1200
|
+
for k, part in enumerate(_G_CODE_RE.split(piece)):
|
|
1201
|
+
out.append(f'<code class="ctk ctn">{_esc(part)}</code>' if k % 2 else _esc(part))
|
|
1202
|
+
return "".join(out)
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
def _g_tip_item(item: str) -> str:
|
|
1206
|
+
"""
|
|
1207
|
+
One thing a service box lists, for its card: 'PutItem (dynamodb:PutItem)' as the operation in code and what it
|
|
1208
|
+
needs beside it.
|
|
1209
|
+
"""
|
|
1210
|
+
m = re.fullmatch(r"(.+?) \((.+)\)", item)
|
|
1211
|
+
if not m:
|
|
1212
|
+
return f'<li><code class="ctk ctn">{_esc(item)}</code></li>'
|
|
1213
|
+
return (
|
|
1214
|
+
f'<li><code class="ctk ctn">{_esc(m.group(1))}</code> <span class="ctm">{_g_tip_text(m.group(2))}</span></li>'
|
|
1215
|
+
)
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
def _g_tip_signature(n: GraphNode, lines_of: Callable[[str], list[str]]) -> list[str]:
|
|
1219
|
+
"""
|
|
1220
|
+
A function's def as it's written, in colour: its decorators and the lines up to the colon that opens its body.
|
|
1221
|
+
[] when its file wasn't read.
|
|
1222
|
+
"""
|
|
1223
|
+
if not n.code:
|
|
1224
|
+
return []
|
|
1225
|
+
span = n.code[0]
|
|
1226
|
+
lines = lines_of(span.file)
|
|
1227
|
+
if not lines or span.start > len(lines):
|
|
1228
|
+
return []
|
|
1229
|
+
start = span.start
|
|
1230
|
+
while start > 1 and lines[start - 2].lstrip().startswith("@"):
|
|
1231
|
+
start -= 1
|
|
1232
|
+
shown = []
|
|
1233
|
+
for k in range(start, min(len(lines), span.end, start + _G_TIP_SIGNATURE - 1) + 1):
|
|
1234
|
+
shown.append(lines[k - 1])
|
|
1235
|
+
if k >= span.start and re.sub(r"<[^>]*>", "", lines[k - 1]).rstrip().endswith(":"):
|
|
1236
|
+
break
|
|
1237
|
+
indent = min((len(line) - len(line.lstrip(" ")) for line in shown if line.strip()), default=0)
|
|
1238
|
+
return [line[indent:] for line in shown]
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
def _g_tip(n: GraphNode, lines_of: Callable[[str], list[str]], opens: bool) -> tuple[str, float]:
|
|
1242
|
+
"""
|
|
1243
|
+
What a box says on hover, as a card: what kind of box it is and its name, a function's def in colour and its
|
|
1244
|
+
docstring, then the rest of its words with the code in them set as code, its warnings apart, and when it has a
|
|
1245
|
+
panel (opens), that a click shows its code. With how tall it is likely to be, to pick whether it goes under the
|
|
1246
|
+
box or over it.
|
|
1247
|
+
"""
|
|
1248
|
+
said = [line for line in (n.tip or n.label).split("\n") if line]
|
|
1249
|
+
warnings = [w for line in said if line.startswith(_G_TIP_WARNING) for w in line[len(_G_TIP_WARNING) :].split("; ")]
|
|
1250
|
+
said = [line for line in said if not line.startswith(_G_TIP_WARNING)]
|
|
1251
|
+
mono = n.kind in ("handler", "function")
|
|
1252
|
+
body, tall, sub = [], 80.0 + (20 if n.sub else 0), n.sub
|
|
1253
|
+
if mono and said and _CALL_RE.match(said[0]) and " in " in said[0]: # 'name(args) in file, 3 lines: its doc'
|
|
1254
|
+
head = said.pop(0)
|
|
1255
|
+
signature = _g_tip_signature(n, lines_of) or [_python_html(head.split(" in ", 1)[0])]
|
|
1256
|
+
body.append(f'<pre class="ctc">{chr(10).join(signature)}</pre>')
|
|
1257
|
+
tall += 21 * len(signature) + 34
|
|
1258
|
+
lines = re.search(r", (\d+ lines?)", head)
|
|
1259
|
+
sub = f"{n.sub} · {lines.group(1)}" if lines and n.sub else sub
|
|
1260
|
+
if n.lines and n.lines[0]:
|
|
1261
|
+
body.append(f'<p class="ctd">{_g_tip_text(n.lines[0])}</p>')
|
|
1262
|
+
tall += 23 * math.ceil(len(n.lines[0]) / 42) + 10
|
|
1263
|
+
for line in said:
|
|
1264
|
+
lead, _, rest = line.partition(": ")
|
|
1265
|
+
if rest and lead == n.label: # 'S3: GetObject (s3:GetObject), PutObject (s3:PutObject)': a list
|
|
1266
|
+
items = rest.split(", ")
|
|
1267
|
+
body.append(f'<ul class="ctl">{"".join(_g_tip_item(item) for item in items)}</ul>')
|
|
1268
|
+
tall += 30 * len(items) + 8
|
|
1269
|
+
else:
|
|
1270
|
+
body.append(f'<p class="ctp">{_g_tip_text(line)}</p>')
|
|
1271
|
+
tall += 23 * math.ceil(len(line) / 42) + 10
|
|
1272
|
+
if warnings:
|
|
1273
|
+
body.append(
|
|
1274
|
+
'<div class="ctw"><b>Warning</b><ul>'
|
|
1275
|
+
+ "".join(f"<li>{_g_tip_text(w)}</li>" for w in warnings)
|
|
1276
|
+
+ "</ul></div>"
|
|
1277
|
+
)
|
|
1278
|
+
tall += 50 + sum(23 * math.ceil(len(w) / 36) + 4 for w in warnings)
|
|
1279
|
+
kind = _G_PANEL_KINDS.get(n.kind, n.kind)
|
|
1280
|
+
name = _python_html(n.label) if mono else _esc(n.label)
|
|
1281
|
+
card = (
|
|
1282
|
+
f'<div class="ctt k-{_esc(n.kind)}{" warn" if warnings else ""}"><div class="cth">'
|
|
1283
|
+
f'<span class="ctkd">{_esc(kind)}</span><b class="ctn{" mono" if mono else ""}">{name}</b>'
|
|
1284
|
+
+ (f'<span class="cts{" mono" if mono else ""}">{_esc(sub)}</span>' if sub else "")
|
|
1285
|
+
+ f"</div>{''.join(body)}"
|
|
1286
|
+
+ ('<div class="cto">Click it to read its code</div>' if opens else "")
|
|
1287
|
+
+ "</div>"
|
|
1288
|
+
)
|
|
1289
|
+
return card, tall + (40 if opens else 0)
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
def _g_tip_svg(
|
|
1293
|
+
n: GraphNode,
|
|
1294
|
+
box: tuple[float, float, float, float],
|
|
1295
|
+
width: float,
|
|
1296
|
+
tall: float,
|
|
1297
|
+
lines_of: Callable[[str], list[str]],
|
|
1298
|
+
opens: bool,
|
|
1299
|
+
) -> str:
|
|
1300
|
+
"""
|
|
1301
|
+
A box's hover card, in the graph so it zooms with it: under the box when it fits there, else over it, else beside
|
|
1302
|
+
it, and inside the graph from left to right. Hidden until the box is pointed at.
|
|
1303
|
+
"""
|
|
1304
|
+
card, high = _g_tip(n, lines_of, opens)
|
|
1305
|
+
x, y, w, h = box
|
|
1306
|
+
card_w = min(_G_TIP_W, max(width - 16, 220))
|
|
1307
|
+
left = max(8.0, min(x, width - card_w - 8))
|
|
1308
|
+
below, above = tall - (y + h + 10) - 8, y - 10 - 8
|
|
1309
|
+
if high <= below:
|
|
1310
|
+
top, room, side = y + h + 10, below, "dn"
|
|
1311
|
+
elif high <= above:
|
|
1312
|
+
top, room, side = 8.0, above, "up"
|
|
1313
|
+
else: # beside the box, as high up as keeps all of it in the graph; over the box only when there's no room beside
|
|
1314
|
+
if width - (x + w + 12) - 8 >= card_w:
|
|
1315
|
+
left = x + w + 12
|
|
1316
|
+
elif x - 12 - 8 >= card_w:
|
|
1317
|
+
left = x - 12 - card_w
|
|
1318
|
+
top, room, side = max(8.0, min(y, tall - high - 8)), high, "dn"
|
|
1319
|
+
return (
|
|
1320
|
+
f'<foreignObject class="ctip tp-{_esc(n.id)} {side}" x="{left:.0f}" y="{top:.0f}" width="{card_w:.0f}" '
|
|
1321
|
+
f'height="{room:.0f}" aria-hidden="true"><div class="ctx">{card}</div></foreignObject>'
|
|
1322
|
+
)
|
|
1323
|
+
|
|
1324
|
+
|
|
1178
1325
|
def _g_captions(graph: CodeGraph, xs: dict[int, float], widths: dict[int, float], column_of: dict[str, int]) -> str:
|
|
1179
1326
|
"""
|
|
1180
1327
|
The words over the columns: COMES IN, HANDLER, CALLS, REACHES, each over the columns it covers.
|
|
@@ -1256,6 +1403,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1256
1403
|
for n in graph.nodes: # pointing at a box leaves only it, its arrows and the boxes they join in sight
|
|
1257
1404
|
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .ce:not(.s-{n.id}):not(.t-{n.id}){{opacity:.06}}")
|
|
1258
1405
|
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .cn:not(.n-{n.id}):not(.a-{n.id}){{opacity:.28}}")
|
|
1406
|
+
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .tp-{n.id}{{display:inline}}")
|
|
1259
1407
|
report.rules.add(
|
|
1260
1408
|
f".{root} .cg:has(.n-{n.id}:hover) :is(.s-{n.id},.t-{n.id}) .ln{{stroke-width:2.4;stroke-opacity:1}}"
|
|
1261
1409
|
)
|
|
@@ -1307,6 +1455,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1307
1455
|
for n in graph.nodes
|
|
1308
1456
|
for box in [_node_svg(cards[n.id], boxes[n.id], list(dict.fromkeys(near[n.id])), access[n.id])]
|
|
1309
1457
|
)
|
|
1458
|
+
tips = "".join(_g_tip_svg(n, boxes[n.id], width, tall, lines_of, bool(panels.get(n.id))) for n in graph.nodes)
|
|
1310
1459
|
kinds = {e.kind for e in graph.edges}
|
|
1311
1460
|
pills = [f'<span class="kp">{_g_swatch(k)}{_esc(word)}</span>' for k, word in _G_LEGEND if k in kinds]
|
|
1312
1461
|
if any(e.guessed for e in graph.edges):
|
|
@@ -1362,7 +1511,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1362
1511
|
f'{title}<div class="cgw">{switches}<div class="cgb">{bar}<div class="cg">'
|
|
1363
1512
|
f'<svg viewBox="0 0 {width:.0f} {tall:.0f}" width="{width:.0f}" height="{tall:.0f}" '
|
|
1364
1513
|
f'style="--w:{width:.0f}px" role="img" aria-label="{_esc(block.title or "How the code fits together")}">'
|
|
1365
|
-
f"{_g_captions(graph, xs, widths, column_of)}{edges}{nodes}{ports}</svg></div>"
|
|
1514
|
+
f"{_g_captions(graph, xs, widths, column_of)}{edges}{nodes}{ports}{tips}</svg></div>"
|
|
1366
1515
|
f'<div class="cgk">{"".join(pills)}{hidden}{hint}</div></div>{"".join(panels.values())}</div>'
|
|
1367
1516
|
)
|
|
1368
1517
|
|
code_node/report/style.py
CHANGED
|
@@ -95,12 +95,12 @@ _EXTRA_CSS = """\
|
|
|
95
95
|
.cnd .flow .oq{font-style:italic}
|
|
96
96
|
.cnd .flow .os{display:inline-flex;flex-wrap:wrap;gap:3px 5px}
|
|
97
97
|
.cnd .flow .ob{margin-left:22px}
|
|
98
|
-
.cnd :is(.flow,.cside,.walk) .pk{color:var(--jp-mirror-editor-keyword-color,light-dark(#7c3aed,#c792ea))}
|
|
99
|
-
.cnd :is(.flow,.cside,.walk) .pf{color:var(--jp-mirror-editor-def-color,light-dark(#2563eb,#82aaff))}
|
|
100
|
-
.cnd :is(.flow,.cside,.walk) :is(.js,.jk){color:var(--jp-mirror-editor-string-color,light-dark(#047857,#a5d6a7))}
|
|
101
|
-
.cnd :is(.flow,.cside,.walk) :is(.jn,.jl){color:var(--jp-mirror-editor-number-color,light-dark(#c2410c,#f78c6c))}
|
|
102
|
-
.cnd :is(.flow,.cside,.walk) .pa{font-style:italic}
|
|
103
|
-
.cnd :is(.flow,.cside,.walk) .pc{opacity:.6;font-style:italic}
|
|
98
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pk{color:var(--jp-mirror-editor-keyword-color,light-dark(#7c3aed,#c792ea))}
|
|
99
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pf{color:var(--jp-mirror-editor-def-color,light-dark(#2563eb,#82aaff))}
|
|
100
|
+
.cnd :is(.flow,.cside,.walk,.ctip) :is(.js,.jk){color:var(--jp-mirror-editor-string-color,light-dark(#047857,#a5d6a7))}
|
|
101
|
+
.cnd :is(.flow,.cside,.walk,.ctip) :is(.jn,.jl){color:var(--jp-mirror-editor-number-color,light-dark(#c2410c,#f78c6c))}
|
|
102
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pa{font-style:italic}
|
|
103
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pc{opacity:.6;font-style:italic}
|
|
104
104
|
.cnd .cgb{width:fit-content;max-width:min(100%,1180px)}
|
|
105
105
|
.cnd .cg{border:1px solid rgba(127,127,127,.2);border-radius:14px;margin:6px 0 8px;overflow:auto;background-color:rgba(127,127,127,.035);background-attachment:local;background-size:18px 18px;
|
|
106
106
|
background-image:radial-gradient(circle at 1px 1px,rgba(127,127,127,.3) 1px,transparent 0);background-position:9px 9px}
|
|
@@ -221,6 +221,34 @@ _EXTRA_CSS = """\
|
|
|
221
221
|
.cnd .cgk .kl path{fill:none;stroke:currentColor;stroke-opacity:.8;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
|
|
222
222
|
.cnd .cg a.cl{cursor:pointer;outline:none}
|
|
223
223
|
.cnd .cg a.cl:focus-visible .fg{stroke:light-dark(#2563eb,#60a5fa);stroke-opacity:1;stroke-width:2}
|
|
224
|
+
.cnd .cg .ctip{display:none;overflow:visible;pointer-events:none}
|
|
225
|
+
.cnd .cg .ctip .ctx{display:flex;flex-direction:column;height:100%}
|
|
226
|
+
.cnd .cg .ctip.up .ctx{justify-content:flex-end}
|
|
227
|
+
.cnd .cg .ctt{position:relative;box-sizing:border-box;padding:16px 18px;border:1px solid rgba(127,127,127,.3);border-radius:12px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));color:CanvasText;box-shadow:0 2px 6px rgba(15,23,42,.08),0 14px 34px rgba(15,23,42,.18);font-size:14px;line-height:1.6;text-align:left;animation:cnTip .14s ease-out .18s both}
|
|
228
|
+
@keyframes cnTip{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
|
|
229
|
+
@media (prefers-reduced-motion:reduce){.cnd .cg .ctt{animation:none}}
|
|
230
|
+
.cnd .cg .ctt.k-function,.cnd .cg .ctt.k-handler{--c:light-dark(#2563eb,#82aaff)}
|
|
231
|
+
.cnd .cg .cth{display:flex;flex-direction:column;gap:3px;margin:0 0 14px}
|
|
232
|
+
.cnd .cg .ctkd{font-size:10.5px;font-weight:650;letter-spacing:.08em;text-transform:uppercase;color:var(--c,currentColor);opacity:.9}
|
|
233
|
+
.cnd .cg .ctt b.ctn{font-size:16px;font-weight:650;overflow-wrap:anywhere}
|
|
234
|
+
.cnd .cg .ctt b.ctn.mono{font:650 15px var(--mono)}
|
|
235
|
+
.cnd .cg .cts{font-size:12.5px;opacity:.65;overflow-wrap:anywhere}
|
|
236
|
+
.cnd .cg .cts.mono{font-family:var(--mono)}
|
|
237
|
+
.cnd .cg .ctt pre.ctc{margin:0 0 12px;padding:10px 12px;border:1px solid rgba(127,127,127,.2);border-radius:8px;background:rgba(127,127,127,.06);font:13px/1.55 var(--mono);white-space:pre-wrap;overflow-wrap:anywhere}
|
|
238
|
+
.cnd .cg .cto{margin:16px -18px -16px;padding:9px 18px;border-top:1px solid rgba(127,127,127,.16);border-radius:0 0 12px 12px;background:rgba(127,127,127,.05);font-size:12px;opacity:.7}
|
|
239
|
+
.cnd .cg .ctt p{margin:0 0 10px;overflow-wrap:anywhere}
|
|
240
|
+
.cnd .cg .ctt p:last-child{margin-bottom:0}
|
|
241
|
+
.cnd .cg .ctt p.ctd{font-style:italic;opacity:.85}
|
|
242
|
+
.cnd .cg .ctt p.ctp{opacity:.88}
|
|
243
|
+
.cnd .cg .ctt code.ctk{font:12.5px var(--mono);padding:1px 5px;border-radius:4px;background:rgba(127,127,127,.12);overflow-wrap:anywhere}
|
|
244
|
+
.cnd .cg .ctt code.ctn{color:light-dark(#0f766e,#7dd3c0)}
|
|
245
|
+
.cnd .cg .ctt ul{margin:0;padding:0;list-style:none}
|
|
246
|
+
.cnd .cg .ctt ul.ctl li{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;padding:6px 0;border-top:1px solid rgba(127,127,127,.14)}
|
|
247
|
+
.cnd .cg .ctt ul.ctl li:first-child{border-top:none}
|
|
248
|
+
.cnd .cg .ctt .ctm{font-size:12px;opacity:.7}
|
|
249
|
+
.cnd .cg .ctt .ctw{margin:12px 0 0;padding:10px 14px;border-radius:8px;background:rgba(245,158,11,.12);border-left:3px solid #f59e0b}
|
|
250
|
+
.cnd .cg .ctt .ctw b{display:block;margin:0 0 4px;font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:light-dark(#b45309,#fbbf24)}
|
|
251
|
+
.cnd .cg .ctt .ctw li{margin:4px 0 0;overflow-wrap:anywhere}
|
|
224
252
|
.cnd .cside{position:fixed;top:0;right:0;bottom:0;z-index:30;box-sizing:border-box;width:min(660px,94vw);overflow:auto;padding:0 20px 28px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));color:CanvasText;border-left:1px solid rgba(127,127,127,.3);box-shadow:-14px 0 36px rgba(15,23,42,.14);transform:translateX(104%);visibility:hidden;transition:transform .22s ease,visibility 0s linear .22s}
|
|
225
253
|
.cnd .cside:target{transform:none;visibility:visible;transition:transform .22s ease}
|
|
226
254
|
.cnd .cside .csh{display:flex;align-items:flex-start;gap:12px;position:sticky;top:0;z-index:1;margin:0 -20px 12px;padding:16px 20px 12px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));border-bottom:1px solid rgba(127,127,127,.2)}
|
|
@@ -270,13 +298,27 @@ _EXTRA_CSS = """\
|
|
|
270
298
|
.cnd .walk .ws{border-left:1px solid rgba(127,127,127,.2)}
|
|
271
299
|
.cnd .walk .wch{position:sticky;top:0;z-index:2;padding:12px 16px 9px;font-size:12.5px;font-weight:650;background:var(--bg);border-bottom:1px solid rgba(127,127,127,.14)}
|
|
272
300
|
.cnd .walk .wr{display:block;width:0;height:0;margin:0;border:0;padding:0;opacity:0;appearance:none;-webkit-appearance:none;pointer-events:none}
|
|
273
|
-
.cnd .walk .wil{display:flex;align-items:center;gap:10px;min-height:30px;padding:0 14px 0 4px;cursor:pointer;white-space:nowrap;user-select:none;-webkit-user-select:none;transition:background-color .
|
|
301
|
+
.cnd .walk .wil{display:flex;align-items:center;gap:10px;min-height:30px;padding:0 14px 0 4px;cursor:pointer;white-space:nowrap;user-select:none;-webkit-user-select:none;transition:background-color .2s,box-shadow .2s;animation:cnd-row .22s ease-out}
|
|
302
|
+
@keyframes cnd-row{from{opacity:0;transform:translateY(-3px)}}
|
|
303
|
+
.cnd .walk .wcx{position:absolute;width:0;height:0;margin:0;opacity:0;pointer-events:none}
|
|
304
|
+
.cnd .walk .wtg{position:relative;z-index:1;display:block;height:0}
|
|
305
|
+
.cnd .walk .wtg i{position:absolute;top:0;left:calc(40px + var(--d)*16px);width:16px;height:30px;border-radius:4px;cursor:pointer;opacity:.45;transition:opacity .15s,background-color .15s}
|
|
306
|
+
.cnd .walk .wtg i::before{content:"";position:absolute;left:5px;top:12px;width:5px;height:5px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg);transition:transform .2s cubic-bezier(.3,.7,.3,1)}
|
|
307
|
+
.cnd .walk .wtg:hover i{opacity:1;background:rgba(127,127,127,.14)}
|
|
308
|
+
.cnd .walk .wcx:checked+.wtg i{opacity:.8}
|
|
309
|
+
.cnd .walk .wcx:checked+.wtg i::before{transform:translate(-1px,1px) rotate(-45deg)}
|
|
310
|
+
.cnd .walk .wcnt{display:none;flex:none;font-size:11px;padding:0 7px;border-radius:9px;line-height:17px;background:rgba(127,127,127,.14);opacity:.75;animation:cnd-in .2s ease}
|
|
311
|
+
.cnd .walk .wcx:checked+.wtg+.wr+.wil .wcnt{display:inline-block}
|
|
274
312
|
.cnd .walk .wil:hover{background-color:rgba(127,127,127,.08)}
|
|
275
313
|
.cnd .walk .wr:checked+.wil{background-color:rgba(245,158,11,.16);box-shadow:inset 3px 0 #f59e0b}
|
|
276
314
|
.cnd .walk .wr:focus-visible+.wil{outline:2px solid var(--blue);outline-offset:-2px}
|
|
277
315
|
.cnd .walk .wno{flex:0 0 26px;text-align:right;font:11px var(--mono);opacity:.4;font-variant-numeric:tabular-nums}
|
|
278
|
-
.cnd .walk .wr:checked+.wil .wno{opacity:.
|
|
279
|
-
.cnd .walk .
|
|
316
|
+
.cnd .walk .wr:checked+.wil .wno{opacity:.9;color:#d97706;font-weight:600}
|
|
317
|
+
.cnd .walk .wtx{transition:transform .2s ease}
|
|
318
|
+
.cnd .walk .wr:checked+.wil .wtx{transform:translateX(2px)}
|
|
319
|
+
.cnd .walk .wr:checked+.wil .wdot{animation:cnd-ping 1s ease-out 2}
|
|
320
|
+
@keyframes cnd-ping{from{box-shadow:0 0 0 0 var(--c,rgba(127,127,127,.6))}to{box-shadow:0 0 0 6px transparent}}
|
|
321
|
+
.cnd .walk .wx{display:flex;align-items:center;align-self:stretch;gap:8px;min-width:0;flex:1;padding-left:calc(var(--d)*16px + 18px);background:repeating-linear-gradient(90deg,rgba(127,127,127,.18) 0 1px,transparent 1px 16px) 8px 0/calc(var(--d)*16px) 100% no-repeat}
|
|
280
322
|
.cnd .walk .wtx{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
|
281
323
|
.cnd .walk .wtx code{font:12px var(--mono);background:none;padding:0}
|
|
282
324
|
.cnd .walk :is(.k-def,.k-module) .wtx b{font:650 12.5px var(--mono)}
|
|
@@ -284,7 +326,10 @@ _EXTRA_CSS = """\
|
|
|
284
326
|
.cnd .walk .wdot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--c,rgba(127,127,127,.6))}
|
|
285
327
|
.cnd .walk :is(.d-aws-reads,.d-lib-reads){--c:#3b82f6}.cnd .walk :is(.d-aws-writes,.d-lib-writes){--c:#ea580c}
|
|
286
328
|
.cnd .walk :is(.d-aws-sends,.d-lib-sends,.d-http){--c:#db2777}.cnd .walk :is(.d-aws-runs,.d-lib-runs){--c:#9333ea}.cnd .walk .d-aws-signs{--c:#64748b}
|
|
287
|
-
.cnd .walk .wc{display:none;position:absolute;left:var(--lw);right:0;top:0;height:var(--ch);box-sizing:border-box;overflow:auto;padding:14px 22px 12px;white-space:normal;cursor:auto;border-left:1px solid rgba(127,127,127,.2);border-bottom:1px solid rgba(127,127,127,.18);background:var(--bg)
|
|
329
|
+
.cnd .walk .wc{display:none;position:absolute;left:var(--lw);right:0;top:0;height:var(--ch);box-sizing:border-box;overflow:auto;padding:14px 22px 12px;white-space:normal;cursor:auto;border-left:1px solid rgba(127,127,127,.2);border-bottom:1px solid rgba(127,127,127,.18);background:var(--bg)}
|
|
330
|
+
.cnd .walk .wc>*{animation:cnd-in .24s ease both}
|
|
331
|
+
.cnd .walk .wc>.whead{animation-delay:.03s}.cnd .walk .wc>.wstk{animation-delay:.06s}.cnd .walk .wc>.wsay{animation-delay:.09s}.cnd .walk .wc>.wthen{animation-delay:.12s}
|
|
332
|
+
.cnd .walk .wfacts li{animation:cnd-in .24s ease both;animation-delay:.12s}.cnd .walk .wfacts li:nth-child(2){animation-delay:.15s}.cnd .walk .wfacts li:nth-child(n+3){animation-delay:.18s}
|
|
288
333
|
.cnd .walk .wr:checked+.wil+.wc{display:block}
|
|
289
334
|
.cnd .walk .wnav{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
|
|
290
335
|
.cnd .walk .wbt{display:inline-flex;align-items:center;gap:5px;padding:4px 14px;border:1px solid rgba(127,127,127,.32);border-radius:8px;font-size:13px;font-weight:600;line-height:20px;cursor:pointer;user-select:none;-webkit-user-select:none;transition:background-color .12s,transform .06s}
|
|
@@ -320,7 +365,9 @@ _EXTRA_CSS = """\
|
|
|
320
365
|
.cnd .walk :is(.wfm,.wfv){opacity:.6}
|
|
321
366
|
.cnd .walk .wthen{margin-top:10px;font-size:12px;opacity:.6}
|
|
322
367
|
.cnd .walk .wf{display:none;position:absolute;left:var(--lw);right:0;top:var(--ch);bottom:0;flex-direction:column;border-left:1px solid rgba(127,127,127,.2);background:var(--bg)}
|
|
323
|
-
.cnd .walk .wfn>.wr:checked~.wf{display:flex}
|
|
368
|
+
.cnd .walk .wfn>.wr:checked~.wf{display:flex;animation:cnd-fade .25s ease}
|
|
369
|
+
.cnd .walk .wfh{animation:cnd-in .25s ease}
|
|
370
|
+
@keyframes cnd-fade{from{opacity:0}}
|
|
324
371
|
.cnd .walk .wfh{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:8px 22px;font-size:12px;border-bottom:1px solid rgba(127,127,127,.12)}
|
|
325
372
|
.cnd .walk .wfh b{font:650 12.5px var(--mono)}
|
|
326
373
|
.cnd .walk .wfh span{opacity:.62}
|
|
@@ -328,15 +375,16 @@ _EXTRA_CSS = """\
|
|
|
328
375
|
.cnd .walk .wfw{position:relative;flex:1;min-height:0;overflow-x:auto;overflow-y:hidden;container-type:size;background:rgba(127,127,127,.03)}
|
|
329
376
|
.cnd .walk .wfp{position:relative;box-sizing:border-box;width:max-content;min-width:100%;padding:var(--pad) 0;font:12.5px/var(--lh) var(--mono);
|
|
330
377
|
translate:0 min(0px,max(calc(100cqh - var(--n)*var(--lh) - 2*var(--pad)),calc(36cqh - var(--k,0)*var(--lh))));transition:translate .32s cubic-bezier(.25,.8,.25,1)}
|
|
331
|
-
.cnd .walk .wbar{position:absolute;left:0;right:0;top:calc(var(--pad) + var(--k,-9)*var(--lh));height:var(--lh);background:rgba(245,158,11,.2);box-shadow:inset 3px 0 #f59e0b;transition:top .32s cubic-bezier(.25,.8,.25,1)}
|
|
378
|
+
.cnd .walk .wbar{position:absolute;left:0;right:0;top:calc(var(--pad) + var(--k,-9)*var(--lh));height:var(--lh);background:rgba(245,158,11,.2);box-shadow:inset 3px 0 #f59e0b;transition:top .32s cubic-bezier(.25,.8,.25,1);animation:cnd-glow 1.2s ease-in-out 2}
|
|
379
|
+
@keyframes cnd-glow{50%{background:rgba(245,158,11,.3)}}
|
|
332
380
|
.cnd .walk .sl{position:relative;display:block;padding-right:16px;white-space:pre}
|
|
333
381
|
.cnd .walk span.sl{opacity:.6}
|
|
334
|
-
.cnd .walk label.sl{cursor:pointer}
|
|
382
|
+
.cnd .walk label.sl{cursor:pointer;transition:background-color .15s}
|
|
335
383
|
.cnd .walk label.sl:hover{background:rgba(127,127,127,.1)}
|
|
336
384
|
.cnd .walk .sn{display:inline-block;width:3.2em;padding-right:14px;text-align:right;opacity:.42;user-select:none;-webkit-user-select:none}
|
|
337
385
|
.cnd .walk label.sl .sn{opacity:.8}
|
|
338
386
|
@media (max-width:860px){.cnd .walk{--lt:40vh;grid-template-columns:minmax(0,1fr);grid-template-rows:var(--lt) 1fr;height:calc(var(--lt) + var(--ch) + 380px)}.cnd .walk .wl{max-height:none}.cnd .walk :is(.wc,.wf){left:0;border-left:0}.cnd .walk .wc{top:var(--lt);border-top:1px solid rgba(127,127,127,.2);padding:12px 16px}.cnd .walk .wf{top:calc(var(--lt) + var(--ch))}.cnd .walk .ws{border-left:0}}
|
|
339
|
-
@media (prefers-reduced-motion:reduce){.cnd .walk .wfp,.
|
|
387
|
+
@media (prefers-reduced-motion:reduce){.cnd .walk :is(.wfp,.wbar,.wc,.wc>*,.wfacts li,.wil,.wtx,.wdot,.wcnt,.wf,.wfh,.wtg i,.wtg i::before),.cnd .tabs>.tp{transition:none;animation:none}}"""
|
|
340
388
|
|
|
341
389
|
_CSS = _base_css(_ROOT, _EXTRA_CSS)
|
|
342
390
|
|
code_node/report/walk.py
CHANGED
|
@@ -7,6 +7,11 @@ No JavaScript: each step is a radio button (one group, so once one has focus the
|
|
|
7
7
|
Each function's steps sit in a box of their own, with the function's code drawn once at the end of it; the CSS shows
|
|
8
8
|
the card after the checked button and the code of its box with sibling selectors, so the light slides from line to
|
|
9
9
|
line as you step, and a step costs the same however many there are.
|
|
10
|
+
|
|
11
|
+
The list folds like a tree: a step with steps under it has a checkbox before it, and its arrow folds them away. Each
|
|
12
|
+
step under it carries the class `wu<step>`, so one rule per fold hides them, whether they sit beside it or inside the
|
|
13
|
+
box of a function it calls (`#cx5:checked ~ .wu5, #cx5:checked ~ * .wu5`). Only the steps' rows are hidden: the
|
|
14
|
+
current one's card and code still show when it's folded away.
|
|
10
15
|
"""
|
|
11
16
|
|
|
12
17
|
from __future__ import annotations
|
|
@@ -523,11 +528,29 @@ def _frame_html(index: int, frame: _Frame, rows: list[tuple[int, str]]) -> str:
|
|
|
523
528
|
)
|
|
524
529
|
|
|
525
530
|
|
|
526
|
-
def
|
|
531
|
+
def _folds(stops: list[_Stop]) -> tuple[list[int], list[list[int]]]:
|
|
532
|
+
"""
|
|
533
|
+
How many steps sit under each stop in the list, and the stops each one sits under, outermost first.
|
|
534
|
+
"""
|
|
535
|
+
under = [0] * len(stops)
|
|
536
|
+
above: list[list[int]] = []
|
|
537
|
+
opened: list[int] = []
|
|
538
|
+
for i, stop in enumerate(stops):
|
|
539
|
+
while opened and (stops[opened[-1]].depth >= stop.depth or stops[opened[-1]].chapter != stop.chapter):
|
|
540
|
+
opened.pop()
|
|
541
|
+
for j in opened:
|
|
542
|
+
under[j] += 1
|
|
543
|
+
above.append(list(opened))
|
|
544
|
+
opened.append(i)
|
|
545
|
+
return under, above
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
def _item_html(stops: list[_Stop], i: int, card: str, under: int = 0, above: tuple[int, ...] = ()) -> str:
|
|
527
549
|
"""
|
|
528
550
|
A step in the list: its radio button, then its number and what it does in a few words (or, for a function it goes
|
|
529
551
|
into, the function's name and file, as a heading over its steps) as the button's label, then its card, which shows
|
|
530
|
-
(beside the list) while the button is checked.
|
|
552
|
+
(beside the list) while the button is checked. under: how many steps sit under it, folded away by the checkbox and
|
|
553
|
+
arrow before it; above: the steps it sits under, whose folds hide it.
|
|
531
554
|
"""
|
|
532
555
|
stop = stops[i]
|
|
533
556
|
step = stop.step
|
|
@@ -543,10 +566,18 @@ def _item_html(stops: list[_Stop], i: int, card: str) -> str:
|
|
|
543
566
|
dot = f'<span class="wdot d-{said}" title="{_esc(_NOTE_TIPS.get(said, ""))}"></span>' if said in _DOTS else ""
|
|
544
567
|
text = f'<span class="wtx">{headline}</span>{dot}'
|
|
545
568
|
checked = " checked" if i == 0 else ""
|
|
569
|
+
hidden_by = "".join(f" wu{j}" for j in above)
|
|
570
|
+
fold = ""
|
|
571
|
+
if under:
|
|
572
|
+
fold = (
|
|
573
|
+
f'<input type="checkbox" class="wcx" id="cx{i}" tabindex="-1"><label class="wtg{hidden_by}" for="cx{i}" '
|
|
574
|
+
f'style="--d:{stop.depth}" title="Fold or unfold the {_plural(under, "step")} under it"><i></i></label>'
|
|
575
|
+
)
|
|
576
|
+
text += f'<span class="wcnt">{_plural(under, "step")}</span>'
|
|
546
577
|
return (
|
|
547
|
-
f'<input type="radio" class="wr" name="{_GROUP}" id="cw{i}"{checked}><label class="wil
|
|
548
|
-
f'for="cw{i}" style="--d:{stop.depth}"><span class="wno">{i + 1}</span
|
|
549
|
-
f"</label>{card}
|
|
578
|
+
f'{fold}<input type="radio" class="wr" name="{_GROUP}" id="cw{i}"{checked}><label class="wil '
|
|
579
|
+
f'k-{_esc(step.kind)}{hidden_by}" for="cw{i}" style="--d:{stop.depth}"><span class="wno">{i + 1}</span>'
|
|
580
|
+
f'<span class="wx">{text}</span></label>{card}'
|
|
550
581
|
)
|
|
551
582
|
|
|
552
583
|
|
|
@@ -576,6 +607,7 @@ def _walk_html(block: _Walk, report: _Report) -> str:
|
|
|
576
607
|
rows = _frame_rows(frame, highlighted.get(frame.file, []), stops)
|
|
577
608
|
rows_of.append({number: n for n, (number, _) in enumerate(rows) if number})
|
|
578
609
|
drawn.append(_frame_html(k, frame, rows))
|
|
610
|
+
under, above = _folds(stops)
|
|
579
611
|
out: list[str] = []
|
|
580
612
|
opened: list[int] = [] # the frames whose boxes are open, innermost last
|
|
581
613
|
chapter = -1
|
|
@@ -593,7 +625,9 @@ def _walk_html(block: _Walk, report: _Report) -> str:
|
|
|
593
625
|
if not opened or opened[-1] != stop.frame: # into a call
|
|
594
626
|
out.append('<div class="wfn">')
|
|
595
627
|
opened.append(stop.frame)
|
|
596
|
-
out.append(_item_html(stops, i, _card_html(stops, i, first, docs, block.editor)))
|
|
628
|
+
out.append(_item_html(stops, i, _card_html(stops, i, first, docs, block.editor), under[i], tuple(above[i])))
|
|
629
|
+
if under[i]: # its fold hides the steps under it, beside it or in the boxes of what it calls
|
|
630
|
+
report.rules.add(f".{root} #cx{i}:checked~.wu{i},.{root} #cx{i}:checked~* .wu{i}{{display:none}}")
|
|
597
631
|
at = rows_of[stop.frame].get(stop.lit)
|
|
598
632
|
if at is not None: # the line its code lights
|
|
599
633
|
report.rules.add(f".{root} #cw{i}:checked~.wf{stop.frame}{{--k:{at}}}")
|
|
@@ -601,7 +635,8 @@ def _walk_html(block: _Walk, report: _Report) -> str:
|
|
|
601
635
|
out.append(drawn[opened.pop()] + "</div>")
|
|
602
636
|
sub = (
|
|
603
637
|
f'<div class="wsub">{_plural(len(stops), "step")}, in the order the code runs. Press Next or click a step to '
|
|
604
|
-
"light its line in the code; after a click, <kbd>↑</kbd> <kbd>↓</kbd> move through them
|
|
638
|
+
"light its line in the code; after a click, <kbd>↑</kbd> <kbd>↓</kbd> move through them. The arrow beside a "
|
|
639
|
+
"step folds the steps under it away.</div>"
|
|
605
640
|
)
|
|
606
641
|
return (
|
|
607
642
|
f'{title}{sub}<div class="walk"><div class="wl" role="radiogroup" aria-label="The steps">{"".join(out)}'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: code-node-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: See how Python code works without running it: a graph of who calls whom from an entry point, and what each path reaches.
|
|
5
5
|
Project-URL: Homepage, https://github.com/utkarsh5026/code-node
|
|
6
6
|
Project-URL: Documentation, https://utkarsh5026.github.io/code-node/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
code_node/__init__.py,sha256=
|
|
1
|
+
code_node/__init__.py,sha256=RGdvFZ4nq5pe5UXLWQMZaZvneTOwgLS-aGK6TqTBTG4,1106
|
|
2
2
|
code_node/__main__.py,sha256=0W2bmerF1S96rjlTNJZKVzO4FvVhN6ENzAl451A08sQ,101
|
|
3
3
|
code_node/cli.py,sha256=GI0vZY1t4Pf7qtZI2coTpWZi-ulQEWNREDJPkTtmxG0,12302
|
|
4
4
|
code_node/pages.py,sha256=2UOrHUz3G_vAjPO89phJxhF4652FysVLgrLtJ-Iw6p4,3234
|
|
@@ -34,11 +34,11 @@ code_node/report/__init__.py,sha256=l3dfZFbLEo-7Fl7O_Rk2lvyAElQnyugSZPI_PzHrG_Q,
|
|
|
34
34
|
code_node/report/brands.py,sha256=n32BfFz2d02ZVUHvy8L4wPHBtiD_1FCTKzdR4NyvU88,8372
|
|
35
35
|
code_node/report/build.py,sha256=F0wdC0ibu3WSAenUsovUWuKwLC0vVxnNYKJVXtU5jRk,4644
|
|
36
36
|
code_node/report/editor.py,sha256=TRUX6BTB-oe-m5Vf3xM9PppnC99sCLL4PObXkYAGKoU,1466
|
|
37
|
-
code_node/report/graph.py,sha256=
|
|
37
|
+
code_node/report/graph.py,sha256=YbrVWbymYUL8-KOdsDSRhD2RxCMWbGVEhHD0-MSjX1I,66832
|
|
38
38
|
code_node/report/outline.py,sha256=3RRxU4FMUZKBVjFDsscKZkvDlj_W4ZeW4DwUztg4wd0,8539
|
|
39
|
-
code_node/report/style.py,sha256=
|
|
39
|
+
code_node/report/style.py,sha256=a5JesVQaDnqLqmqnuh-ZeayA-VZKTlUoDCPDcoUrK3M,35883
|
|
40
40
|
code_node/report/tabs.py,sha256=K2XR16owfgEL1kfux61PI9nBcRsgjQurTx1ptMM5Mac,3016
|
|
41
|
-
code_node/report/walk.py,sha256=
|
|
41
|
+
code_node/report/walk.py,sha256=LWJDGJ3efF0fPWlMO4G4HBQqnNVn2RHXgLeuLrC-WnA,29466
|
|
42
42
|
code_node/report/logos/README.md,sha256=8Evw8eApl_56QJrwY7LAtGgJMZE0mp0-HIpRz9bu1ME,613
|
|
43
43
|
code_node/report/logos/anthropic-icon.svg,sha256=-_25zx86lfDTm-ksVXkLE4uQ_ldzLbTd3U0z-wjT-JA,302
|
|
44
44
|
code_node/report/logos/aws-amplify.svg,sha256=62WXM0XCn4WrQYWcVZFz4ln62xidiqF8eO4ELlgO8hg,531
|
|
@@ -171,8 +171,8 @@ code_node/report/logos/small/aws-systems-manager.svg,sha256=9VzzFdTjaRZO9ulR8Ulp
|
|
|
171
171
|
code_node/report/logos/small/aws-timestream.svg,sha256=yKdKIj7pbooFqDKClEQxW9h7dYV5mnDn0RCHnLUDf8Q,639
|
|
172
172
|
code_node/report/logos/small/aws-waf.svg,sha256=l9ZzBZAl2g8bK1-m6A50ga37l5g1t-9Mj70bxWDykWE,591
|
|
173
173
|
code_node/report/logos/small/aws-xray.svg,sha256=VKg_QtKGZKDCbZvKBRDn7eReuNVbJpduBUVV8MQrZZU,591
|
|
174
|
-
code_node_graph-0.
|
|
175
|
-
code_node_graph-0.
|
|
176
|
-
code_node_graph-0.
|
|
177
|
-
code_node_graph-0.
|
|
178
|
-
code_node_graph-0.
|
|
174
|
+
code_node_graph-0.3.0.dist-info/METADATA,sha256=N1ODeR5ZEpH4roWDSuYXxMNjQu_q31V2uCuYsQQyTig,7619
|
|
175
|
+
code_node_graph-0.3.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
176
|
+
code_node_graph-0.3.0.dist-info/entry_points.txt,sha256=eEArp-uk7ZzODIWr6l62rI0-mIA0-mLDaqJEyKikPJw,49
|
|
177
|
+
code_node_graph-0.3.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
178
|
+
code_node_graph-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|