@jackens/nnn 2024.2.20 → 2024.2.25

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/nnn.js CHANGED
@@ -1,40 +1,422 @@
1
- import { chartable } from './chartable.js'
2
- import { eq } from './eq.js'
3
- import { escape, escapeValues } from './escape.js'
4
- import { fixTypography } from './fixTypography.js'
5
- import { h, s } from './h.js'
6
- import { has } from './has.js'
7
- import { is } from './is.js'
8
- import { jcss } from './jcss.js'
9
- import { jsOnParse } from './jsOnParse.js'
10
- import { locale } from './locale.js'
11
- import { nanolight } from './nanolight.js'
12
- import { nanolightJs } from './nanolightJs.js'
13
- import { omit, pick } from './pick.js'
14
- import { plUral } from './plUral.js'
15
- import { pro } from './pro.js'
16
- import { refsInfo } from './refsInfo.js'
17
- import { uuid1 } from './uuid1.js'
1
+ // src/nnn/is.ts
2
+ function is(type, arg) {
3
+ return arg?.constructor === type;
4
+ }
5
+
6
+ // src/nnn/h.ts
7
+ var NS = {
8
+ xlink: "http://www.w3.org/1999/xlink"
9
+ };
10
+ var _h = (namespaceURI) => {
11
+ const createElement = namespaceURI == null ? (tag) => document.createElement(tag) : (tag) => document.createElementNS(namespaceURI, tag);
12
+ const h = (tagOrNode, ...args) => {
13
+ const node = is(String, tagOrNode) ? createElement(tagOrNode) : tagOrNode;
14
+ args.forEach((arg) => {
15
+ let child = null;
16
+ if (arg instanceof Node) {
17
+ child = arg;
18
+ } else if (is(String, arg) || is(Number, arg)) {
19
+ child = document.createTextNode(arg);
20
+ } else if (is(Array, arg)) {
21
+ child = h(...arg);
22
+ } else if (arg != null) {
23
+ for (const name in arg) {
24
+ const value = arg[name];
25
+ if (name[0] === "$") {
26
+ const name1 = name.slice(1);
27
+ if (is(Object, value)) {
28
+ node[name1] = node[name1] ?? {};
29
+ Object.assign(node[name1], value);
30
+ } else {
31
+ node[name1] = value;
32
+ }
33
+ } else if (node instanceof Element) {
34
+ const indexOfColon = name.indexOf(":");
35
+ if (indexOfColon >= 0) {
36
+ const ns = NS[name.slice(0, indexOfColon)];
37
+ if (ns != null) {
38
+ const basename = name.slice(indexOfColon + 1);
39
+ if (value === true) {
40
+ node.setAttributeNS(ns, basename, "");
41
+ } else if (value === false) {
42
+ node.removeAttributeNS(ns, basename);
43
+ } else {
44
+ node.setAttributeNS(ns, basename, is(String, value) ? value : "" + value);
45
+ }
46
+ }
47
+ } else {
48
+ if (value === true) {
49
+ node.setAttribute(name, "");
50
+ } else if (value === false) {
51
+ node.removeAttribute(name);
52
+ } else {
53
+ node.setAttribute(name, is(String, value) ? value : "" + value);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ if (child != null) {
60
+ node.appendChild(child);
61
+ }
62
+ });
63
+ return node;
64
+ };
65
+ return h;
66
+ };
67
+ var h = _h();
68
+ var s = _h("http://www.w3.org/2000/svg");
69
+
70
+ // src/nnn/chartable.ts
71
+ var COLORS = ["#e22", "#e73", "#fc3", "#ad4", "#4d9", "#3be", "#45d", "#c3e"];
72
+ var PADDING = 15;
73
+ var _svg = s("svg", { viewBox: "0 0 0 0", width: 0, height: 0 });
74
+ h(document.body, ["div", { $style: { width: 0, height: 0 } }, _svg]);
75
+ var toFixed2 = (value) => value.toFixed(2);
76
+ var chartable = ({
77
+ table,
78
+ headerColumn = false,
79
+ xGap = 70,
80
+ xLabelsMinHeight = 0,
81
+ xLabelsRotate = false,
82
+ xReverse = false,
83
+ yGap = 30,
84
+ yLabelsLeftMinWidth = 100,
85
+ yLabelsRightMinWidth = 100,
86
+ yMax = 10,
87
+ zLabelsMinWidth = 0,
88
+ zyMappings = []
89
+ }) => {
90
+ const zxValues = [];
91
+ const xLabels = [];
92
+ const zLabels = [];
93
+ table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c) => {
94
+ const x = r - 1;
95
+ const z = c - +headerColumn;
96
+ const value = col.innerText;
97
+ if (x >= 0 && z >= 0) {
98
+ zxValues[z] = zxValues[z] ?? [];
99
+ zxValues[z][x] = (zyMappings?.[z]?.[0] ?? parseFloat)(value);
100
+ } else if (x >= 0 && z < 0) {
101
+ xLabels[x] = value;
102
+ } else if (x < 0 && z >= 0) {
103
+ zLabels[z] = value;
104
+ }
105
+ }));
106
+ if (xReverse) {
107
+ xLabels.reverse();
108
+ zxValues.forEach((xValues) => xValues.reverse());
109
+ }
110
+ const xMax = zxValues[0].length;
111
+ const xPx = Array.from({ length: xMax }, (_, x) => x * xGap);
112
+ const yPx = Array.from({ length: yMax }, (_, y) => y * yGap);
113
+ const width = xGap * (xMax - 1);
114
+ const height = yGap * (yMax - 1);
115
+ const gGraph = s("g", ...yPx.map((px) => ["line", { x1: 0, x2: width, y1: px, y2: px, stroke: "#8888" }]), ...xPx.map((px) => ["line", { x1: px, x2: px, y1: 0, y2: height, stroke: "#8888" }]));
116
+ const gXLabels = s("g");
117
+ const gYLabelsL = zxValues.map((_) => s("g"));
118
+ const gYLabelsR = zxValues.map((_) => s("g"));
119
+ const gZColors = s("g");
120
+ const gZLabels = [];
121
+ const onclick = (z) => {
122
+ gYLabelsL.forEach((g, z2) => s(g, { $style: { display: z2 === z ? "block" : "none" } }));
123
+ gYLabelsR.forEach((g, z2) => s(g, { $style: { display: z2 === z ? "block" : "none" } }));
124
+ gZLabels.forEach((text, z2) => s(text, { $style: { fontWeight: z2 === z ? "bold" : "normal", cursor: "pointer" } }));
125
+ };
126
+ zxValues.forEach((values, z) => {
127
+ const fill = COLORS[z % COLORS.length];
128
+ const minValue = Math.min(...values.filter((value) => !isNaN(value)));
129
+ const maxValue = Math.max(...values.filter((value) => !isNaN(value)));
130
+ yPx.forEach((yp, y) => {
131
+ const value = (zyMappings?.[z]?.[1] ?? toFixed2)(maxValue - (maxValue - minValue) / yMax * (y + 1));
132
+ const textL = s("text", { x: 0, y: yp, "text-anchor": "end", "alignment-baseline": "middle" }, value);
133
+ const textR = s("text", { x: 0, y: yp, "text-anchor": "start", "alignment-baseline": "middle" }, value);
134
+ s(_svg, textL, textR);
135
+ yLabelsLeftMinWidth = Math.max(yLabelsLeftMinWidth, textL.getBBox().width);
136
+ yLabelsRightMinWidth = Math.max(yLabelsRightMinWidth, textR.getBBox().width);
137
+ s(gYLabelsL[z], textL);
138
+ s(gYLabelsR[z], textR);
139
+ });
140
+ const text = s("text", {
141
+ x: 0,
142
+ y: yGap * z,
143
+ "text-anchor": "start",
144
+ "alignment-baseline": "middle",
145
+ $onclick: () => onclick(z),
146
+ $style: { fontWeight: "bold" }
147
+ }, zLabels[z]);
148
+ s(_svg, text);
149
+ zLabelsMinWidth = Math.max(zLabelsMinWidth, text.getBBox().width);
150
+ gZLabels[z] = text;
151
+ s(gZColors, ["circle", { cx: 0, cy: yGap * z, r: 5, fill }]);
152
+ const valuesPx = values.map((value) => isNaN(value) ? value : height * (maxValue - value) / (maxValue - minValue));
153
+ xPx.forEach((px, x) => {
154
+ if (!isNaN(valuesPx[x])) {
155
+ s(gGraph, ["g", ["circle", { cx: px, cy: valuesPx[x], r: 5, fill }]]);
156
+ if (!isNaN(valuesPx[x - 1])) {
157
+ s(gGraph, ["line", { x1: px, x2: xPx[x - 1], y1: valuesPx[x], y2: valuesPx[x - 1], stroke: fill }]);
158
+ }
159
+ }
160
+ });
161
+ });
162
+ if (xLabels.length > 0) {
163
+ xPx.forEach((xp, x) => {
164
+ const text = s("text", xLabelsRotate ? { x: 0, y: -xp, "text-anchor": "start", "alignment-baseline": "middle", transform: "rotate(90)" } : { x: xp, y: PADDING, "text-anchor": "middle", "alignment-baseline": "middle" }, xLabels[x]);
165
+ s(_svg, text);
166
+ xLabelsMinHeight = Math.max(xLabelsMinHeight, xLabelsRotate ? text.getBBox().width : text.getBBox().height);
167
+ s(gXLabels, text);
168
+ });
169
+ }
170
+ const svgW = width + yLabelsLeftMinWidth + yLabelsRightMinWidth + zLabelsMinWidth + 4 * PADDING;
171
+ const svgH = height + xLabelsMinHeight + (xLabels.length > 0 ? 3 : 2) * PADDING;
172
+ s(gGraph, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${PADDING})` });
173
+ gYLabelsL.forEach((g) => s(g, { transform: `translate(${yLabelsLeftMinWidth} ${PADDING})` }));
174
+ gYLabelsR.forEach((g) => s(g, { transform: `translate(${width + yLabelsLeftMinWidth + 2 * PADDING} ${PADDING})` }));
175
+ s(gZColors, { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 3 * PADDING} ${PADDING})` });
176
+ s(gXLabels, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${height + 2 * PADDING})` });
177
+ onclick(0);
178
+ return s("svg", { viewBox: `0 0 ${svgW} ${svgH}`, width: `${svgW}px`, height: `${svgH}px`, class: "chartable" }, gGraph, gXLabels, ...gYLabelsL, ...gYLabelsR, gZColors, ["g", { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 4 * PADDING} ${PADDING})` }, ...gZLabels]);
179
+ };
180
+
181
+ // src/nnn/eq.ts
182
+ var eq = (x, y) => {
183
+ if (x === y) {
184
+ return true;
185
+ }
186
+ const xConstructor = x?.constructor;
187
+ if (xConstructor === y?.constructor) {
188
+ if (xConstructor === Number) {
189
+ return isNaN(x) && isNaN(y) || +x === +y;
190
+ }
191
+ if (xConstructor === Date) {
192
+ return +x === +y;
193
+ }
194
+ if (xConstructor === String || xConstructor === RegExp) {
195
+ return "" + x === "" + y;
196
+ }
197
+ if (xConstructor === Array) {
198
+ return x.length === y.length && x.every((item, index) => eq(item, y[index]));
199
+ }
200
+ if (xConstructor === Object) {
201
+ const keysOfX = Object.keys(x);
202
+ return keysOfX.length === Object.keys(y).length && keysOfX.every((key) => eq(x[key], y[key]));
203
+ }
204
+ if (xConstructor === Set || xConstructor === Map) {
205
+ if (x.size !== y.size) {
206
+ return false;
207
+ }
208
+ const xa = [...x];
209
+ const ya = [...y];
210
+ return xa.every((xv) => ya.find((yv) => eq(xv, yv)));
211
+ }
212
+ }
213
+ return false;
214
+ };
215
+
216
+ // src/nnn/escape.ts
217
+ var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
218
+ var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
219
+
220
+ // src/nnn/has.ts
221
+ var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
222
+
223
+ // src/nnn/fixTypography.ts
224
+ var TAGS_TO_SKIP = { IFRAME: 1, NOSCRIPT: 1, PRE: 1, SCRIPT: 1, STYLE: 1, TEXTAREA: 1 };
225
+ var fixTypography = (node) => {
226
+ const queue = [node];
227
+ while (queue.length > 0) {
228
+ const node0 = queue.shift();
229
+ if (node0 instanceof Element) {
230
+ node0.childNodes.forEach((childNode) => {
231
+ if (childNode instanceof Text) {
232
+ queue.push(childNode);
233
+ } else if (childNode instanceof Element && !has(childNode.tagName, TAGS_TO_SKIP)) {
234
+ queue.push(childNode);
235
+ }
236
+ });
237
+ } else if (node0 instanceof Text) {
238
+ const nodeValue = node0.nodeValue?.trim?.();
239
+ if (nodeValue != null) {
240
+ let previousNode = node0;
241
+ nodeValue.split(/(\s|\(|„)([aiouwz—]\s)/gi).forEach((chunk, i) => {
242
+ i %= 3;
243
+ const currentNode = i === 2 ? h("span", { style: "white-space:nowrap" }, chunk) : i === 1 ? document.createTextNode(chunk) : document.createTextNode(chunk.replace(/(\/(?=[^/\s])|\.(?=[^\s]))/g, "$1\u200B"));
244
+ if (node0.parentNode != null) {
245
+ node0.parentNode.insertBefore(currentNode, previousNode.nextSibling);
246
+ }
247
+ previousNode = currentNode;
248
+ });
249
+ node0.parentNode?.removeChild(node0);
250
+ }
251
+ }
252
+ }
253
+ };
254
+
255
+ // src/nnn/jcss.ts
256
+ var _jcss = (node, prefix, result, split) => {
257
+ const queue = [[node, prefix]];
258
+ while (queue.length > 0) {
259
+ const [style0, prefix0] = queue.shift() ?? [];
260
+ if (style0 == null || prefix0 == null) {
261
+ continue;
262
+ }
263
+ if (is(Array, style0)) {
264
+ result.push(prefix0, prefix0 !== "" ? "{" : "", style0.join(";"), prefix0 !== "" ? "}" : "");
265
+ } else {
266
+ const todo = [];
267
+ let attributes = [];
268
+ let attributesPushed = false;
269
+ for (const key in style0) {
270
+ const value = style0[key];
271
+ if (is(String, value) || is(Number, value)) {
272
+ if (!attributesPushed) {
273
+ attributesPushed = true;
274
+ attributes = [];
275
+ todo.push([attributes, prefix0]);
276
+ }
277
+ attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
278
+ } else if (value != null) {
279
+ attributesPushed = false;
280
+ const prefixN = [];
281
+ const keyChunks = key.split(",");
282
+ prefix0.split(",").forEach((prefixChunk) => keyChunks.forEach((keyChunk) => prefixN.push(prefixChunk + keyChunk)));
283
+ todo.push([value, prefixN.join(",")]);
284
+ }
285
+ }
286
+ queue.unshift(...todo);
287
+ }
288
+ }
289
+ };
290
+ var jcss = (root, splitter = "$$") => {
291
+ const split = (text) => text.split(splitter)[0];
292
+ const chunks = [];
293
+ for (const key in root) {
294
+ const value = root[key];
295
+ if (value != null) {
296
+ if (key[0] === "@") {
297
+ chunks.push(split(key) + "{");
298
+ _jcss(value, "", chunks, split);
299
+ chunks.push("}");
300
+ } else {
301
+ _jcss(value, split(key), chunks, split);
302
+ }
303
+ }
304
+ }
305
+ return chunks.join("");
306
+ };
307
+
308
+ // src/nnn/jsOnParse.ts
309
+ var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
310
+ if (is(Object, value)) {
311
+ let isSecondKey = false;
312
+ for (key in value) {
313
+ if (isSecondKey) {
314
+ return value;
315
+ }
316
+ isSecondKey = true;
317
+ }
318
+ if (has(key, handlers) && is(Array, value[key])) {
319
+ return handlers[key](...value[key]);
320
+ }
321
+ }
322
+ return value;
323
+ });
324
+
325
+ // src/nnn/locale.ts
326
+ var locale = (map, defaultVersion) => (text, version = defaultVersion) => {
327
+ const textV = map?.[version]?.[text];
328
+ const textD = map?.[defaultVersion]?.[text];
329
+ return is(String, textV) ? textV : is(String, textD) ? textD : text;
330
+ };
331
+
332
+ // src/nnn/nanolight.ts
333
+ var nanolight = (pattern, highlighters, code) => {
334
+ const result = [];
335
+ code.split(pattern).forEach((chunk, index) => {
336
+ if (chunk != null && chunk !== "") {
337
+ index %= highlighters.length;
338
+ result.push(highlighters[index](chunk, index));
339
+ }
340
+ });
341
+ return result;
342
+ };
343
+
344
+ // src/nnn/nanolightJs.ts
345
+ var nanolightJs = nanolight.bind(0, /('.*?'|".*?"|`[\s\S]*?`)|(\/\/.*?\n|\/\*[\s\S]*?\*\/)|(any|bigint|break|boolean|case|catch|const|continue|debugger|default|delete|do|else|eval|export|extends|false|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|NaN|new|number|null|package|return|string|super|switch|symbol|this|throw|true|try|type|typeof|undefined|unknown|var|void|while|with|yield)(?!\w)|([<>=.?:&|!^~*/%+-])|(0x[\dabcdef]+|0o[01234567]+|0b[01]+|\d+(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)|([$\w]+)(?=\()|([$\wąćęłńóśżźĄĆĘŁŃÓŚŻŹ]+)/, [
346
+ (chunk) => chunk,
347
+ (chunk) => ["span", { class: "string" }, chunk],
348
+ (chunk) => ["span", { class: "comment" }, chunk],
349
+ (chunk) => ["span", { class: "keyword" }, chunk],
350
+ (chunk) => ["span", { class: "operator" }, chunk],
351
+ (chunk) => ["span", { class: "number" }, chunk],
352
+ (chunk) => ["span", { class: "function" }, chunk],
353
+ (chunk) => ["span", { class: "literal" }, chunk]
354
+ ]);
355
+
356
+ // src/nnn/pick.ts
357
+ var pick = (obj, keys) => Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key)));
358
+ var omit = (obj, keys) => Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)));
18
359
 
360
+ // src/nnn/plUral.ts
361
+ var plUral = (singular, plural2, plural5, value) => {
362
+ const absValue = Math.abs(value);
363
+ const absValueMod10 = absValue % 10;
364
+ return value === 1 ? singular : (absValueMod10 === 2 || absValueMod10 === 3 || absValueMod10 === 4) && absValue !== 12 && absValue !== 13 && absValue !== 14 ? plural2 : plural5;
365
+ };
366
+
367
+ // src/nnn/pro.ts
368
+ var pro = (ref) => new Proxy(ref, {
369
+ get(target, key) {
370
+ return pro(target[key] = target[key] ?? {});
371
+ }
372
+ });
373
+
374
+ // src/nnn/refsInfo.ts
375
+ var refsInfo = (...refs) => {
376
+ const fns = new Set;
377
+ refs.forEach((ref) => {
378
+ while (is(Function, ref) && !fns.has(ref) && `${ref}`.includes("[native code]")) {
379
+ fns.add(ref);
380
+ ref = Object.getPrototypeOf(ref);
381
+ }
382
+ });
383
+ return Array.from(fns.values()).map((fn) => [
384
+ fn.name,
385
+ Object.getPrototypeOf(fn)?.name ?? "",
386
+ Object.getOwnPropertyNames(fn.prototype ?? Object.create(null)).sort()
387
+ ]).sort((a, b) => -(a[0] < b[0]));
388
+ };
389
+
390
+ // src/nnn/uuid1.ts
391
+ var ZEROS = "0".repeat(16);
392
+ var counter = 0;
393
+ var uuid1 = ({
394
+ date = new Date,
395
+ node = Math.random().toString(16).slice(2)
396
+ } = {}) => {
397
+ const time = ZEROS + (1e4 * (+date + 12219292800000)).toString(16);
398
+ counter = counter + 1 & 16383;
399
+ return time.slice(-8).concat("-", time.slice(-12, -8), -1, time.slice(-15, -12), "-", (8 | counter >> 12).toString(16), (ZEROS + (counter & 4095).toString(16)).slice(-3), "-", (ZEROS + node).slice(-12));
400
+ };
19
401
  export {
20
- chartable,
21
- eq,
22
- escape,
23
- escapeValues,
24
- fixTypography,
25
- h,
26
- has,
27
- is,
28
- jcss,
29
- jsOnParse,
30
- locale,
31
- nanolight,
32
- nanolightJs,
33
- omit,
34
- pick,
35
- plUral,
36
- pro,
37
- refsInfo,
402
+ uuid1,
38
403
  s,
39
- uuid1
40
- }
404
+ refsInfo,
405
+ pro,
406
+ plUral,
407
+ pick,
408
+ omit,
409
+ nanolightJs,
410
+ nanolight,
411
+ locale,
412
+ jsOnParse,
413
+ jcss,
414
+ is,
415
+ has,
416
+ h,
417
+ fixTypography,
418
+ escapeValues,
419
+ escape,
420
+ eq,
421
+ chartable
422
+ };
package/package.json CHANGED
@@ -42,5 +42,5 @@
42
42
  "types": "nnn.d.ts",
43
43
  "name": "@jackens/nnn",
44
44
  "type": "module",
45
- "version": "2024.2.20"
45
+ "version": "2024.2.25"
46
46
  }