@mdzip/editor 1.3.21 → 1.4.4
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.
- package/README.md +62 -0
- package/dist/archive-utils.d.ts.map +1 -1
- package/dist/archive-utils.js +16 -2
- package/dist/archive-utils.js.map +1 -1
- package/dist/asset-cache.d.ts +14 -0
- package/dist/asset-cache.d.ts.map +1 -1
- package/dist/asset-cache.js +57 -0
- package/dist/asset-cache.js.map +1 -1
- package/dist/front-matter-extension.d.ts +45 -0
- package/dist/front-matter-extension.d.ts.map +1 -0
- package/dist/front-matter-extension.js +114 -0
- package/dist/front-matter-extension.js.map +1 -0
- package/dist/front-matter.d.ts +18 -0
- package/dist/front-matter.d.ts.map +1 -0
- package/dist/front-matter.js +48 -0
- package/dist/front-matter.js.map +1 -0
- package/dist/highlight-core.d.ts +3 -0
- package/dist/highlight-core.d.ts.map +1 -0
- package/dist/highlight-core.js +53 -0
- package/dist/highlight-core.js.map +1 -0
- package/dist/image-edit.d.ts +26 -0
- package/dist/image-edit.d.ts.map +1 -0
- package/dist/image-edit.js +195 -0
- package/dist/image-edit.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/library-info.d.ts +2 -2
- package/dist/library-info.js +2 -2
- package/dist/library-info.js.map +1 -1
- package/dist/mdz-archive-worker-protocol.d.ts +36 -0
- package/dist/mdz-archive-worker-protocol.d.ts.map +1 -0
- package/dist/mdz-archive-worker-protocol.js +2 -0
- package/dist/mdz-archive-worker-protocol.js.map +1 -0
- package/dist/mdz-archive.worker-client.d.ts +30 -0
- package/dist/mdz-archive.worker-client.d.ts.map +1 -0
- package/dist/mdz-archive.worker-client.js +97 -0
- package/dist/mdz-archive.worker-client.js.map +1 -0
- package/dist/mdz-archive.worker.d.ts +2 -0
- package/dist/mdz-archive.worker.d.ts.map +1 -0
- package/dist/mdz-archive.worker.js +8870 -0
- package/dist/mdz-archive.worker.js.map +1 -0
- package/dist/mermaid.d.ts.map +1 -1
- package/dist/mermaid.js +60 -41
- package/dist/mermaid.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +12 -2
- package/dist/metadata.js.map +1 -1
- package/dist/preview.d.ts +1 -0
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +1 -0
- package/dist/preview.js.map +1 -1
- package/dist/rendering.d.ts +114 -0
- package/dist/rendering.d.ts.map +1 -1
- package/dist/rendering.js +153 -1
- package/dist/rendering.js.map +1 -1
- package/dist/stats.d.ts +23 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +31 -0
- package/dist/stats.js.map +1 -0
- package/dist/view-css.d.ts.map +1 -1
- package/dist/view-css.js +112 -0
- package/dist/view-css.js.map +1 -1
- package/dist/view.d.ts +421 -1
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +2219 -410
- package/dist/view.js.map +1 -1
- package/dist/workspace.d.ts +14 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +53 -41
- package/dist/workspace.js.map +1 -1
- package/package.json +11 -5
package/dist/stats.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Word, character, line, and reading-time stats for a document's raw text. */
|
|
2
|
+
export interface MdzipDocumentStats {
|
|
3
|
+
words: number;
|
|
4
|
+
characters: number;
|
|
5
|
+
charactersNoSpaces: number;
|
|
6
|
+
lines: number;
|
|
7
|
+
readingTimeMinutes: number;
|
|
8
|
+
}
|
|
9
|
+
/** Default reading speed used for `readingTimeMinutes`, in words per minute. */
|
|
10
|
+
export declare const MDZIP_DEFAULT_READING_WORDS_PER_MINUTE = 200;
|
|
11
|
+
/** Count words in text, splitting on runs of whitespace. */
|
|
12
|
+
export declare function countWords(text: string): number;
|
|
13
|
+
/** Count lines in text, matching how the editor's own gutter numbers lines
|
|
14
|
+
* (an empty document is one empty line, not zero). */
|
|
15
|
+
export declare function countLines(text: string): number;
|
|
16
|
+
/** Count non-whitespace characters in text. */
|
|
17
|
+
export declare function countCharactersExcludingWhitespace(text: string): number;
|
|
18
|
+
/**
|
|
19
|
+
* Compute live document stats from raw text (e.g. `MdzipWorkspaceSnapshot.currentText`).
|
|
20
|
+
* Operates on the raw markdown source, not rendered/plain text.
|
|
21
|
+
*/
|
|
22
|
+
export declare function computeDocumentStats(text: string, wordsPerMinute?: number): MdzipDocumentStats;
|
|
23
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,gFAAgF;AAChF,eAAO,MAAM,sCAAsC,MAAM,CAAC;AAE1D,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;sDACsD;AACtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,+CAA+C;AAC/C,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,cAAc,GAAE,MAA+C,GAC9D,kBAAkB,CASpB"}
|
package/dist/stats.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Default reading speed used for `readingTimeMinutes`, in words per minute. */
|
|
2
|
+
export const MDZIP_DEFAULT_READING_WORDS_PER_MINUTE = 200;
|
|
3
|
+
/** Count words in text, splitting on runs of whitespace. */
|
|
4
|
+
export function countWords(text) {
|
|
5
|
+
const trimmed = text.trim();
|
|
6
|
+
return trimmed === '' ? 0 : trimmed.split(/\s+/).length;
|
|
7
|
+
}
|
|
8
|
+
/** Count lines in text, matching how the editor's own gutter numbers lines
|
|
9
|
+
* (an empty document is one empty line, not zero). */
|
|
10
|
+
export function countLines(text) {
|
|
11
|
+
return text === '' ? 1 : text.split('\n').length;
|
|
12
|
+
}
|
|
13
|
+
/** Count non-whitespace characters in text. */
|
|
14
|
+
export function countCharactersExcludingWhitespace(text) {
|
|
15
|
+
return text.replace(/\s/g, '').length;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Compute live document stats from raw text (e.g. `MdzipWorkspaceSnapshot.currentText`).
|
|
19
|
+
* Operates on the raw markdown source, not rendered/plain text.
|
|
20
|
+
*/
|
|
21
|
+
export function computeDocumentStats(text, wordsPerMinute = MDZIP_DEFAULT_READING_WORDS_PER_MINUTE) {
|
|
22
|
+
const words = countWords(text);
|
|
23
|
+
return {
|
|
24
|
+
words,
|
|
25
|
+
characters: text.length,
|
|
26
|
+
charactersNoSpaces: countCharactersExcludingWhitespace(text),
|
|
27
|
+
lines: countLines(text),
|
|
28
|
+
readingTimeMinutes: words === 0 ? 0 : Math.max(1, Math.round(words / wordsPerMinute))
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AASA,gFAAgF;AAChF,MAAM,CAAC,MAAM,sCAAsC,GAAG,GAAG,CAAC;AAE1D,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAC1D,CAAC;AAED;sDACsD;AACtD,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,kCAAkC,CAAC,IAAY;IAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,iBAAyB,sCAAsC;IAE/D,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO;QACL,KAAK;QACL,UAAU,EAAE,IAAI,CAAC,MAAM;QACvB,kBAAkB,EAAE,kCAAkC,CAAC,IAAI,CAAC;QAC5D,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC;QACvB,kBAAkB,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC;KACtF,CAAC;AACJ,CAAC"}
|
package/dist/view-css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-css.d.ts","sourceRoot":"","sources":["../src/view-css.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"view-css.d.ts","sourceRoot":"","sources":["../src/view-css.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,aAAa,QAkkEzB,CAAC"}
|
package/dist/view-css.js
CHANGED
|
@@ -849,6 +849,24 @@ export const WORKSPACE_CSS = `
|
|
|
849
849
|
pointer-events: none;
|
|
850
850
|
}
|
|
851
851
|
|
|
852
|
+
.mdzip-root .mdzip-copy-toast {
|
|
853
|
+
position: fixed;
|
|
854
|
+
z-index: 10000;
|
|
855
|
+
left: 50%;
|
|
856
|
+
bottom: 20px;
|
|
857
|
+
transform: translateX(-50%);
|
|
858
|
+
max-width: min(320px, calc(100vw - 32px));
|
|
859
|
+
padding: 8px 14px;
|
|
860
|
+
border-radius: 6px;
|
|
861
|
+
background: var(--mdzip-editor-foreground-color);
|
|
862
|
+
color: var(--mdzip-editor-background-color);
|
|
863
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
|
|
864
|
+
font-size: 12px;
|
|
865
|
+
line-height: 1.35;
|
|
866
|
+
text-align: center;
|
|
867
|
+
pointer-events: none;
|
|
868
|
+
}
|
|
869
|
+
|
|
852
870
|
.mdzip-root .pane-stack {
|
|
853
871
|
display: block;
|
|
854
872
|
flex: 1;
|
|
@@ -887,6 +905,19 @@ export const WORKSPACE_CSS = `
|
|
|
887
905
|
|
|
888
906
|
.mdzip-root .preview-pane {
|
|
889
907
|
overflow: auto;
|
|
908
|
+
/* Chrome's scroll-anchoring tries to keep the same visible content pinned
|
|
909
|
+
* when a layout shift happens above the viewport (e.g. a chunk reconcile
|
|
910
|
+
* re-rendering a mermaid diagram to a different height, or an image
|
|
911
|
+
* finishing decode) by silently adjusting scrollTop on its own — firing a
|
|
912
|
+
* genuine, non-echo 'scroll' event with no explicit write behind it. The
|
|
913
|
+
* editor/preview scroll-sync listeners can't distinguish that from a real
|
|
914
|
+
* user scroll, so they propagate it to the other pane, whose own
|
|
915
|
+
* anchoring can then react in turn, compounding into a visible jump on
|
|
916
|
+
* the very next edit after a layout-affecting mount. Disabling anchoring
|
|
917
|
+
* here means a layout shift leaves scrollTop exactly where it was
|
|
918
|
+
* instead of "helpfully" moving it.
|
|
919
|
+
*/
|
|
920
|
+
overflow-anchor: none;
|
|
890
921
|
}
|
|
891
922
|
|
|
892
923
|
.mdzip-root .preview-pane:focus {
|
|
@@ -908,6 +939,16 @@ export const WORKSPACE_CSS = `
|
|
|
908
939
|
flex-direction: column;
|
|
909
940
|
}
|
|
910
941
|
|
|
942
|
+
/* See the matching comment on .preview-pane's overflow-anchor: none — same
|
|
943
|
+
* reasoning applies here. CodeMirror's own line-height re-measurement after
|
|
944
|
+
* an edit can shift content above the viewport too, and native scroll
|
|
945
|
+
* anchoring reacting to that is indistinguishable, from the sync listener's
|
|
946
|
+
* side, from the user actually scrolling.
|
|
947
|
+
*/
|
|
948
|
+
.mdzip-root .cm-scroller {
|
|
949
|
+
overflow-anchor: none;
|
|
950
|
+
}
|
|
951
|
+
|
|
911
952
|
.mdzip-root .edit-pane.active {
|
|
912
953
|
display: flex;
|
|
913
954
|
}
|
|
@@ -1106,6 +1147,20 @@ export const WORKSPACE_CSS = `
|
|
|
1106
1147
|
margin-top: 0;
|
|
1107
1148
|
}
|
|
1108
1149
|
|
|
1150
|
+
/* Chunked (progressiveTextRendering) mounting wraps each rendered chunk in
|
|
1151
|
+
a mount boundary. display:contents drops it from the box tree so margin
|
|
1152
|
+
collapsing and other layout behave exactly as the non-chunked path (one
|
|
1153
|
+
flat run of blocks) — but :first-child selector matching still follows
|
|
1154
|
+
the real DOM tree regardless of display, so the rule above needs a
|
|
1155
|
+
companion for the now one-level-deeper first real content element. */
|
|
1156
|
+
.mdzip-root .preview-content > .mdzip-chunk {
|
|
1157
|
+
display: contents;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.mdzip-root .preview-content > .mdzip-chunk:first-child > :first-child {
|
|
1161
|
+
margin-top: 0;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1109
1164
|
.mdzip-root .preview-content h2 {
|
|
1110
1165
|
font-size: 1.5em;
|
|
1111
1166
|
border-bottom: 1px solid var(--mdzip-border-color);
|
|
@@ -1399,6 +1454,50 @@ export const WORKSPACE_CSS = `
|
|
|
1399
1454
|
}
|
|
1400
1455
|
}
|
|
1401
1456
|
|
|
1457
|
+
.mdzip-root .preview-content .mdzip-frontmatter {
|
|
1458
|
+
margin: 0 0 1em 0;
|
|
1459
|
+
border: 1px solid var(--mdzip-border-color);
|
|
1460
|
+
border-radius: 5px;
|
|
1461
|
+
overflow: hidden;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.mdzip-root .preview-content .mdzip-frontmatter-summary {
|
|
1465
|
+
padding: 6px 12px;
|
|
1466
|
+
background: var(--mdzip-widget-background-color);
|
|
1467
|
+
color: var(--mdzip-muted-foreground-color);
|
|
1468
|
+
font-size: 0.8em;
|
|
1469
|
+
border-bottom: 1px solid var(--mdzip-border-color);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
/* Only the collapsible (<details>) variant is interactive — the static
|
|
1473
|
+
variant's header is a plain <div>, never clickable. */
|
|
1474
|
+
.mdzip-root .preview-content details.mdzip-frontmatter > .mdzip-frontmatter-summary {
|
|
1475
|
+
cursor: pointer;
|
|
1476
|
+
user-select: none;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
.mdzip-root .preview-content .mdzip-frontmatter-table {
|
|
1480
|
+
width: 100%;
|
|
1481
|
+
border-collapse: collapse;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.mdzip-root .preview-content .mdzip-frontmatter-table th,
|
|
1485
|
+
.mdzip-root .preview-content .mdzip-frontmatter-table td {
|
|
1486
|
+
padding: 4px 12px;
|
|
1487
|
+
border: none;
|
|
1488
|
+
text-align: left;
|
|
1489
|
+
vertical-align: top;
|
|
1490
|
+
font-size: 0.85em;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
.mdzip-root .preview-content .mdzip-frontmatter-table th {
|
|
1494
|
+
width: 1%;
|
|
1495
|
+
white-space: nowrap;
|
|
1496
|
+
color: var(--mdzip-muted-foreground-color);
|
|
1497
|
+
font-weight: 600;
|
|
1498
|
+
background: none;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1402
1501
|
.mdzip-root .preview-content .mdzip-mermaid {
|
|
1403
1502
|
display: flex;
|
|
1404
1503
|
justify-content: center;
|
|
@@ -1711,6 +1810,19 @@ export const WORKSPACE_CSS = `
|
|
|
1711
1810
|
margin-top: 8px;
|
|
1712
1811
|
}
|
|
1713
1812
|
|
|
1813
|
+
.mdzip-root .copy-render-progress-track {
|
|
1814
|
+
height: 6px;
|
|
1815
|
+
border-radius: 3px;
|
|
1816
|
+
background: var(--mdzip-secondary-background-color);
|
|
1817
|
+
overflow: hidden;
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
.mdzip-root .copy-render-progress-bar {
|
|
1821
|
+
height: 100%;
|
|
1822
|
+
background: var(--mdzip-accent-color);
|
|
1823
|
+
transition: width 0.1s linear;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1714
1826
|
.mdzip-root .metadata-dialog dl {
|
|
1715
1827
|
margin: 12px 0 0;
|
|
1716
1828
|
}
|
package/dist/view-css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-css.js","sourceRoot":"","sources":["../src/view-css.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,wBAAwB,GAAG,qBAAqB,CAAC,UAAU,CAC/D,UAAU,EACV,kBAAkB,CACnB,CAAC;AACF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,UAAU,CAC7D,UAAU,EACV,kBAAkB,CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;IAUzB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4DnB,wBAAwB;;;;;IAKxB,uBAAuB
|
|
1
|
+
{"version":3,"file":"view-css.js","sourceRoot":"","sources":["../src/view-css.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,wBAAwB,GAAG,qBAAqB,CAAC,UAAU,CAC/D,UAAU,EACV,kBAAkB,CACnB,CAAC;AACF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,UAAU,CAC7D,UAAU,EACV,kBAAkB,CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;IAUzB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4DnB,wBAAwB;;;;;IAKxB,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAu/D1B,CAAC"}
|