rshow 0.0.0-stage → 0.0.2
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 +21 -0
- package/README.md +50 -2
- package/dist/main.js +8500 -0
- package/package.json +48 -4
- package/skills/rshow/SKILL.md +144 -0
- package/skills/rshow/reference/cli.md +263 -0
- package/skills/rshow/reference/dashboard.md +122 -0
- package/skills/rshow/reference/mockups.md +113 -0
- package/skills/rshow/reference/page-contract.md +83 -0
- package/skills/rshow/reference/pages.md +174 -0
- package/skills/rshow/reference/poster.md +137 -0
- package/skills/rshow/reference/project-page.md +132 -0
- package/skills/rshow/reference/reports.md +158 -0
- package/skills/rshow/reference/sketch.md +78 -0
- package/skills/rshow/reference/terminal.md +148 -0
- package/skills/rshow/reference/themes.md +139 -0
- package/skills/rshow-implement/SKILL.md +112 -0
- package/skills/rshow-implement/reference/compare.md +156 -0
- package/skills/rshow-implement/reference/handoff.md +125 -0
- package/skills/rshow-implement/reference/map.md +151 -0
- package/skills/rshow-slides/SKILL.md +136 -0
- package/skills/rshow-slides/reference/layouts.md +251 -0
- package/themes/default/dashboard.css +521 -0
- package/themes/default/dashboard.js +1390 -0
- package/themes/default/deck.css +586 -0
- package/themes/default/deck.js +741 -0
- package/themes/default/example/capture.ans +1 -0
- package/themes/default/example/dashboard.html +106 -0
- package/themes/default/example/demo.cast +14 -0
- package/themes/default/example/drawing.excalidraw +377 -0
- package/themes/default/example/index.html +311 -0
- package/themes/default/example/mockup-desktop.html +331 -0
- package/themes/default/example/mockup-platforms.html +742 -0
- package/themes/default/example/mockup.html +416 -0
- package/themes/default/example/page.html +153 -0
- package/themes/default/example/poster-figure.svg +58 -0
- package/themes/default/example/poster.html +181 -0
- package/themes/default/example/project.html +229 -0
- package/themes/default/example/report.html +404 -0
- package/themes/default/example/results.csv +61 -0
- package/themes/default/example/sketch.html +178 -0
- package/themes/default/example/teaser.svg +66 -0
- package/themes/default/example/terminal.html +231 -0
- package/themes/default/example/tui.html +223 -0
- package/themes/default/fonts/IBMPlexMono-Regular-Latin1.woff2 +0 -0
- package/themes/default/fonts/IBMPlexSans-Light-Latin1.woff2 +0 -0
- package/themes/default/fonts/IBMPlexSans-Regular-Latin1.woff2 +0 -0
- package/themes/default/fonts/IBMPlexSans-SemiBold-Latin1.woff2 +0 -0
- package/themes/default/fonts/OFL.txt +93 -0
- package/themes/default/fonts.css +63 -0
- package/themes/default/index.html +573 -0
- package/themes/default/mockup.css +1078 -0
- package/themes/default/mockup.js +1433 -0
- package/themes/default/mode.js +242 -0
- package/themes/default/page.css +320 -0
- package/themes/default/poster.css +480 -0
- package/themes/default/poster.js +223 -0
- package/themes/default/project.css +482 -0
- package/themes/default/project.js +116 -0
- package/themes/default/report.css +776 -0
- package/themes/default/report.js +427 -0
- package/themes/default/sketch.css +166 -0
- package/themes/default/sketch.js +681 -0
- package/themes/default/skins/adwaita.css +669 -0
- package/themes/default/skins/custom.css +596 -0
- package/themes/default/skins/egui.css +639 -0
- package/themes/default/skins/fluent.css +1093 -0
- package/themes/default/skins/fluent.js +458 -0
- package/themes/default/skins/mac.css +647 -0
- package/themes/default/skins/material.css +692 -0
- package/themes/default/skins/sketch.css +436 -0
- package/themes/default/skins/sketch.js +494 -0
- package/themes/default/skins/wire.css +561 -0
- package/themes/default/terminal.css +292 -0
- package/themes/default/terminal.js +433 -0
- package/themes/default/theme.json +149 -0
- package/themes/default/tokens.css +255 -0
- package/themes/default/tui.css +703 -0
- package/themes/default/tui.js +472 -0
- package/worker/index.js +6918 -0
- package/worker/migrations/0001_init.sql +52 -0
- package/worker/migrations/0002_blobs.sql +5 -0
- package/worker/migrations/0003_projects.sql +31 -0
- package/worker/migrations/0004_page_data_blob.sql +19 -0
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* rshow theme "default": terminal viewer. Two pinned libraries, loaded from
|
|
3
|
+
* jsDelivr only when a figure needs one of them:
|
|
4
|
+
*
|
|
5
|
+
* ansi mode @xterm/xterm@6.0.0
|
|
6
|
+
* @xterm/xterm@6.0.0/css/xterm.css
|
|
7
|
+
* @xterm/addon-unicode11@0.9.0 (box drawing and wide glyphs)
|
|
8
|
+
* cast mode asciinema-player@3.17.0
|
|
9
|
+
* asciinema-player@3.17.0 bundle css
|
|
10
|
+
*
|
|
11
|
+
* Markup:
|
|
12
|
+
*
|
|
13
|
+
* <figure class="terminal" data-mode="ansi" data-src="capture.ans"
|
|
14
|
+
* data-cols="100" data-rows="30" data-title="procview"
|
|
15
|
+
* data-palette="default"></figure>
|
|
16
|
+
* <figure class="terminal" data-mode="cast" data-src="demo.cast"
|
|
17
|
+
* data-title="rshow publish ./deck"></figure>
|
|
18
|
+
*
|
|
19
|
+
* data-mode ansi (a capture of a screen) or cast (an asciicast recording)
|
|
20
|
+
* data-src the file, relative to the page
|
|
21
|
+
* data-cols the grid the capture was taken on, ansi only
|
|
22
|
+
* data-rows and its height
|
|
23
|
+
* data-title what goes in the title bar; the file name by default
|
|
24
|
+
* data-palette default, dark, light or high-contrast; terminal.css owns the
|
|
25
|
+
* sixteen colours and this file only reads them back
|
|
26
|
+
*
|
|
27
|
+
* The palette and the font are read from the theme's custom properties on the
|
|
28
|
+
* figure, so a capture changes colour with the page and nothing is duplicated
|
|
29
|
+
* here. xterm gets the values as a theme object; asciinema-player reads
|
|
30
|
+
* --term-color-* from its own element, which terminal.css points at the figure,
|
|
31
|
+
* and the player is rebuilt when the mode changes because it reads them once,
|
|
32
|
+
* on mount.
|
|
33
|
+
*
|
|
34
|
+
* The capture is a fixed grid and it is read only: no stdin, no blinking
|
|
35
|
+
* cursor, no scrollback. A terminal in a page is a picture of one, not a shell.
|
|
36
|
+
*/
|
|
37
|
+
(function () {
|
|
38
|
+
'use strict';
|
|
39
|
+
|
|
40
|
+
var LIB = {
|
|
41
|
+
xterm: 'https://cdn.jsdelivr.net/npm/@xterm/xterm@6.0.0/lib/xterm.js',
|
|
42
|
+
xtermCss: 'https://cdn.jsdelivr.net/npm/@xterm/xterm@6.0.0/css/xterm.css',
|
|
43
|
+
unicode11: 'https://cdn.jsdelivr.net/npm/@xterm/addon-unicode11@0.9.0/lib/addon-unicode11.js',
|
|
44
|
+
player: 'https://cdn.jsdelivr.net/npm/asciinema-player@3.17.0/dist/bundle/asciinema-player.min.js',
|
|
45
|
+
playerCss: 'https://cdn.jsdelivr.net/npm/asciinema-player@3.17.0/dist/bundle/asciinema-player.css'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
var ANCHORS = [
|
|
49
|
+
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
|
|
50
|
+
'brightBlack', 'brightRed', 'brightGreen', 'brightYellow',
|
|
51
|
+
'brightBlue', 'brightMagenta', 'brightCyan', 'brightWhite'
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
var WORDS = {
|
|
55
|
+
noFile: 'The capture did not load.',
|
|
56
|
+
still: ' The file is still here: ',
|
|
57
|
+
noPlayer: 'The recording needs asciinema-player from the CDN and it did not arrive.'
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// ------------------------------------------------------------- loading ---
|
|
61
|
+
|
|
62
|
+
var loaded = {};
|
|
63
|
+
|
|
64
|
+
function loadScript(src) {
|
|
65
|
+
if (loaded[src]) {
|
|
66
|
+
return loaded[src];
|
|
67
|
+
}
|
|
68
|
+
loaded[src] = new Promise(function (resolve, reject) {
|
|
69
|
+
var script = document.createElement('script');
|
|
70
|
+
script.src = src;
|
|
71
|
+
script.async = false;
|
|
72
|
+
script.onload = function () {
|
|
73
|
+
resolve();
|
|
74
|
+
};
|
|
75
|
+
script.onerror = function () {
|
|
76
|
+
reject(new Error(src));
|
|
77
|
+
};
|
|
78
|
+
(document.head || document.documentElement).appendChild(script);
|
|
79
|
+
});
|
|
80
|
+
return loaded[src];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function loadStyle(href) {
|
|
84
|
+
if (loaded[href]) {
|
|
85
|
+
return loaded[href];
|
|
86
|
+
}
|
|
87
|
+
loaded[href] = new Promise(function (resolve) {
|
|
88
|
+
var link = document.createElement('link');
|
|
89
|
+
link.rel = 'stylesheet';
|
|
90
|
+
link.href = href;
|
|
91
|
+
// A missing stylesheet is not worth failing a capture over.
|
|
92
|
+
link.onload = function () {
|
|
93
|
+
resolve();
|
|
94
|
+
};
|
|
95
|
+
link.onerror = function () {
|
|
96
|
+
resolve();
|
|
97
|
+
};
|
|
98
|
+
(document.head || document.documentElement).appendChild(link);
|
|
99
|
+
});
|
|
100
|
+
return loaded[href];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function loadXterm() {
|
|
104
|
+
return loadStyle(LIB.xtermCss)
|
|
105
|
+
.then(function () {
|
|
106
|
+
return loadScript(LIB.xterm);
|
|
107
|
+
})
|
|
108
|
+
.then(function () {
|
|
109
|
+
if (typeof window.Terminal !== 'function') {
|
|
110
|
+
throw new Error(LIB.xterm);
|
|
111
|
+
}
|
|
112
|
+
// The addon is a nicety: a capture with box drawing reads without it.
|
|
113
|
+
return loadScript(LIB.unicode11).then(null, function () {
|
|
114
|
+
return null;
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function loadPlayer() {
|
|
120
|
+
return loadStyle(LIB.playerCss)
|
|
121
|
+
.then(function () {
|
|
122
|
+
return loadScript(LIB.player);
|
|
123
|
+
})
|
|
124
|
+
.then(function () {
|
|
125
|
+
if (!window.AsciinemaPlayer) {
|
|
126
|
+
throw new Error(LIB.player);
|
|
127
|
+
}
|
|
128
|
+
return window.AsciinemaPlayer;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// --------------------------------------------------------------- words ---
|
|
133
|
+
|
|
134
|
+
function text(value) {
|
|
135
|
+
return (value || '').replace(/^\s+|\s+$/g, '');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function count(value, fallback) {
|
|
139
|
+
var number = parseInt(value, 10);
|
|
140
|
+
return isNaN(number) || number <= 0 ? fallback : number;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function property(host, name, fallback) {
|
|
144
|
+
var value = window.getComputedStyle(host).getPropertyValue(name);
|
|
145
|
+
value = (value || '').replace(/^\s+|\s+$/g, '');
|
|
146
|
+
return value === '' ? fallback : value;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function fontSize(host) {
|
|
150
|
+
return count(property(host, '--term-font-size', '13px'), 13);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function fileName(src) {
|
|
154
|
+
var name = src.split('/').pop();
|
|
155
|
+
return name === '' || name === undefined ? 'terminal' : name;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// The sixteen colours live in terminal.css. Both libraries are handed the
|
|
159
|
+
// same values, so a capture and a recording of the same program agree.
|
|
160
|
+
function colours(host) {
|
|
161
|
+
var palette = {
|
|
162
|
+
background: property(host, '--term-color-background', '#ffffff'),
|
|
163
|
+
foreground: property(host, '--term-color-foreground', '#161616'),
|
|
164
|
+
selection: property(host, '--term-color-selection', 'rgba(15, 98, 254, 0.18)'),
|
|
165
|
+
values: []
|
|
166
|
+
};
|
|
167
|
+
var i;
|
|
168
|
+
for (i = 0; i < ANCHORS.length; i += 1) {
|
|
169
|
+
palette.values.push(property(host, '--term-color-' + i, palette.foreground));
|
|
170
|
+
}
|
|
171
|
+
return palette;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function xtermTheme(palette) {
|
|
175
|
+
var theme = {
|
|
176
|
+
background: palette.background,
|
|
177
|
+
foreground: palette.foreground,
|
|
178
|
+
selectionBackground: palette.selection
|
|
179
|
+
};
|
|
180
|
+
var i;
|
|
181
|
+
for (i = 0; i < ANCHORS.length; i += 1) {
|
|
182
|
+
theme[ANCHORS[i]] = palette.values[i];
|
|
183
|
+
}
|
|
184
|
+
// Read only, so the cursor is painted in the ground colour and never seen.
|
|
185
|
+
theme.cursor = palette.background;
|
|
186
|
+
theme.cursorAccent = palette.background;
|
|
187
|
+
return theme;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function whenFonts(ready) {
|
|
191
|
+
var fonts = window.document.fonts;
|
|
192
|
+
if (fonts && fonts.ready && fonts.status !== 'loaded') {
|
|
193
|
+
fonts.ready.then(ready, ready);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
ready();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ------------------------------------------------------------- escapes ---
|
|
200
|
+
|
|
201
|
+
// The fallback: the same screen, without colour. Cursor addressing becomes a
|
|
202
|
+
// line break, which is what makes the stripped capture read as a screen.
|
|
203
|
+
function strip(capture) {
|
|
204
|
+
return capture
|
|
205
|
+
.replace(/\u001b\]8;;[^\u0007\u001b]*(?:\u0007|\u001b\\)/g, '')
|
|
206
|
+
.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, '')
|
|
207
|
+
.replace(/\u001b\[[0-9;]*H/g, '\n')
|
|
208
|
+
.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, '')
|
|
209
|
+
.replace(/\u001b[@-Z\\-_]/g, '')
|
|
210
|
+
.replace(/\r\n?/g, '\n')
|
|
211
|
+
.replace(/[ ]+$/gm, '')
|
|
212
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
213
|
+
.replace(/^\n+|\n+$/g, '');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ---------------------------------------------------------------- frame ---
|
|
217
|
+
|
|
218
|
+
function element(tag, className) {
|
|
219
|
+
var node = document.createElement(tag);
|
|
220
|
+
node.className = className;
|
|
221
|
+
return node;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function link(href) {
|
|
225
|
+
var anchor = document.createElement('a');
|
|
226
|
+
anchor.href = href;
|
|
227
|
+
anchor.textContent = href;
|
|
228
|
+
return anchor;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function build(host) {
|
|
232
|
+
var src = text(host.getAttribute('data-src'));
|
|
233
|
+
var title = text(host.getAttribute('data-title')) || (src === '' ? 'terminal' : fileName(src));
|
|
234
|
+
|
|
235
|
+
var shell = element('div', 'terminal-window');
|
|
236
|
+
var bar = element('div', 'terminal-bar');
|
|
237
|
+
var heading = element('p', 'terminal-title');
|
|
238
|
+
heading.textContent = title;
|
|
239
|
+
bar.appendChild(heading);
|
|
240
|
+
|
|
241
|
+
var body = element('div', 'terminal-body');
|
|
242
|
+
shell.appendChild(bar);
|
|
243
|
+
shell.appendChild(body);
|
|
244
|
+
host.appendChild(shell);
|
|
245
|
+
return { shell: shell, body: body };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function sorry(body, words, href) {
|
|
249
|
+
body.textContent = '';
|
|
250
|
+
var note = element('p', 'terminal-fallback');
|
|
251
|
+
note.appendChild(document.createTextNode(words + WORDS.still));
|
|
252
|
+
if (href !== '') {
|
|
253
|
+
note.appendChild(link(href));
|
|
254
|
+
}
|
|
255
|
+
body.appendChild(note);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function plain(body, capture) {
|
|
259
|
+
body.textContent = '';
|
|
260
|
+
var pre = element('pre', 'terminal-pre');
|
|
261
|
+
pre.textContent = strip(capture);
|
|
262
|
+
body.appendChild(pre);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ----------------------------------------------------------------- ansi ---
|
|
266
|
+
|
|
267
|
+
// A terminal window is as wide as its grid: the capture was taken at cols by
|
|
268
|
+
// rows, so the frame is stretched to that width and no further.
|
|
269
|
+
function hug(shell, body, term) {
|
|
270
|
+
if (!term.element) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
var width = term.element.getBoundingClientRect().width;
|
|
274
|
+
if (width <= 0) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
var box = window.getComputedStyle(body);
|
|
278
|
+
var side = (parseFloat(box.paddingLeft) || 0) + (parseFloat(box.paddingRight) || 0);
|
|
279
|
+
shell.style.width = Math.ceil(width + side + 2) + 'px';
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function ansi(host, body, shell, src) {
|
|
283
|
+
var cols = count(host.getAttribute('data-cols'), 80);
|
|
284
|
+
var rows = count(host.getAttribute('data-rows'), 24);
|
|
285
|
+
|
|
286
|
+
window.fetch(src, { credentials: 'same-origin' }).then(function (reply) {
|
|
287
|
+
if (!reply.ok) {
|
|
288
|
+
throw new Error(src + ' answered HTTP ' + reply.status);
|
|
289
|
+
}
|
|
290
|
+
return reply.text();
|
|
291
|
+
}).then(function (capture) {
|
|
292
|
+
return loadXterm().then(function () {
|
|
293
|
+
whenFonts(function () {
|
|
294
|
+
var term;
|
|
295
|
+
try {
|
|
296
|
+
term = new window.Terminal({
|
|
297
|
+
cols: cols,
|
|
298
|
+
rows: rows,
|
|
299
|
+
disableStdin: true,
|
|
300
|
+
cursorBlink: false,
|
|
301
|
+
cursorStyle: 'bar',
|
|
302
|
+
cursorInactiveStyle: 'none',
|
|
303
|
+
scrollback: 0,
|
|
304
|
+
convertEol: false,
|
|
305
|
+
fontFamily: property(host, '--font-mono', 'monospace'),
|
|
306
|
+
fontSize: fontSize(host),
|
|
307
|
+
lineHeight: 1.25,
|
|
308
|
+
letterSpacing: 0,
|
|
309
|
+
theme: xtermTheme(colours(host))
|
|
310
|
+
});
|
|
311
|
+
term.open(body);
|
|
312
|
+
} catch (err) {
|
|
313
|
+
plain(body, capture);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (window.Unicode11Addon) {
|
|
317
|
+
try {
|
|
318
|
+
term.loadAddon(new window.Unicode11Addon.Unicode11Addon());
|
|
319
|
+
term.unicode.activeVersion = '11';
|
|
320
|
+
} catch (err) {
|
|
321
|
+
// Widths fall back to the built in table; the capture still reads.
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
term.write(capture);
|
|
325
|
+
window.requestAnimationFrame(function () {
|
|
326
|
+
hug(shell, body, term);
|
|
327
|
+
});
|
|
328
|
+
document.addEventListener('rshowmodechange', function () {
|
|
329
|
+
term.options.theme = xtermTheme(colours(host));
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
}, function () {
|
|
333
|
+
plain(body, capture);
|
|
334
|
+
});
|
|
335
|
+
}, function () {
|
|
336
|
+
sorry(body, WORDS.noFile, src);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ----------------------------------------------------------------- cast ---
|
|
341
|
+
|
|
342
|
+
function cast(host, body, src) {
|
|
343
|
+
var settings = {
|
|
344
|
+
fit: 'width',
|
|
345
|
+
controls: true,
|
|
346
|
+
autoPlay: false,
|
|
347
|
+
// At rest, the recording shows its opening frames rather than a black
|
|
348
|
+
// rectangle: the prompt and the command being typed.
|
|
349
|
+
poster: 'npt:0:02',
|
|
350
|
+
terminalFontFamily: property(host, '--font-mono', 'monospace'),
|
|
351
|
+
terminalFontSize: fontSize(host) + 'px',
|
|
352
|
+
terminalLineHeight: 1.4
|
|
353
|
+
};
|
|
354
|
+
var cols = count(host.getAttribute('data-cols'), 0);
|
|
355
|
+
var rows = count(host.getAttribute('data-rows'), 0);
|
|
356
|
+
if (cols > 0) {
|
|
357
|
+
settings.cols = cols;
|
|
358
|
+
}
|
|
359
|
+
if (rows > 0) {
|
|
360
|
+
settings.rows = rows;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
var player = null;
|
|
364
|
+
|
|
365
|
+
function start(at) {
|
|
366
|
+
var options = {};
|
|
367
|
+
var key;
|
|
368
|
+
for (key in settings) {
|
|
369
|
+
if (Object.prototype.hasOwnProperty.call(settings, key)) {
|
|
370
|
+
options[key] = settings[key];
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (at > 0) {
|
|
374
|
+
options.startAt = at;
|
|
375
|
+
}
|
|
376
|
+
body.textContent = '';
|
|
377
|
+
player = window.AsciinemaPlayer.create(src, body, options);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
loadPlayer().then(function () {
|
|
381
|
+
start(0);
|
|
382
|
+
// The player reads the palette once, when it mounts, so a mode change
|
|
383
|
+
// means a new player, put back where the old one was.
|
|
384
|
+
document.addEventListener('rshowmodechange', function () {
|
|
385
|
+
var at = 0;
|
|
386
|
+
try {
|
|
387
|
+
at = player && player.getCurrentTime ? player.getCurrentTime() : 0;
|
|
388
|
+
} catch (err) {
|
|
389
|
+
at = 0;
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
if (player && player.dispose) {
|
|
393
|
+
player.dispose();
|
|
394
|
+
}
|
|
395
|
+
} catch (err) {
|
|
396
|
+
// Nothing to dispose of: the mount below replaces the body anyway.
|
|
397
|
+
}
|
|
398
|
+
start(at || 0);
|
|
399
|
+
});
|
|
400
|
+
}, function () {
|
|
401
|
+
sorry(body, WORDS.noPlayer, src);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// ---------------------------------------------------------------- mount ---
|
|
406
|
+
|
|
407
|
+
function mount(host) {
|
|
408
|
+
var src = text(host.getAttribute('data-src'));
|
|
409
|
+
if (src === '') {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
var frame = build(host);
|
|
413
|
+
if (host.getAttribute('data-mode') === 'cast') {
|
|
414
|
+
cast(host, frame.body, src);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
ansi(host, frame.body, frame.shell, src);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function start() {
|
|
421
|
+
var hosts = document.querySelectorAll('.terminal[data-src]');
|
|
422
|
+
var i;
|
|
423
|
+
for (i = 0; i < hosts.length; i += 1) {
|
|
424
|
+
mount(hosts[i]);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (document.readyState === 'loading') {
|
|
429
|
+
document.addEventListener('DOMContentLoaded', start);
|
|
430
|
+
} else {
|
|
431
|
+
start();
|
|
432
|
+
}
|
|
433
|
+
}());
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "default",
|
|
3
|
+
"description": "IBM Carbon v11 theme in two modes: white (light) and g100 (dark), system by default with a reader override. Plex Sans for text, Plex Mono for code and data, square corners, one blue for interactive elements and Carbon's eight colour data palette. Layouts: a 1280x720 deck canvas with twelve layouts, a 72 character prose page, a report with contents and side notes, a project page, an A0 poster, a metrics dashboard, mockups with eight skins, an Excalidraw sketch viewer, a terminal capture viewer and a cell grid tui kit.",
|
|
4
|
+
"defaultMode": "system",
|
|
5
|
+
"modes": ["system", "light", "dark"],
|
|
6
|
+
"layouts": {
|
|
7
|
+
"deck": {
|
|
8
|
+
"css": ["fonts.css", "tokens.css", "deck.css"],
|
|
9
|
+
"js": ["deck.js"],
|
|
10
|
+
"example": "example/index.html"
|
|
11
|
+
},
|
|
12
|
+
"page": {
|
|
13
|
+
"css": ["fonts.css", "tokens.css", "page.css"],
|
|
14
|
+
"js": ["mode.js"],
|
|
15
|
+
"example": "example/page.html"
|
|
16
|
+
},
|
|
17
|
+
"report": {
|
|
18
|
+
"css": ["fonts.css", "tokens.css", "report.css"],
|
|
19
|
+
"js": ["mode.js", "report.js"],
|
|
20
|
+
"example": "example/report.html"
|
|
21
|
+
},
|
|
22
|
+
"project": {
|
|
23
|
+
"css": ["fonts.css", "tokens.css", "project.css"],
|
|
24
|
+
"js": ["mode.js", "project.js"],
|
|
25
|
+
"example": "example/project.html"
|
|
26
|
+
},
|
|
27
|
+
"poster": {
|
|
28
|
+
"css": ["fonts.css", "tokens.css", "poster.css"],
|
|
29
|
+
"js": ["mode.js", "poster.js"],
|
|
30
|
+
"example": "example/poster.html"
|
|
31
|
+
},
|
|
32
|
+
"dashboard": {
|
|
33
|
+
"css": ["fonts.css", "tokens.css", "dashboard.css"],
|
|
34
|
+
"js": ["mode.js", "dashboard.js"],
|
|
35
|
+
"example": "example/dashboard.html"
|
|
36
|
+
},
|
|
37
|
+
"mockup": {
|
|
38
|
+
"css": ["fonts.css", "tokens.css", "mockup.css", "skins/wire.css"],
|
|
39
|
+
"js": ["mode.js", "mockup.js", "skins/sketch.js", "skins/fluent.js"],
|
|
40
|
+
"example": "example/mockup.html"
|
|
41
|
+
},
|
|
42
|
+
"sketch": {
|
|
43
|
+
"css": ["fonts.css", "tokens.css", "sketch.css"],
|
|
44
|
+
"js": ["mode.js", "sketch.js"],
|
|
45
|
+
"example": "example/sketch.html"
|
|
46
|
+
},
|
|
47
|
+
"terminal": {
|
|
48
|
+
"css": ["fonts.css", "tokens.css", "terminal.css"],
|
|
49
|
+
"js": ["mode.js", "terminal.js"],
|
|
50
|
+
"example": "example/terminal.html"
|
|
51
|
+
},
|
|
52
|
+
"tui": {
|
|
53
|
+
"css": ["fonts.css", "tokens.css", "mockup.css", "skins/wire.css", "tui.css"],
|
|
54
|
+
"js": ["mode.js", "mockup.js", "tui.js"],
|
|
55
|
+
"example": "example/tui.html"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"tokens": {
|
|
59
|
+
"--font-sans": "\"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", sans-serif",
|
|
60
|
+
"--font-mono": "\"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
61
|
+
"--text-2xs": "14px",
|
|
62
|
+
"--text-xs": "16px",
|
|
63
|
+
"--text-sm": "18px",
|
|
64
|
+
"--text-base": "20px",
|
|
65
|
+
"--text-md": "24px",
|
|
66
|
+
"--text-lg": "28px",
|
|
67
|
+
"--text-xl": "32px",
|
|
68
|
+
"--text-2xl": "42px",
|
|
69
|
+
"--text-3xl": "54px",
|
|
70
|
+
"--text-4xl": "60px",
|
|
71
|
+
"--text-5xl": "76px",
|
|
72
|
+
"--lh-flat": "1",
|
|
73
|
+
"--lh-heading": "1.25",
|
|
74
|
+
"--lh-list": "1.4",
|
|
75
|
+
"--lh-body": "1.45",
|
|
76
|
+
"--lh-read": "1.6",
|
|
77
|
+
"--lh-code": "1.6",
|
|
78
|
+
"--tracking-display": "-0.02em",
|
|
79
|
+
"--space-01": "2px",
|
|
80
|
+
"--space-02": "4px",
|
|
81
|
+
"--space-03": "8px",
|
|
82
|
+
"--space-04": "12px",
|
|
83
|
+
"--space-05": "16px",
|
|
84
|
+
"--space-06": "24px",
|
|
85
|
+
"--space-07": "32px",
|
|
86
|
+
"--space-08": "40px",
|
|
87
|
+
"--space-09": "48px",
|
|
88
|
+
"--space-10": "64px",
|
|
89
|
+
"--space-11": "80px",
|
|
90
|
+
"--space-12": "96px",
|
|
91
|
+
"--space-13": "160px",
|
|
92
|
+
"--radius": "0",
|
|
93
|
+
"--radius-sm": "0",
|
|
94
|
+
"--pad-x": "96px",
|
|
95
|
+
"--pad-y": "64px"
|
|
96
|
+
},
|
|
97
|
+
"modeTokens": {
|
|
98
|
+
"light": {
|
|
99
|
+
"--color-scheme": "light",
|
|
100
|
+
"--bg": "#ffffff",
|
|
101
|
+
"--bg-shell": "#f4f4f4",
|
|
102
|
+
"--layer-01": "#f4f4f4",
|
|
103
|
+
"--layer-02": "#ffffff",
|
|
104
|
+
"--border-subtle": "#e0e0e0",
|
|
105
|
+
"--border-strong": "#8d8d8d",
|
|
106
|
+
"--fg": "#161616",
|
|
107
|
+
"--muted": "#525252",
|
|
108
|
+
"--placeholder": "#a8a8a8",
|
|
109
|
+
"--accent": "#0f62fe",
|
|
110
|
+
"--focus": "#0f62fe",
|
|
111
|
+
"--support-error": "#da1e28",
|
|
112
|
+
"--support-success": "#24a148",
|
|
113
|
+
"--support-warning": "#f1c21b",
|
|
114
|
+
"--chart-1": "#6929c4",
|
|
115
|
+
"--chart-2": "#1192e8",
|
|
116
|
+
"--chart-3": "#005d5d",
|
|
117
|
+
"--chart-4": "#9f1853",
|
|
118
|
+
"--chart-5": "#fa4d56",
|
|
119
|
+
"--chart-6": "#570408",
|
|
120
|
+
"--chart-7": "#198038",
|
|
121
|
+
"--chart-8": "#002d9c"
|
|
122
|
+
},
|
|
123
|
+
"dark": {
|
|
124
|
+
"--color-scheme": "dark",
|
|
125
|
+
"--bg": "#161616",
|
|
126
|
+
"--bg-shell": "#262626",
|
|
127
|
+
"--layer-01": "#262626",
|
|
128
|
+
"--layer-02": "#393939",
|
|
129
|
+
"--border-subtle": "#393939",
|
|
130
|
+
"--border-strong": "#6f6f6f",
|
|
131
|
+
"--fg": "#f4f4f4",
|
|
132
|
+
"--muted": "#c6c6c6",
|
|
133
|
+
"--placeholder": "#6f6f6f",
|
|
134
|
+
"--accent": "#78a9ff",
|
|
135
|
+
"--focus": "#ffffff",
|
|
136
|
+
"--support-error": "#fa4d56",
|
|
137
|
+
"--support-success": "#42be65",
|
|
138
|
+
"--support-warning": "#f1c21b",
|
|
139
|
+
"--chart-1": "#8a3ffc",
|
|
140
|
+
"--chart-2": "#33b1ff",
|
|
141
|
+
"--chart-3": "#007d79",
|
|
142
|
+
"--chart-4": "#ff7eb6",
|
|
143
|
+
"--chart-5": "#fa4d56",
|
|
144
|
+
"--chart-6": "#fff1f1",
|
|
145
|
+
"--chart-7": "#6fdc8c",
|
|
146
|
+
"--chart-8": "#4589ff"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|