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.
- package/LICENSE.txt +21 -0
- package/README.md +154 -0
- package/dist/animated/GraphAgni.svelte +430 -0
- package/dist/animated/GraphAgni.svelte.d.ts +22 -0
- package/dist/animated/GraphAum.svelte +294 -0
- package/dist/animated/GraphAum.svelte.d.ts +20 -0
- package/dist/animated/GraphBoot.svelte +325 -0
- package/dist/animated/GraphBoot.svelte.d.ts +28 -0
- package/dist/animated/GraphCron.svelte +476 -0
- package/dist/animated/GraphCron.svelte.d.ts +42 -0
- package/dist/animated/GraphDamru.svelte +341 -0
- package/dist/animated/GraphDamru.svelte.d.ts +18 -0
- package/dist/animated/GraphDeps.svelte +245 -0
- package/dist/animated/GraphDeps.svelte.d.ts +29 -0
- package/dist/animated/GraphDiya.svelte +330 -0
- package/dist/animated/GraphDiya.svelte.d.ts +22 -0
- package/dist/animated/GraphFire.svelte +246 -0
- package/dist/animated/GraphFire.svelte.d.ts +22 -0
- package/dist/animated/GraphFlame.svelte +258 -0
- package/dist/animated/GraphFlame.svelte.d.ts +14 -0
- package/dist/animated/GraphFlowPlayer.svelte +346 -0
- package/dist/animated/GraphFlowPlayer.svelte.d.ts +27 -0
- package/dist/animated/GraphGanga.svelte +305 -0
- package/dist/animated/GraphGanga.svelte.d.ts +20 -0
- package/dist/animated/GraphHash.svelte +251 -0
- package/dist/animated/GraphHash.svelte.d.ts +20 -0
- package/dist/animated/GraphJapa.svelte +253 -0
- package/dist/animated/GraphJapa.svelte.d.ts +20 -0
- package/dist/animated/GraphLife.svelte +312 -0
- package/dist/animated/GraphLife.svelte.d.ts +27 -0
- package/dist/animated/GraphMandala.svelte +262 -0
- package/dist/animated/GraphMandala.svelte.d.ts +24 -0
- package/dist/animated/GraphMandel.svelte +290 -0
- package/dist/animated/GraphMandel.svelte.d.ts +27 -0
- package/dist/animated/GraphPulse.svelte +248 -0
- package/dist/animated/GraphPulse.svelte.d.ts +24 -0
- package/dist/animated/GraphRain.svelte +280 -0
- package/dist/animated/GraphRain.svelte.d.ts +22 -0
- package/dist/animated/GraphScatter.svelte +395 -0
- package/dist/animated/GraphScatter.svelte.d.ts +31 -0
- package/dist/animated/GraphScope.svelte +197 -0
- package/dist/animated/GraphScope.svelte.d.ts +22 -0
- package/dist/animated/GraphSequence.svelte +247 -0
- package/dist/animated/GraphSequence.svelte.d.ts +18 -0
- package/dist/animated/GraphSpinners.svelte +109 -0
- package/dist/animated/GraphSpinners.svelte.d.ts +22 -0
- package/dist/animated/GraphState.svelte +270 -0
- package/dist/animated/GraphState.svelte.d.ts +14 -0
- package/dist/animated/GraphStream.svelte +223 -0
- package/dist/animated/GraphStream.svelte.d.ts +24 -0
- package/dist/animated/GraphSurya.svelte +268 -0
- package/dist/animated/GraphSurya.svelte.d.ts +22 -0
- package/dist/animated/GraphTerminal.svelte +238 -0
- package/dist/animated/GraphTerminal.svelte.d.ts +28 -0
- package/dist/animated/GraphTicker.svelte +163 -0
- package/dist/animated/GraphTicker.svelte.d.ts +21 -0
- package/dist/animated/GraphTypewriter.svelte +130 -0
- package/dist/animated/GraphTypewriter.svelte.d.ts +22 -0
- package/dist/animated/GraphWorkflow.svelte +570 -0
- package/dist/animated/GraphWorkflow.svelte.d.ts +29 -0
- package/dist/assets/favicon.svg +21 -0
- package/dist/diagram/AmplifierDiagram.svelte +206 -0
- package/dist/diagram/AmplifierDiagram.svelte.d.ts +12 -0
- package/dist/diagram/AsciiDiagram.svelte +212 -0
- package/dist/diagram/AsciiDiagram.svelte.d.ts +24 -0
- package/dist/diagram/DiagramEditor.svelte +414 -0
- package/dist/diagram/DiagramEditor.svelte.d.ts +3 -0
- package/dist/diagram/MetricsTableDiagram.svelte +125 -0
- package/dist/diagram/MetricsTableDiagram.svelte.d.ts +18 -0
- package/dist/diagram/NestedRadiiDiagram.svelte +218 -0
- package/dist/diagram/NestedRadiiDiagram.svelte.d.ts +12 -0
- package/dist/diagram/PromptLoopDiagram.svelte +331 -0
- package/dist/diagram/PromptLoopDiagram.svelte.d.ts +12 -0
- package/dist/diagram/ascii.d.ts +35 -0
- package/dist/diagram/ascii.js +83 -0
- package/dist/diagram/parser.d.ts +16 -0
- package/dist/diagram/parser.js +71 -0
- package/dist/frame/Graph.svelte +141 -0
- package/dist/frame/Graph.svelte.d.ts +14 -0
- package/dist/frame/GraphArrow.svelte +49 -0
- package/dist/frame/GraphArrow.svelte.d.ts +9 -0
- package/dist/frame/GraphBody.svelte +39 -0
- package/dist/frame/GraphBody.svelte.d.ts +10 -0
- package/dist/frame/GraphRule.svelte +21 -0
- package/dist/frame/GraphRule.svelte.d.ts +6 -0
- package/dist/frame/GraphTick.svelte +23 -0
- package/dist/frame/GraphTick.svelte.d.ts +9 -0
- package/dist/frame/GraphTrack.svelte +29 -0
- package/dist/frame/GraphTrack.svelte.d.ts +14 -0
- package/dist/frame/clock.d.ts +10 -0
- package/dist/frame/clock.js +62 -0
- package/dist/frame/glyphs.d.ts +22 -0
- package/dist/frame/glyphs.js +53 -0
- package/dist/frame/motion.css +27 -0
- package/dist/frame/motion.d.ts +24 -0
- package/dist/frame/motion.js +47 -0
- package/dist/frame/tone.d.ts +11 -0
- package/dist/frame/tone.js +64 -0
- package/dist/graphs/GraphActivity.svelte +387 -0
- package/dist/graphs/GraphActivity.svelte.d.ts +22 -0
- package/dist/graphs/GraphBars.svelte +194 -0
- package/dist/graphs/GraphBars.svelte.d.ts +20 -0
- package/dist/graphs/GraphBullet.svelte +208 -0
- package/dist/graphs/GraphBullet.svelte.d.ts +22 -0
- package/dist/graphs/GraphCalendar.svelte +203 -0
- package/dist/graphs/GraphCalendar.svelte.d.ts +20 -0
- package/dist/graphs/GraphCells.svelte +181 -0
- package/dist/graphs/GraphCells.svelte.d.ts +18 -0
- package/dist/graphs/GraphCompare.svelte +192 -0
- package/dist/graphs/GraphCompare.svelte.d.ts +18 -0
- package/dist/graphs/GraphCountdown.svelte +96 -0
- package/dist/graphs/GraphCountdown.svelte.d.ts +14 -0
- package/dist/graphs/GraphDiff.svelte +181 -0
- package/dist/graphs/GraphDiff.svelte.d.ts +18 -0
- package/dist/graphs/GraphFlow.svelte +137 -0
- package/dist/graphs/GraphFlow.svelte.d.ts +21 -0
- package/dist/graphs/GraphFunnel.svelte +190 -0
- package/dist/graphs/GraphFunnel.svelte.d.ts +21 -0
- package/dist/graphs/GraphGantt.svelte +258 -0
- package/dist/graphs/GraphGantt.svelte.d.ts +25 -0
- package/dist/graphs/GraphHeatmap.svelte +287 -0
- package/dist/graphs/GraphHeatmap.svelte.d.ts +22 -0
- package/dist/graphs/GraphInvoice.svelte +294 -0
- package/dist/graphs/GraphInvoice.svelte.d.ts +34 -0
- package/dist/graphs/GraphKpi.svelte +166 -0
- package/dist/graphs/GraphKpi.svelte.d.ts +17 -0
- package/dist/graphs/GraphLatency.svelte +340 -0
- package/dist/graphs/GraphLatency.svelte.d.ts +28 -0
- package/dist/graphs/GraphMeter.svelte +121 -0
- package/dist/graphs/GraphMeter.svelte.d.ts +16 -0
- package/dist/graphs/GraphPlot.svelte +226 -0
- package/dist/graphs/GraphPlot.svelte.d.ts +18 -0
- package/dist/graphs/GraphQuota.svelte +303 -0
- package/dist/graphs/GraphQuota.svelte.d.ts +27 -0
- package/dist/graphs/GraphRank.svelte +141 -0
- package/dist/graphs/GraphRank.svelte.d.ts +21 -0
- package/dist/graphs/GraphSlo.svelte +325 -0
- package/dist/graphs/GraphSlo.svelte.d.ts +31 -0
- package/dist/graphs/GraphSlope.svelte +197 -0
- package/dist/graphs/GraphSlope.svelte.d.ts +19 -0
- package/dist/graphs/GraphSpark.svelte +125 -0
- package/dist/graphs/GraphSpark.svelte.d.ts +15 -0
- package/dist/graphs/GraphSpec.svelte +69 -0
- package/dist/graphs/GraphSpec.svelte.d.ts +14 -0
- package/dist/graphs/GraphStack.svelte +266 -0
- package/dist/graphs/GraphStack.svelte.d.ts +25 -0
- package/dist/graphs/GraphStat.svelte +103 -0
- package/dist/graphs/GraphStat.svelte.d.ts +16 -0
- package/dist/graphs/GraphTable.svelte +133 -0
- package/dist/graphs/GraphTable.svelte.d.ts +15 -0
- package/dist/graphs/GraphTimeline.svelte +164 -0
- package/dist/graphs/GraphTimeline.svelte.d.ts +18 -0
- package/dist/graphs/GraphTimer.svelte +117 -0
- package/dist/graphs/GraphTimer.svelte.d.ts +15 -0
- package/dist/graphs/GraphTree.svelte +147 -0
- package/dist/graphs/GraphTree.svelte.d.ts +16 -0
- package/dist/graphs/GraphUptime.svelte +210 -0
- package/dist/graphs/GraphUptime.svelte.d.ts +18 -0
- package/dist/graphs/GraphWaffle.svelte +131 -0
- package/dist/graphs/GraphWaffle.svelte.d.ts +17 -0
- package/dist/graphs/GraphWaterfall.svelte +258 -0
- package/dist/graphs/GraphWaterfall.svelte.d.ts +22 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.js +87 -0
- package/dist/themes.css +54 -0
- package/package.json +67 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export interface NestedRadiiDiagramProps {
|
|
3
|
+
/** Starting outer radius in px. Default 16. */
|
|
4
|
+
initialOuter?: number;
|
|
5
|
+
/** Starting inset (padding) in px. Default 4. */
|
|
6
|
+
initialInset?: number;
|
|
7
|
+
/** Show the sliders and the live CSS preview. Default true. */
|
|
8
|
+
interactive?: boolean;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { dashEdge, labeledEdgeSegs, overlayRow, padRow, type ArtCell, type ArtSeg } from './ascii';
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
initialOuter = 16,
|
|
18
|
+
initialInset = 4,
|
|
19
|
+
interactive = true,
|
|
20
|
+
class: className = ''
|
|
21
|
+
}: NestedRadiiDiagramProps = $props();
|
|
22
|
+
|
|
23
|
+
const WIDTH = 47;
|
|
24
|
+
|
|
25
|
+
const uid = $props.id();
|
|
26
|
+
|
|
27
|
+
// svelte-ignore state_referenced_locally
|
|
28
|
+
let outer = $state(initialOuter);
|
|
29
|
+
// svelte-ignore state_referenced_locally
|
|
30
|
+
let inset = $state(initialInset);
|
|
31
|
+
const inner = $derived(Math.max(0, outer - inset));
|
|
32
|
+
|
|
33
|
+
const px = (value: number) => `${String(value).padStart(2, ' ')}px`;
|
|
34
|
+
|
|
35
|
+
function edgeCells(left: number, right: number, cornerL: string, cornerR: string): ArtCell[] {
|
|
36
|
+
const cells: ArtCell[] = [
|
|
37
|
+
{ at: left, text: cornerL, cls: 'corner' },
|
|
38
|
+
{ at: right, text: cornerR, cls: 'corner' }
|
|
39
|
+
];
|
|
40
|
+
for (let i = left + 2; i <= right - 2; i += 2) {
|
|
41
|
+
cells.push({ at: i, text: '-' });
|
|
42
|
+
}
|
|
43
|
+
return cells;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const art = $derived.by((): ArtSeg[][] => {
|
|
47
|
+
return [
|
|
48
|
+
labeledEdgeSegs(WIDTH, 'Nested Radii'),
|
|
49
|
+
[{ text: padRow(WIDTH) }],
|
|
50
|
+
overlayRow(WIDTH, edgeCells(4, 42, '╭', '╮')),
|
|
51
|
+
overlayRow(WIDTH, [
|
|
52
|
+
{ at: 4, text: '|' },
|
|
53
|
+
{ at: 42, text: '|' },
|
|
54
|
+
{ at: 7, text: `outer ${px(outer)}`, cls: 'val' }
|
|
55
|
+
]),
|
|
56
|
+
overlayRow(WIDTH, edgeCells(10, 36, '╭', '╮')),
|
|
57
|
+
overlayRow(WIDTH, [
|
|
58
|
+
{ at: 4, text: '|' },
|
|
59
|
+
{ at: 5, text: '◀ - ▶', cls: 'arrow' },
|
|
60
|
+
{ at: 10, text: '|' },
|
|
61
|
+
{ at: 13, text: `inner ${px(inner)}`, cls: 'val' },
|
|
62
|
+
{ at: 36, text: '|' },
|
|
63
|
+
{ at: 42, text: '|' }
|
|
64
|
+
]),
|
|
65
|
+
overlayRow(WIDTH, edgeCells(10, 36, '╰', '╯')),
|
|
66
|
+
overlayRow(WIDTH, [
|
|
67
|
+
{ at: 4, text: '|' },
|
|
68
|
+
{ at: 42, text: '|' },
|
|
69
|
+
{ at: 15, text: `inset ${px(inset)}`, cls: 'val' }
|
|
70
|
+
]),
|
|
71
|
+
overlayRow(WIDTH, edgeCells(4, 42, '╰', '╯')),
|
|
72
|
+
[{ text: padRow(WIDTH) }],
|
|
73
|
+
overlayRow(WIDTH, [{ at: 8, text: 'inner = outer - inset', cls: 'muted' }]),
|
|
74
|
+
overlayRow(WIDTH, [{ at: 8, text: `${px(inner)} = ${px(outer)} - ${px(inset)}`, cls: 'val' }]),
|
|
75
|
+
[{ text: dashEdge(WIDTH) }]
|
|
76
|
+
];
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<div class="radii {className}">
|
|
81
|
+
<div class="viewport">
|
|
82
|
+
<pre class="art"><code>{#each art as line, i (i)}{#each line as seg, j (j)}{#if seg.cls}<span class={seg.cls}>{seg.text}</span>{:else}{seg.text}{/if}{/each}{#if i < art.length - 1}{'\n'}{/if}{/each}</code></pre>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
{#if interactive}
|
|
86
|
+
<div class="controls">
|
|
87
|
+
<label class="row" for="{uid}-outer">
|
|
88
|
+
Outer radius <span class="badge">{outer}px</span>
|
|
89
|
+
<input id="{uid}-outer" type="range" min="6" max="48" step="1" bind:value={outer} />
|
|
90
|
+
</label>
|
|
91
|
+
<label class="row" for="{uid}-inset">
|
|
92
|
+
Inset <span class="badge">{inset}px</span>
|
|
93
|
+
<input id="{uid}-inset" type="range" min="0" max="32" step="1" bind:value={inset} />
|
|
94
|
+
</label>
|
|
95
|
+
<div class="preview-row">
|
|
96
|
+
<div class="box-outer" style:border-radius="{outer}px" style:padding="{inset}px">
|
|
97
|
+
<div class="box-inner" style:border-radius="{inner}px">
|
|
98
|
+
<span>{inner}px</span>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
<p class="hint">inner = max(0, {outer} - {inset}) = {inner}px</p>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
{/if}
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<style>
|
|
108
|
+
.radii {
|
|
109
|
+
display: flex;
|
|
110
|
+
flex-direction: column;
|
|
111
|
+
gap: 1rem;
|
|
112
|
+
min-width: 0;
|
|
113
|
+
font-size: 0.875rem;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.viewport {
|
|
117
|
+
overflow-x: auto;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.art {
|
|
121
|
+
margin: 0;
|
|
122
|
+
font-size: 0.85rem;
|
|
123
|
+
line-height: 1.35;
|
|
124
|
+
color: var(--graph-frame, oklch(0.6 0 0 / 0.5));
|
|
125
|
+
white-space: pre;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.title {
|
|
129
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
130
|
+
font-weight: 600;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.corner {
|
|
134
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.arrow {
|
|
139
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
140
|
+
font-weight: 600;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.val {
|
|
144
|
+
color: var(--graph-foreground, oklch(0.93 0 0));
|
|
145
|
+
font-weight: 500;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.muted {
|
|
149
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.controls {
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
gap: 0.75rem;
|
|
156
|
+
padding-top: 0.875rem;
|
|
157
|
+
border-top: 1px dashed var(--graph-frame, oklch(0.6 0 0 / 0.5));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.row {
|
|
161
|
+
display: flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
justify-content: space-between;
|
|
164
|
+
gap: 1rem;
|
|
165
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
166
|
+
white-space: nowrap;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.row input {
|
|
170
|
+
flex: 1;
|
|
171
|
+
min-width: 0;
|
|
172
|
+
height: 4px;
|
|
173
|
+
accent-color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.badge {
|
|
178
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
179
|
+
border: 1px dashed var(--graph-accent, oklch(0.78 0.17 155));
|
|
180
|
+
padding: 0.1rem 0.4rem;
|
|
181
|
+
font-size: 0.75rem;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.preview-row {
|
|
185
|
+
display: flex;
|
|
186
|
+
align-items: center;
|
|
187
|
+
gap: 1.25rem;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.box-outer {
|
|
191
|
+
flex-shrink: 0;
|
|
192
|
+
width: 100px;
|
|
193
|
+
height: 70px;
|
|
194
|
+
border: 2px solid var(--graph-accent, oklch(0.78 0.17 155));
|
|
195
|
+
box-sizing: border-box;
|
|
196
|
+
display: flex;
|
|
197
|
+
align-items: center;
|
|
198
|
+
justify-content: center;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.box-inner {
|
|
202
|
+
width: 100%;
|
|
203
|
+
height: 100%;
|
|
204
|
+
border: 1px dashed var(--graph-accent, oklch(0.78 0.17 155));
|
|
205
|
+
box-sizing: border-box;
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: center;
|
|
208
|
+
justify-content: center;
|
|
209
|
+
font-size: 0.7rem;
|
|
210
|
+
color: var(--graph-foreground, oklch(0.93 0 0));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.hint {
|
|
214
|
+
margin: 0;
|
|
215
|
+
font-size: 0.75rem;
|
|
216
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
217
|
+
}
|
|
218
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface NestedRadiiDiagramProps {
|
|
2
|
+
/** Starting outer radius in px. Default 16. */
|
|
3
|
+
initialOuter?: number;
|
|
4
|
+
/** Starting inset (padding) in px. Default 4. */
|
|
5
|
+
initialInset?: number;
|
|
6
|
+
/** Show the sliders and the live CSS preview. Default true. */
|
|
7
|
+
interactive?: boolean;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const NestedRadiiDiagram: import("svelte").Component<NestedRadiiDiagramProps, {}, "">;
|
|
11
|
+
type NestedRadiiDiagram = ReturnType<typeof NestedRadiiDiagram>;
|
|
12
|
+
export default NestedRadiiDiagram;
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export interface PromptLoopDiagramProps {
|
|
3
|
+
/** Start playing on mount. Default true. */
|
|
4
|
+
autoPlay?: boolean;
|
|
5
|
+
/** Milliseconds per step. Default 1200. */
|
|
6
|
+
speedMs?: number;
|
|
7
|
+
/** Show the playback controls. Default true. */
|
|
8
|
+
showControls?: boolean;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { dashEdge, labeledEdgeSegs, overlayRow, padRow, type ArtSeg } from './ascii';
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
autoPlay = true,
|
|
18
|
+
speedMs = 1200,
|
|
19
|
+
showControls = true,
|
|
20
|
+
class: className = ''
|
|
21
|
+
}: PromptLoopDiagramProps = $props();
|
|
22
|
+
|
|
23
|
+
const WIDTH = 55;
|
|
24
|
+
const STEPS = 6;
|
|
25
|
+
|
|
26
|
+
const uid = $props.id();
|
|
27
|
+
|
|
28
|
+
// svelte-ignore state_referenced_locally
|
|
29
|
+
let step = $state(0);
|
|
30
|
+
// svelte-ignore state_referenced_locally
|
|
31
|
+
let isPlaying = $state(autoPlay);
|
|
32
|
+
// svelte-ignore state_referenced_locally
|
|
33
|
+
let intervalTime = $state(speedMs);
|
|
34
|
+
|
|
35
|
+
$effect(() => {
|
|
36
|
+
if (!isPlaying) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const timer = window.setInterval(() => {
|
|
41
|
+
step = (step + 1) % STEPS;
|
|
42
|
+
}, intervalTime);
|
|
43
|
+
|
|
44
|
+
return () => window.clearInterval(timer);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
function handleTogglePlay() {
|
|
48
|
+
isPlaying = !isPlaying;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function handleNext() {
|
|
52
|
+
step = (step + 1) % STEPS;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handlePrev() {
|
|
56
|
+
step = (step - 1 + STEPS) % STEPS;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const flow = (k: number) => (step === k ? 'flow on' : 'flow');
|
|
60
|
+
const node = (k: number) => (step === k ? 'node on' : 'node');
|
|
61
|
+
const back = () => (step === 5 ? 'back on' : 'back');
|
|
62
|
+
|
|
63
|
+
const art = $derived.by((): ArtSeg[][] => {
|
|
64
|
+
return [
|
|
65
|
+
labeledEdgeSegs(WIDTH, 'The Prompt Loop'),
|
|
66
|
+
[{ text: padRow(WIDTH) }],
|
|
67
|
+
overlayRow(WIDTH, [{ at: 8, text: '~> Ask for the thing you want', cls: node(0) }]),
|
|
68
|
+
overlayRow(WIDTH, [{ at: 26, text: '│', cls: flow(0) }]),
|
|
69
|
+
overlayRow(WIDTH, [{ at: 26, text: 'v', cls: flow(0) }]),
|
|
70
|
+
overlayRow(WIDTH, [
|
|
71
|
+
{ at: 21, text: 'AI builds it', cls: node(1) },
|
|
72
|
+
{ at: 35, text: '◀ - - - - - - - ┐', cls: back() }
|
|
73
|
+
]),
|
|
74
|
+
overlayRow(WIDTH, [
|
|
75
|
+
{ at: 26, text: '│', cls: flow(1) },
|
|
76
|
+
{ at: 51, text: '│', cls: back() }
|
|
77
|
+
]),
|
|
78
|
+
overlayRow(WIDTH, [
|
|
79
|
+
{ at: 26, text: 'v', cls: flow(1) },
|
|
80
|
+
{ at: 51, text: '│', cls: back() }
|
|
81
|
+
]),
|
|
82
|
+
overlayRow(WIDTH, [
|
|
83
|
+
{ at: 16, text: "It's not quite right", cls: node(2) },
|
|
84
|
+
{ at: 51, text: '│', cls: back() }
|
|
85
|
+
]),
|
|
86
|
+
overlayRow(WIDTH, [
|
|
87
|
+
{ at: 26, text: '│', cls: flow(2) },
|
|
88
|
+
{ at: 51, text: '│', cls: back() }
|
|
89
|
+
]),
|
|
90
|
+
overlayRow(WIDTH, [
|
|
91
|
+
{ at: 26, text: 'v', cls: flow(2) },
|
|
92
|
+
{ at: 51, text: '│', cls: back() }
|
|
93
|
+
]),
|
|
94
|
+
overlayRow(WIDTH, [
|
|
95
|
+
{ at: 8, text: '~> Make me a few variants', cls: node(3) },
|
|
96
|
+
{ at: 51, text: '│', cls: back() }
|
|
97
|
+
]),
|
|
98
|
+
overlayRow(WIDTH, [
|
|
99
|
+
{ at: 26, text: '│', cls: flow(3) },
|
|
100
|
+
{ at: 51, text: '│', cls: back() }
|
|
101
|
+
]),
|
|
102
|
+
overlayRow(WIDTH, [
|
|
103
|
+
{ at: 26, text: 'v', cls: flow(3) },
|
|
104
|
+
{ at: 51, text: '│', cls: back() }
|
|
105
|
+
]),
|
|
106
|
+
overlayRow(WIDTH, [
|
|
107
|
+
{ at: 16, text: 'v1 · v2 · v3 · v4', cls: node(3) },
|
|
108
|
+
{ at: 51, text: '│', cls: back() }
|
|
109
|
+
]),
|
|
110
|
+
overlayRow(WIDTH, [
|
|
111
|
+
{ at: 26, text: '│', cls: flow(3) },
|
|
112
|
+
{ at: 51, text: '│', cls: back() }
|
|
113
|
+
]),
|
|
114
|
+
overlayRow(WIDTH, [
|
|
115
|
+
{ at: 26, text: 'v', cls: flow(3) },
|
|
116
|
+
{ at: 51, text: '│', cls: back() }
|
|
117
|
+
]),
|
|
118
|
+
overlayRow(WIDTH, [
|
|
119
|
+
{ at: 17, text: 'None of them are it', cls: node(4) },
|
|
120
|
+
{ at: 51, text: '│', cls: back() }
|
|
121
|
+
]),
|
|
122
|
+
overlayRow(WIDTH, [
|
|
123
|
+
{ at: 26, text: '│', cls: flow(4) },
|
|
124
|
+
{ at: 51, text: '│', cls: back() }
|
|
125
|
+
]),
|
|
126
|
+
overlayRow(WIDTH, [
|
|
127
|
+
{ at: 26, text: 'v', cls: flow(4) },
|
|
128
|
+
{ at: 51, text: '│', cls: back() }
|
|
129
|
+
]),
|
|
130
|
+
overlayRow(WIDTH, [
|
|
131
|
+
{ at: 26, text: '└', cls: back() },
|
|
132
|
+
{ at: 28, text: '- - - - - - - - - - -', cls: back() },
|
|
133
|
+
{ at: 51, text: '┘', cls: back() }
|
|
134
|
+
]),
|
|
135
|
+
overlayRow(WIDTH, [{ at: 30, text: 'Repeat forever', cls: step === 5 ? 'tag on' : 'tag' }]),
|
|
136
|
+
[{ text: padRow(WIDTH) }],
|
|
137
|
+
[{ text: dashEdge(WIDTH) }]
|
|
138
|
+
];
|
|
139
|
+
});
|
|
140
|
+
</script>
|
|
141
|
+
|
|
142
|
+
<div class="loop {className}">
|
|
143
|
+
<div class="viewport">
|
|
144
|
+
<pre class="art"><code>{#each art as line, i (i)}{#each line as seg, j (j)}{#if seg.cls}<span class={seg.cls}>{seg.text}</span>{:else}{seg.text}{/if}{/each}{#if i < art.length - 1}{'\n'}{/if}{/each}</code></pre>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
{#if showControls}
|
|
148
|
+
<div class="controls">
|
|
149
|
+
<div class="buttons">
|
|
150
|
+
<button class="ctrl" type="button" onclick={handlePrev} aria-label="Previous step">◀</button>
|
|
151
|
+
<button class="ctrl primary" type="button" onclick={handleTogglePlay}>
|
|
152
|
+
{isPlaying ? '❚❚ pause' : '▶ play'}
|
|
153
|
+
</button>
|
|
154
|
+
<button class="ctrl" type="button" onclick={handleNext} aria-label="Next step">▶</button>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="dots">
|
|
158
|
+
{#each [0, 1, 2, 3, 4, 5] as s (s)}
|
|
159
|
+
<button
|
|
160
|
+
class="dot"
|
|
161
|
+
class:on={step === s}
|
|
162
|
+
type="button"
|
|
163
|
+
onclick={() => {
|
|
164
|
+
step = s;
|
|
165
|
+
isPlaying = false;
|
|
166
|
+
}}
|
|
167
|
+
aria-label="Step {s + 1}"
|
|
168
|
+
></button>
|
|
169
|
+
{/each}
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<label class="speed" for="{uid}-speed">
|
|
173
|
+
Speed {(intervalTime / 1000).toFixed(1)}s
|
|
174
|
+
<input id="{uid}-speed" type="range" min="400" max="2500" step="100" bind:value={intervalTime} />
|
|
175
|
+
</label>
|
|
176
|
+
</div>
|
|
177
|
+
{/if}
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<style>
|
|
181
|
+
.back {
|
|
182
|
+
display: flex;
|
|
183
|
+
flex-direction: column;
|
|
184
|
+
gap: 1rem;
|
|
185
|
+
min-width: 0;
|
|
186
|
+
font-size: 0.875rem;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.viewport {
|
|
190
|
+
overflow-x: auto;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.art {
|
|
194
|
+
margin: 0;
|
|
195
|
+
font-size: 0.85rem;
|
|
196
|
+
line-height: 1.35;
|
|
197
|
+
color: var(--graph-frame, oklch(0.6 0 0 / 0.5));
|
|
198
|
+
white-space: pre;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.title {
|
|
202
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.node {
|
|
207
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
208
|
+
transition: color 0.25s ease;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.node.on {
|
|
212
|
+
color: var(--graph-foreground, oklch(0.93 0 0));
|
|
213
|
+
font-weight: 600;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.flow {
|
|
217
|
+
color: var(--graph-faint, oklch(0.3 0 0));
|
|
218
|
+
transition: color 0.25s ease;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.back {
|
|
222
|
+
color: var(--graph-faint, oklch(0.3 0 0));
|
|
223
|
+
transition: color 0.25s ease;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.back.on {
|
|
227
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.tag {
|
|
232
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
233
|
+
font-style: italic;
|
|
234
|
+
transition: color 0.25s ease;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.tag.on {
|
|
238
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
242
|
+
.flow.on {
|
|
243
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
244
|
+
font-weight: 600;
|
|
245
|
+
animation: pulse 1s infinite alternate;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@keyframes pulse {
|
|
249
|
+
from {
|
|
250
|
+
opacity: 0.7;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
to {
|
|
254
|
+
opacity: 1;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.controls {
|
|
260
|
+
display: flex;
|
|
261
|
+
align-items: center;
|
|
262
|
+
justify-content: space-between;
|
|
263
|
+
flex-wrap: wrap;
|
|
264
|
+
gap: 1rem;
|
|
265
|
+
padding-top: 0.875rem;
|
|
266
|
+
border-top: 1px dashed var(--graph-frame, oklch(0.6 0 0 / 0.5));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.buttons {
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
gap: 0.35rem;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.ctrl {
|
|
276
|
+
padding: 0.25rem 0.6rem;
|
|
277
|
+
font-size: 0.75rem;
|
|
278
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
279
|
+
background: none;
|
|
280
|
+
border: 1px dashed var(--graph-frame, oklch(0.6 0 0 / 0.5));
|
|
281
|
+
border-radius: 0;
|
|
282
|
+
cursor: pointer;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.ctrl:hover {
|
|
286
|
+
color: var(--graph-foreground, oklch(0.93 0 0));
|
|
287
|
+
border-color: var(--graph-muted, oklch(0.62 0 0));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.primary {
|
|
291
|
+
color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
292
|
+
border-color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
293
|
+
font-weight: 600;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.dots {
|
|
297
|
+
display: flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
gap: 0.4rem;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.dot {
|
|
303
|
+
width: 8px;
|
|
304
|
+
height: 8px;
|
|
305
|
+
padding: 0;
|
|
306
|
+
background: var(--graph-faint, oklch(0.3 0 0));
|
|
307
|
+
border: none;
|
|
308
|
+
border-radius: 50%;
|
|
309
|
+
cursor: pointer;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.dot.on {
|
|
313
|
+
background: var(--graph-accent, oklch(0.78 0.17 155));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.speed {
|
|
317
|
+
display: flex;
|
|
318
|
+
align-items: center;
|
|
319
|
+
gap: 0.5rem;
|
|
320
|
+
font-size: 0.75rem;
|
|
321
|
+
color: var(--graph-muted, oklch(0.62 0 0));
|
|
322
|
+
white-space: nowrap;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.speed input {
|
|
326
|
+
width: 80px;
|
|
327
|
+
height: 4px;
|
|
328
|
+
accent-color: var(--graph-accent, oklch(0.78 0.17 155));
|
|
329
|
+
cursor: pointer;
|
|
330
|
+
}
|
|
331
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface PromptLoopDiagramProps {
|
|
2
|
+
/** Start playing on mount. Default true. */
|
|
3
|
+
autoPlay?: boolean;
|
|
4
|
+
/** Milliseconds per step. Default 1200. */
|
|
5
|
+
speedMs?: number;
|
|
6
|
+
/** Show the playback controls. Default true. */
|
|
7
|
+
showControls?: boolean;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const PromptLoopDiagram: import("svelte").Component<PromptLoopDiagramProps, {}, "">;
|
|
11
|
+
type PromptLoopDiagram = ReturnType<typeof PromptLoopDiagram>;
|
|
12
|
+
export default PromptLoopDiagram;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type ArtSeg = {
|
|
2
|
+
text: string;
|
|
3
|
+
cls?: string;
|
|
4
|
+
};
|
|
5
|
+
/** Left-pad a string with spaces to exactly `width` characters. */
|
|
6
|
+
export declare function padStart(text: string, width: number): string;
|
|
7
|
+
/** Right-pad a string with spaces to exactly `width` characters. */
|
|
8
|
+
export declare function padEnd(text: string, width: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* A `+ - - - - +` frame edge of exactly `width` characters:
|
|
11
|
+
* dashes on odd columns, spaces elsewhere.
|
|
12
|
+
*/
|
|
13
|
+
export declare function dashEdge(width: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* A frame edge split into three segments around a centered `[ LABEL ]`
|
|
16
|
+
* overlay, so the label can take its own class without moving the dashes.
|
|
17
|
+
*/
|
|
18
|
+
export declare function splitLabeledEdge(width: number, label: string): [string, string, string];
|
|
19
|
+
/** A row of `width` characters inside side borders: `| ... |`. */
|
|
20
|
+
export declare function padRow(width: number): string;
|
|
21
|
+
export type ArtCell = {
|
|
22
|
+
/** Column the text starts at, 0-based. */
|
|
23
|
+
at: number;
|
|
24
|
+
text: string;
|
|
25
|
+
cls?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Builds one art row from absolutely-positioned cells. Side borders are
|
|
29
|
+
* painted at columns 0 and width-1, then the cells are stamped on top.
|
|
30
|
+
* The finished row is split into segments at class boundaries so styled
|
|
31
|
+
* cells (titles, values, arrows) can take their own classes.
|
|
32
|
+
*/
|
|
33
|
+
export declare function overlayRow(width: number, cells: ArtCell[]): ArtSeg[];
|
|
34
|
+
/** A labeled frame edge as segments, so the label can take its own class. */
|
|
35
|
+
export declare function labeledEdgeSegs(width: number, label: string): ArtSeg[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Shared helpers for the diagram components' ASCII art.
|
|
3
|
+
* The art is built as segments so every line lands on the same width —
|
|
4
|
+
* borders line up because they are computed, not hand-counted.
|
|
5
|
+
*/
|
|
6
|
+
/** Left-pad a string with spaces to exactly `width` characters. */
|
|
7
|
+
export function padStart(text, width) {
|
|
8
|
+
return text.length >= width ? text : text.padStart(width, ' ');
|
|
9
|
+
}
|
|
10
|
+
/** Right-pad a string with spaces to exactly `width` characters. */
|
|
11
|
+
export function padEnd(text, width) {
|
|
12
|
+
return text.length >= width ? text : text.padEnd(width, ' ');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A `+ - - - - +` frame edge of exactly `width` characters:
|
|
16
|
+
* dashes on odd columns, spaces elsewhere.
|
|
17
|
+
*/
|
|
18
|
+
export function dashEdge(width) {
|
|
19
|
+
const chars = Array.from({ length: width }, (_, i) => (i % 2 === 1 ? '-' : ' '));
|
|
20
|
+
chars[0] = '+';
|
|
21
|
+
chars[width - 1] = '+';
|
|
22
|
+
return chars.join('');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A frame edge split into three segments around a centered `[ LABEL ]`
|
|
26
|
+
* overlay, so the label can take its own class without moving the dashes.
|
|
27
|
+
*/
|
|
28
|
+
export function splitLabeledEdge(width, label) {
|
|
29
|
+
const base = dashEdge(width);
|
|
30
|
+
const overlay = `[ ${label.toUpperCase()} ]`;
|
|
31
|
+
const start = Math.max(1, Math.round((width - overlay.length) / 2));
|
|
32
|
+
return [base.slice(0, start), overlay, base.slice(start + overlay.length)];
|
|
33
|
+
}
|
|
34
|
+
/** A row of `width` characters inside side borders: `| ... |`. */
|
|
35
|
+
export function padRow(width) {
|
|
36
|
+
return '|' + ' '.repeat(Math.max(0, width - 2)) + '|';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds one art row from absolutely-positioned cells. Side borders are
|
|
40
|
+
* painted at columns 0 and width-1, then the cells are stamped on top.
|
|
41
|
+
* The finished row is split into segments at class boundaries so styled
|
|
42
|
+
* cells (titles, values, arrows) can take their own classes.
|
|
43
|
+
*/
|
|
44
|
+
export function overlayRow(width, cells) {
|
|
45
|
+
const chars = Array.from({ length: width }, () => ' ');
|
|
46
|
+
chars[0] = '|';
|
|
47
|
+
chars[width - 1] = '|';
|
|
48
|
+
const sorted = [...cells].sort((a, b) => a.at - b.at);
|
|
49
|
+
for (const cell of sorted) {
|
|
50
|
+
for (let i = 0; i < cell.text.length; i++) {
|
|
51
|
+
const at = cell.at + i;
|
|
52
|
+
if (at > 0 && at < width - 1) {
|
|
53
|
+
chars[at] = cell.text[i];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const segs = [];
|
|
58
|
+
let cursor = 0;
|
|
59
|
+
for (const cell of sorted) {
|
|
60
|
+
if (!cell.cls) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const start = Math.max(cell.at, 1);
|
|
64
|
+
const end = Math.min(cell.at + cell.text.length, width - 1);
|
|
65
|
+
if (end <= start) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (start > cursor) {
|
|
69
|
+
segs.push({ text: chars.slice(cursor, start).join('') });
|
|
70
|
+
}
|
|
71
|
+
segs.push({ text: chars.slice(start, end).join(''), cls: cell.cls });
|
|
72
|
+
cursor = end;
|
|
73
|
+
}
|
|
74
|
+
if (cursor < width) {
|
|
75
|
+
segs.push({ text: chars.slice(cursor).join('') });
|
|
76
|
+
}
|
|
77
|
+
return segs;
|
|
78
|
+
}
|
|
79
|
+
/** A labeled frame edge as segments, so the label can take its own class. */
|
|
80
|
+
export function labeledEdgeSegs(width, label) {
|
|
81
|
+
const [before, overlay, after] = splitLabeledEdge(width, label);
|
|
82
|
+
return [{ text: before }, { text: overlay, cls: 'title' }, { text: after }];
|
|
83
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function escapeHtml(str: string): string;
|
|
2
|
+
export interface DiagramToken {
|
|
3
|
+
type: 'box' | 'title' | 'arrow' | 'glyph' | 'accent' | 'text';
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
export interface HighlightRule {
|
|
7
|
+
pattern: RegExp;
|
|
8
|
+
className: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parses a raw text diagram into safe, syntax-highlighted HTML spans.
|
|
12
|
+
* Callers style the .diag-* classes; AsciiDiagram is the reference skin.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatDiagramHtml(rawText: string, customAccentPattern?: RegExp): string;
|
|
15
|
+
/** Pads or trims every line to a shared width so box borders line up. */
|
|
16
|
+
export declare function alignBoxLines(text: string, targetWidth?: number): string;
|