vintage-frames 0.19.1 → 0.20.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 (59) hide show
  1. package/README.md +1 -18
  2. package/custom-elements.json +72 -13
  3. package/dist/components/vf-desktop.d.ts +36 -6
  4. package/dist/components/vf-desktop.js +41 -23
  5. package/dist/components/vf-window.d.ts +19 -0
  6. package/dist/components/vf-window.js +33 -3
  7. package/dist/text-control.d.ts +3 -3
  8. package/docs/SPEC.md +8 -6
  9. package/editor/vscode.html-custom-data.json +10 -5
  10. package/editor/web-types.json +25 -10
  11. package/package.json +4 -34
  12. package/dist/build/app-file.d.ts +0 -21
  13. package/dist/build/app-file.js +0 -42
  14. package/dist/build/box.d.ts +0 -57
  15. package/dist/build/box.js +0 -93
  16. package/dist/build/client.d.ts +0 -12
  17. package/dist/build/frame-picture.d.ts +0 -6
  18. package/dist/build/frame-picture.js +0 -4
  19. package/dist/build/frame.d.ts +0 -11
  20. package/dist/build/frame.js +0 -44
  21. package/dist/build/index.d.ts +0 -14
  22. package/dist/build/index.js +0 -4
  23. package/dist/build/plugins.d.ts +0 -41
  24. package/dist/build/plugins.js +0 -134
  25. package/dist/build/png.d.ts +0 -24
  26. package/dist/build/png.js +0 -116
  27. package/dist/shell/alert.d.ts +0 -40
  28. package/dist/shell/alert.js +0 -41
  29. package/dist/shell/app-file.d.ts +0 -115
  30. package/dist/shell/app-file.js +0 -189
  31. package/dist/shell/catalog.d.ts +0 -250
  32. package/dist/shell/catalog.js +0 -349
  33. package/dist/shell/clock.d.ts +0 -16
  34. package/dist/shell/clock.js +0 -36
  35. package/dist/shell/filing.d.ts +0 -39
  36. package/dist/shell/filing.js +0 -68
  37. package/dist/shell/finder.d.ts +0 -180
  38. package/dist/shell/finder.js +0 -676
  39. package/dist/shell/geometry.d.ts +0 -203
  40. package/dist/shell/geometry.js +0 -257
  41. package/dist/shell/index.d.ts +0 -30
  42. package/dist/shell/index.js +0 -12
  43. package/dist/shell/pure.d.ts +0 -13
  44. package/dist/shell/pure.js +0 -6
  45. package/dist/shell/shell.d.ts +0 -177
  46. package/dist/shell/shell.js +0 -277
  47. package/dist/shell/state.d.ts +0 -88
  48. package/dist/shell/state.js +0 -103
  49. package/dist/shell/storage.d.ts +0 -14
  50. package/dist/shell/storage.js +0 -41
  51. package/dist/shell/version.d.ts +0 -2
  52. package/dist/shell/version.js +0 -4
  53. package/dist/shell/windows.d.ts +0 -278
  54. package/dist/shell/windows.js +0 -447
  55. package/dist/styles/body-strike.d.ts +0 -12
  56. package/dist/styles/body-strike.js +0 -3961
  57. package/dist/styles/display-strike.d.ts +0 -12
  58. package/dist/styles/display-strike.js +0 -4343
  59. package/dist/styles/strike.d.ts +0 -30
@@ -1,42 +0,0 @@
1
- import { CODE_KEYWORD as e, MANIFEST_KEYWORD as t, PNG_SIGNATURE as n, deflate as r, itxtKeyword as i, manifestOf as a, pngChunks as o } from "../shell/app-file.js";
2
- import { concat as s, pngChunk as c } from "./png.js";
3
- import { composeBox as l } from "./box.js";
4
- //#region src/build/app-file.ts
5
- var u = new TextEncoder();
6
- function d(e, t, n) {
7
- let r = Uint8Array.from([...e].map((e) => e.charCodeAt(0)));
8
- return c("iTXt", s([
9
- r,
10
- Uint8Array.of(0, +!!n, 0, 0, 0),
11
- t
12
- ]));
13
- }
14
- async function f(c, l, f) {
15
- let p = o(c);
16
- if (!p) throw Error("vintage-frames/build: the box is not a whole PNG");
17
- let m = a(l);
18
- if (typeof m == "string") throw Error(`vintage-frames/build: the manifest won't read back: ${m}`);
19
- let h = [d(t, u.encode(JSON.stringify(m)), !1), d(e, await r(u.encode(f)), !0)], g = [n];
20
- for (let e of p) e.type === "iTXt" && ["vintage-frames.app", "vintage-frames.code"].includes(i(e.data)) || (e.type === "IEND" && g.push(...h), g.push(c.subarray(e.start, e.end)));
21
- return s(g);
22
- }
23
- async function p({ manifest: e, icon: t, code: n, artwork: r }) {
24
- let i = {
25
- ...e,
26
- format: 1,
27
- api: 2,
28
- icon: `data:image/png;base64,${m(t)}`
29
- };
30
- return f(await l({
31
- manifest: i,
32
- icon: t,
33
- artwork: r
34
- }), i, n);
35
- }
36
- function m(e) {
37
- let t = "";
38
- for (let n = 0; n < e.length; n += 32768) t += String.fromCharCode(...e.subarray(n, n + 32768));
39
- return btoa(t);
40
- }
41
- //#endregion
42
- export { p as packApp, f as writeAppFile };
@@ -1,57 +0,0 @@
1
- /**
2
- * The box: the picture an app file shows. The kit's frame, with the
3
- * application's artwork in the artwork slot, or its icon stamped large on
4
- * the slot's backdrop when there is none, and lines of text set from the
5
- * kit's strikes with the manifest's fields in them. Artwork and the stamp
6
- * are pasted by their alpha. Nothing is drawn outside the slots.
7
- */
8
- import type { AppManifest } from '../shell/app-file.js';
9
- import type { Strike } from '../styles/strike.js';
10
- import type { Pixels } from './png.js';
11
- /** A box in a frame's picture, in its px. */
12
- export interface Slot {
13
- left: number;
14
- top: number;
15
- width: number;
16
- height: number;
17
- }
18
- /** A frame: a picture with everything fixed drawn in, and its slots. */
19
- export interface BoxFrame {
20
- /** The picture, a PNG. */
21
- picture: Uint8Array;
22
- /** One system px, in the picture's px. Each of the artwork's px is a whole number of them. */
23
- scale: number;
24
- /** Where the artwork goes. Without artwork the icon goes there, `stamp` times its size and centered. */
25
- artwork: Slot & {
26
- stamp: number;
27
- };
28
- /** The lines of text. */
29
- text: readonly TextSlot[];
30
- }
31
- /** A line of text on the box. */
32
- export interface TextSlot {
33
- /** The top-left of its em box, and the width it fits in. */
34
- left: number;
35
- top: number;
36
- width: number;
37
- strike: Strike;
38
- /** Picture px per design px. */
39
- scale: number;
40
- /** `#rrggbb`. */
41
- ink: string;
42
- align?: 'left' | 'center' | 'right';
43
- /** The line, with manifest fields in braces: `{name}`, `Version {version}`, `by {author}`, or fixed text. */
44
- text: string;
45
- }
46
- /** What a box is composed from. */
47
- export interface BoxInput {
48
- manifest: AppManifest;
49
- /** The icon's PNG, 32 × 32. */
50
- icon: Uint8Array;
51
- /** The artwork's PNG: the artwork slot's size in system px, or that divided by a whole number. */
52
- artwork?: Uint8Array;
53
- }
54
- /** The box in the kit's frame, as a PNG. */
55
- export declare function composeBox(input: BoxInput): Promise<Uint8Array>;
56
- /** The box in `frame`, as pixels. */
57
- export declare function drawBox(frame: BoxFrame, { manifest, icon, artwork }: BoxInput): Promise<Pixels>;
package/dist/build/box.js DELETED
@@ -1,93 +0,0 @@
1
- import { FRAME as e } from "./frame.js";
2
- import { decodePng as t, encodePng as n } from "./png.js";
3
- //#region src/build/box.ts
4
- var r = [
5
- "id",
6
- "name",
7
- "version",
8
- "requires",
9
- "author"
10
- ];
11
- async function i(t) {
12
- return n(await a(e, t));
13
- }
14
- async function a(e, { manifest: n, icon: r, artwork: i }) {
15
- let a = await t(e.picture, "the frame"), c = await t(r, "the icon");
16
- if (c.width !== 32 || c.height !== 32) throw Error(`the icon is ${c.width} × ${c.height}, and an icon is 32 × 32`);
17
- let u = e.artwork;
18
- if (i) {
19
- let n = await t(i, "the artwork"), r = {
20
- width: u.width / e.scale,
21
- height: u.height / e.scale
22
- }, c = r.width / n.width;
23
- if (!Number.isInteger(c) || n.height * c !== r.height) throw Error(`the artwork is ${n.width} × ${n.height}: draw it at ${r.width} × ${r.height}, or that divided by a whole number (${o(r)})`);
24
- s(a, n, u.left, u.top, c * e.scale, u);
25
- } else {
26
- let e = 32 * u.stamp;
27
- s(a, c, u.left + Math.floor((u.width - e) / 2), u.top + Math.floor((u.height - e) / 2), u.stamp, u);
28
- }
29
- for (let t of e.text) p(a, t, l(t.text, n));
30
- return a;
31
- }
32
- function o({ width: e, height: t }) {
33
- let n = [];
34
- for (let r = 2; r <= e && n.length < 3; r++) e % r === 0 && t % r === 0 && n.push(`${e / r} × ${t / r}`);
35
- return [...n, "…"].join(", ");
36
- }
37
- function s(e, t, n, r, i, a) {
38
- let o = Math.max(n, a.left, 0), s = Math.max(r, a.top, 0), l = Math.min(n + t.width * i, a.left + a.width, e.width), u = Math.min(r + t.height * i, a.top + a.height, e.height);
39
- for (let a = s; a < u; a++) for (let s = o; s < l; s++) {
40
- let o = (Math.floor((a - r) / i) * t.width + Math.floor((s - n) / i)) * 4;
41
- c(e, s, a, t.data.subarray(o, o + 4));
42
- }
43
- }
44
- function c(e, t, n, [r, i, a, o]) {
45
- if (!o) return;
46
- let s = e.data, c = (n * e.width + t) * 4;
47
- if (o === 255) {
48
- s[c] = r, s[c + 1] = i, s[c + 2] = a, s[c + 3] = 255;
49
- return;
50
- }
51
- let l = s[c + 3] * (255 - o) / 255, u = o + l;
52
- s[c] = Math.round((r * o + s[c] * l) / u), s[c + 1] = Math.round((i * o + s[c + 1] * l) / u), s[c + 2] = Math.round((a * o + s[c + 2] * l) / u), s[c + 3] = Math.round(u);
53
- }
54
- function l(e, t) {
55
- return e.replace(/\{(\w+)\}/g, (n, i) => {
56
- let a = r.find((e) => e === i);
57
- if (!a) throw Error(`the frame's line "${e}" names {${i}}, which a manifest doesn't have`);
58
- return t[a];
59
- });
60
- }
61
- var u = (e) => `"${e}" (U+${e.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")})`, d = (e, t) => [...t].reduce((t, n) => t + e.glyphs[n].advance, 0);
62
- function f(e, t, n) {
63
- if (d(e, t) <= n) return t;
64
- if (!e.glyphs["…"]) throw Error(`${e.family} has no ${u("…")} to shorten "${t}" with`);
65
- let r = [...t];
66
- for (; r.length && d(e, r.join("").trimEnd() + "…") > n;) r.pop();
67
- return r.join("").trimEnd() + "…";
68
- }
69
- function p(e, t, n) {
70
- let { strike: r, scale: i } = t;
71
- for (let e of n) if (!r.glyphs[e]) throw Error(`${r.family} has no ${u(e)}, in "${n}"`);
72
- let a = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(t.ink);
73
- if (!a) throw Error(`the frame's ink "${t.ink}" is not #rrggbb`);
74
- let o = Uint8Array.of(parseInt(a[1], 16), parseInt(a[2], 16), parseInt(a[3], 16), 255), s = f(r, n, t.width / i), l = d(r, s) * i, p = t.align === "center" ? Math.floor((t.width - l) / 2 / i) * i : t.align === "right" ? t.width - l : 0, m = {
75
- left: t.left,
76
- top: t.top,
77
- width: t.width,
78
- height: (r.ascent + r.descent) * i
79
- }, h = t.top + r.ascent * i, g = t.left + p;
80
- for (let t of s) {
81
- let n = r.glyphs[t];
82
- n.rows.forEach((t, r) => {
83
- let a = h - (n.y0 + n.height - r) * i;
84
- for (let r = 0; r < t.length; r++) {
85
- if (t[r] !== "#") continue;
86
- let s = g + (n.x0 + r) * i;
87
- for (let t = Math.max(a, m.top, 0); t < Math.min(a + i, m.top + m.height, e.height); t++) for (let n = Math.max(s, m.left, 0); n < Math.min(s + i, m.left + m.width, e.width); n++) c(e, n, t, o);
88
- }
89
- }), g += n.advance * i;
90
- }
91
- }
92
- //#endregion
93
- export { i as composeBox, a as drawBox };
@@ -1,12 +0,0 @@
1
- /**
2
- * `vintage-frames/build/client`: the types of a `*.png?app` import, which
3
- * `appFiles()` serves. A site adds it to tsconfig's `types` beside
4
- * `vite/client`.
5
- */
6
- declare module '*.png?app' {
7
- /** The application's factory: its definition, given the manifest's icon. */
8
- const app: (...args: any[]) => import('../shell/index.js').AppDefinition<any>;
9
- export default app;
10
- /** The app file's manifest. */
11
- export const manifest: import('../shell/pure.js').AppManifest;
12
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * The kit's frame's picture: box/frame.png, 480 × 615, 3095 bytes.
3
- * GENERATED by `npm run embed:frame`: redraw box/frame.png and re-run rather
4
- * than editing this file. Its slots are src/build/frame.ts's.
5
- */
6
- export declare const FRAME_PNG: Uint8Array;
@@ -1,4 +0,0 @@
1
- //#region src/build/frame-picture.ts
2
- var e = Uint8Array.from(atob("iVBORw0KGgoAAAANSUhEUgAAAeAAAAJnCAYAAABPiYBoAAAL3klEQVR42u3VwQkAIAwEwfRfW3rSBnwJBuFmYQpQAldVtQCAcT4BAAwwAKQNsCRJepcBliTJAEuSZIAlSZIBliTJAEuSJAMsSZIBliRJBliSJAMsSZIMsCRJBliSJAMsSZIMsCRJBliSJBlgSZIMsCRJMsCSJBlgSZJkgCVJMsCSJBlgAyxJkgGWJMkAS5IkAyxJkgGWJEkGWJIkAyxJkgywJEkGWJIkA2yAJUkywJIkGWBJkmSAJUkywJIkyQBLkmSAJUmSAZYkyQBLkmSADbAkSQZYkiQDLEmSDPDxAQCEM8AGGAADbIABMMAG+NEDuhuAQAbYAANggA0wAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADTAABtgAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMAAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA0wAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADTAABtgAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMAAG2AADYIANsCMEMMAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wgAE2wAYYAANsgAEwwAbYAANggA0wAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAAQywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAG2AADLABBsAAG2ADDGCADbABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2AADYIANMAAG2AAbYAADbIANMAAG2AADYIANsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYAANsgAEwwAbYAANggA0wAAbYAANggA2wAQbAABtgAAywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAA2CADbABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2AADYIANMAAG2AADYIANsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYAANsgAEwwAbYAANggA0wAAbYAANggA2wAQbAABtgAAywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAO0IAA2yADTAABtgAA2CADbABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2BECGGADbIABMMAGGAADbIANMAAG2AADYIANsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA2wAQbAABtgAAywATbAAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADbABBjDABtgAA2CADTAABtgAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMAAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA0wAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADTAABtgAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMAAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA0wAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADbAjBDDABtgAA2CADTAABtgAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMIABNsAGGAADbIABMMAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEMsAE2wAAYYAMMgAE2wAYYAANsgAEwwAbYAANggA0wAAbYABtgAAywAQbAABtgAwxggA2wAQbAABtgAAywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAG2AADLABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYAANsgAEwwAbYAANggA0wAAbYABtgAAywAQbAABtgAAywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAG2AADLABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2AADYIANMAAG2AAbYAAMsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYAANsgAEwwAbYAANggA0wAAbYABtgAAywAQbAABtgRwhggA2wAQbAABtgAAywATbAABhgAwyAATbABhgAA2yAATDABtgAA2CADTAABtgAG2AAA2yADTAABtgAA2CADbABBsAAG2AADLABNsAAGGADDIABNsAGGAADbIABMMAG2AADGGADbIABMMAGGAADbIANMAAG2AADYIANsAEGwAAbYAAMsAE2wAAYYAMMgAE2wAYYwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA2wAQbAABtgAAywATbAAAbYABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADbABBsAAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbIANMAAG2AADYIANsAEGwAAbYAAMsAEGwAAbYAMMgAE2wAAYYANsgAEwwAYYAANsgA0wAAbYAANggA2wAQbAABtgAAywAQbAABtgAwyAATbAABhgA2yAATDABhgAA2yADTAABtgAA2CADbABBsAAG2AADLABBsAAG2ADDIABNsAAGGADbIABMMAGGAADbICvHwBAOANsgAEwwAYYAANsgCVJCs8AS5JkgCVJMsCSJMkAS5JkgCVJkgGWJMkAS5IkAyxJkgGWJEkGWJIkAyxJkgGWJEkGWJIkAyxJkgywJEkGWJIkGWBJkgywJEkywJIkGWBJkgywAZYkyQBLkmSAJUmSAZYkyQBLkiQDLEmSAZYkSQZYkiQDLEmSATbAkiQZYEmSDLAkSTLAkiQZYEmSZIAlSTLAkiTJAEuSZIAlSTLABliSJAMsSZIBliRJBliSJAMsSZIMsCRJBliSJBlgSZIMsCRJBtgAS5JkgCVJMsCSJMkAS5JkgCVJkgGWJMkAS5IkAyxJkgGWJMkAG2BJkgywJEkGWJIkGWBJkgywJEkywJIkGWBJkmSAJUkywJIkGWADLEmSAZYkyQBLkiQDLEmSAZYkSQZYkiQDLEmSDLAkSQZYkiQDbIAlSTLAkiQZYEmSZIAlSTLAkiTJAEuSZIAlSZIBliTJAEuSZIANsCRJBliSJAMsSZIMsCRJBliSJBlgSZIMsCRJMsCSJBlgSZJkgCVJMsCSJBlgSZJkgCVJMsCSJMkAS5JkgCVJkgGWJMkAS5IkAyxJkgGWJMkAG2BJkgywJEkGWJIkGWBJkgywJEkywJIkGWBJkmSAJUkywJIkGWADLEmSAZYkyQBLkiQDLEmSAZYkSQZYkiQDLEmSDLAkSQZYkiQDbIAlSTLAkiQZYEmSZIAlSTLAkiTJAEuSZIAlSZIBliTJAEuSZIANsCRJBliSJAMsSZIMsCRJBliSJBlgSZIMsCRJMsCSJBlgSZIMsAGWJMkAS5JkgCVJkgGWJMkAS5IkAyxJkgGWJEkGWJIkAyxJkgE2wJIkGWBJkgywJEkywJIkGWBJkmSAJUkywJIkyQBLkmSAJUkywAZYkiQDLEmSAZYkSQZYkiQDLEmSDLAkSQZYkiQZYEmSDLAkSQbYAEuSZIAlSTLAkiTJAEuSZIAlSZIBliTJAEuSJAMsSZIBliRJBliSpK8GGAAY4xMAwAADQIANOM+x56UXUawAAAAASUVORK5CYII="), (e) => e.charCodeAt(0));
3
- //#endregion
4
- export { e as FRAME_PNG };
@@ -1,11 +0,0 @@
1
- /**
2
- * The kit's frame: the picture every app file's box is drawn on, and its
3
- * slots, in the picture's px. A placeholder: a white card on 160 × 205
4
- * system px drawn at 3×, the artwork's slot on a gray backdrop inside a
5
- * black rule, then the name, the version and the author, centered.
6
- *
7
- * The picture is box/frame.png (`npm run embed:frame`). A redrawn picture
8
- * moves its slots here.
9
- */
10
- import type { BoxFrame } from './box.js';
11
- export declare const FRAME: BoxFrame;
@@ -1,44 +0,0 @@
1
- import "../shell/app-file.js";
2
- import { VF_BODY_STRIKE as e } from "../styles/body-strike.js";
3
- import { VF_DISPLAY_STRIKE as t } from "../styles/display-strike.js";
4
- import { FRAME_PNG as n } from "./frame-picture.js";
5
- //#region src/build/frame.ts
6
- var r = 3, i = {
7
- left: 16 * r,
8
- width: 128 * r,
9
- scale: r,
10
- ink: "#000000",
11
- align: "center"
12
- }, a = {
13
- picture: n,
14
- scale: r,
15
- artwork: {
16
- left: 16 * r,
17
- top: 16 * r,
18
- width: 128 * r,
19
- height: 128 * r,
20
- stamp: 3 * r
21
- },
22
- text: [
23
- {
24
- ...i,
25
- top: 152 * r,
26
- strike: t,
27
- text: "{name}"
28
- },
29
- {
30
- ...i,
31
- top: 170 * r,
32
- strike: e,
33
- text: "Version {version}"
34
- },
35
- {
36
- ...i,
37
- top: 182 * r,
38
- strike: e,
39
- text: "by {author}"
40
- }
41
- ]
42
- };
43
- //#endregion
44
- export { a as FRAME };
@@ -1,14 +0,0 @@
1
- /**
2
- * `vintage-frames/build` — app files, written: the Vite plugin that makes an
3
- * application's build write its app file, the one that builds app files
4
- * into a site, and the pieces under them: the packer, the writer and the box
5
- * in the kit's frame. Build-only: it runs under Node, and no page imports
6
- * it. Reading an app file is `vintage-frames/shell/pure`'s.
7
- * docs/APP-FILES.md is the guide.
8
- */
9
- export { appFile, appFiles } from './plugins.js';
10
- export type { AppFileOptions } from './plugins.js';
11
- export { packApp, writeAppFile } from './app-file.js';
12
- export type { PackAppInput } from './app-file.js';
13
- export { composeBox } from './box.js';
14
- export type { BoxInput } from './box.js';
@@ -1,4 +0,0 @@
1
- import { composeBox as e } from "./box.js";
2
- import { packApp as t, writeAppFile as n } from "./app-file.js";
3
- import { appFile as r, appFiles as i } from "./plugins.js";
4
- export { r as appFile, i as appFiles, e as composeBox, t as packApp, n as writeAppFile };
@@ -1,41 +0,0 @@
1
- /**
2
- * The Vite plugins. `appFile()` makes an application's build write its app
3
- * file; `appFiles()` builds app files into a site.
4
- */
5
- import type { Plugin } from 'vite';
6
- export interface AppFileOptions {
7
- /** The application's id, name, version and author, and its description if it has one: its `app.ts`. */
8
- app: {
9
- id: string;
10
- name: string;
11
- version: string;
12
- author: string;
13
- description?: string;
14
- };
15
- /** The module whose default export is the application's factory. */
16
- entry: string;
17
- /** Its 32 × 32 icon, a PNG. */
18
- icon: string;
19
- /** Its artwork for the box: a 128 × 128 PNG, or that divided by a whole number. */
20
- artwork?: string;
21
- /** A directory to write the app file to as well, such as a site's `apps/`. */
22
- copyTo?: string;
23
- }
24
- /**
25
- * Makes an application's build write its app file, `dist/<name>.png`. It
26
- * builds the entry as a library, one ES module with the kit's entries left
27
- * as imports, and fails the build when the bundle breaks a rule: CSS or any
28
- * other file beside the code, more than one module, Lit or the kit bundled
29
- * in, or an import of anything but the kit's three entries. `npm run dev`
30
- * is untouched.
31
- */
32
- export declare function appFile(options: AppFileOptions): Plugin;
33
- /**
34
- * Builds app files into a site. An import of `*.png?app` reads the file and
35
- * refuses one that isn't an app file, or one this kit doesn't run
36
- * (`appRuns`). Its default export is the application's factory,
37
- * its definition given the manifest's icon, and `manifest` is the manifest.
38
- * The code imports the kit by name, so the page keeps one copy of it. A new
39
- * file reloads the dev server's page.
40
- */
41
- export declare function appFiles(): Plugin;
@@ -1,134 +0,0 @@
1
- import { VERSION as e } from "../shell/version.js";
2
- import { appRuns as t, inspectAppFile as n, isVersion as r, satisfies as i } from "../shell/app-file.js";
3
- import { packApp as a } from "./app-file.js";
4
- import { mkdir as o, readFile as s, writeFile as c } from "node:fs/promises";
5
- import { join as l, relative as u, resolve as d } from "node:path";
6
- //#region src/build/plugins.ts
7
- var f = [
8
- "vintage-frames",
9
- "vintage-frames/shell",
10
- "vintage-frames/shell/pure"
11
- ], p = "app-code";
12
- function m(e) {
13
- let t = e.match(/(?<=[\\/]node_modules[\\/])(?:@[^\\/]+[\\/])?[^\\/]+/g)?.at(-1)?.replace("\\", "/");
14
- return t === "vintage-frames" ? "a copy of vintage-frames" : t && /^(?:lit|lit-html|lit-element|@lit\/.+|@lit-labs\/.+)$/.test(t) ? `Lit (${t})` : null;
15
- }
16
- async function h(t) {
17
- let n = JSON.parse(await s(l(t, "package.json"), "utf8")), i = n.devDependencies?.["vintage-frames"] ?? n.dependencies?.["vintage-frames"];
18
- if (typeof i != "string") throw Error("package.json has no vintage-frames dev dependency");
19
- if (!i.startsWith("^") || !r(i.slice(1))) throw Error(`package.json's vintage-frames range is "${i}", and an app file requires a caret range: ^${e}`);
20
- return i;
21
- }
22
- function g(t) {
23
- let { app: n, entry: u, icon: p, artwork: g, copyTo: _ } = t;
24
- for (let e of [
25
- "id",
26
- "name",
27
- "version",
28
- "author"
29
- ]) if (typeof n?.[e] != "string" || !n[e]) throw Error(`vintage-frames appFile(): app.${e} is missing`);
30
- if (!r(n.version)) throw Error(`vintage-frames appFile(): app.version, ${n.version}, is not a version`);
31
- if (!u || !p) throw Error(`vintage-frames appFile(): ${u ? "icon" : "entry"} is missing`);
32
- let v = `${n.name.replace(/[\\/:*?"<>|]/g, "-")}.png`, y = "", b = null;
33
- return {
34
- name: "vintage-frames:app-file",
35
- apply: "build",
36
- config: () => ({ build: {
37
- lib: {
38
- entry: u,
39
- formats: ["es"],
40
- fileName: "app"
41
- },
42
- copyPublicDir: !1,
43
- rolldownOptions: {
44
- external: /^vintage-frames(?:\/|$)/,
45
- output: { codeSplitting: !1 }
46
- }
47
- } }),
48
- configResolved(e) {
49
- y = e.root;
50
- },
51
- buildStart() {
52
- for (let e of [
53
- p,
54
- g,
55
- "package.json"
56
- ]) e && this.addWatchFile(d(y, e));
57
- },
58
- generateBundle: {
59
- order: "post",
60
- async handler(t, r) {
61
- let o = Object.values(r), c = o.filter((e) => e.type === "chunk"), l = o.filter((e) => e.type === "asset").map((e) => e.fileName);
62
- l.length && this.error(`${n.name} emits ${l.join(", ")} beside its code, and an app file holds one module: no CSS import, no source map file, its art inlined.`);
63
- let [u] = c;
64
- (!u || c.length > 1) && this.error(`${n.name} builds to ${c.length} modules, and an app file holds one.`);
65
- for (let e of Object.keys(u.modules)) {
66
- let t = m(e);
67
- t && this.error(`${n.name} bundles ${t}. It composes the page's kit and brings none of its own.`);
68
- }
69
- let _ = [...u.imports, ...u.dynamicImports].filter((e) => !f.includes(e));
70
- _.length && this.error(`${n.name} imports ${_.join(", ")}. An application imports ${f.join(", ")} and its own files.`);
71
- try {
72
- let t = await h(y);
73
- if (!i("0.19.1", t)) throw Error(`package.json requires vintage-frames ${t}, and the build is on ${e}: move the range`);
74
- b = await a({
75
- manifest: {
76
- id: n.id,
77
- name: n.name,
78
- version: n.version,
79
- requires: t,
80
- author: n.author,
81
- description: n.description
82
- },
83
- icon: new Uint8Array(await s(d(y, p))),
84
- code: u.code,
85
- artwork: g ? new Uint8Array(await s(d(y, g))) : void 0
86
- });
87
- } catch (e) {
88
- this.error(`${n.name}: ${e.message}`);
89
- }
90
- delete r[u.fileName], this.emitFile({
91
- type: "asset",
92
- fileName: v,
93
- source: b
94
- });
95
- }
96
- },
97
- async writeBundle() {
98
- if (!_ || !b) return;
99
- let e = d(y, _);
100
- await o(e, { recursive: !0 }), await c(l(e, v), b);
101
- }
102
- };
103
- }
104
- function _(t) {
105
- return t.api === void 0 ? `requires vintage-frames ${t.requires}, and this site has ${e}` : `is built for app API ${t.api}, and this site's kit runs app API 2`;
106
- }
107
- function v() {
108
- let r = "";
109
- return {
110
- name: "vintage-frames:app-files",
111
- enforce: "pre",
112
- configResolved(e) {
113
- r = e.root;
114
- },
115
- async load(i) {
116
- let a = i.indexOf("?");
117
- if (a < 0) return null;
118
- let o = i.slice(0, a), c = new URLSearchParams(i.slice(a + 1));
119
- if (!o.endsWith(".png") || !(c.has("app") || c.has(p))) return null;
120
- this.addWatchFile(o);
121
- let l = u(r, o), d = await n(new Uint8Array(await s(o)));
122
- typeof d == "string" && this.error(`${l} is not an app file: ${d}.`);
123
- let { manifest: f, code: m } = d;
124
- return c.has(p) ? m : (t(f) || this.error(`${l}: ${f.name} ${f.version} ${_(f)}. Build ${f.name} on ${e} and copy its app file in.`), [
125
- `import factory from ${JSON.stringify(`${o}?${p}`)}`,
126
- `export const manifest = ${JSON.stringify(f)}`,
127
- "export default (...args) => ({ ...factory(...args), icon: manifest.icon })",
128
- ""
129
- ].join("\n"));
130
- }
131
- };
132
- }
133
- //#endregion
134
- export { g as appFile, v as appFiles };
@@ -1,24 +0,0 @@
1
- /**
2
- * PNG pixels, with no canvas and no dependency: a decoder for the forms art
3
- * comes in, and an encoder for the box.
4
- *
5
- * - Decoding takes 8-bit gray, RGB, gray with alpha and RGBA, and indexed
6
- * or gray at 1, 2, 4 or 8 bits, non-interlaced, with their transparency.
7
- * 16-bit and interlaced files are refused, naming what to save them as.
8
- * - Encoding writes 8-bit RGBA, each row filtered the way that compresses
9
- * it best.
10
- */
11
- /** Straight RGBA, 8 bits a channel, rows top first. */
12
- export interface Pixels {
13
- width: number;
14
- height: number;
15
- data: Uint8Array;
16
- }
17
- /** `parts`, end to end. */
18
- export declare function concat(parts: readonly Uint8Array[]): Uint8Array;
19
- /** One chunk, with its length and CRC. */
20
- export declare function pngChunk(type: string, data: Uint8Array): Uint8Array;
21
- /** A PNG's pixels. `what` names it in an error: "the artwork". */
22
- export declare function decodePng(bytes: Uint8Array, what?: string): Promise<Pixels>;
23
- /** Pixels as an 8-bit RGBA PNG. */
24
- export declare function encodePng({ width, height, data }: Pixels): Promise<Uint8Array>;
package/dist/build/png.js DELETED
@@ -1,116 +0,0 @@
1
- import { PNG_SIGNATURE as e, crc32 as t, deflate as n, inflate as r, pngChunks as i } from "../shell/app-file.js";
2
- //#region src/build/png.ts
3
- var a = {
4
- 0: 1,
5
- 2: 3,
6
- 3: 1,
7
- 4: 2,
8
- 6: 4
9
- };
10
- function o(e) {
11
- let t = new Uint8Array(e.reduce((e, t) => e + t.length, 0)), n = 0;
12
- for (let r of e) t.set(r, n), n += r.length;
13
- return t;
14
- }
15
- function s(e, n) {
16
- let r = new Uint8Array(12 + n.length), i = new DataView(r.buffer);
17
- i.setUint32(0, n.length);
18
- for (let t = 0; t < 4; t++) r[4 + t] = e.charCodeAt(t);
19
- return r.set(n, 8), i.setUint32(8 + n.length, t(r.subarray(4, 8 + n.length))), r;
20
- }
21
- async function c(e, t = "the PNG") {
22
- let n = i(e), s = n?.[0];
23
- if (!n || s?.type !== "IHDR" || s.data.length !== 13) throw Error(`${t} is not a whole PNG`);
24
- let c = new DataView(s.data.buffer, s.data.byteOffset, 13), l = c.getUint32(0), u = c.getUint32(4), [f, p, m, h, g] = s.data.subarray(8);
25
- if (f === 16) throw Error(`${t} is a 16-bit PNG: save it as an 8-bit PNG`);
26
- if (g) throw Error(`${t} is interlaced: save it as a non-interlaced PNG`);
27
- let _ = a[p], v = p === 0 || p === 3 ? [
28
- 1,
29
- 2,
30
- 4,
31
- 8
32
- ].includes(f) : f === 8;
33
- if (!_ || !v || m || h) throw Error(`${t} is a kind of PNG this kit doesn't read (color type ${p}, ${f} bits): save it as an 8-bit PNG`);
34
- let y = null, b = null, x = [];
35
- for (let { type: e, data: t } of n) e === "PLTE" ? y = t : e === "tRNS" ? b = t : e === "IDAT" && x.push(t);
36
- if (p === 3 && !y) throw Error(`${t} is indexed and has no palette`);
37
- let S = _ * f, C = Math.ceil(l * S / 8), w = await r(o(x)).catch(() => {
38
- throw Error(`${t} is not a whole PNG`);
39
- });
40
- if (w.length < u * (C + 1)) throw Error(`${t} is not a whole PNG`);
41
- let T = d(w, u, C, Math.max(1, S >> 3), t), E = (1 << f) - 1, D = (e, t) => {
42
- let n = t * f;
43
- return T[e + (n >> 3)] >> 8 - f - (n & 7) & E;
44
- }, O = (e) => b && b.length >= e * 2 + 2 ? b[e * 2] << 8 | b[e * 2 + 1] : -1, k = new Uint8Array(l * u * 4);
45
- for (let e = 0; e < u; e++) {
46
- let n = e * C;
47
- for (let r = 0; r < l; r++) {
48
- let i = (e * l + r) * 4;
49
- if (p === 0) {
50
- let e = f === 8 ? T[n + r] : D(n, r);
51
- k[i] = k[i + 1] = k[i + 2] = Math.round(e * 255 / E), k[i + 3] = e === O(0) ? 0 : 255;
52
- } else if (p === 3) {
53
- let e = f === 8 ? T[n + r] : D(n, r);
54
- if (e * 3 + 2 >= y.length) throw Error(`${t} uses a color its palette lacks`);
55
- k[i] = y[e * 3], k[i + 1] = y[e * 3 + 1], k[i + 2] = y[e * 3 + 2], k[i + 3] = b?.[e] ?? 255;
56
- } else if (p === 2) {
57
- let e = n + r * 3;
58
- k.set(T.subarray(e, e + 3), i);
59
- let t = T[e] !== O(0) || T[e + 1] !== O(1) || T[e + 2] !== O(2);
60
- k[i + 3] = t ? 255 : 0;
61
- } else if (p === 4) {
62
- let e = n + r * 2;
63
- k[i] = k[i + 1] = k[i + 2] = T[e], k[i + 3] = T[e + 1];
64
- } else k.set(T.subarray(n + r * 4, n + r * 4 + 4), i);
65
- }
66
- }
67
- return {
68
- width: l,
69
- height: u,
70
- data: k
71
- };
72
- }
73
- function l(e, t, n) {
74
- let r = e + t - n, i = Math.abs(r - e), a = Math.abs(r - t), o = Math.abs(r - n);
75
- return i <= a && i <= o ? e : a <= o ? t : n;
76
- }
77
- function u(e, t, n, r) {
78
- return e === 1 ? t : e === 2 ? n : e === 3 ? t + n >> 1 : e === 4 ? l(t, n, r) : 0;
79
- }
80
- function d(e, t, n, r, i) {
81
- let a = new Uint8Array(t * n);
82
- for (let o = 0; o < t; o++) {
83
- let t = e[o * (n + 1)];
84
- if (t > 4) throw Error(`${i} is not a whole PNG`);
85
- let s = o * (n + 1) + 1, c = o * n;
86
- for (let i = 0; i < n; i++) {
87
- let l = i >= r ? a[c + i - r] : 0, d = o ? a[c - n + i] : 0, f = i >= r && o ? a[c - n + i - r] : 0;
88
- a[c + i] = e[s + i] + u(t, l, d, f) & 255;
89
- }
90
- }
91
- return a;
92
- }
93
- async function f({ width: t, height: r, data: i }) {
94
- let a = t * 4, c = new Uint8Array(r * (a + 1)), l = Array.from({ length: 5 }, () => new Uint8Array(a));
95
- for (let e = 0; e < r; e++) {
96
- let t = e * a, n = 0, r = Infinity;
97
- for (let o = 0; o < 5; o++) {
98
- let s = l[o], c = 0;
99
- for (let n = 0; n < a; n++) {
100
- let r = n >= 4 ? i[t + n - 4] : 0, l = e ? i[t - a + n] : 0, d = n >= 4 && e ? i[t - a + n - 4] : 0, f = i[t + n] - u(o, r, l, d) & 255;
101
- s[n] = f, c += f < 128 ? f : 256 - f;
102
- }
103
- c < r && (r = c, n = o);
104
- }
105
- c[e * (a + 1)] = n, c.set(l[n], e * (a + 1) + 1);
106
- }
107
- let d = /* @__PURE__ */ new Uint8Array(13), f = new DataView(d.buffer);
108
- return f.setUint32(0, t), f.setUint32(4, r), d[8] = 8, d[9] = 6, o([
109
- e,
110
- s("IHDR", d),
111
- s("IDAT", await n(c)),
112
- s("IEND", /* @__PURE__ */ new Uint8Array())
113
- ]);
114
- }
115
- //#endregion
116
- export { o as concat, c as decodePng, f as encodePng, s as pngChunk };
@@ -1,40 +0,0 @@
1
- /**
2
- * The Finder's alert: a plain-framed `vf-dialog` with the site's caution art,
3
- * a message and a row of buttons, sized to the message — composed from kit
4
- * elements, as every alert in the kit is. Its buttons submit a
5
- * `<form method="dialog">`, so it answers with the pressed button's `value`
6
- * like any dialog an application holds.
7
- *
8
- * The layout follows the plain frame's body, its width and height less 10:
9
- * the art and the message 16 in from the body's top-left, the buttons'
10
- * bottom-right corner 16 in from the body's.
11
- */
12
- import type { VfDialog } from '../index.js';
13
- /** One button of an alert. */
14
- export interface AlertButton {
15
- label: string;
16
- /** What the alert answers when it is pressed. */
17
- value: string;
18
- /** The default button, which Return presses. */
19
- default?: boolean;
20
- }
21
- export interface AlertOptions {
22
- /** Default: OK, the default button. */
23
- buttons?: AlertButton[];
24
- /** The dialog's width, system px. Default 400. */
25
- width?: number;
26
- /** The 32×32 art beside the message, or null for none. */
27
- art?: string | null;
28
- /** The dialog's accessible name. Default "Alert". */
29
- label?: string;
30
- }
31
- /** An alert, made but not yet shown. */
32
- export interface ComposedAlert {
33
- dialog: VfDialog;
34
- /** Resolves once its parts have rendered, so `show()` opens it at once. Call it once the dialog is in the page. */
35
- rendered(): Promise<unknown>;
36
- /** Size the box to the message. Call it right after `show()`: a closed dialog lays out nothing. */
37
- fit(): void;
38
- }
39
- /** Make an alert for `message`. */
40
- export declare function composeAlert(message: string, options?: AlertOptions): ComposedAlert;