vyasa 0.3.6__py3-none-any.whl → 0.3.10__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.
- vyasa/__init__.py +1 -1
- vyasa/core.py +217 -3
- vyasa/static/scripts.js +81 -0
- {vyasa-0.3.6.dist-info → vyasa-0.3.10.dist-info}/METADATA +1 -1
- vyasa-0.3.10.dist-info/RECORD +16 -0
- vyasa-0.3.6.dist-info/RECORD +0 -16
- {vyasa-0.3.6.dist-info → vyasa-0.3.10.dist-info}/WHEEL +0 -0
- {vyasa-0.3.6.dist-info → vyasa-0.3.10.dist-info}/entry_points.txt +0 -0
- {vyasa-0.3.6.dist-info → vyasa-0.3.10.dist-info}/licenses/LICENSE +0 -0
- {vyasa-0.3.6.dist-info → vyasa-0.3.10.dist-info}/top_level.txt +0 -0
vyasa/__init__.py
CHANGED
vyasa/core.py
CHANGED
|
@@ -67,6 +67,10 @@ def span_token(name, pat, attr, prec=5):
|
|
|
67
67
|
self.caption = match.group(2) if match.group(2) else None
|
|
68
68
|
elif name == 'MermaidEmbed':
|
|
69
69
|
self.option = match.group(2) if match.group(2) else None
|
|
70
|
+
elif name == 'IframeEmbed':
|
|
71
|
+
self.options = match.group(2) if match.group(2) else None
|
|
72
|
+
elif name == 'DownloadEmbed':
|
|
73
|
+
self.label = match.group(2) if match.group(2) else None
|
|
70
74
|
T.__name__ = name
|
|
71
75
|
return T
|
|
72
76
|
|
|
@@ -77,6 +81,18 @@ YoutubeEmbed = span_token(
|
|
|
77
81
|
'video_id',
|
|
78
82
|
6
|
|
79
83
|
)
|
|
84
|
+
IframeEmbed = span_token(
|
|
85
|
+
'IframeEmbed',
|
|
86
|
+
r'\[iframe:([^\|\]]+)(?:\|(.+))?\]',
|
|
87
|
+
'src',
|
|
88
|
+
6
|
|
89
|
+
)
|
|
90
|
+
DownloadEmbed = span_token(
|
|
91
|
+
'DownloadEmbed',
|
|
92
|
+
r'\[download:([^\|\]]+)(?:\|(.+))?\]',
|
|
93
|
+
'path',
|
|
94
|
+
6
|
|
95
|
+
)
|
|
80
96
|
|
|
81
97
|
# Superscript and Subscript tokens with higher precedence
|
|
82
98
|
class Superscript(mst.span_token.SpanToken):
|
|
@@ -221,6 +237,7 @@ class ContentRenderer(FrankenRenderer):
|
|
|
221
237
|
self.current_path = current_path # Current post path for resolving relative links and images
|
|
222
238
|
self.heading_counts = {}
|
|
223
239
|
self.mermaid_counter = 0
|
|
240
|
+
self.iframe_counter = 0
|
|
224
241
|
|
|
225
242
|
def render_list_item(self, token):
|
|
226
243
|
"""Render list items with task list checkbox support"""
|
|
@@ -273,6 +290,124 @@ class ContentRenderer(FrankenRenderer):
|
|
|
273
290
|
if caption:
|
|
274
291
|
return iframe + f'<p class="text-sm text-slate-500 dark:text-slate-400 text-center mt-2">{caption}</p>'
|
|
275
292
|
return iframe
|
|
293
|
+
|
|
294
|
+
def render_iframe_embed(self, token):
|
|
295
|
+
src = token.src.strip()
|
|
296
|
+
options_raw = getattr(token, 'options', None)
|
|
297
|
+
|
|
298
|
+
# Defaults
|
|
299
|
+
width = '65vw'
|
|
300
|
+
height = '400px'
|
|
301
|
+
title = 'Embedded content'
|
|
302
|
+
allow = 'clipboard-read; clipboard-write; fullscreen'
|
|
303
|
+
allowfullscreen = True
|
|
304
|
+
caption = None
|
|
305
|
+
popup = False
|
|
306
|
+
border = 'default'
|
|
307
|
+
|
|
308
|
+
# Parse options: key=value;key=value
|
|
309
|
+
if options_raw:
|
|
310
|
+
for part in options_raw.split(';'):
|
|
311
|
+
if not part.strip() or '=' not in part:
|
|
312
|
+
continue
|
|
313
|
+
key, value = part.split('=', 1)
|
|
314
|
+
key = key.strip().lower()
|
|
315
|
+
value = value.strip()
|
|
316
|
+
if key == 'width':
|
|
317
|
+
width = value
|
|
318
|
+
elif key == 'height':
|
|
319
|
+
height = value
|
|
320
|
+
elif key == 'title':
|
|
321
|
+
title = value
|
|
322
|
+
elif key == 'allow':
|
|
323
|
+
allow = value
|
|
324
|
+
elif key == 'fullscreen':
|
|
325
|
+
allowfullscreen = value.lower() in ('1', 'true', 'yes', 'on')
|
|
326
|
+
elif key == 'caption':
|
|
327
|
+
caption = value
|
|
328
|
+
elif key == 'popup':
|
|
329
|
+
popup = value.lower() in ('1', 'true', 'yes', 'on')
|
|
330
|
+
elif key == 'border':
|
|
331
|
+
border = value.lower()
|
|
332
|
+
|
|
333
|
+
# Break out of normal content flow for viewport widths
|
|
334
|
+
break_out = 'vw' in str(width).lower()
|
|
335
|
+
if break_out:
|
|
336
|
+
container_style = f"width: {width}; position: relative; left: 50%; transform: translateX(-50%);"
|
|
337
|
+
else:
|
|
338
|
+
container_style = f"width: {width};"
|
|
339
|
+
|
|
340
|
+
self.iframe_counter += 1
|
|
341
|
+
iframe_id = f"iframe-{abs(hash(src)) & 0xFFFFFF}-{self.iframe_counter}"
|
|
342
|
+
|
|
343
|
+
fullscreen_button = ''
|
|
344
|
+
if popup:
|
|
345
|
+
fullscreen_button = (
|
|
346
|
+
'<div class="iframe-controls absolute top-2 right-2 z-10 flex gap-1 '
|
|
347
|
+
'bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm rounded">'
|
|
348
|
+
f'<button data-iframe-fullscreen-toggle="true" '
|
|
349
|
+
f'data-iframe-src="{src}" '
|
|
350
|
+
f'data-iframe-title="{title}" '
|
|
351
|
+
f'data-iframe-allow="{allow}" '
|
|
352
|
+
f'data-iframe-allowfullscreen="{str(allowfullscreen).lower()}" '
|
|
353
|
+
'class="px-2 py-1 text-xs border rounded hover:bg-slate-100 '
|
|
354
|
+
'dark:hover:bg-slate-700" title="Fullscreen">⛶</button>'
|
|
355
|
+
'</div>'
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
if border in ('black', 'dark'):
|
|
359
|
+
border_classes = 'border border-black'
|
|
360
|
+
elif border in ('none', 'false', '0', 'off'):
|
|
361
|
+
border_classes = 'border border-transparent'
|
|
362
|
+
else:
|
|
363
|
+
border_classes = 'border border-slate-200 dark:border-slate-800'
|
|
364
|
+
|
|
365
|
+
iframe = f'''
|
|
366
|
+
<div class="relative my-6 rounded-lg overflow-hidden {border_classes}" style="{container_style}">
|
|
367
|
+
{fullscreen_button}
|
|
368
|
+
<iframe
|
|
369
|
+
id="{iframe_id}"
|
|
370
|
+
src="{src}"
|
|
371
|
+
title="{title}"
|
|
372
|
+
frameborder="0"
|
|
373
|
+
allow="{allow}"
|
|
374
|
+
{'allowfullscreen' if allowfullscreen else ''}
|
|
375
|
+
style="width: 100%; height: {height};">
|
|
376
|
+
</iframe>
|
|
377
|
+
</div>
|
|
378
|
+
'''
|
|
379
|
+
|
|
380
|
+
if caption:
|
|
381
|
+
return iframe + f'<p class="text-sm text-slate-500 dark:text-slate-400 text-center mt-2">{caption}</p>'
|
|
382
|
+
return iframe
|
|
383
|
+
|
|
384
|
+
def render_download_embed(self, token):
|
|
385
|
+
from pathlib import Path
|
|
386
|
+
raw_path = token.path.strip()
|
|
387
|
+
label = getattr(token, 'label', None)
|
|
388
|
+
|
|
389
|
+
# Resolve relative paths against current_path like normal links
|
|
390
|
+
if self.current_path:
|
|
391
|
+
root = get_root_folder().resolve()
|
|
392
|
+
current_file_full = root / self.current_path
|
|
393
|
+
current_dir = current_file_full.parent
|
|
394
|
+
resolved = (current_dir / raw_path).resolve()
|
|
395
|
+
try:
|
|
396
|
+
rel_path = resolved.relative_to(root).as_posix()
|
|
397
|
+
download_path = f"/download/{rel_path}"
|
|
398
|
+
except ValueError:
|
|
399
|
+
download_path = raw_path
|
|
400
|
+
else:
|
|
401
|
+
download_path = f"/download/{raw_path}"
|
|
402
|
+
|
|
403
|
+
if not label:
|
|
404
|
+
label = Path(raw_path).name
|
|
405
|
+
|
|
406
|
+
link_class = (
|
|
407
|
+
"text-amber-600 dark:text-amber-400 underline underline-offset-2 "
|
|
408
|
+
"hover:text-amber-800 dark:hover:text-amber-200 font-medium transition-colors"
|
|
409
|
+
)
|
|
410
|
+
return f'<a href="{download_path}" class="{link_class}" download>{label}</a>'
|
|
276
411
|
|
|
277
412
|
def render_footnote_ref(self, token):
|
|
278
413
|
self.fn_counter += 1
|
|
@@ -473,6 +608,12 @@ class ContentRenderer(FrankenRenderer):
|
|
|
473
608
|
is_external = href.startswith(('http://', 'https://', 'mailto:', 'tel:', '//'))
|
|
474
609
|
is_absolute_internal = href.startswith('/') and not href.startswith('//')
|
|
475
610
|
is_relative = not is_external and not is_absolute_internal
|
|
611
|
+
download_flag = False
|
|
612
|
+
if token.title and 'download=true' in token.title.lower():
|
|
613
|
+
download_flag = True
|
|
614
|
+
if '?download=true' in href.lower():
|
|
615
|
+
href = re.sub(r'\?download=true', '', href, flags=re.IGNORECASE)
|
|
616
|
+
download_flag = True
|
|
476
617
|
if is_hash:
|
|
477
618
|
link_class = (
|
|
478
619
|
"text-amber-600 dark:text-amber-400 underline underline-offset-2 "
|
|
@@ -504,12 +645,23 @@ class ContentRenderer(FrankenRenderer):
|
|
|
504
645
|
is_internal = is_absolute_internal and '.' not in href.split('/')[-1]
|
|
505
646
|
hx = f' hx-get="{href}" hx-target="#main-content" hx-push-url="true" hx-swap="innerHTML show:window:top"' if is_internal else ''
|
|
506
647
|
ext = '' if (is_internal or is_absolute_internal or is_hash) else ' target="_blank" rel="noopener noreferrer"'
|
|
648
|
+
download_attr = ''
|
|
649
|
+
if download_flag:
|
|
650
|
+
download_attr = ' download'
|
|
651
|
+
if href.startswith('/posts/'):
|
|
652
|
+
download_target = href[len('/posts/'):]
|
|
653
|
+
elif href.startswith('/'):
|
|
654
|
+
download_target = href.lstrip('/')
|
|
655
|
+
else:
|
|
656
|
+
download_target = href
|
|
657
|
+
href = f'/download/{download_target}'
|
|
658
|
+
hx = ''
|
|
507
659
|
# Amber/gold link styling, stands out and is accessible
|
|
508
660
|
link_class = (
|
|
509
661
|
"text-amber-600 dark:text-amber-400 underline underline-offset-2 "
|
|
510
662
|
"hover:text-amber-800 dark:hover:text-amber-200 font-medium transition-colors"
|
|
511
663
|
)
|
|
512
|
-
return f'<a href="{href}"{hx}{ext} class="{link_class}"{title}>{inner}</a>'
|
|
664
|
+
return f'<a href="{href}"{hx}{ext}{download_attr} class="{link_class}"{title}>{inner}</a>'
|
|
513
665
|
|
|
514
666
|
|
|
515
667
|
def postprocess_tabs(html, tab_data_store, img_dir, current_path, footnotes):
|
|
@@ -532,7 +684,7 @@ def postprocess_tabs(html, tab_data_store, img_dir, current_path, footnotes):
|
|
|
532
684
|
for i, (_, tab_content) in enumerate(tabs):
|
|
533
685
|
active = 'active' if i == 0 else ''
|
|
534
686
|
# Render each tab's content as fresh markdown
|
|
535
|
-
with ContentRenderer(YoutubeEmbed, InlineCodeAttr, Strikethrough, FootnoteRef, Superscript, Subscript, img_dir=img_dir, footnotes=footnotes, current_path=current_path) as renderer:
|
|
687
|
+
with ContentRenderer(YoutubeEmbed, IframeEmbed, DownloadEmbed, InlineCodeAttr, Strikethrough, FootnoteRef, Superscript, Subscript, img_dir=img_dir, footnotes=footnotes, current_path=current_path) as renderer:
|
|
536
688
|
doc = mst.Document(tab_content)
|
|
537
689
|
rendered = renderer.render(doc)
|
|
538
690
|
html_parts.append(f'<div class="tab-panel {active}" data-tab-index="{i}">{rendered}</div>')
|
|
@@ -613,7 +765,7 @@ def from_md(content, img_dir=None, current_path=None):
|
|
|
613
765
|
'table': 'uk-table uk-table-striped uk-table-hover uk-table-divider uk-table-middle my-6'}
|
|
614
766
|
|
|
615
767
|
# Register custom tokens with renderer context manager
|
|
616
|
-
with ContentRenderer(YoutubeEmbed, InlineCodeAttr, Strikethrough, FootnoteRef, Superscript, Subscript, img_dir=img_dir, footnotes=footnotes, current_path=current_path) as renderer:
|
|
768
|
+
with ContentRenderer(YoutubeEmbed, IframeEmbed, DownloadEmbed, InlineCodeAttr, Strikethrough, FootnoteRef, Superscript, Subscript, img_dir=img_dir, footnotes=footnotes, current_path=current_path) as renderer:
|
|
617
769
|
doc = mst.Document(content)
|
|
618
770
|
html = renderer.render(doc)
|
|
619
771
|
|
|
@@ -818,6 +970,41 @@ hdrs = (
|
|
|
818
970
|
height: calc(100vh - 6rem) !important;
|
|
819
971
|
}
|
|
820
972
|
|
|
973
|
+
/* Iframe fullscreen overlay */
|
|
974
|
+
body.iframe-fullscreen-open {
|
|
975
|
+
overflow: hidden;
|
|
976
|
+
}
|
|
977
|
+
.iframe-fullscreen-overlay {
|
|
978
|
+
position: fixed;
|
|
979
|
+
inset: 0;
|
|
980
|
+
z-index: 1000;
|
|
981
|
+
background: rgba(2, 6, 23, 0.85);
|
|
982
|
+
display: flex;
|
|
983
|
+
flex-direction: column;
|
|
984
|
+
}
|
|
985
|
+
.iframe-fullscreen-header {
|
|
986
|
+
display: flex;
|
|
987
|
+
align-items: center;
|
|
988
|
+
justify-content: space-between;
|
|
989
|
+
gap: 1rem;
|
|
990
|
+
padding: 0.75rem 1rem;
|
|
991
|
+
color: #e2e8f0;
|
|
992
|
+
font-size: 0.9rem;
|
|
993
|
+
background: rgba(15, 23, 42, 0.9);
|
|
994
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.3);
|
|
995
|
+
}
|
|
996
|
+
.iframe-fullscreen-body {
|
|
997
|
+
flex: 1;
|
|
998
|
+
padding: 0.75rem;
|
|
999
|
+
}
|
|
1000
|
+
.iframe-fullscreen-frame {
|
|
1001
|
+
width: 100%;
|
|
1002
|
+
height: 100%;
|
|
1003
|
+
border: 0;
|
|
1004
|
+
border-radius: 0.5rem;
|
|
1005
|
+
background: #0f172a;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
821
1008
|
.layout-fluid {
|
|
822
1009
|
--layout-breakpoint: 1280px;
|
|
823
1010
|
--layout-blend: 240px;
|
|
@@ -1800,6 +1987,33 @@ def serve_post_static(path: str, ext: str):
|
|
|
1800
1987
|
return FileResponse(file_path)
|
|
1801
1988
|
return Response(status_code=404)
|
|
1802
1989
|
|
|
1990
|
+
# Serve JSON attachments from blog posts (not included in fasthtml static exts)
|
|
1991
|
+
@rt("/posts/{path:path}.json")
|
|
1992
|
+
def serve_post_json(path: str):
|
|
1993
|
+
from starlette.responses import FileResponse
|
|
1994
|
+
file_path = get_root_folder() / f'{path}.json'
|
|
1995
|
+
if file_path.exists():
|
|
1996
|
+
return FileResponse(
|
|
1997
|
+
file_path,
|
|
1998
|
+
headers={"Content-Disposition": f'attachment; filename="{file_path.name}"'}
|
|
1999
|
+
)
|
|
2000
|
+
return Response(status_code=404)
|
|
2001
|
+
|
|
2002
|
+
# Generic download route for any file under the blog root
|
|
2003
|
+
@rt("/download/{path:path}")
|
|
2004
|
+
def download_file(path: str):
|
|
2005
|
+
from starlette.responses import FileResponse
|
|
2006
|
+
root = get_root_folder().resolve()
|
|
2007
|
+
file_path = (root / path).resolve()
|
|
2008
|
+
if not str(file_path).startswith(str(root) + os.sep):
|
|
2009
|
+
return Response(status_code=403)
|
|
2010
|
+
if file_path.exists() and file_path.is_file():
|
|
2011
|
+
return FileResponse(
|
|
2012
|
+
file_path,
|
|
2013
|
+
headers={"Content-Disposition": f'attachment; filename="{file_path.name}"'}
|
|
2014
|
+
)
|
|
2015
|
+
return Response(status_code=404)
|
|
2016
|
+
|
|
1803
2017
|
def theme_toggle():
|
|
1804
2018
|
theme_script = """on load set franken to (localStorage's __FRANKEN__ or '{}') as Object
|
|
1805
2019
|
if franken's mode is 'dark' then add .dark to <html/> end
|
vyasa/static/scripts.js
CHANGED
|
@@ -1174,6 +1174,86 @@ function initPdfFocusToggle() {
|
|
|
1174
1174
|
});
|
|
1175
1175
|
}
|
|
1176
1176
|
|
|
1177
|
+
function openIframeFullscreen(button) {
|
|
1178
|
+
const src = button.getAttribute('data-iframe-src');
|
|
1179
|
+
const title = button.getAttribute('data-iframe-title') || 'Embedded content';
|
|
1180
|
+
const allow = button.getAttribute('data-iframe-allow') || '';
|
|
1181
|
+
const allowfullscreen = button.getAttribute('data-iframe-allowfullscreen') === 'true';
|
|
1182
|
+
|
|
1183
|
+
let overlay = document.querySelector('.iframe-fullscreen-overlay');
|
|
1184
|
+
if (!overlay) {
|
|
1185
|
+
overlay = document.createElement('div');
|
|
1186
|
+
overlay.className = 'iframe-fullscreen-overlay';
|
|
1187
|
+
overlay.innerHTML = `
|
|
1188
|
+
<div class="iframe-fullscreen-header">
|
|
1189
|
+
<div class="iframe-fullscreen-title"></div>
|
|
1190
|
+
<button type="button" class="iframe-fullscreen-close px-2 py-1 text-xs border rounded hover:bg-slate-700">
|
|
1191
|
+
Close
|
|
1192
|
+
</button>
|
|
1193
|
+
</div>
|
|
1194
|
+
<div class="iframe-fullscreen-body">
|
|
1195
|
+
<iframe class="iframe-fullscreen-frame" frameborder="0"></iframe>
|
|
1196
|
+
</div>
|
|
1197
|
+
`;
|
|
1198
|
+
document.body.appendChild(overlay);
|
|
1199
|
+
|
|
1200
|
+
overlay.addEventListener('click', (event) => {
|
|
1201
|
+
if (event.target.classList.contains('iframe-fullscreen-overlay')) {
|
|
1202
|
+
closeIframeFullscreen();
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
overlay.querySelector('.iframe-fullscreen-close').addEventListener('click', () => {
|
|
1207
|
+
closeIframeFullscreen();
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
overlay.querySelector('.iframe-fullscreen-title').textContent = title;
|
|
1212
|
+
const frame = overlay.querySelector('.iframe-fullscreen-frame');
|
|
1213
|
+
frame.setAttribute('src', src);
|
|
1214
|
+
frame.setAttribute('title', title);
|
|
1215
|
+
frame.setAttribute('allow', allow);
|
|
1216
|
+
if (allowfullscreen) {
|
|
1217
|
+
frame.setAttribute('allowfullscreen', '');
|
|
1218
|
+
} else {
|
|
1219
|
+
frame.removeAttribute('allowfullscreen');
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
document.body.classList.add('iframe-fullscreen-open');
|
|
1223
|
+
overlay.style.display = 'flex';
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
function closeIframeFullscreen() {
|
|
1227
|
+
const overlay = document.querySelector('.iframe-fullscreen-overlay');
|
|
1228
|
+
if (!overlay) {
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
const frame = overlay.querySelector('.iframe-fullscreen-frame');
|
|
1232
|
+
if (frame) {
|
|
1233
|
+
frame.setAttribute('src', 'about:blank');
|
|
1234
|
+
}
|
|
1235
|
+
overlay.style.display = 'none';
|
|
1236
|
+
document.body.classList.remove('iframe-fullscreen-open');
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function initIframeFullscreenToggle() {
|
|
1240
|
+
document.addEventListener('click', (event) => {
|
|
1241
|
+
const button = event.target.closest('[data-iframe-fullscreen-toggle]');
|
|
1242
|
+
if (!button) {
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1245
|
+
event.preventDefault();
|
|
1246
|
+
openIframeFullscreen(button);
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
document.addEventListener('keydown', (event) => {
|
|
1250
|
+
if (event.key !== 'Escape') {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
closeIframeFullscreen();
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1177
1257
|
// Initialize on page load
|
|
1178
1258
|
document.addEventListener('DOMContentLoaded', () => {
|
|
1179
1259
|
updateActivePostLink();
|
|
@@ -1183,6 +1263,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
1183
1263
|
initFolderChevronState();
|
|
1184
1264
|
initKeyboardShortcuts();
|
|
1185
1265
|
initPdfFocusToggle();
|
|
1266
|
+
initIframeFullscreenToggle();
|
|
1186
1267
|
initSearchPlaceholderCycle(document);
|
|
1187
1268
|
initPostsSearchPersistence(document);
|
|
1188
1269
|
initCodeBlockCopyButtons(document);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
vyasa/__init__.py,sha256=T0ZRRHOvcleFaTybYJyhb7pRgPUBQjeQHftxbLgmLj4,158
|
|
2
|
+
vyasa/agent.py,sha256=XD4V6rM-JrVtqTVa3pZqPy_BUmcQgKdidQaY4il632Q,3196
|
|
3
|
+
vyasa/build.py,sha256=USqeZsXGPB8COzdWRPLgSgkVg6DIzQwL0qGGJaMM7Ec,26548
|
|
4
|
+
vyasa/config.py,sha256=7mjBTnv7MlBF4CUHA-2IZDt9l9_EMjgOLmQ00I2LQZA,7768
|
|
5
|
+
vyasa/core.py,sha256=79HAv7f-cIF3jMbU6A6wTh7wyUDSSosMnsVrZaI4p4s,134134
|
|
6
|
+
vyasa/helpers.py,sha256=VgOzAIoL3X8RYLvKQRd-S4jM-sjmlolyxFlyOiP7bmM,12489
|
|
7
|
+
vyasa/layout_helpers.py,sha256=uodzhyrGoqC6egbGuzuAPJP2yiWYM8krxb64dE4nwpc,1082
|
|
8
|
+
vyasa/main.py,sha256=xcneOe3Vw3vxfxSii2Y7C5DJTFLz71JDCY_CDZKVwxc,4073
|
|
9
|
+
vyasa/static/scripts.js,sha256=ofLQZWt4QHkuR6RyNvkDxQaEoMBop5vqYLaUBn1TDlE,47954
|
|
10
|
+
vyasa/static/sidenote.css,sha256=9YEl111Qs6kGnrgcVQtC1eiccMGY3-lu05l_NnwXVME,1045
|
|
11
|
+
vyasa-0.3.10.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
|
|
12
|
+
vyasa-0.3.10.dist-info/METADATA,sha256=5ZqmrcpkHAsXxfKnIC7COk_rDcEQeX_BBfGMLUH4qYs,9792
|
|
13
|
+
vyasa-0.3.10.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
14
|
+
vyasa-0.3.10.dist-info/entry_points.txt,sha256=ypyjtxRlygocldmIxOIijoME2BIfxzU0uuNfdi3_1us,41
|
|
15
|
+
vyasa-0.3.10.dist-info/top_level.txt,sha256=Pwy2VqkeYm2zJ5zQ-6XsJHNPsAU4xwscZn-8siQz9Pg,6
|
|
16
|
+
vyasa-0.3.10.dist-info/RECORD,,
|
vyasa-0.3.6.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
vyasa/__init__.py,sha256=l6KpjZx1i1_wMJSbuQIqteDjUJ_h9MM1W8xpm-5ISPA,158
|
|
2
|
-
vyasa/agent.py,sha256=XD4V6rM-JrVtqTVa3pZqPy_BUmcQgKdidQaY4il632Q,3196
|
|
3
|
-
vyasa/build.py,sha256=USqeZsXGPB8COzdWRPLgSgkVg6DIzQwL0qGGJaMM7Ec,26548
|
|
4
|
-
vyasa/config.py,sha256=7mjBTnv7MlBF4CUHA-2IZDt9l9_EMjgOLmQ00I2LQZA,7768
|
|
5
|
-
vyasa/core.py,sha256=3p_HMM5wfpHLCbtWEDW-gdluZCVj3tFV3N6DBXO4PGQ,126211
|
|
6
|
-
vyasa/helpers.py,sha256=VgOzAIoL3X8RYLvKQRd-S4jM-sjmlolyxFlyOiP7bmM,12489
|
|
7
|
-
vyasa/layout_helpers.py,sha256=uodzhyrGoqC6egbGuzuAPJP2yiWYM8krxb64dE4nwpc,1082
|
|
8
|
-
vyasa/main.py,sha256=xcneOe3Vw3vxfxSii2Y7C5DJTFLz71JDCY_CDZKVwxc,4073
|
|
9
|
-
vyasa/static/scripts.js,sha256=SBFM8klicaI77-GsozUVxdMJwTuaJWoVrV6FsY4Kuws,45124
|
|
10
|
-
vyasa/static/sidenote.css,sha256=9YEl111Qs6kGnrgcVQtC1eiccMGY3-lu05l_NnwXVME,1045
|
|
11
|
-
vyasa-0.3.6.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
|
|
12
|
-
vyasa-0.3.6.dist-info/METADATA,sha256=sMt4Yt11hsTD6w1i47BKCo4bhGQsYPoEjI65aWEUMFw,9791
|
|
13
|
-
vyasa-0.3.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
14
|
-
vyasa-0.3.6.dist-info/entry_points.txt,sha256=ypyjtxRlygocldmIxOIijoME2BIfxzU0uuNfdi3_1us,41
|
|
15
|
-
vyasa-0.3.6.dist-info/top_level.txt,sha256=Pwy2VqkeYm2zJ5zQ-6XsJHNPsAU4xwscZn-8siQz9Pg,6
|
|
16
|
-
vyasa-0.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|