@fnndsc/brasa 0.31.5 → 0.32.0
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/dist/buildinfo.json +1 -1
- package/dist/builtins/games/bytes.d.ts +21 -0
- package/dist/builtins/games/bytes.js +224 -0
- package/dist/builtins/games/bytes.js.map +1 -0
- package/dist/builtins/games/chimes.d.ts +64 -0
- package/dist/builtins/games/chimes.js +223 -0
- package/dist/builtins/games/chimes.js.map +1 -0
- package/dist/builtins/games/cowsay.d.ts +36 -0
- package/dist/builtins/games/cowsay.js +127 -0
- package/dist/builtins/games/cowsay.js.map +1 -0
- package/dist/builtins/games/figlet.d.ts +25 -0
- package/dist/builtins/games/figlet.js +109 -0
- package/dist/builtins/games/figlet.js.map +1 -0
- package/dist/builtins/games/lab.d.ts +51 -0
- package/dist/builtins/games/lab.js +161 -0
- package/dist/builtins/games/lab.js.map +1 -0
- package/dist/builtins/games/lolcat.d.ts +26 -0
- package/dist/builtins/games/lolcat.js +71 -0
- package/dist/builtins/games/lolcat.js.map +1 -0
- package/dist/builtins/games/morse.d.ts +18 -0
- package/dist/builtins/games/morse.js +46 -0
- package/dist/builtins/games/morse.js.map +1 -0
- package/dist/builtins/games/numbers.d.ts +55 -0
- package/dist/builtins/games/numbers.js +270 -0
- package/dist/builtins/games/numbers.js.map +1 -0
- package/dist/builtins/games/play.d.ts +53 -0
- package/dist/builtins/games/play.js +228 -0
- package/dist/builtins/games/play.js.map +1 -0
- package/dist/builtins/games/qr.d.ts +40 -0
- package/dist/builtins/games/qr.js +336 -0
- package/dist/builtins/games/qr.js.map +1 -0
- package/dist/builtins/games/shelf.d.ts +27 -0
- package/dist/builtins/games/shelf.js +71 -0
- package/dist/builtins/games/shelf.js.map +1 -0
- package/dist/builtins/games/show.d.ts +32 -0
- package/dist/builtins/games/show.js +68 -0
- package/dist/builtins/games/show.js.map +1 -0
- package/dist/builtins/games/sky.d.ts +69 -0
- package/dist/builtins/games/sky.js +190 -0
- package/dist/builtins/games/sky.js.map +1 -0
- package/dist/builtins/games/stdin.d.ts +34 -0
- package/dist/builtins/games/stdin.js +48 -0
- package/dist/builtins/games/stdin.js.map +1 -0
- package/dist/builtins/games/text.d.ts +46 -0
- package/dist/builtins/games/text.js +133 -0
- package/dist/builtins/games/text.js.map +1 -0
- package/dist/builtins/games/wtf.d.ts +13 -0
- package/dist/builtins/games/wtf.data.d.ts +12 -0
- package/dist/builtins/games/wtf.data.js +70 -0
- package/dist/builtins/games/wtf.data.js.map +1 -0
- package/dist/builtins/games/wtf.js +45 -0
- package/dist/builtins/games/wtf.js.map +1 -0
- package/dist/builtins/help.d.ts +8 -0
- package/dist/builtins/help.js +296 -0
- package/dist/builtins/help.js.map +1 -1
- package/dist/core/dispatch.js +125 -9
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/engine.js +1 -0
- package/dist/core/engine.js.map +1 -1
- package/dist/core/surface.d.ts +14 -0
- package/dist/core/surface.js.map +1 -1
- package/dist/lib/vfs/providers/static.js +15 -1
- package/dist/lib/vfs/providers/static.js.map +1 -1
- package/dist/lib/vfs/providers/static_content.js +2 -2
- package/dist/lib/vfs/providers/static_content.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `cowsay`, with the ChRIS brain for a cow.
|
|
3
|
+
*
|
|
4
|
+
* The classic: a speech bubble over a creature. Ours thinks rather than
|
|
5
|
+
* lows — the brain is the mascot, and `fortune | cowsay` is what the shelf
|
|
6
|
+
* is for. `-W N` wraps at N columns; `cowthink` is the same with a thought
|
|
7
|
+
* bubble.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { envelope_ok, envelope_error } from '@fnndsc/cumin';
|
|
12
|
+
import { text_input } from './stdin.js';
|
|
13
|
+
/** The brain, as ASCII has long drawn it. */
|
|
14
|
+
export const BRAIN = [
|
|
15
|
+
' _---~~(~~-_.',
|
|
16
|
+
' _{ ) )',
|
|
17
|
+
' , ) -~~- ( ,-\' )_',
|
|
18
|
+
' ( `-,_..`., )-- \'_,)',
|
|
19
|
+
' ( ` _) ( -~( -_ `, }',
|
|
20
|
+
' (_- _ ~_-~~~~`, ,\' )',
|
|
21
|
+
' `~ -^( __;-,((()))',
|
|
22
|
+
' ~~~~ {_ -_(())',
|
|
23
|
+
' `\\ }',
|
|
24
|
+
' { }',
|
|
25
|
+
];
|
|
26
|
+
/** Default wrap width, as cowsay's. */
|
|
27
|
+
export const COWSAY_WIDTH = 40;
|
|
28
|
+
/** Wraps text at a width, keeping the lines it already had. */
|
|
29
|
+
export function text_wrap(text, width) {
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const paragraph of text.split('\n')) {
|
|
32
|
+
const words = paragraph.split(/\s+/).filter((w) => w.length > 0);
|
|
33
|
+
if (words.length === 0) {
|
|
34
|
+
out.push('');
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
let line = '';
|
|
38
|
+
for (const word of words) {
|
|
39
|
+
if (line.length === 0)
|
|
40
|
+
line = word;
|
|
41
|
+
else if (line.length + 1 + word.length <= width)
|
|
42
|
+
line += ` ${word}`;
|
|
43
|
+
else {
|
|
44
|
+
out.push(line);
|
|
45
|
+
line = word;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
out.push(line);
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Draws the bubble: said (speech) or thought.
|
|
54
|
+
*
|
|
55
|
+
* @param lines - The wrapped lines.
|
|
56
|
+
* @param thought - True for a thought bubble (round sides, `o` trail).
|
|
57
|
+
*/
|
|
58
|
+
export function bubble_draw(lines, thought) {
|
|
59
|
+
const width = Math.max(1, ...lines.map((l) => l.length));
|
|
60
|
+
const pad = (l) => l.padEnd(width, ' ');
|
|
61
|
+
const top = ` ${'_'.repeat(width + 2)}`;
|
|
62
|
+
const bottom = ` ${'-'.repeat(width + 2)}`;
|
|
63
|
+
if (thought)
|
|
64
|
+
return [top, ...lines.map((l) => `( ${pad(l)} )`), bottom];
|
|
65
|
+
if (lines.length === 1)
|
|
66
|
+
return [top, `< ${pad(lines[0])} >`, bottom];
|
|
67
|
+
return [
|
|
68
|
+
top,
|
|
69
|
+
...lines.map((l, i) => {
|
|
70
|
+
const [left, right] = i === 0 ? ['/', '\\'] : i === lines.length - 1 ? ['\\', '/'] : ['|', '|'];
|
|
71
|
+
return `${left} ${pad(l)} ${right}`;
|
|
72
|
+
}),
|
|
73
|
+
bottom,
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The whole picture: the bubble, its trail, the brain.
|
|
78
|
+
*
|
|
79
|
+
* @param text - What the brain says.
|
|
80
|
+
* @param thought - Thought bubble rather than speech.
|
|
81
|
+
* @param width - Wrap width.
|
|
82
|
+
*/
|
|
83
|
+
export function cowsay_render(text, thought = false, width = COWSAY_WIDTH) {
|
|
84
|
+
const lines = text_wrap(text, Math.max(8, width));
|
|
85
|
+
const trail = thought ? [' o', ' o'] : [' \\', ' \\'];
|
|
86
|
+
return [...bubble_draw(lines, thought), ...trail, ...BRAIN].join('\n') + '\n';
|
|
87
|
+
}
|
|
88
|
+
/** Parses `-W N` out of the arguments; the rest is the text. */
|
|
89
|
+
function cowsayArgs_parse(args) {
|
|
90
|
+
let width = COWSAY_WIDTH;
|
|
91
|
+
const words = [];
|
|
92
|
+
for (let i = 0; i < args.length; i++) {
|
|
93
|
+
if (args[i] === '-W') {
|
|
94
|
+
const n = Number(args[i + 1]);
|
|
95
|
+
if (!Number.isInteger(n) || n < 8)
|
|
96
|
+
return { refusal: 'cowsay: -W wants a width of 8 or more' };
|
|
97
|
+
width = n;
|
|
98
|
+
i++;
|
|
99
|
+
}
|
|
100
|
+
else if (args[i]?.startsWith('-') && (args[i]?.length ?? 0) > 1) {
|
|
101
|
+
return { refusal: `cowsay: unknown flag '${args[i]}' (only -W N)` };
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
words.push(args[i]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { width, words };
|
|
108
|
+
}
|
|
109
|
+
async function cow_run(args, thought, name) {
|
|
110
|
+
const parsed = cowsayArgs_parse(args);
|
|
111
|
+
if ('refusal' in parsed)
|
|
112
|
+
return envelope_error('', undefined, `${parsed.refusal}\n`);
|
|
113
|
+
const text = text_input(parsed.words);
|
|
114
|
+
if (text === null)
|
|
115
|
+
return envelope_error('', undefined, `${name}: nothing to say (pipe text in, or give it: fortune | ${name})\n`);
|
|
116
|
+
const said = text.replace(/\n$/, '');
|
|
117
|
+
return envelope_ok(cowsay_render(said, thought, parsed.width), { kind: 'games.cowsay', data: { text: said, thought } });
|
|
118
|
+
}
|
|
119
|
+
/** `cowsay [-W N] [text]` */
|
|
120
|
+
export async function builtin_cowsay(args) {
|
|
121
|
+
return cow_run(args, false, 'cowsay');
|
|
122
|
+
}
|
|
123
|
+
/** `cowthink [-W N] [text]` */
|
|
124
|
+
export async function builtin_cowthink(args) {
|
|
125
|
+
return cow_run(args, true, 'cowthink');
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=cowsay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cowsay.js","sourceRoot":"","sources":["../../../src/builtins/games/cowsay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAmB,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,KAAK,GAA0B;IAC1C,sBAAsB;IACtB,uBAAuB;IACvB,0BAA0B;IAC1B,2BAA2B;IAC3B,2BAA2B;IAC3B,4BAA4B;IAC5B,2BAA2B;IAC3B,0BAA0B;IAC1B,yBAAyB;IACzB,wBAAwB;CACzB,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAW,EAAE,CAAC;AAEvC,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,GAAa,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAS,EAAW,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACnD,IAAI,IAAI,GAAW,EAAE,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,IAAI,GAAG,IAAI,CAAC;iBAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK;gBAAE,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;iBAC/D,CAAC;gBAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC;QACvC,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe,EAAE,OAAgB;IAC3D,MAAM,KAAK,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,GAAG,GAAW,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,MAAM,GAAW,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;IACnD,IAAI,OAAO;QAAE,OAAO,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACxF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/E,OAAO;QACL,GAAG;QACH,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE;YAC5C,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAClH,OAAO,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;QACtC,CAAC,CAAC;QACF,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,UAAmB,KAAK,EAAE,QAAgB,YAAY;IAChG,MAAM,KAAK,GAAa,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAa,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAC9F,OAAO,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAChF,CAAC;AAED,gEAAgE;AAChE,SAAS,gBAAgB,CAAC,IAAc;IACtC,IAAI,KAAK,GAAW,YAAY,CAAC;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,CAAC,GAAW,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC;YAC/F,KAAK,GAAG,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;QACjB,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,OAAO,EAAE,yBAAyB,IAAI,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAc,EAAE,OAAgB,EAAE,IAAY;IACnE,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,SAAS,IAAI,MAAM;QAAE,OAAO,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;IACrF,MAAM,IAAI,GAAkB,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,IAAI,yDAAyD,IAAI,KAAK,CAAC,CAAC;IACnI,MAAM,IAAI,GAAW,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1H,CAAC;AAED,6BAA6B;AAC7B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAc;IACnD,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `figlet` and `banner`: big letters.
|
|
3
|
+
*
|
|
4
|
+
* One bundled face, five rows tall, drawn in `#` the way `banner` always
|
|
5
|
+
* was; `figlet` fills with `█` for a solid look. Letters, digits and the
|
|
6
|
+
* punctuation a title needs. A glyph is five strings of equal width; the
|
|
7
|
+
* row of a word is its glyphs' rows side by side with one column between.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
12
|
+
/** The rows of the face, five. */
|
|
13
|
+
export declare const FACE_ROWS: number;
|
|
14
|
+
/**
|
|
15
|
+
* Sets a text in the face.
|
|
16
|
+
*
|
|
17
|
+
* @param text - The words; lowercase is set as capitals, an unknown character as `?`.
|
|
18
|
+
* @param ink - The character to draw with.
|
|
19
|
+
* @returns The five rows (more for several lines).
|
|
20
|
+
*/
|
|
21
|
+
export declare function figlet_render(text: string, ink?: string): string[];
|
|
22
|
+
/** `figlet [text]`: big letters, solid. */
|
|
23
|
+
export declare function builtin_figlet(args: string[]): Promise<CommandEnvelope>;
|
|
24
|
+
/** `banner [text]`: big letters in `#`, as banner always drew them. */
|
|
25
|
+
export declare function builtin_banner(args: string[]): Promise<CommandEnvelope>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `figlet` and `banner`: big letters.
|
|
3
|
+
*
|
|
4
|
+
* One bundled face, five rows tall, drawn in `#` the way `banner` always
|
|
5
|
+
* was; `figlet` fills with `█` for a solid look. Letters, digits and the
|
|
6
|
+
* punctuation a title needs. A glyph is five strings of equal width; the
|
|
7
|
+
* row of a word is its glyphs' rows side by side with one column between.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { envelope_ok, envelope_error } from '@fnndsc/cumin';
|
|
12
|
+
import { text_input } from './stdin.js';
|
|
13
|
+
/** The face: each glyph five rows, `#` for ink. */
|
|
14
|
+
const FACE = {
|
|
15
|
+
A: [' ### ', '# #', '#####', '# #', '# #'],
|
|
16
|
+
B: ['#### ', '# #', '#### ', '# #', '#### '],
|
|
17
|
+
C: [' ####', '# ', '# ', '# ', ' ####'],
|
|
18
|
+
D: ['#### ', '# #', '# #', '# #', '#### '],
|
|
19
|
+
E: ['#####', '# ', '#### ', '# ', '#####'],
|
|
20
|
+
F: ['#####', '# ', '#### ', '# ', '# '],
|
|
21
|
+
G: [' ####', '# ', '# ##', '# #', ' ####'],
|
|
22
|
+
H: ['# #', '# #', '#####', '# #', '# #'],
|
|
23
|
+
I: ['#####', ' # ', ' # ', ' # ', '#####'],
|
|
24
|
+
J: [' #', ' #', ' #', '# #', ' ### '],
|
|
25
|
+
K: ['# #', '# # ', '### ', '# # ', '# #'],
|
|
26
|
+
L: ['# ', '# ', '# ', '# ', '#####'],
|
|
27
|
+
M: ['# #', '## ##', '# # #', '# #', '# #'],
|
|
28
|
+
N: ['# #', '## #', '# # #', '# ##', '# #'],
|
|
29
|
+
O: [' ### ', '# #', '# #', '# #', ' ### '],
|
|
30
|
+
P: ['#### ', '# #', '#### ', '# ', '# '],
|
|
31
|
+
Q: [' ### ', '# #', '# # #', '# # ', ' ## #'],
|
|
32
|
+
R: ['#### ', '# #', '#### ', '# # ', '# #'],
|
|
33
|
+
S: [' ####', '# ', ' ### ', ' #', '#### '],
|
|
34
|
+
T: ['#####', ' # ', ' # ', ' # ', ' # '],
|
|
35
|
+
U: ['# #', '# #', '# #', '# #', ' ### '],
|
|
36
|
+
V: ['# #', '# #', '# #', ' # # ', ' # '],
|
|
37
|
+
W: ['# #', '# #', '# # #', '## ##', '# #'],
|
|
38
|
+
X: ['# #', ' # # ', ' # ', ' # # ', '# #'],
|
|
39
|
+
Y: ['# #', ' # # ', ' # ', ' # ', ' # '],
|
|
40
|
+
Z: ['#####', ' # ', ' # ', ' # ', '#####'],
|
|
41
|
+
'0': [' ### ', '# ##', '# # #', '## #', ' ### '],
|
|
42
|
+
'1': [' # ', ' ## ', ' # ', ' # ', '#####'],
|
|
43
|
+
'2': [' ### ', '# #', ' ## ', ' # ', '#####'],
|
|
44
|
+
'3': ['#### ', ' #', ' ### ', ' #', '#### '],
|
|
45
|
+
'4': ['# # ', '# # ', '#####', ' # ', ' # '],
|
|
46
|
+
'5': ['#####', '# ', '#### ', ' #', '#### '],
|
|
47
|
+
'6': [' ### ', '# ', '#### ', '# #', ' ### '],
|
|
48
|
+
'7': ['#####', ' #', ' # ', ' # ', ' # '],
|
|
49
|
+
'8': [' ### ', '# #', ' ### ', '# #', ' ### '],
|
|
50
|
+
'9': [' ### ', '# #', ' ####', ' #', ' ### '],
|
|
51
|
+
' ': [' ', ' ', ' ', ' ', ' '],
|
|
52
|
+
'.': [' ', ' ', ' ', ' ', '#'],
|
|
53
|
+
',': [' ', ' ', ' ', '#', '#'],
|
|
54
|
+
'!': ['#', '#', '#', ' ', '#'],
|
|
55
|
+
'?': [' ### ', '# #', ' # ', ' ', ' # '],
|
|
56
|
+
'-': [' ', ' ', '#####', ' ', ' '],
|
|
57
|
+
'_': [' ', ' ', ' ', ' ', '#####'],
|
|
58
|
+
':': [' ', '#', ' ', '#', ' '],
|
|
59
|
+
'/': [' #', ' # ', ' # ', ' # ', '# '],
|
|
60
|
+
'+': [' ', ' # ', '#####', ' # ', ' '],
|
|
61
|
+
'=': [' ', '#####', ' ', '#####', ' '],
|
|
62
|
+
'*': [' ', '# # #', ' ### ', '# # #', ' '],
|
|
63
|
+
'#': [' # # ', '#####', ' # # ', '#####', ' # # '],
|
|
64
|
+
'(': [' #', '# ', '# ', '# ', ' #'],
|
|
65
|
+
')': ['# ', ' #', ' #', ' #', '# '],
|
|
66
|
+
'\'': ['#', '#', ' ', ' ', ' '],
|
|
67
|
+
'"': ['# #', '# #', ' ', ' ', ' '],
|
|
68
|
+
'&': [' ## ', '# #', ' ## ', '# # ', ' # #'],
|
|
69
|
+
'@': [' ### ', '# ##', '# # #', '# # ', ' ### '],
|
|
70
|
+
'%': ['# #', ' # ', ' # ', ' # ', '# #'],
|
|
71
|
+
};
|
|
72
|
+
/** The rows of the face, five. */
|
|
73
|
+
export const FACE_ROWS = 5;
|
|
74
|
+
/**
|
|
75
|
+
* Sets a text in the face.
|
|
76
|
+
*
|
|
77
|
+
* @param text - The words; lowercase is set as capitals, an unknown character as `?`.
|
|
78
|
+
* @param ink - The character to draw with.
|
|
79
|
+
* @returns The five rows (more for several lines).
|
|
80
|
+
*/
|
|
81
|
+
export function figlet_render(text, ink = '#') {
|
|
82
|
+
const rows = [];
|
|
83
|
+
for (const line of text.split('\n')) {
|
|
84
|
+
const glyphs = [...line.toUpperCase()].map((c) => FACE[c] ?? FACE['?']);
|
|
85
|
+
for (let r = 0; r < FACE_ROWS; r++) {
|
|
86
|
+
const row = glyphs.map((g) => g[r] ?? '').join(' ').replace(/#/g, ink).trimEnd();
|
|
87
|
+
rows.push(row);
|
|
88
|
+
}
|
|
89
|
+
rows.push('');
|
|
90
|
+
}
|
|
91
|
+
rows.pop();
|
|
92
|
+
return rows;
|
|
93
|
+
}
|
|
94
|
+
async function big_run(args, ink, name) {
|
|
95
|
+
const text = text_input(args);
|
|
96
|
+
if (text === null)
|
|
97
|
+
return envelope_error('', undefined, `${name}: nothing to set (give words, or pipe them in)\n`);
|
|
98
|
+
const said = text.replace(/\n$/, '');
|
|
99
|
+
return envelope_ok(`${figlet_render(said, ink).join('\n')}\n`, { kind: 'games.figlet', data: { text: said, ink } });
|
|
100
|
+
}
|
|
101
|
+
/** `figlet [text]`: big letters, solid. */
|
|
102
|
+
export async function builtin_figlet(args) {
|
|
103
|
+
return big_run(args, '█', 'figlet');
|
|
104
|
+
}
|
|
105
|
+
/** `banner [text]`: big letters in `#`, as banner always drew them. */
|
|
106
|
+
export async function builtin_banner(args) {
|
|
107
|
+
return big_run(args, '#', 'banner');
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=figlet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figlet.js","sourceRoot":"","sources":["../../../src/builtins/games/figlet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAmB,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,mDAAmD;AACnD,MAAM,IAAI,GAAoD;IAC5D,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC9B,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC9B,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAClD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,E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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The lab's own toys: `who`, `uptime`, `ping`, `chrisfetch`, `say`.
|
|
3
|
+
*
|
|
4
|
+
* Small tools that happen to be fun. `who` names the surfaces on this
|
|
5
|
+
* session, `uptime` how long the process has been up, `ping` the round
|
|
6
|
+
* trip to CUBE, `chrisfetch` the brain beside the session's facts, and
|
|
7
|
+
* `say` hands words to a surface with a voice (the console prints them).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
12
|
+
/** Round trips `ping` makes when not told. */
|
|
13
|
+
export declare const PING_COUNT: number;
|
|
14
|
+
/** The most round trips `ping` makes however asked. */
|
|
15
|
+
export declare const PING_MAX: number;
|
|
16
|
+
/** A span of seconds in words: `2d 3h 04m`, `17m 05s`. */
|
|
17
|
+
export declare function uptime_words(seconds: number): string;
|
|
18
|
+
/** `who`: the surfaces attached to this session. */
|
|
19
|
+
export declare function builtin_who(_args: string[]): Promise<CommandEnvelope>;
|
|
20
|
+
/** `uptime`: how long this process has been up, and who is here. */
|
|
21
|
+
export declare function builtin_uptime(_args: string[]): Promise<CommandEnvelope>;
|
|
22
|
+
/** One round trip's outcome. */
|
|
23
|
+
export interface PingSample {
|
|
24
|
+
seq: number;
|
|
25
|
+
ms: number | null;
|
|
26
|
+
status: number | null;
|
|
27
|
+
}
|
|
28
|
+
/** What `ping` uses to reach CUBE; a test hands in its own. */
|
|
29
|
+
export type PingFetch = (url: string, init: {
|
|
30
|
+
method: string;
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
}) => Promise<{
|
|
33
|
+
status: number;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Round-trips to a URL `count` times.
|
|
37
|
+
*
|
|
38
|
+
* @param url - Where.
|
|
39
|
+
* @param count - How many.
|
|
40
|
+
* @param fetchFn - The fetch to use.
|
|
41
|
+
* @param onSample - Told each sample as it lands, for a surface that streams.
|
|
42
|
+
*/
|
|
43
|
+
export declare function ping_run(url: string, count: number, fetchFn: PingFetch, onSample?: (s: PingSample) => void): Promise<PingSample[]>;
|
|
44
|
+
/** The summary line, as ping prints it. */
|
|
45
|
+
export declare function ping_summary(samples: PingSample[]): string;
|
|
46
|
+
/** `ping [-c N]`: round trips to CUBE. */
|
|
47
|
+
export declare function builtin_ping(args: string[], fetchFn?: PingFetch): Promise<CommandEnvelope>;
|
|
48
|
+
/** `chrisfetch`: the brain beside the session's facts, neofetch style. */
|
|
49
|
+
export declare function builtin_chrisfetch(_args: string[]): Promise<CommandEnvelope>;
|
|
50
|
+
/** `say [text]`: a surface with a voice speaks it; the console prints it. */
|
|
51
|
+
export declare function builtin_say(args: string[]): Promise<CommandEnvelope>;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The lab's own toys: `who`, `uptime`, `ping`, `chrisfetch`, `say`.
|
|
3
|
+
*
|
|
4
|
+
* Small tools that happen to be fun. `who` names the surfaces on this
|
|
5
|
+
* session, `uptime` how long the process has been up, `ping` the round
|
|
6
|
+
* trip to CUBE, `chrisfetch` the brain beside the session's facts, and
|
|
7
|
+
* `say` hands words to a surface with a voice (the console prints them).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { envelope_ok, envelope_error, chrisContext, requestLedger_snapshot } from '@fnndsc/cumin';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { surface_get } from '../../core/surface.js';
|
|
14
|
+
import { motd_gather } from '../sys/motd.js';
|
|
15
|
+
import { BRAIN } from './cowsay.js';
|
|
16
|
+
import { text_input } from './stdin.js';
|
|
17
|
+
/** Round trips `ping` makes when not told. */
|
|
18
|
+
export const PING_COUNT = 3;
|
|
19
|
+
/** The most round trips `ping` makes however asked. */
|
|
20
|
+
export const PING_MAX = 20;
|
|
21
|
+
/** How long one round trip may take before it is called lost. */
|
|
22
|
+
const PING_TIMEOUT_MS = 8_000;
|
|
23
|
+
/** A span of seconds in words: `2d 3h 04m`, `17m 05s`. */
|
|
24
|
+
export function uptime_words(seconds) {
|
|
25
|
+
const s = Math.floor(seconds);
|
|
26
|
+
const days = Math.floor(s / 86400);
|
|
27
|
+
const hours = Math.floor((s % 86400) / 3600);
|
|
28
|
+
const minutes = Math.floor((s % 3600) / 60);
|
|
29
|
+
const secs = s % 60;
|
|
30
|
+
if (days > 0)
|
|
31
|
+
return `${days}d ${hours}h ${String(minutes).padStart(2, '0')}m`;
|
|
32
|
+
if (hours > 0)
|
|
33
|
+
return `${hours}h ${String(minutes).padStart(2, '0')}m`;
|
|
34
|
+
return `${minutes}m ${String(secs).padStart(2, '0')}s`;
|
|
35
|
+
}
|
|
36
|
+
/** `who`: the surfaces attached to this session. */
|
|
37
|
+
export async function builtin_who(_args) {
|
|
38
|
+
const peers = surface_get().peers?.() ?? null;
|
|
39
|
+
const user = (await chrisContext.ChRISuser_get()) ?? '?';
|
|
40
|
+
if (peers === null) {
|
|
41
|
+
return envelope_ok(`${user} this terminal\n`, { kind: 'games.who', data: { user, peers: [] } });
|
|
42
|
+
}
|
|
43
|
+
const lines = peers.map((p) => `${user.padEnd(16)} ${p.kind.padEnd(8)} ${p.id}${p.you ? chalk.gray(' (you)') : ''}`);
|
|
44
|
+
return envelope_ok(`${lines.join('\n')}\n`, { kind: 'games.who', data: { user, peers } });
|
|
45
|
+
}
|
|
46
|
+
/** `uptime`: how long this process has been up, and who is here. */
|
|
47
|
+
export async function builtin_uptime(_args) {
|
|
48
|
+
const seconds = process.uptime();
|
|
49
|
+
const peers = surface_get().peers?.() ?? null;
|
|
50
|
+
const since = new Date(Date.now() - seconds * 1000);
|
|
51
|
+
const now = new Date().toTimeString().slice(0, 8);
|
|
52
|
+
const who = peers === null ? '' : `, ${peers.length} surface${peers.length === 1 ? '' : 's'}`;
|
|
53
|
+
const line = ` ${now} up ${uptime_words(seconds)}${who} (since ${since.toISOString().replace('T', ' ').slice(0, 19)}Z, pid ${process.pid})`;
|
|
54
|
+
return envelope_ok(`${line}\n`, { kind: 'games.uptime', data: { seconds, since: since.toISOString(), pid: process.pid, surfaces: peers?.length ?? null } });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Round-trips to a URL `count` times.
|
|
58
|
+
*
|
|
59
|
+
* @param url - Where.
|
|
60
|
+
* @param count - How many.
|
|
61
|
+
* @param fetchFn - The fetch to use.
|
|
62
|
+
* @param onSample - Told each sample as it lands, for a surface that streams.
|
|
63
|
+
*/
|
|
64
|
+
export async function ping_run(url, count, fetchFn, onSample) {
|
|
65
|
+
const samples = [];
|
|
66
|
+
for (let seq = 1; seq <= count; seq++) {
|
|
67
|
+
const started = performance.now();
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
const timer = setTimeout(() => controller.abort(), PING_TIMEOUT_MS);
|
|
70
|
+
let sample;
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetchFn(url, { method: 'GET', signal: controller.signal });
|
|
73
|
+
sample = { seq, ms: Math.round((performance.now() - started) * 10) / 10, status: response.status };
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
sample = { seq, ms: null, status: null };
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
}
|
|
81
|
+
samples.push(sample);
|
|
82
|
+
onSample?.(sample);
|
|
83
|
+
}
|
|
84
|
+
return samples;
|
|
85
|
+
}
|
|
86
|
+
/** The summary line, as ping prints it. */
|
|
87
|
+
export function ping_summary(samples) {
|
|
88
|
+
const got = samples.map((s) => s.ms).filter((ms) => ms !== null);
|
|
89
|
+
const lost = samples.length - got.length;
|
|
90
|
+
const loss = samples.length === 0 ? '0' : String(Math.round((lost / samples.length) * 100));
|
|
91
|
+
let out = `${samples.length} sent, ${got.length} answered, ${loss}% lost`;
|
|
92
|
+
if (got.length > 0) {
|
|
93
|
+
const min = Math.min(...got);
|
|
94
|
+
const max = Math.max(...got);
|
|
95
|
+
const avg = got.reduce((a, b) => a + b, 0) / got.length;
|
|
96
|
+
out += `\nround-trip min/avg/max = ${min}/${avg.toFixed(1)}/${max} ms`;
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
/** `ping [-c N]`: round trips to CUBE. */
|
|
101
|
+
export async function builtin_ping(args, fetchFn = (url, init) => fetch(url, init)) {
|
|
102
|
+
let count = PING_COUNT;
|
|
103
|
+
for (let i = 0; i < args.length; i++) {
|
|
104
|
+
if (args[i] === '-c') {
|
|
105
|
+
const n = Number(args[i + 1]);
|
|
106
|
+
if (!Number.isInteger(n) || n < 1)
|
|
107
|
+
return envelope_error('', undefined, 'ping: -c wants a positive whole number\n');
|
|
108
|
+
count = Math.min(n, PING_MAX);
|
|
109
|
+
i++;
|
|
110
|
+
}
|
|
111
|
+
else if (args[i] !== 'cube') {
|
|
112
|
+
return envelope_error('', undefined, `ping: only CUBE is pinged from here (ping [-c N] [cube]); '${args[i]}' is not that\n`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const url = await chrisContext.ChRISURL_get();
|
|
116
|
+
if (url === null)
|
|
117
|
+
return envelope_error('', undefined, 'ping: not connected to a CUBE\n');
|
|
118
|
+
const lines = [`PING cube (${url})`];
|
|
119
|
+
const samples = await ping_run(url, count, fetchFn, (s) => {
|
|
120
|
+
lines.push(s.ms === null ? `seq=${s.seq} lost (no answer in ${PING_TIMEOUT_MS / 1000}s)` : `seq=${s.seq} http=${s.status} time=${s.ms} ms`);
|
|
121
|
+
});
|
|
122
|
+
const ledger = requestLedger_snapshot({ last: 0 });
|
|
123
|
+
const recent = ledger.total > 0 ? `\nthis session's own calls: ${ledger.total} to CUBE, ${(ledger.ms / ledger.total).toFixed(0)} ms each on average` : '';
|
|
124
|
+
return envelope_ok(`${lines.join('\n')}\n--- cube ping statistics ---\n${ping_summary(samples)}${recent}\n`, { kind: 'games.ping', data: { url, samples } });
|
|
125
|
+
}
|
|
126
|
+
/** `chrisfetch`: the brain beside the session's facts, neofetch style. */
|
|
127
|
+
export async function builtin_chrisfetch(_args) {
|
|
128
|
+
const user = (await chrisContext.ChRISuser_get()) ?? '?';
|
|
129
|
+
const url = await chrisContext.ChRISURL_get();
|
|
130
|
+
const host = url === null ? '(not connected)' : url.replace(/^https?:\/\//, '').replace(/\/api\/v1\/?$/, '');
|
|
131
|
+
const motd = motd_gather(user, 'chrisfetch');
|
|
132
|
+
const peers = surface_get().peers?.() ?? null;
|
|
133
|
+
const facts = [
|
|
134
|
+
['CUBE', host],
|
|
135
|
+
['Feeds', `${motd.feeds.total} (${motd.feeds.own} own, ${motd.feeds.shared} shared, ${motd.feeds.public} public)`],
|
|
136
|
+
['Jobs', `${motd.jobs.total.toLocaleString('en-US')} run · ${motd.jobs.running} running · ${motd.jobs.scheduled} scheduled`],
|
|
137
|
+
['Failed', motd.failureRate === null ? 'none settled yet' : `${(motd.failureRate * 100).toFixed(1)} %`],
|
|
138
|
+
['Index', motd.index.state === 'current' ? 'whole' : `${motd.index.state} (${motd.index.loaded}/${motd.index.total})`],
|
|
139
|
+
['Surfaces', peers === null ? 'this terminal' : `${peers.length} attached (${peers.filter((p) => p.kind === 'browser').length} browser, ${peers.filter((p) => p.kind === 'chell').length} chell)`],
|
|
140
|
+
['Uptime', uptime_words(process.uptime())],
|
|
141
|
+
['Node', process.version],
|
|
142
|
+
];
|
|
143
|
+
const title = `${chalk.bold.cyan(user)}@${chalk.bold.cyan(host.split(':')[0] ?? host)}`;
|
|
144
|
+
const right = [title, chalk.gray('─'.repeat(Math.min(40, user.length + host.length + 1))), ...facts.map(([k, v]) => `${chalk.cyan(k.padEnd(9))}${v}`)];
|
|
145
|
+
const rows = Math.max(BRAIN.length, right.length);
|
|
146
|
+
const lines = [];
|
|
147
|
+
for (let i = 0; i < rows; i++) {
|
|
148
|
+
const left = (BRAIN[i] ?? '').padEnd(27);
|
|
149
|
+
lines.push(`${chalk.cyan(left)} ${right[i] ?? ''}`.trimEnd());
|
|
150
|
+
}
|
|
151
|
+
return envelope_ok(`${lines.join('\n')}\n`, { kind: 'games.chrisfetch', data: { user, cube: url, feeds: motd.feeds, jobs: motd.jobs, failureRate: motd.failureRate, index: motd.index, surfaces: peers, uptimeSeconds: process.uptime() } });
|
|
152
|
+
}
|
|
153
|
+
/** `say [text]`: a surface with a voice speaks it; the console prints it. */
|
|
154
|
+
export async function builtin_say(args) {
|
|
155
|
+
const text = text_input(args);
|
|
156
|
+
if (text === null)
|
|
157
|
+
return envelope_error('', undefined, 'say: nothing to say (say hello, or fortune | say)\n');
|
|
158
|
+
const said = text.replace(/\n$/, '').replace(/\s+/g, ' ').trim();
|
|
159
|
+
return envelope_ok(`${chalk.gray('♪')} ${said}\n`, { kind: 'games.say', data: { text: said } });
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=lab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lab.js","sourceRoot":"","sources":["../../../src/builtins/games/lab.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `lolcat`: text in a rainbow.
|
|
3
|
+
*
|
|
4
|
+
* Each character takes the next hue along a sine rainbow, the hue drifting
|
|
5
|
+
* down the lines, as the original does. The colour is 24-bit ANSI, which
|
|
6
|
+
* every surface here renders; `-p N` sets the spread (characters per cycle),
|
|
7
|
+
* `-S N` the starting phase.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
12
|
+
/** Characters per rainbow cycle when none is asked. */
|
|
13
|
+
export declare const LOLCAT_SPREAD: number;
|
|
14
|
+
/** The colour at a point along the rainbow. */
|
|
15
|
+
export declare function rainbow_rgb(position: number, spread: number): [number, number, number];
|
|
16
|
+
/**
|
|
17
|
+
* Paints a text.
|
|
18
|
+
*
|
|
19
|
+
* @param text - The lines.
|
|
20
|
+
* @param spread - Characters per cycle.
|
|
21
|
+
* @param phase - Where the first character starts.
|
|
22
|
+
* @returns The text with a colour per character; plain spaces stay plain.
|
|
23
|
+
*/
|
|
24
|
+
export declare function lolcat_paint(text: string, spread?: number, phase?: number): string;
|
|
25
|
+
/** `lolcat [-p SPREAD] [-S PHASE] [text]` */
|
|
26
|
+
export declare function builtin_lolcat(args: string[]): Promise<CommandEnvelope>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `lolcat`: text in a rainbow.
|
|
3
|
+
*
|
|
4
|
+
* Each character takes the next hue along a sine rainbow, the hue drifting
|
|
5
|
+
* down the lines, as the original does. The colour is 24-bit ANSI, which
|
|
6
|
+
* every surface here renders; `-p N` sets the spread (characters per cycle),
|
|
7
|
+
* `-S N` the starting phase.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { envelope_ok, envelope_error } from '@fnndsc/cumin';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { text_input } from './stdin.js';
|
|
14
|
+
/** 24-bit colour whatever the host thinks of its terminal: every surface here renders it. */
|
|
15
|
+
const paint = new chalk.Instance({ level: 3 });
|
|
16
|
+
/** Characters per rainbow cycle when none is asked. */
|
|
17
|
+
export const LOLCAT_SPREAD = 24;
|
|
18
|
+
/** The colour at a point along the rainbow. */
|
|
19
|
+
export function rainbow_rgb(position, spread) {
|
|
20
|
+
const t = (position / spread) * 2 * Math.PI;
|
|
21
|
+
const channel = (phase) => Math.round(Math.sin(t + phase) * 100 + 155);
|
|
22
|
+
return [channel(0), channel(2 * Math.PI / 3), channel(4 * Math.PI / 3)];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Paints a text.
|
|
26
|
+
*
|
|
27
|
+
* @param text - The lines.
|
|
28
|
+
* @param spread - Characters per cycle.
|
|
29
|
+
* @param phase - Where the first character starts.
|
|
30
|
+
* @returns The text with a colour per character; plain spaces stay plain.
|
|
31
|
+
*/
|
|
32
|
+
export function lolcat_paint(text, spread = LOLCAT_SPREAD, phase = 0) {
|
|
33
|
+
const clean = text.replace(/\x1b\[[0-9;]*m/g, '');
|
|
34
|
+
return clean.split('\n').map((line, row) => [...line].map((c, col) => {
|
|
35
|
+
if (c === ' ')
|
|
36
|
+
return c;
|
|
37
|
+
const [r, g, b] = rainbow_rgb(phase + col + row * 3, spread);
|
|
38
|
+
return paint.rgb(r, g, b)(c);
|
|
39
|
+
}).join('')).join('\n');
|
|
40
|
+
}
|
|
41
|
+
/** `lolcat [-p SPREAD] [-S PHASE] [text]` */
|
|
42
|
+
export async function builtin_lolcat(args) {
|
|
43
|
+
let spread = LOLCAT_SPREAD;
|
|
44
|
+
let phase = Math.floor(Math.random() * 256);
|
|
45
|
+
const words = [];
|
|
46
|
+
for (let i = 0; i < args.length; i++) {
|
|
47
|
+
const flag = args[i];
|
|
48
|
+
if (flag === '-p' || flag === '-S') {
|
|
49
|
+
const n = Number(args[i + 1]);
|
|
50
|
+
if (!Number.isFinite(n) || (flag === '-p' && n < 1))
|
|
51
|
+
return envelope_error('', undefined, `lolcat: ${flag} wants a number${flag === '-p' ? ' of 1 or more' : ''}\n`);
|
|
52
|
+
if (flag === '-p')
|
|
53
|
+
spread = n;
|
|
54
|
+
else
|
|
55
|
+
phase = n;
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
else if (flag.startsWith('-') && flag.length > 1) {
|
|
59
|
+
return envelope_error('', undefined, `lolcat: unknown flag '${flag}' (only -p SPREAD and -S PHASE)\n`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
words.push(flag);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const text = text_input(words);
|
|
66
|
+
if (text === null)
|
|
67
|
+
return envelope_error('', undefined, 'lolcat: nothing to paint (pipe text in: fortune | lolcat)\n');
|
|
68
|
+
const said = text.replace(/\n$/, '');
|
|
69
|
+
return envelope_ok(`${lolcat_paint(said, spread, phase)}\n`, { kind: 'games.lolcat', data: { text: said, spread, phase } });
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=lolcat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lolcat.js","sourceRoot":"","sources":["../../../src/builtins/games/lolcat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAmB,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,6FAA6F;AAC7F,MAAM,KAAK,GAAgB,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAE5D,uDAAuD;AACvD,MAAM,CAAC,MAAM,aAAa,GAAW,EAAE,CAAC;AAExC,+CAA+C;AAC/C,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,MAAc;IAC1D,MAAM,CAAC,GAAW,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACvF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB,aAAa,EAAE,QAAgB,CAAC;IAC1F,MAAM,KAAK,GAAW,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,GAAW,EAAU,EAAE,CACjE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,GAAW,EAAU,EAAE;QAC/C,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAA6B,WAAW,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,IAAI,MAAM,GAAW,aAAa,CAAC;IACnC,IAAI,KAAK,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAW,IAAI,CAAC,CAAC,CAAW,CAAC;QACvC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,CAAC,GAAW,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,IAAI,kBAAkB,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACrK,IAAI,IAAI,KAAK,IAAI;gBAAE,MAAM,GAAG,CAAC,CAAC;;gBAAM,KAAK,GAAG,CAAC,CAAC;YAC9C,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,OAAO,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,yBAAyB,IAAI,mCAAmC,CAAC,CAAC;QACzG,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAkB,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,6DAA6D,CAAC,CAAC;IACvH,MAAM,IAAI,GAAW,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,WAAW,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9H,CAAC"}
|