markgraphy 0.1.1

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 (166) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +154 -0
  3. package/dist/animated/GraphAgni.svelte +430 -0
  4. package/dist/animated/GraphAgni.svelte.d.ts +22 -0
  5. package/dist/animated/GraphAum.svelte +294 -0
  6. package/dist/animated/GraphAum.svelte.d.ts +20 -0
  7. package/dist/animated/GraphBoot.svelte +325 -0
  8. package/dist/animated/GraphBoot.svelte.d.ts +28 -0
  9. package/dist/animated/GraphCron.svelte +476 -0
  10. package/dist/animated/GraphCron.svelte.d.ts +42 -0
  11. package/dist/animated/GraphDamru.svelte +341 -0
  12. package/dist/animated/GraphDamru.svelte.d.ts +18 -0
  13. package/dist/animated/GraphDeps.svelte +245 -0
  14. package/dist/animated/GraphDeps.svelte.d.ts +29 -0
  15. package/dist/animated/GraphDiya.svelte +330 -0
  16. package/dist/animated/GraphDiya.svelte.d.ts +22 -0
  17. package/dist/animated/GraphFire.svelte +246 -0
  18. package/dist/animated/GraphFire.svelte.d.ts +22 -0
  19. package/dist/animated/GraphFlame.svelte +258 -0
  20. package/dist/animated/GraphFlame.svelte.d.ts +14 -0
  21. package/dist/animated/GraphFlowPlayer.svelte +346 -0
  22. package/dist/animated/GraphFlowPlayer.svelte.d.ts +27 -0
  23. package/dist/animated/GraphGanga.svelte +305 -0
  24. package/dist/animated/GraphGanga.svelte.d.ts +20 -0
  25. package/dist/animated/GraphHash.svelte +251 -0
  26. package/dist/animated/GraphHash.svelte.d.ts +20 -0
  27. package/dist/animated/GraphJapa.svelte +253 -0
  28. package/dist/animated/GraphJapa.svelte.d.ts +20 -0
  29. package/dist/animated/GraphLife.svelte +312 -0
  30. package/dist/animated/GraphLife.svelte.d.ts +27 -0
  31. package/dist/animated/GraphMandala.svelte +262 -0
  32. package/dist/animated/GraphMandala.svelte.d.ts +24 -0
  33. package/dist/animated/GraphMandel.svelte +290 -0
  34. package/dist/animated/GraphMandel.svelte.d.ts +27 -0
  35. package/dist/animated/GraphPulse.svelte +248 -0
  36. package/dist/animated/GraphPulse.svelte.d.ts +24 -0
  37. package/dist/animated/GraphRain.svelte +280 -0
  38. package/dist/animated/GraphRain.svelte.d.ts +22 -0
  39. package/dist/animated/GraphScatter.svelte +395 -0
  40. package/dist/animated/GraphScatter.svelte.d.ts +31 -0
  41. package/dist/animated/GraphScope.svelte +197 -0
  42. package/dist/animated/GraphScope.svelte.d.ts +22 -0
  43. package/dist/animated/GraphSequence.svelte +247 -0
  44. package/dist/animated/GraphSequence.svelte.d.ts +18 -0
  45. package/dist/animated/GraphSpinners.svelte +109 -0
  46. package/dist/animated/GraphSpinners.svelte.d.ts +22 -0
  47. package/dist/animated/GraphState.svelte +270 -0
  48. package/dist/animated/GraphState.svelte.d.ts +14 -0
  49. package/dist/animated/GraphStream.svelte +223 -0
  50. package/dist/animated/GraphStream.svelte.d.ts +24 -0
  51. package/dist/animated/GraphSurya.svelte +268 -0
  52. package/dist/animated/GraphSurya.svelte.d.ts +22 -0
  53. package/dist/animated/GraphTerminal.svelte +238 -0
  54. package/dist/animated/GraphTerminal.svelte.d.ts +28 -0
  55. package/dist/animated/GraphTicker.svelte +163 -0
  56. package/dist/animated/GraphTicker.svelte.d.ts +21 -0
  57. package/dist/animated/GraphTypewriter.svelte +130 -0
  58. package/dist/animated/GraphTypewriter.svelte.d.ts +22 -0
  59. package/dist/animated/GraphWorkflow.svelte +570 -0
  60. package/dist/animated/GraphWorkflow.svelte.d.ts +29 -0
  61. package/dist/assets/favicon.svg +21 -0
  62. package/dist/diagram/AmplifierDiagram.svelte +206 -0
  63. package/dist/diagram/AmplifierDiagram.svelte.d.ts +12 -0
  64. package/dist/diagram/AsciiDiagram.svelte +212 -0
  65. package/dist/diagram/AsciiDiagram.svelte.d.ts +24 -0
  66. package/dist/diagram/DiagramEditor.svelte +414 -0
  67. package/dist/diagram/DiagramEditor.svelte.d.ts +3 -0
  68. package/dist/diagram/MetricsTableDiagram.svelte +125 -0
  69. package/dist/diagram/MetricsTableDiagram.svelte.d.ts +18 -0
  70. package/dist/diagram/NestedRadiiDiagram.svelte +218 -0
  71. package/dist/diagram/NestedRadiiDiagram.svelte.d.ts +12 -0
  72. package/dist/diagram/PromptLoopDiagram.svelte +331 -0
  73. package/dist/diagram/PromptLoopDiagram.svelte.d.ts +12 -0
  74. package/dist/diagram/ascii.d.ts +35 -0
  75. package/dist/diagram/ascii.js +83 -0
  76. package/dist/diagram/parser.d.ts +16 -0
  77. package/dist/diagram/parser.js +71 -0
  78. package/dist/frame/Graph.svelte +141 -0
  79. package/dist/frame/Graph.svelte.d.ts +14 -0
  80. package/dist/frame/GraphArrow.svelte +49 -0
  81. package/dist/frame/GraphArrow.svelte.d.ts +9 -0
  82. package/dist/frame/GraphBody.svelte +39 -0
  83. package/dist/frame/GraphBody.svelte.d.ts +10 -0
  84. package/dist/frame/GraphRule.svelte +21 -0
  85. package/dist/frame/GraphRule.svelte.d.ts +6 -0
  86. package/dist/frame/GraphTick.svelte +23 -0
  87. package/dist/frame/GraphTick.svelte.d.ts +9 -0
  88. package/dist/frame/GraphTrack.svelte +29 -0
  89. package/dist/frame/GraphTrack.svelte.d.ts +14 -0
  90. package/dist/frame/clock.d.ts +10 -0
  91. package/dist/frame/clock.js +62 -0
  92. package/dist/frame/glyphs.d.ts +22 -0
  93. package/dist/frame/glyphs.js +53 -0
  94. package/dist/frame/motion.css +27 -0
  95. package/dist/frame/motion.d.ts +24 -0
  96. package/dist/frame/motion.js +47 -0
  97. package/dist/frame/tone.d.ts +11 -0
  98. package/dist/frame/tone.js +64 -0
  99. package/dist/graphs/GraphActivity.svelte +387 -0
  100. package/dist/graphs/GraphActivity.svelte.d.ts +22 -0
  101. package/dist/graphs/GraphBars.svelte +194 -0
  102. package/dist/graphs/GraphBars.svelte.d.ts +20 -0
  103. package/dist/graphs/GraphBullet.svelte +208 -0
  104. package/dist/graphs/GraphBullet.svelte.d.ts +22 -0
  105. package/dist/graphs/GraphCalendar.svelte +203 -0
  106. package/dist/graphs/GraphCalendar.svelte.d.ts +20 -0
  107. package/dist/graphs/GraphCells.svelte +181 -0
  108. package/dist/graphs/GraphCells.svelte.d.ts +18 -0
  109. package/dist/graphs/GraphCompare.svelte +192 -0
  110. package/dist/graphs/GraphCompare.svelte.d.ts +18 -0
  111. package/dist/graphs/GraphCountdown.svelte +96 -0
  112. package/dist/graphs/GraphCountdown.svelte.d.ts +14 -0
  113. package/dist/graphs/GraphDiff.svelte +181 -0
  114. package/dist/graphs/GraphDiff.svelte.d.ts +18 -0
  115. package/dist/graphs/GraphFlow.svelte +137 -0
  116. package/dist/graphs/GraphFlow.svelte.d.ts +21 -0
  117. package/dist/graphs/GraphFunnel.svelte +190 -0
  118. package/dist/graphs/GraphFunnel.svelte.d.ts +21 -0
  119. package/dist/graphs/GraphGantt.svelte +258 -0
  120. package/dist/graphs/GraphGantt.svelte.d.ts +25 -0
  121. package/dist/graphs/GraphHeatmap.svelte +287 -0
  122. package/dist/graphs/GraphHeatmap.svelte.d.ts +22 -0
  123. package/dist/graphs/GraphInvoice.svelte +294 -0
  124. package/dist/graphs/GraphInvoice.svelte.d.ts +34 -0
  125. package/dist/graphs/GraphKpi.svelte +166 -0
  126. package/dist/graphs/GraphKpi.svelte.d.ts +17 -0
  127. package/dist/graphs/GraphLatency.svelte +340 -0
  128. package/dist/graphs/GraphLatency.svelte.d.ts +28 -0
  129. package/dist/graphs/GraphMeter.svelte +121 -0
  130. package/dist/graphs/GraphMeter.svelte.d.ts +16 -0
  131. package/dist/graphs/GraphPlot.svelte +226 -0
  132. package/dist/graphs/GraphPlot.svelte.d.ts +18 -0
  133. package/dist/graphs/GraphQuota.svelte +303 -0
  134. package/dist/graphs/GraphQuota.svelte.d.ts +27 -0
  135. package/dist/graphs/GraphRank.svelte +141 -0
  136. package/dist/graphs/GraphRank.svelte.d.ts +21 -0
  137. package/dist/graphs/GraphSlo.svelte +325 -0
  138. package/dist/graphs/GraphSlo.svelte.d.ts +31 -0
  139. package/dist/graphs/GraphSlope.svelte +197 -0
  140. package/dist/graphs/GraphSlope.svelte.d.ts +19 -0
  141. package/dist/graphs/GraphSpark.svelte +125 -0
  142. package/dist/graphs/GraphSpark.svelte.d.ts +15 -0
  143. package/dist/graphs/GraphSpec.svelte +69 -0
  144. package/dist/graphs/GraphSpec.svelte.d.ts +14 -0
  145. package/dist/graphs/GraphStack.svelte +266 -0
  146. package/dist/graphs/GraphStack.svelte.d.ts +25 -0
  147. package/dist/graphs/GraphStat.svelte +103 -0
  148. package/dist/graphs/GraphStat.svelte.d.ts +16 -0
  149. package/dist/graphs/GraphTable.svelte +133 -0
  150. package/dist/graphs/GraphTable.svelte.d.ts +15 -0
  151. package/dist/graphs/GraphTimeline.svelte +164 -0
  152. package/dist/graphs/GraphTimeline.svelte.d.ts +18 -0
  153. package/dist/graphs/GraphTimer.svelte +117 -0
  154. package/dist/graphs/GraphTimer.svelte.d.ts +15 -0
  155. package/dist/graphs/GraphTree.svelte +147 -0
  156. package/dist/graphs/GraphTree.svelte.d.ts +16 -0
  157. package/dist/graphs/GraphUptime.svelte +210 -0
  158. package/dist/graphs/GraphUptime.svelte.d.ts +18 -0
  159. package/dist/graphs/GraphWaffle.svelte +131 -0
  160. package/dist/graphs/GraphWaffle.svelte.d.ts +17 -0
  161. package/dist/graphs/GraphWaterfall.svelte +258 -0
  162. package/dist/graphs/GraphWaterfall.svelte.d.ts +22 -0
  163. package/dist/index.d.ts +147 -0
  164. package/dist/index.js +87 -0
  165. package/dist/themes.css +54 -0
  166. package/package.json +67 -0
@@ -0,0 +1,71 @@
1
+ /*
2
+ * ASCII and Unicode diagram tokenizer, ported from fractalsvelte.
3
+ * Formats box-drawing lines, titles, arrows, and glyphs into styled spans.
4
+ * The spans are plain class names — AsciiDiagram supplies the colors through
5
+ * the --graph-* variables. Input is HTML-escaped before tokenizing, so the
6
+ * formatted output is safe to inject with {@html}.
7
+ */
8
+ // Regex patterns for the diagram elements we recognize.
9
+ const TITLE_PATTERN = /\[\s*[A-Z0-9\s_\-\.·:]+\s*\]/g;
10
+ const GLYPH_BLOCKS = /[▂▃▄▅▆▇█░▒▓■□▪▫◆◇●○•]/g;
11
+ export function escapeHtml(str) {
12
+ return str
13
+ .replace(/&/g, '&')
14
+ .replace(/</g, '&lt;')
15
+ .replace(/>/g, '&gt;')
16
+ .replace(/"/g, '&quot;')
17
+ .replace(/'/g, '&#039;');
18
+ }
19
+ /**
20
+ * Parses a raw text diagram into safe, syntax-highlighted HTML spans.
21
+ * Callers style the .diag-* classes; AsciiDiagram is the reference skin.
22
+ */
23
+ export function formatDiagramHtml(rawText, customAccentPattern) {
24
+ const lines = rawText.split('\n');
25
+ const processedLines = lines.map((line) => {
26
+ if (!line.trim()) {
27
+ return '';
28
+ }
29
+ // Escape first, then match against the escaped forms of < and >.
30
+ let escaped = escapeHtml(line);
31
+ escaped = escaped.replace(TITLE_PATTERN, (match) => {
32
+ return `<span class="diag-title">${match}</span>`;
33
+ });
34
+ const escapedArrowPattern = /(?:~&gt;|-&gt;|--&gt;|&lt;-|&lt;--|&lt;-&gt;|&lt;=|=&gt;|◀\s*-\s*▶|◀-▶|◀|▶|▼|▲|▷|◁|▸|◂|→|←|↑|↓|↔|↕|↖|↗|↘|↙)/g;
35
+ escaped = escaped.replace(escapedArrowPattern, (match) => {
36
+ return `<span class="diag-arrow">${match}</span>`;
37
+ });
38
+ if (customAccentPattern) {
39
+ escaped = escaped.replace(customAccentPattern, (match) => {
40
+ return `<span class="diag-accent">${match}</span>`;
41
+ });
42
+ }
43
+ escaped = escaped.replace(GLYPH_BLOCKS, (match) => {
44
+ return `<span class="diag-glyph">${match}</span>`;
45
+ });
46
+ // Rounded corners and junctions get their own class.
47
+ const roundedCorners = /[╭╮╯╰┏┓┗┛╔╗╚╝]/g;
48
+ escaped = escaped.replace(roundedCorners, (match) => {
49
+ return `<span class="diag-corner">${match}</span>`;
50
+ });
51
+ const boxBorderChars = /[┌┐└┘├┤┬┴┼─│━┃═║]/g;
52
+ escaped = escaped.replace(boxBorderChars, (match) => {
53
+ return `<span class="diag-box">${match}</span>`;
54
+ });
55
+ return escaped;
56
+ });
57
+ return processedLines.join('\n');
58
+ }
59
+ /** Pads or trims every line to a shared width so box borders line up. */
60
+ export function alignBoxLines(text, targetWidth) {
61
+ const lines = text.split('\n');
62
+ const maxWidth = targetWidth ?? Math.max(...lines.map((l) => l.length));
63
+ return lines
64
+ .map((line) => {
65
+ if (line.length < maxWidth) {
66
+ return line + ' '.repeat(maxWidth - line.length);
67
+ }
68
+ return line;
69
+ })
70
+ .join('\n');
71
+ }
@@ -0,0 +1,141 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ /** Caption drawn on the top edge as `[ TITLE ]`. Uppercase, 1–2 words. */
6
+ title?: string;
7
+ /** Character at each corner of the frame. Default "+". */
8
+ corner?: string;
9
+ /** Frame motion. 'march' animates the dashes; off under reduced motion. Default 'none'. */
10
+ motion?: 'none' | 'march';
11
+ class?: string;
12
+ children?: Snippet;
13
+ }
14
+
15
+ let { title, corner = '+', motion = 'none', class: className = '', children }: Props = $props();
16
+
17
+ const uid = $props.id();
18
+ </script>
19
+
20
+ <figure class="graph {className}" data-motion={motion} aria-labelledby={title ? uid : undefined}>
21
+ {#if title}
22
+ <figcaption id={uid} class="title"><span class="ink">[ {title} ]</span></figcaption>
23
+ {/if}
24
+ <span aria-hidden="true" class="corner tl">{corner}</span>
25
+ <span aria-hidden="true" class="corner tr">{corner}</span>
26
+ <span aria-hidden="true" class="corner bl">{corner}</span>
27
+ <span aria-hidden="true" class="corner br">{corner}</span>
28
+ {@render children?.()}
29
+ </figure>
30
+
31
+ <style>
32
+ /*
33
+ * The frame is four repeating gradients, one per edge. The dash pattern is
34
+ * a token (--graph-framer) so a host can swap the rhythm without touching
35
+ * the component; it falls back to 4px on / 4px off in --graph-frame.
36
+ */
37
+ .graph {
38
+ --fg-dash: var(
39
+ --graph-framer,
40
+ var(--graph-frame, oklch(0.6 0 0 / 0.5)) 0 4px,
41
+ transparent 4px 8px
42
+ );
43
+ position: relative;
44
+ min-width: 0;
45
+ margin: 0;
46
+ font-family: var(--graph-font, ui-monospace, monospace);
47
+ font-size: 0.875rem;
48
+ line-height: 1.6;
49
+ color: var(--graph-foreground, oklch(0.93 0 0));
50
+ font-variant-numeric: tabular-nums;
51
+ background-image:
52
+ repeating-linear-gradient(to right, var(--fg-dash)),
53
+ repeating-linear-gradient(to bottom, var(--fg-dash)),
54
+ repeating-linear-gradient(to right, var(--fg-dash)),
55
+ repeating-linear-gradient(to bottom, var(--fg-dash));
56
+ background-repeat: repeat-x, repeat-y, repeat-x, repeat-y;
57
+ background-position:
58
+ 0 0,
59
+ 100% 0,
60
+ 0 100%,
61
+ 0 0;
62
+ background-size:
63
+ 100% 1px,
64
+ 1px 100%,
65
+ 100% 1px,
66
+ 1px 100%;
67
+ }
68
+
69
+ @media (prefers-reduced-motion: no-preference) {
70
+ .graph[data-motion='march'] {
71
+ animation: fg-march 0.7s linear infinite;
72
+ }
73
+ }
74
+
75
+ @keyframes fg-march {
76
+ to {
77
+ background-position:
78
+ 8px 0,
79
+ 100% 8px,
80
+ -8px 100%,
81
+ 0 -8px;
82
+ }
83
+ }
84
+
85
+ .corner {
86
+ position: absolute;
87
+ z-index: 10;
88
+ display: flex;
89
+ width: 1rem;
90
+ height: 1rem;
91
+ align-items: center;
92
+ justify-content: center;
93
+ background: var(--graph-background, oklch(0.16 0.01 160));
94
+ font-size: 0.875rem;
95
+ line-height: 1;
96
+ color: var(--graph-accent, oklch(0.78 0.17 155));
97
+ user-select: none;
98
+ pointer-events: none;
99
+ }
100
+
101
+ .tl {
102
+ top: 0;
103
+ left: 0;
104
+ transform: translate(-50%, -50%);
105
+ }
106
+
107
+ .tr {
108
+ top: 0;
109
+ right: 0;
110
+ transform: translate(50%, -50%);
111
+ }
112
+
113
+ .bl {
114
+ bottom: 0;
115
+ left: 0;
116
+ transform: translate(-50%, 50%);
117
+ }
118
+
119
+ .br {
120
+ right: 0;
121
+ bottom: 0;
122
+ transform: translate(50%, 50%);
123
+ }
124
+
125
+ .title {
126
+ position: absolute;
127
+ top: 0;
128
+ left: 50%;
129
+ z-index: 10;
130
+ transform: translate(-50%, -50%);
131
+ background: var(--graph-background, oklch(0.16 0.01 160));
132
+ padding: 0 0.625rem;
133
+ letter-spacing: 0.05em;
134
+ white-space: nowrap;
135
+ text-transform: uppercase;
136
+ }
137
+
138
+ .ink {
139
+ color: var(--graph-accent, oklch(0.78 0.17 155));
140
+ }
141
+ </style>
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Caption drawn on the top edge as `[ TITLE ]`. Uppercase, 1–2 words. */
4
+ title?: string;
5
+ /** Character at each corner of the frame. Default "+". */
6
+ corner?: string;
7
+ /** Frame motion. 'march' animates the dashes; off under reduced motion. Default 'none'. */
8
+ motion?: 'none' | 'march';
9
+ class?: string;
10
+ children?: Snippet;
11
+ }
12
+ declare const Graph: import("svelte").Component<Props, {}, "">;
13
+ type Graph = ReturnType<typeof Graph>;
14
+ export default Graph;
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ /** Dashed arrow between flow nodes. `stretch` spans the available row. */
3
+ interface Props {
4
+ accent?: boolean;
5
+ stretch?: boolean;
6
+ class?: string;
7
+ }
8
+
9
+ let { accent = false, stretch = false, class: className = '' }: Props = $props();
10
+ </script>
11
+
12
+ <div class="arrow {className}" class:accent class:stretch aria-hidden="true">
13
+ {#if stretch}
14
+ <span class="line"></span>
15
+ {:else}
16
+ <span>- - -</span>
17
+ {/if}
18
+ <span class="head">▶</span>
19
+ </div>
20
+
21
+ <style>
22
+ .arrow {
23
+ display: flex;
24
+ min-width: 1.5rem;
25
+ align-items: center;
26
+ gap: 0.25rem;
27
+ color: var(--graph-frame, oklch(0.6 0 0 / 0.5));
28
+ }
29
+
30
+ .stretch {
31
+ min-width: 2.5rem;
32
+ flex: 1;
33
+ }
34
+
35
+ .accent {
36
+ color: var(--graph-accent, oklch(0.78 0.17 155));
37
+ }
38
+
39
+ .line {
40
+ height: 1px;
41
+ min-width: 1.5rem;
42
+ flex: 1;
43
+ border-top: 1px dashed currentColor;
44
+ }
45
+
46
+ .head {
47
+ flex-shrink: 0;
48
+ }
49
+ </style>
@@ -0,0 +1,9 @@
1
+ /** Dashed arrow between flow nodes. `stretch` spans the available row. */
2
+ interface Props {
3
+ accent?: boolean;
4
+ stretch?: boolean;
5
+ class?: string;
6
+ }
7
+ declare const GraphArrow: import("svelte").Component<Props, {}, "">;
8
+ type GraphArrow = ReturnType<typeof GraphArrow>;
9
+ export default GraphArrow;
@@ -0,0 +1,39 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ class?: string;
6
+ /** Compact padding for dense graphs like Table and Invoice. */
7
+ tight?: boolean;
8
+ children?: Snippet;
9
+ }
10
+
11
+ let { class: className = '', tight = false, children }: Props = $props();
12
+ </script>
13
+
14
+ <div class="body {className}" class:tight>
15
+ {@render children?.()}
16
+ </div>
17
+
18
+ <style>
19
+ .body {
20
+ min-width: 0;
21
+ padding: 1.75rem 1.25rem;
22
+ }
23
+
24
+ @media (min-width: 640px) {
25
+ .body {
26
+ padding: 2rem;
27
+ }
28
+ }
29
+
30
+ .body.tight {
31
+ padding: 1.5rem 0.75rem;
32
+ }
33
+
34
+ @media (min-width: 640px) {
35
+ .body.tight {
36
+ padding: 2rem 1.5rem;
37
+ }
38
+ }
39
+ </style>
@@ -0,0 +1,10 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ class?: string;
4
+ /** Compact padding for dense graphs like Table and Invoice. */
5
+ tight?: boolean;
6
+ children?: Snippet;
7
+ }
8
+ declare const GraphBody: import("svelte").Component<Props, {}, "">;
9
+ type GraphBody = ReturnType<typeof GraphBody>;
10
+ export default GraphBody;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ class?: string;
4
+ }
5
+
6
+ let { class: className = '' }: Props = $props();
7
+ </script>
8
+
9
+ <div class="rule {className}" aria-hidden="true"></div>
10
+
11
+ <style>
12
+ .rule {
13
+ width: 100%;
14
+ height: 1px;
15
+ background-image: repeating-linear-gradient(
16
+ to right,
17
+ var(--graph-frame, oklch(0.6 0 0 / 0.5)) 0 2px,
18
+ transparent 2px 7px
19
+ );
20
+ }
21
+ </style>
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ class?: string;
3
+ }
4
+ declare const GraphRule: import("svelte").Component<Props, {}, "">;
5
+ type GraphRule = ReturnType<typeof GraphRule>;
6
+ export default GraphRule;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ /** One glyph on a GraphTrack: flexes to fill, stays 1ch wide, centered. */
5
+ interface Props {
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { class: className = '', children }: Props = $props();
11
+ </script>
12
+
13
+ <span class="tick {className}">
14
+ {@render children?.()}
15
+ </span>
16
+
17
+ <style>
18
+ .tick {
19
+ flex: 1 1 0%;
20
+ min-width: 1ch;
21
+ text-align: center;
22
+ }
23
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ /** One glyph on a GraphTrack: flexes to fill, stays 1ch wide, centered. */
3
+ interface Props {
4
+ class?: string;
5
+ children?: Snippet;
6
+ }
7
+ declare const GraphTick: import("svelte").Component<Props, {}, "">;
8
+ type GraphTick = ReturnType<typeof GraphTick>;
9
+ export default GraphTick;
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ /**
5
+ * Horizontal track that spans the frame. Use for graphs that represent
6
+ * a range (meter, stack, bullet, rank) — pair with GraphTick so ticks
7
+ * flex edge to edge. Packed graphs (spark, bars, cells, uptime) should
8
+ * not use tracks.
9
+ */
10
+ interface Props {
11
+ class?: string;
12
+ children?: Snippet;
13
+ }
14
+
15
+ let { class: className = '', children }: Props = $props();
16
+ </script>
17
+
18
+ <span class="track {className}" aria-hidden="true">
19
+ {@render children?.()}
20
+ </span>
21
+
22
+ <style>
23
+ .track {
24
+ display: flex;
25
+ width: 100%;
26
+ min-width: 0;
27
+ user-select: none;
28
+ }
29
+ </style>
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ /**
3
+ * Horizontal track that spans the frame. Use for graphs that represent
4
+ * a range (meter, stack, bullet, rank) — pair with GraphTick so ticks
5
+ * flex edge to edge. Packed graphs (spark, bars, cells, uptime) should
6
+ * not use tracks.
7
+ */
8
+ interface Props {
9
+ class?: string;
10
+ children?: Snippet;
11
+ }
12
+ declare const GraphTrack: import("svelte").Component<Props, {}, "">;
13
+ type GraphTrack = ReturnType<typeof GraphTrack>;
14
+ export default GraphTrack;
@@ -0,0 +1,10 @@
1
+ export declare function parseInstant(value: Date | number | string): number;
2
+ export declare function pad2(value: number): string;
3
+ export declare function formatHms(ms: number): string;
4
+ export declare function formatAgo(ms: number): string;
5
+ export declare function formatClock(ms: number): string;
6
+ /**
7
+ * The current time, ticking once per interval. SSR-safe: renders null
8
+ * on the server and starts the interval on the client.
9
+ */
10
+ export declare function graphNow(interval?: number): import("svelte/store").Readable<number | null>;
@@ -0,0 +1,62 @@
1
+ /*
2
+ * Clock helpers for Timer / Countdown, ported from markdown-graphs.
3
+ * Timers tick once a second — as text, never as animation.
4
+ */
5
+ import { readable } from 'svelte/store';
6
+ export function parseInstant(value) {
7
+ if (value instanceof Date) {
8
+ return value.getTime();
9
+ }
10
+ if (typeof value === 'number') {
11
+ return Number.isFinite(value) ? value : Number.NaN;
12
+ }
13
+ return Date.parse(value);
14
+ }
15
+ export function pad2(value) {
16
+ return String(Math.trunc(value)).padStart(2, '0');
17
+ }
18
+ export function formatHms(ms) {
19
+ const total = Math.max(0, Math.floor(ms / 1000));
20
+ const days = Math.floor(total / 86400);
21
+ const hours = Math.floor((total % 86400) / 3600);
22
+ const minutes = Math.floor((total % 3600) / 60);
23
+ const seconds = total % 60;
24
+ const clock = `${pad2(hours)}:${pad2(minutes)}:${pad2(seconds)}`;
25
+ if (days > 0) {
26
+ return `${days}d ${clock}`;
27
+ }
28
+ return clock;
29
+ }
30
+ export function formatAgo(ms) {
31
+ const seconds = Math.max(0, Math.floor(ms / 1000));
32
+ if (seconds < 60) {
33
+ return `${seconds}s ago`;
34
+ }
35
+ const minutes = Math.floor(seconds / 60);
36
+ if (minutes < 60) {
37
+ return `${minutes}m ago`;
38
+ }
39
+ const hours = Math.floor(minutes / 60);
40
+ if (hours < 48) {
41
+ return `${hours}h ago`;
42
+ }
43
+ return `${Math.floor(hours / 24)}d ago`;
44
+ }
45
+ export function formatClock(ms) {
46
+ const date = new Date(ms);
47
+ return `${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;
48
+ }
49
+ /**
50
+ * The current time, ticking once per interval. SSR-safe: renders null
51
+ * on the server and starts the interval on the client.
52
+ */
53
+ export function graphNow(interval = 1000) {
54
+ return readable(null, (set) => {
55
+ if (typeof window === 'undefined') {
56
+ return;
57
+ }
58
+ set(Date.now());
59
+ const id = window.setInterval(() => set(Date.now()), interval);
60
+ return () => window.clearInterval(id);
61
+ });
62
+ }
@@ -0,0 +1,22 @@
1
+ export declare const GLYPH_SETS: {
2
+ readonly shade: readonly ["·", "░", "▒", "▓", "█"];
3
+ readonly ascii: readonly [".", "-", "=", "#", "@"];
4
+ readonly hash: readonly [".", ":", "+", "#", "█"];
5
+ readonly bar: readonly ["▁", "▂", "▃", "▅", "█"];
6
+ };
7
+ export type GlyphSetName = keyof typeof GLYPH_SETS;
8
+ export type Glyphs = GlyphSetName | readonly string[];
9
+ export declare const INTENSITY_GLYPHS: readonly string[];
10
+ export declare function clamp01(value: number): number;
11
+ export declare function resolveGlyphs(glyphs?: Glyphs): readonly string[];
12
+ export declare function trackMarks(glyphs?: Glyphs, fallback?: {
13
+ empty: string;
14
+ rest: string;
15
+ fill: string;
16
+ }): {
17
+ empty: string;
18
+ rest: string;
19
+ fill: string;
20
+ };
21
+ export declare function intensityLevel(value: number, max: number): number;
22
+ export declare function intensityGlyph(level: number, glyphs?: readonly string[]): string;
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Glyph sets and intensity math, ported from markdown-graphs.
3
+ * Glyphs draw the chart — no SVG, no canvas.
4
+ */
5
+ export const GLYPH_SETS = {
6
+ shade: ['·', '░', '▒', '▓', '█'],
7
+ ascii: ['.', '-', '=', '#', '@'],
8
+ hash: ['.', ':', '+', '#', '█'],
9
+ bar: ['▁', '▂', '▃', '▅', '█']
10
+ };
11
+ export const INTENSITY_GLYPHS = GLYPH_SETS.shade;
12
+ export function clamp01(value) {
13
+ return Math.min(1, Math.max(0, value));
14
+ }
15
+ export function resolveGlyphs(glyphs) {
16
+ if (glyphs == null) {
17
+ return GLYPH_SETS.shade;
18
+ }
19
+ if (typeof glyphs === 'string') {
20
+ return GLYPH_SETS[glyphs] ?? GLYPH_SETS.shade;
21
+ }
22
+ return glyphs.length > 0 ? glyphs : GLYPH_SETS.shade;
23
+ }
24
+ export function trackMarks(glyphs, fallback = {
25
+ empty: '-',
26
+ rest: '░',
27
+ fill: '█'
28
+ }) {
29
+ if (glyphs == null) {
30
+ return fallback;
31
+ }
32
+ const set = resolveGlyphs(glyphs);
33
+ const last = set.length - 1;
34
+ return {
35
+ empty: set[0] ?? fallback.empty,
36
+ rest: set[Math.min(1, last)] ?? fallback.rest,
37
+ fill: set[last] ?? fallback.fill
38
+ };
39
+ }
40
+ export function intensityLevel(value, max) {
41
+ if (value <= 0 || max <= 0) {
42
+ return 0;
43
+ }
44
+ return Math.max(1, Math.round(clamp01(value / max) * 4));
45
+ }
46
+ export function intensityGlyph(level, glyphs = INTENSITY_GLYPHS) {
47
+ if (glyphs.length === 0) {
48
+ return '·';
49
+ }
50
+ const clamped = Math.min(4, Math.max(0, Math.round(level)));
51
+ const index = Math.round((clamped / 4) * (glyphs.length - 1));
52
+ return glyphs[index] ?? glyphs[0] ?? '·';
53
+ }
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Markgraphy motion.
3
+ * Transform + opacity only, 220ms, ease-out cubic. No loops.
4
+ * prefers-reduced-motion: reduce disables everything.
5
+ */
6
+
7
+ .fg-motion {
8
+ opacity: 0;
9
+ transform: translateY(var(--fg-y, 8px));
10
+ transition:
11
+ opacity 220ms cubic-bezier(0.215, 0.61, 0.355, 1),
12
+ transform 220ms cubic-bezier(0.215, 0.61, 0.355, 1);
13
+ transition-delay: var(--fg-delay, 0ms);
14
+ }
15
+
16
+ .fg-motion.is-revealed {
17
+ opacity: 1;
18
+ transform: translateY(0);
19
+ }
20
+
21
+ @media (prefers-reduced-motion: reduce) {
22
+ .fg-motion {
23
+ opacity: 1;
24
+ transform: none;
25
+ transition: none;
26
+ }
27
+ }
@@ -0,0 +1,24 @@
1
+ import './motion.css';
2
+ export declare const EASE_OUT_CUBIC = "cubic-bezier(0.215, 0.61, 0.355, 1)";
3
+ export declare const DIM_OPACITY = 0.4;
4
+ export type RevealOptions = {
5
+ /** Delay in ms. Use `stagger()` — capped at 280ms. */
6
+ delay?: number;
7
+ /** IntersectionObserver threshold (0–1). Default 0.25. */
8
+ amount?: number;
9
+ /** Vertical offset in px. Default 8. */
10
+ y?: number;
11
+ /** Reveal once only. Default true. */
12
+ once?: boolean;
13
+ };
14
+ /**
15
+ * Svelte action: fade-and-rise when the element enters the viewport.
16
+ * Stagger rows, weeks, or lists — never hundreds of individual cells.
17
+ *
18
+ * <div use:reveal={{ delay: stagger(i, 40) }}>
19
+ */
20
+ export declare function reveal(node: HTMLElement, options?: RevealOptions): {
21
+ destroy(): void;
22
+ };
23
+ /** Stagger delay for index `i`, capped at 280ms. */
24
+ export declare function stagger(index: number, step?: number): number;