@jackens/nnn 2026.9.30 → 2026.11.16
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/README.md +219 -600
- package/nnn.d.ts +26 -88
- package/nnn.js +135 -270
- package/package.json +14 -10
package/nnn.js
CHANGED
|
@@ -1,304 +1,174 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/c.ts
|
|
2
2
|
var DEFAULT_SPLITTER = "$$";
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
var OPENING_BRACKETS = "([";
|
|
4
|
+
var CLOSING_BRACKETS = ")]";
|
|
5
|
+
var scan = (selector, onChar) => {
|
|
6
|
+
let depth = 0;
|
|
7
|
+
let quote = "";
|
|
8
|
+
for (const char of selector) {
|
|
9
|
+
if (quote !== "") {
|
|
10
|
+
if (char === quote) {
|
|
11
|
+
quote = "";
|
|
12
|
+
}
|
|
13
|
+
} else if (char === '"' || char === "'") {
|
|
14
|
+
quote = char;
|
|
15
|
+
} else if (OPENING_BRACKETS.includes(char)) {
|
|
16
|
+
++depth;
|
|
17
|
+
} else if (CLOSING_BRACKETS.includes(char)) {
|
|
18
|
+
--depth;
|
|
19
|
+
}
|
|
20
|
+
onChar(char, quote === "" && depth === 0);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var splitSelectorList = (selectorList) => {
|
|
24
|
+
const selectors = [""];
|
|
25
|
+
scan(selectorList, (char, topLevel) => {
|
|
26
|
+
if (topLevel && char === ",") {
|
|
27
|
+
selectors.push("");
|
|
28
|
+
} else {
|
|
29
|
+
selectors[selectors.length - 1] += char;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return selectors.map((selector, index) => (index === 0 ? selector : selector.trimStart()).trimEnd());
|
|
33
|
+
};
|
|
34
|
+
var nestSelector = (parent, selector) => {
|
|
35
|
+
let nested = "";
|
|
36
|
+
let ampersandFound = false;
|
|
37
|
+
scan(selector, (char, topLevel) => {
|
|
38
|
+
if (char === "&" && topLevel) {
|
|
39
|
+
nested += parent;
|
|
40
|
+
ampersandFound = true;
|
|
41
|
+
} else {
|
|
42
|
+
nested += char;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return ampersandFound ? nested : parent + selector;
|
|
46
|
+
};
|
|
47
|
+
var stripSplitter = (key, splitter) => {
|
|
48
|
+
const splitterIndex = splitter === "" ? -1 : key.indexOf(splitter);
|
|
49
|
+
return splitterIndex < 0 ? key : key.slice(0, splitterIndex);
|
|
50
|
+
};
|
|
51
|
+
var cProperties = (node, splitter, prefix) => {
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const [key, value] of Object.entries(node)) {
|
|
54
|
+
if (value != null) {
|
|
55
|
+
const name = prefix + stripSplitter(key, splitter);
|
|
56
|
+
if (typeof value === "object") {
|
|
57
|
+
out.push(...cProperties(value, splitter, name));
|
|
58
|
+
} else {
|
|
59
|
+
out.push(`${name}:${value}`);
|
|
60
|
+
}
|
|
10
61
|
}
|
|
11
62
|
}
|
|
12
|
-
return
|
|
63
|
+
return out;
|
|
13
64
|
};
|
|
14
|
-
var
|
|
65
|
+
var cRules = (node, splitter, selectors) => {
|
|
15
66
|
const out = [];
|
|
16
|
-
let
|
|
67
|
+
let declarations = [];
|
|
17
68
|
const flush = () => {
|
|
18
|
-
if (
|
|
19
|
-
|
|
69
|
+
if (declarations.length > 0) {
|
|
70
|
+
out.push(selectors.length === 0 ? `${declarations.join(";")};` : `${selectors.join(",")}{${declarations.join(";")}}`);
|
|
71
|
+
declarations = [];
|
|
20
72
|
}
|
|
21
|
-
out.push(prefix === "" ? buffer.join(";") : `${prefix}{${buffer.join(";")}}`);
|
|
22
|
-
buffer = [];
|
|
23
73
|
};
|
|
24
|
-
for (const [
|
|
74
|
+
for (const [key, value] of Object.entries(node)) {
|
|
25
75
|
if (value == null) {
|
|
26
76
|
continue;
|
|
27
77
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (flatten) {
|
|
32
|
-
out.push(`${prefix + name}:${value}`);
|
|
33
|
-
} else {
|
|
34
|
-
buffer.push(`${name}:${value}`);
|
|
35
|
-
}
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (flatten) {
|
|
39
|
-
out.push(_c(value, splitter, prefix + name, true));
|
|
78
|
+
const name = stripSplitter(key, splitter);
|
|
79
|
+
if (typeof value !== "object") {
|
|
80
|
+
declarations.push(`${name}:${value}`);
|
|
40
81
|
continue;
|
|
41
82
|
}
|
|
42
83
|
flush();
|
|
43
|
-
if (
|
|
44
|
-
out.push(`${name}{${
|
|
84
|
+
if (name[0] === "@") {
|
|
85
|
+
out.push(`${name}{${cRules(value, splitter, selectors)}}`);
|
|
86
|
+
} else if (selectors.length === 0 && name === ":root") {
|
|
87
|
+
out.push(`:root{${cProperties(value, splitter, "").join(";")}}`);
|
|
45
88
|
} else {
|
|
46
|
-
|
|
89
|
+
const alternatives = splitSelectorList(name);
|
|
90
|
+
const parents = selectors.length === 0 ? [""] : selectors;
|
|
91
|
+
out.push(cRules(value, splitter, parents.flatMap((parent) => alternatives.map((selector) => nestSelector(parent, selector)))));
|
|
47
92
|
}
|
|
48
93
|
}
|
|
49
94
|
flush();
|
|
50
|
-
|
|
95
|
+
const css = out.join("");
|
|
96
|
+
return css.endsWith(";") ? css.slice(0, -1) : css;
|
|
51
97
|
};
|
|
52
|
-
var c = (node, splitter = DEFAULT_SPLITTER) =>
|
|
53
|
-
// src/
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return [-1, ""];
|
|
79
|
-
};
|
|
80
|
-
return (code) => {
|
|
81
|
-
const result = [];
|
|
82
|
-
const stack = [ROOT];
|
|
83
|
-
const cache = compiled.map(() => ({ from: -1, index: -1, chunk: "" }));
|
|
84
|
-
let position = 0;
|
|
85
|
-
while (position < code.length) {
|
|
86
|
-
const state = stack.at(-1);
|
|
87
|
-
let best = -1;
|
|
88
|
-
let bestIndex = Infinity;
|
|
89
|
-
let bestChunk = "";
|
|
90
|
-
compiled.forEach(({ pattern, states }, i) => {
|
|
91
|
-
if (!states.includes(state)) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
const cached = cache[i];
|
|
95
|
-
const isValid = cached.from >= 0 && (pattern instanceof RegExp && pattern.sticky ? cached.from === position : cached.from <= position && (cached.index < 0 || cached.index >= position));
|
|
96
|
-
if (!isValid) {
|
|
97
|
-
[cached.index, cached.chunk] = find(pattern, code, position);
|
|
98
|
-
cached.from = position;
|
|
99
|
-
}
|
|
100
|
-
if (cached.index >= 0 && (cached.index < bestIndex || cached.index === bestIndex && cached.chunk.length > bestChunk.length)) {
|
|
101
|
-
best = i;
|
|
102
|
-
bestIndex = cached.index;
|
|
103
|
-
bestChunk = cached.chunk;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
if (best < 0) {
|
|
107
|
-
result.push(decorator(code.slice(position)));
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
const { metadata, pop, push } = compiled[best];
|
|
111
|
-
if (bestIndex > position) {
|
|
112
|
-
result.push(decorator(code.slice(position, bestIndex)));
|
|
113
|
-
}
|
|
114
|
-
result.push(decorator(bestChunk, metadata));
|
|
115
|
-
position = bestIndex + bestChunk.length;
|
|
116
|
-
if (pop && stack.length > 1) {
|
|
117
|
-
stack.pop();
|
|
118
|
-
}
|
|
119
|
-
if (push != null) {
|
|
120
|
-
stack.push(push);
|
|
121
|
-
}
|
|
98
|
+
var c = (node, splitter = DEFAULT_SPLITTER) => cRules(node, splitter, []);
|
|
99
|
+
// src/h.ts
|
|
100
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
101
|
+
var NAMESPACES = {
|
|
102
|
+
xlink: "http://www.w3.org/1999/xlink",
|
|
103
|
+
xml: "http://www.w3.org/XML/1998/namespace",
|
|
104
|
+
xmlns: "http://www.w3.org/2000/xmlns/"
|
|
105
|
+
};
|
|
106
|
+
var isPlainObject = (value) => {
|
|
107
|
+
if (typeof value !== "object" || value == null) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
const prototype = Object.getPrototypeOf(value);
|
|
111
|
+
return prototype === Object.prototype || prototype == null;
|
|
112
|
+
};
|
|
113
|
+
var setAttribute = (element, name, value) => {
|
|
114
|
+
if (value == null) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const indexOfColon = name.indexOf(":");
|
|
118
|
+
const namespace = indexOfColon < 0 ? undefined : NAMESPACES[name.slice(0, indexOfColon)];
|
|
119
|
+
if (namespace == null) {
|
|
120
|
+
if (value === false) {
|
|
121
|
+
element.removeAttribute(name);
|
|
122
|
+
} else {
|
|
123
|
+
element.setAttribute(name, value === true ? "" : String(value));
|
|
122
124
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
} else if (value === false) {
|
|
126
|
+
element.removeAttributeNS(namespace, name.slice(indexOfColon + 1));
|
|
127
|
+
} else {
|
|
128
|
+
element.setAttributeNS(namespace, name, value === true ? "" : String(value));
|
|
129
|
+
}
|
|
125
130
|
};
|
|
126
|
-
|
|
127
|
-
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
128
|
-
var _h = (createElement, tagOrNode, ...args) => {
|
|
131
|
+
var hyperscript = (createElement, tagOrNode, ...args) => {
|
|
129
132
|
const node = typeof tagOrNode === "string" ? createElement(tagOrNode) : tagOrNode;
|
|
130
|
-
|
|
131
|
-
let child = null;
|
|
133
|
+
for (const arg of args) {
|
|
132
134
|
if (arg instanceof Node) {
|
|
133
|
-
|
|
135
|
+
node.appendChild(arg);
|
|
134
136
|
} else if (Array.isArray(arg)) {
|
|
135
|
-
|
|
137
|
+
node.appendChild(hyperscript(createElement, ...arg));
|
|
136
138
|
} else if (typeof arg === "string" || typeof arg === "number") {
|
|
137
|
-
|
|
138
|
-
} else if (
|
|
139
|
+
node.appendChild(document.createTextNode(String(arg)));
|
|
140
|
+
} else if (arg != null) {
|
|
139
141
|
for (const name in arg) {
|
|
140
142
|
const value = arg[name];
|
|
141
143
|
if (name[0] === "$") {
|
|
142
144
|
const name1 = name.slice(1);
|
|
143
|
-
if (
|
|
145
|
+
if (isPlainObject(value)) {
|
|
144
146
|
Object.assign(node[name1] ??= {}, value);
|
|
145
147
|
} else {
|
|
146
148
|
node[name1] = value;
|
|
147
149
|
}
|
|
148
150
|
} else if (node instanceof Element) {
|
|
149
|
-
|
|
150
|
-
if (indexOfColon >= 0) {
|
|
151
|
-
const nsKey = name.slice(0, indexOfColon);
|
|
152
|
-
if (nsKey === "xlink") {
|
|
153
|
-
const basename = name.slice(indexOfColon + 1);
|
|
154
|
-
if (value === true) {
|
|
155
|
-
node.setAttributeNS(XLINK_NS, basename, "");
|
|
156
|
-
} else if (value === false) {
|
|
157
|
-
node.removeAttributeNS(XLINK_NS, basename);
|
|
158
|
-
} else {
|
|
159
|
-
node.setAttributeNS(XLINK_NS, basename, "" + value);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
} else {
|
|
163
|
-
if (value === true) {
|
|
164
|
-
node.setAttribute(name, "");
|
|
165
|
-
} else if (value === false) {
|
|
166
|
-
node.removeAttribute(name);
|
|
167
|
-
} else {
|
|
168
|
-
node.setAttribute(name, "" + value);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
151
|
+
setAttribute(node, name, value);
|
|
171
152
|
}
|
|
172
153
|
}
|
|
173
154
|
}
|
|
174
|
-
|
|
175
|
-
node.appendChild(child);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
155
|
+
}
|
|
178
156
|
return node;
|
|
179
157
|
};
|
|
180
|
-
var h =
|
|
181
|
-
var s =
|
|
182
|
-
var svgUse = (id, ...args) => s("svg", ["use", {
|
|
183
|
-
// src/
|
|
184
|
-
var
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
2: "#269d69",
|
|
193
|
-
3: "#1c8ca8",
|
|
194
|
-
4: "#29242a"
|
|
195
|
-
},
|
|
196
|
-
keyword: {
|
|
197
|
-
1: "#e14775",
|
|
198
|
-
2: "#7058be",
|
|
199
|
-
3: "#1c8ca8"
|
|
200
|
-
},
|
|
201
|
-
number: "#7058be",
|
|
202
|
-
operator: "#e14775",
|
|
203
|
-
punctuation: "#918c8e",
|
|
204
|
-
regexp: "#e16032",
|
|
205
|
-
string: "#cc7a0a"
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
pre$$monokai: {
|
|
209
|
-
"background-color": "var(--bg)",
|
|
210
|
-
color: "var(--fg)",
|
|
211
|
-
margin: 0,
|
|
212
|
-
padding: "1em",
|
|
213
|
-
overflow: "visible",
|
|
214
|
-
" code": {
|
|
215
|
-
"font-family": '"Source Code Pro"',
|
|
216
|
-
padding: 0
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
"code>span.$$monokai": {
|
|
220
|
-
bg: { color: "var(--bg)" },
|
|
221
|
-
fg: { color: "var(--fg)" },
|
|
222
|
-
comment: { color: "var(--comment)" },
|
|
223
|
-
identifier: {
|
|
224
|
-
1: { color: "var(--identifier1)" },
|
|
225
|
-
2: { color: "var(--identifier2)" },
|
|
226
|
-
3: { color: "var(--identifier3)" },
|
|
227
|
-
4: { color: "var(--identifier4)" }
|
|
228
|
-
},
|
|
229
|
-
keyword: {
|
|
230
|
-
1: { color: "var(--keyword1)" },
|
|
231
|
-
2: { color: "var(--keyword2)" },
|
|
232
|
-
3: { color: "var(--keyword3)" }
|
|
233
|
-
},
|
|
234
|
-
number: { color: "var(--number)" },
|
|
235
|
-
operator: { color: "var(--operator)" },
|
|
236
|
-
punctuation: { color: "var(--punctuation)" },
|
|
237
|
-
regexp: { color: "var(--regexp)" },
|
|
238
|
-
string: { color: "var(--string)" }
|
|
239
|
-
},
|
|
240
|
-
"@media only screen and (prefers-color-scheme: dark)$$monokai": {
|
|
241
|
-
":root": {
|
|
242
|
-
"--": {
|
|
243
|
-
bg: "#2d2a2e",
|
|
244
|
-
fg: "#fcfcfa",
|
|
245
|
-
comment: "#727072",
|
|
246
|
-
identifier: {
|
|
247
|
-
1: "#ae81ff",
|
|
248
|
-
2: "#a9dc76",
|
|
249
|
-
3: "#66d9ef",
|
|
250
|
-
4: "#fcfcfa"
|
|
251
|
-
},
|
|
252
|
-
keyword: {
|
|
253
|
-
1: "#ff6188",
|
|
254
|
-
2: "#ae81ff",
|
|
255
|
-
3: "#66d9ef"
|
|
256
|
-
},
|
|
257
|
-
number: "#ae81ff",
|
|
258
|
-
operator: "#ff6188",
|
|
259
|
-
punctuation: "#727072",
|
|
260
|
-
regexp: "#fc9867",
|
|
261
|
-
string: "#ffd866"
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
"@media print$$monokai": {
|
|
266
|
-
pre: {
|
|
267
|
-
"background-color": "white"
|
|
268
|
-
},
|
|
269
|
-
":root": {
|
|
270
|
-
"--bg": "white"
|
|
158
|
+
var h = hyperscript.bind(null, (tag) => document.createElement(tag));
|
|
159
|
+
var s = hyperscript.bind(null, (tag) => document.createElementNS(SVG_NS, tag));
|
|
160
|
+
var svgUse = (id, ...args) => s("svg", ["use", { href: "#" + id }], ...args);
|
|
161
|
+
// src/rwd.ts
|
|
162
|
+
var isPositiveInteger = (value) => Number.isInteger(value) && value > 0;
|
|
163
|
+
var rwd = (root, selector, cellWidthPx, cellHeightPx, ...specs) => {
|
|
164
|
+
if (!(cellWidthPx > 0 && cellHeightPx > 0 && Number.isFinite(cellWidthPx) && Number.isFinite(cellHeightPx))) {
|
|
165
|
+
throw new RangeError(`rwd: cell size must be positive: ${cellWidthPx}×${cellHeightPx}`);
|
|
166
|
+
}
|
|
167
|
+
for (const [columns, width = 1, height = 1] of specs) {
|
|
168
|
+
if (!isPositiveInteger(columns) || !isPositiveInteger(width) || !isPositiveInteger(height) || width > columns) {
|
|
169
|
+
throw new RangeError(`rwd: invalid spec: [${columns}, ${width}, ${height}]`);
|
|
271
170
|
}
|
|
272
171
|
}
|
|
273
|
-
};
|
|
274
|
-
// src/nnn/nanolightTs.ts
|
|
275
|
-
var COMMENT = "comment";
|
|
276
|
-
var IDENTIFIER1 = "identifier1";
|
|
277
|
-
var IDENTIFIER2 = "identifier2";
|
|
278
|
-
var IDENTIFIER3 = "identifier3";
|
|
279
|
-
var IDENTIFIER4 = "identifier4";
|
|
280
|
-
var KEYWORD1 = "keyword1";
|
|
281
|
-
var KEYWORD2 = "keyword2";
|
|
282
|
-
var KEYWORD3 = "keyword3";
|
|
283
|
-
var NUMBER = "number";
|
|
284
|
-
var OPERATOR = "operator";
|
|
285
|
-
var PUNCTUATION = "punctuation";
|
|
286
|
-
var REGEXP = "regexp";
|
|
287
|
-
var STRING = "string";
|
|
288
|
-
var ROOT2 = "root";
|
|
289
|
-
var TEMPLATE = "template";
|
|
290
|
-
var REGEXP_BODY = "regexpBody";
|
|
291
|
-
var REGEXP_FLAGS = "regexpFlags";
|
|
292
|
-
var REGEXP_GROUP_NAME = "regexpGroupName";
|
|
293
|
-
var REGEXP_SET = "regexpSet";
|
|
294
|
-
var REGEXP_SET_NEGATION = "regexpSetNegation";
|
|
295
|
-
var nanolightTs = /* @__PURE__ */ createLexer((chunk, name) => name != null ? ["span", { class: name }, chunk] : chunk, [COMMENT, /^#!.*/], [COMMENT, /\/\*[\s\S]*?(?:\*\/|$)/], [COMMENT, /\/\/.*/], [STRING, /"(?:[^"\\\n]|\\[\s\S])*"?/], [STRING, /'(?:[^'\\\n]|\\[\s\S])*'?/], [STRING, /`(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?:`|$)/], [STRING, /`(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?=\$\{)/, { push: TEMPLATE }], [STRING, /(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?:`|$)/y, { in: TEMPLATE, pop: true }], [STRING, /(?:[^`\\$]|\\[\s\S]|\$(?!\{))+(?=\$\{)/y, { in: TEMPLATE }], [PUNCTUATION, "${", { in: TEMPLATE, push: ROOT2 }], [
|
|
296
|
-
REGEXP,
|
|
297
|
-
/(?<=(?:^|[!%&(*,:;<=>?[^{|}~]|(?<!\+)\+|(?<!-)-|(?<!\.)\b(?:await|case|delete|do|else|in|instanceof|new|of|return|throw|typeof|void|yield))\s*)\/(?![*/])(?=(?:[^\\/[\n]|\\.|\[(?:[^\\\]\n]|\\.)*\])+\/)=?/,
|
|
298
|
-
{ push: REGEXP_BODY }
|
|
299
|
-
], [REGEXP, /\/(?=[dgimsuvy])/y, { in: REGEXP_BODY, pop: true, push: REGEXP_FLAGS }], [REGEXP, /\/(?![dgimsuvy])/y, { in: REGEXP_BODY, pop: true }], [KEYWORD1, /[dgimsuvy]+/y, { in: REGEXP_FLAGS, pop: true }], [IDENTIFIER2, /\\[1-9]\d*|\\k<[\p{L}_$][\p{L}\d_$]*>/uy, { in: REGEXP_BODY }], [KEYWORD1, /\\[bB]/y, { in: REGEXP_BODY }], [KEYWORD3, /\\[dDsSwW]|\\[pP]\{[\w=]*\}/y, { in: [REGEXP_BODY, REGEXP_SET] }], [KEYWORD2, /\\(?:c[A-Za-z]|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|.)/uy, { in: [REGEXP_BODY, REGEXP_SET] }], [KEYWORD1, /[$^]/y, { in: REGEXP_BODY }], [KEYWORD3, ".", { in: REGEXP_BODY }], [OPERATOR, /(?:[*+?]|\{\d+(?:,\d*)?\})\??/y, { in: REGEXP_BODY }], [OPERATOR, "|", { in: REGEXP_BODY }], [PUNCTUATION, /\((?:\?(?:[:=!]|<[=!]))?/y, { in: REGEXP_BODY }], [PUNCTUATION, /\(\?<(?=[\p{L}_$][\p{L}\d_$]*>)/uy, { in: REGEXP_BODY, push: REGEXP_GROUP_NAME }], [IDENTIFIER2, /[\p{L}_$][\p{L}\d_$]*/uy, { in: REGEXP_GROUP_NAME }], [PUNCTUATION, ">", { in: REGEXP_GROUP_NAME, pop: true }], [PUNCTUATION, ")", { in: REGEXP_BODY }], [PUNCTUATION, /\[(?!\^)/y, { in: REGEXP_BODY, push: REGEXP_SET }], [PUNCTUATION, /\[(?=\^)/y, { in: REGEXP_BODY, push: REGEXP_SET_NEGATION }], [OPERATOR, "^", { in: REGEXP_SET_NEGATION, pop: true, push: REGEXP_SET }], [OPERATOR, /(?<!(?<!\\)\[\^?)-(?!\])/y, { in: REGEXP_SET }], [PUNCTUATION, "]", { in: REGEXP_SET, pop: true }], [REGEXP, /[^\\/[()|?*+{^$.\n]+/uy, { in: REGEXP_BODY }], [REGEXP, /[^\\\]\-\n]+/uy, { in: REGEXP_SET }], [REGEXP, /[^\n]/uy, { in: [REGEXP_BODY, REGEXP_SET] }], [NUMBER, /0b[01_]+n?/i], [NUMBER, /0o[0-7_]+n?/i], [NUMBER, /0x[\da-f_]+n?/i], [NUMBER, /(?:\d[\d_]*(?:\.[\d_]+)?|\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?n?/i], [OPERATOR, "!"], [OPERATOR, "!="], [OPERATOR, "!=="], [OPERATOR, "%"], [OPERATOR, "%="], [OPERATOR, "&&"], [OPERATOR, "&&="], [OPERATOR, "&"], [OPERATOR, "&="], [OPERATOR, "*"], [OPERATOR, "**"], [OPERATOR, "**="], [OPERATOR, "*="], [OPERATOR, "+"], [OPERATOR, "++"], [OPERATOR, "+="], [OPERATOR, "-"], [OPERATOR, "--"], [OPERATOR, "-="], [OPERATOR, "..."], [OPERATOR, "/"], [OPERATOR, "/="], [OPERATOR, ":"], [OPERATOR, "<"], [OPERATOR, "<<"], [OPERATOR, "<<="], [OPERATOR, "<="], [OPERATOR, "="], [OPERATOR, "=="], [OPERATOR, "==="], [OPERATOR, "=>"], [OPERATOR, ">"], [OPERATOR, ">="], [OPERATOR, ">>"], [OPERATOR, ">>="], [OPERATOR, ">>>"], [OPERATOR, ">>>="], [OPERATOR, "?"], [OPERATOR, "??"], [OPERATOR, "??="], [OPERATOR, "^"], [OPERATOR, "^="], [OPERATOR, "|"], [OPERATOR, "|="], [OPERATOR, "||"], [OPERATOR, "||="], [OPERATOR, "~"], [OPERATOR, "~="], [OPERATOR, /(?<=\s):/], [PUNCTUATION, "("], [PUNCTUATION, ")"], [PUNCTUATION, ","], [PUNCTUATION, "."], [PUNCTUATION, ":"], [PUNCTUATION, ";"], [PUNCTUATION, /\?\.(?!\d)/], [PUNCTUATION, "["], [PUNCTUATION, "]"], [PUNCTUATION, "{", { push: ROOT2 }], [PUNCTUATION, "}", { pop: true }], [IDENTIFIER2, /(?<=(?<!\.)\.)\p{Ll}[\p{L}\d_$]*(?=[(`])/u], [IDENTIFIER4, /(?<=(?<!\.)\.)\p{Ll}[\p{L}\d_$]*/u], [KEYWORD1, "as"], [KEYWORD1, "async"], [KEYWORD1, "await"], [KEYWORD1, "break"], [KEYWORD1, "case"], [KEYWORD1, "catch"], [KEYWORD1, "class"], [KEYWORD1, "const"], [KEYWORD1, "continue"], [KEYWORD1, "debugger"], [KEYWORD1, "default"], [KEYWORD1, "delete"], [KEYWORD1, "do"], [KEYWORD1, "else"], [KEYWORD1, "export"], [KEYWORD1, "extends"], [KEYWORD1, "finally"], [KEYWORD1, "for"], [KEYWORD1, "from"], [KEYWORD1, "function"], [KEYWORD1, "function*"], [KEYWORD1, "goto"], [KEYWORD1, "if"], [KEYWORD1, "import"], [KEYWORD1, "in"], [KEYWORD1, "instanceof"], [KEYWORD1, "is"], [KEYWORD1, "keyof"], [KEYWORD1, "let"], [KEYWORD1, "new"], [KEYWORD1, "of"], [KEYWORD1, "package"], [KEYWORD1, "return"], [KEYWORD1, "super"], [KEYWORD1, "switch"], [KEYWORD1, "this"], [KEYWORD1, "throw"], [KEYWORD1, "try"], [KEYWORD1, "type"], [KEYWORD1, "typeof"], [KEYWORD1, "var"], [KEYWORD1, "void"], [KEYWORD1, "while"], [KEYWORD1, "with"], [KEYWORD1, "yield"], [KEYWORD1, "yield*"], [KEYWORD2, "false"], [KEYWORD2, "Infinity"], [KEYWORD2, "NaN"], [KEYWORD2, "null"], [KEYWORD2, "true"], [KEYWORD2, "undefined"], [KEYWORD3, "any"], [KEYWORD3, "bigint"], [KEYWORD3, "boolean"], [KEYWORD3, "eval"], [KEYWORD3, "number"], [KEYWORD3, "string"], [KEYWORD3, "symbol"], [KEYWORD3, "unknown"], [IDENTIFIER2, /@[\p{L}_$][\p{L}\d_$]*/u], [IDENTIFIER1, /#?[\p{Lu}_$][\p{Lu}\d_$]*/u], [IDENTIFIER2, /#?[\p{L}_$][\p{L}\d_$]*(?=[(`])/u], [IDENTIFIER3, /#?\p{Lu}[\p{L}\d_$]*/u], [IDENTIFIER4, /#?[\p{L}_$][\p{L}\d_$]*/u]);
|
|
300
|
-
// src/nnn/rwd.ts
|
|
301
|
-
var rwd = (root, selector, cellWidthPx, cellHeightPx, ...specs) => {
|
|
302
172
|
const main = root[selector] ??= {};
|
|
303
173
|
main["box-sizing"] = "border-box";
|
|
304
174
|
main.display = "block";
|
|
@@ -306,27 +176,22 @@ var rwd = (root, selector, cellWidthPx, cellHeightPx, ...specs) => {
|
|
|
306
176
|
main.width = "100%";
|
|
307
177
|
main.height = `${cellHeightPx}px`;
|
|
308
178
|
specs.sort(([a], [b]) => a - b);
|
|
309
|
-
for (
|
|
310
|
-
const atRule = `@media(min-width:${cellWidthPx *
|
|
311
|
-
const node =
|
|
312
|
-
width ??= 1;
|
|
313
|
-
height ??= 1;
|
|
179
|
+
for (const [columns, width = 1, height = 1] of specs) {
|
|
180
|
+
const atRule = `@media(min-width:${cellWidthPx * columns}px)`;
|
|
181
|
+
const node = columns === 1 ? main : (root[atRule] ??= {})[selector] ??= {};
|
|
314
182
|
let gcd = 100 * width;
|
|
315
|
-
let tmp =
|
|
183
|
+
let tmp = columns;
|
|
316
184
|
while (tmp > 0) {
|
|
317
185
|
[gcd, tmp] = [tmp, gcd % tmp];
|
|
318
186
|
}
|
|
319
187
|
const widthOverGcd = 100 * width / gcd;
|
|
320
|
-
node.width =
|
|
188
|
+
node.width = columns === gcd ? `${widthOverGcd}%` : `calc(${widthOverGcd}% / ${columns / gcd})`;
|
|
321
189
|
node.height = `${cellHeightPx * height}px`;
|
|
322
190
|
}
|
|
323
191
|
};
|
|
324
192
|
export {
|
|
325
193
|
c,
|
|
326
|
-
createLexer,
|
|
327
194
|
h,
|
|
328
|
-
monokai,
|
|
329
|
-
nanolightTs,
|
|
330
195
|
rwd,
|
|
331
196
|
s,
|
|
332
197
|
svgUse
|
package/package.json
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackens/nnn",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.11.16",
|
|
4
4
|
"description": "Jackens’ JavaScript helpers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CSS-in-JS",
|
|
7
|
-
"highlight",
|
|
8
7
|
"HyperScript",
|
|
9
8
|
"JS-to-CSS",
|
|
10
|
-
"lexer",
|
|
11
|
-
"Monokai",
|
|
12
|
-
"nanolight",
|
|
13
9
|
"nnn",
|
|
14
10
|
"Responsive Web Design",
|
|
15
|
-
"RWD"
|
|
16
|
-
"SVG",
|
|
17
|
-
"tokenize",
|
|
18
|
-
"tokenizer"
|
|
11
|
+
"RWD"
|
|
19
12
|
],
|
|
20
13
|
"license": "MIT",
|
|
21
14
|
"author": "Jackens",
|
|
22
15
|
"type": "module",
|
|
23
16
|
"main": "nnn.js",
|
|
24
|
-
"types": "nnn.d.ts"
|
|
17
|
+
"types": "nnn.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./nnn.d.ts",
|
|
21
|
+
"default": "./nnn.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"nnn.d.ts",
|
|
26
|
+
"nnn.js"
|
|
27
|
+
],
|
|
28
|
+
"sideEffects": false
|
|
25
29
|
}
|