@the-package-labs/idocs-core 0.4.0 → 0.6.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/browser.js +2 -2
- package/dist/chunk-H77C3DSX.js +817 -0
- package/dist/{chunk-S7M3BRFI.js → chunk-MUGDM3EQ.js} +242 -11
- package/dist/{chunk-3QBMUILO.js → chunk-RJUH342Z.js} +1 -1
- package/dist/defaults.d.ts +2 -0
- package/dist/highlight.d.ts +21 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +116 -7
- package/dist/nested-layout.d.ts +4 -1
- package/dist/node.js +3 -3
- package/dist/placeholders.d.ts +40 -0
- package/dist/schema.d.ts +47 -0
- package/dist/scrubber.d.ts +34 -0
- package/dist/start.d.ts +22 -0
- package/dist/types.d.ts +32 -0
- package/package.json +1 -1
- package/dist/chunk-ITBBPZE6.js +0 -145
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type PlaceholderSegment = {
|
|
2
|
+
kind: 'text';
|
|
3
|
+
text: string;
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'var';
|
|
6
|
+
/** As written, braces or angle brackets included: `{yourname}`. */
|
|
7
|
+
raw: string;
|
|
8
|
+
/** As written, without them: `yourname`. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** What `{Token}`, `<token>` and `<TOKEN>` share, so one value fills them all. */
|
|
11
|
+
key: string;
|
|
12
|
+
};
|
|
13
|
+
export interface Placeholder {
|
|
14
|
+
key: string;
|
|
15
|
+
/** The first spelling in the text. */
|
|
16
|
+
name: string;
|
|
17
|
+
raw: string;
|
|
18
|
+
/** A token or a password: kept in memory, never stored, masked on the page. */
|
|
19
|
+
secret: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function varKey(name: string): string;
|
|
22
|
+
export declare function isSecretKey(key: string): boolean;
|
|
23
|
+
export declare function splitPlaceholders(text: string): PlaceholderSegment[];
|
|
24
|
+
/** Each distinct placeholder once, in the order the text first uses it. */
|
|
25
|
+
export declare function placeholdersOf(segments: PlaceholderSegment[]): Placeholder[];
|
|
26
|
+
/** The text to copy: values where the reader set them, the placeholder as written where not. */
|
|
27
|
+
export declare function fillSegments(segments: PlaceholderSegment[], values: Record<string, string>): string;
|
|
28
|
+
export declare function fillPlaceholders(text: string, values: Record<string, string>): string;
|
|
29
|
+
/** Placeholders in `segments` the reader has not set. */
|
|
30
|
+
export declare function unsetPlaceholders(segments: PlaceholderSegment[], values: Record<string, string>): Placeholder[];
|
|
31
|
+
export interface Shown {
|
|
32
|
+
text: string;
|
|
33
|
+
state: 'unset' | 'set' | 'secret';
|
|
34
|
+
}
|
|
35
|
+
/** What the page shows in place of a placeholder: the value, a mask for a secret, or the placeholder. */
|
|
36
|
+
export declare function shownPlaceholder(segment: Extract<PlaceholderSegment, {
|
|
37
|
+
kind: 'var';
|
|
38
|
+
}>, values: Record<string, string>): Shown;
|
|
39
|
+
/** Whether a code block takes placeholders: by language, and `vars` / `novars` in the fence info decide otherwise. */
|
|
40
|
+
export declare function takesPlaceholders(lang: string | undefined, meta: string | undefined): boolean;
|
package/dist/schema.d.ts
CHANGED
|
@@ -28,10 +28,24 @@ export declare const DirectionSchema: z.ZodEnum<{
|
|
|
28
28
|
RIGHT: "RIGHT";
|
|
29
29
|
UP: "UP";
|
|
30
30
|
}>;
|
|
31
|
+
/** One field per list item: `- name`, `- name: type` or `- name: { type, key, ref, note }`. */
|
|
32
|
+
declare const FieldSchema: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNull, z.ZodObject<{
|
|
33
|
+
type: z.ZodOptional<z.ZodString>;
|
|
34
|
+
key: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
36
|
+
note: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strict>]>>]>;
|
|
31
38
|
export declare const NodeSchema: z.ZodObject<{
|
|
32
39
|
title: z.ZodOptional<z.ZodString>;
|
|
33
40
|
sub: z.ZodOptional<z.ZodString>;
|
|
41
|
+
pill: z.ZodOptional<z.ZodString>;
|
|
34
42
|
lines: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
43
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNull, z.ZodObject<{
|
|
44
|
+
type: z.ZodOptional<z.ZodString>;
|
|
45
|
+
key: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
47
|
+
note: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strict>]>>]>>>;
|
|
35
49
|
icon: z.ZodOptional<z.ZodString>;
|
|
36
50
|
kind: z.ZodOptional<z.ZodString>;
|
|
37
51
|
family: z.ZodOptional<z.ZodEnum<{
|
|
@@ -440,10 +454,34 @@ export declare const ScenarioSchema: z.ZodObject<{
|
|
|
440
454
|
}, z.core.$strict>], "type">>;
|
|
441
455
|
}, z.core.$strict>], "type">>>;
|
|
442
456
|
}, z.core.$strict>;
|
|
457
|
+
export declare const DefaultsSchema: z.ZodObject<{
|
|
458
|
+
view: z.ZodOptional<z.ZodString>;
|
|
459
|
+
scenario: z.ZodOptional<z.ZodString>;
|
|
460
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
461
|
+
flow: "flow";
|
|
462
|
+
sequence: "sequence";
|
|
463
|
+
story: "story";
|
|
464
|
+
}>>;
|
|
465
|
+
sidebar: z.ZodOptional<z.ZodBoolean>;
|
|
466
|
+
subtitles: z.ZodOptional<z.ZodBoolean>;
|
|
467
|
+
autoplay: z.ZodOptional<z.ZodBoolean>;
|
|
468
|
+
}, z.core.$strict>;
|
|
443
469
|
export declare const RootSchema: z.ZodObject<{
|
|
444
470
|
$schema: z.ZodOptional<z.ZodString>;
|
|
445
471
|
title: z.ZodString;
|
|
446
472
|
description: z.ZodOptional<z.ZodString>;
|
|
473
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
474
|
+
view: z.ZodOptional<z.ZodString>;
|
|
475
|
+
scenario: z.ZodOptional<z.ZodString>;
|
|
476
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
477
|
+
flow: "flow";
|
|
478
|
+
sequence: "sequence";
|
|
479
|
+
story: "story";
|
|
480
|
+
}>>;
|
|
481
|
+
sidebar: z.ZodOptional<z.ZodBoolean>;
|
|
482
|
+
subtitles: z.ZodOptional<z.ZodBoolean>;
|
|
483
|
+
autoplay: z.ZodOptional<z.ZodBoolean>;
|
|
484
|
+
}, z.core.$strict>>;
|
|
447
485
|
kinds: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
448
486
|
icon: z.ZodOptional<z.ZodString>;
|
|
449
487
|
family: z.ZodOptional<z.ZodEnum<{
|
|
@@ -498,7 +536,14 @@ export declare const RootSchema: z.ZodObject<{
|
|
|
498
536
|
nodes: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
499
537
|
title: z.ZodOptional<z.ZodString>;
|
|
500
538
|
sub: z.ZodOptional<z.ZodString>;
|
|
539
|
+
pill: z.ZodOptional<z.ZodString>;
|
|
501
540
|
lines: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
541
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNull, z.ZodObject<{
|
|
542
|
+
type: z.ZodOptional<z.ZodString>;
|
|
543
|
+
key: z.ZodOptional<z.ZodBoolean>;
|
|
544
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
545
|
+
note: z.ZodOptional<z.ZodString>;
|
|
546
|
+
}, z.core.$strict>]>>]>>>;
|
|
502
547
|
icon: z.ZodOptional<z.ZodString>;
|
|
503
548
|
kind: z.ZodOptional<z.ZodString>;
|
|
504
549
|
family: z.ZodOptional<z.ZodEnum<{
|
|
@@ -784,6 +829,7 @@ export declare const RootSchema: z.ZodObject<{
|
|
|
784
829
|
}, z.core.$strict>>>;
|
|
785
830
|
}, z.core.$strict>;
|
|
786
831
|
export type RootInput = z.infer<typeof RootSchema>;
|
|
832
|
+
export type FieldInput = z.infer<typeof FieldSchema>;
|
|
787
833
|
export type Step = z.infer<typeof StepSchema>;
|
|
788
834
|
export declare const KNOWN_KEYS: {
|
|
789
835
|
readonly root: string[];
|
|
@@ -792,6 +838,7 @@ export declare const KNOWN_KEYS: {
|
|
|
792
838
|
readonly edge: string[];
|
|
793
839
|
readonly view: string[];
|
|
794
840
|
readonly scenario: string[];
|
|
841
|
+
readonly defaults: string[];
|
|
795
842
|
};
|
|
796
843
|
type Json = Record<string, unknown>;
|
|
797
844
|
/**
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Timeline } from './timeline';
|
|
2
|
+
/** One stop of the slider: a step, or the steps of a `par` block that start together. */
|
|
3
|
+
export interface Slot {
|
|
4
|
+
/** First and last step of the slot, as indexes into `scenario.steps`. */
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
/** The time it covers. A slot runs until the next one starts, so pauses belong to the step before. */
|
|
8
|
+
t0: number;
|
|
9
|
+
t1: number;
|
|
10
|
+
}
|
|
11
|
+
/** A run of slots under one phase. A scenario without named phases is one section with no title. */
|
|
12
|
+
export interface Section {
|
|
13
|
+
/** Index in `scenario.phases`. */
|
|
14
|
+
phase: number;
|
|
15
|
+
title: string;
|
|
16
|
+
caption?: string;
|
|
17
|
+
/** First and last slot. */
|
|
18
|
+
from: number;
|
|
19
|
+
to: number;
|
|
20
|
+
}
|
|
21
|
+
export interface Scrubber {
|
|
22
|
+
slots: Slot[];
|
|
23
|
+
sections: Section[];
|
|
24
|
+
duration: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildScrubber(tl: Timeline): Scrubber;
|
|
27
|
+
/** Where on the slider, 0 to 1, the moment `t` falls. */
|
|
28
|
+
export declare function positionAt(s: Scrubber, t: number): number;
|
|
29
|
+
/** The moment a place on the slider stands for. The inverse of `positionAt`. */
|
|
30
|
+
export declare function timeAt(s: Scrubber, position: number): number;
|
|
31
|
+
/** The slot a place on the slider falls in. */
|
|
32
|
+
export declare function slotAt(s: Scrubber, position: number): number;
|
|
33
|
+
/** The slot that holds step `index`, or -1. */
|
|
34
|
+
export declare function slotOfStep(s: Scrubber, index: number): number;
|
package/dist/start.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CompiledDiagram, ScenarioMode } from './types';
|
|
2
|
+
/** What the page that shows a diagram asked for, if anything. Its choices win over the diagram's. */
|
|
3
|
+
export interface StartWant {
|
|
4
|
+
view?: string;
|
|
5
|
+
scenario?: string;
|
|
6
|
+
mode?: ScenarioMode;
|
|
7
|
+
}
|
|
8
|
+
export interface Start {
|
|
9
|
+
/** Always one of the diagram's views. */
|
|
10
|
+
view: string;
|
|
11
|
+
/** The scenario selected first, or null for the overview. */
|
|
12
|
+
scenario: string | null;
|
|
13
|
+
mode: ScenarioMode;
|
|
14
|
+
}
|
|
15
|
+
/** The mode a scenario is drawn in when neither it nor the page says: the diagram's, then `flow`. */
|
|
16
|
+
export declare const defaultMode: (diagram: CompiledDiagram) => ScenarioMode;
|
|
17
|
+
/**
|
|
18
|
+
* Where a diagram opens. The page's props come first, then what the diagram's author wrote under
|
|
19
|
+
* `defaults`, then the first view with nothing selected. The page choosing a scenario takes its
|
|
20
|
+
* view along, and one choosing a view leaves the default scenario out unless it plays there.
|
|
21
|
+
*/
|
|
22
|
+
export declare function startOf(diagram: CompiledDiagram, want?: StartWant): Start;
|
package/dist/types.d.ts
CHANGED
|
@@ -29,11 +29,27 @@ export interface NodeDiagram {
|
|
|
29
29
|
/** Starts shown in place. */
|
|
30
30
|
expanded?: boolean;
|
|
31
31
|
}
|
|
32
|
+
/** A row of an entity card: one column, property or attribute of what the node stores. */
|
|
33
|
+
export interface CompiledField {
|
|
34
|
+
name: string;
|
|
35
|
+
type?: string;
|
|
36
|
+
/** Part of the primary key. */
|
|
37
|
+
key?: boolean;
|
|
38
|
+
/** The node (and field) this one points at, like a foreign key. Each one draws a relation. */
|
|
39
|
+
ref?: {
|
|
40
|
+
node: string;
|
|
41
|
+
field?: string;
|
|
42
|
+
};
|
|
43
|
+
note?: string;
|
|
44
|
+
}
|
|
32
45
|
export interface CompiledNode {
|
|
33
46
|
id: string;
|
|
34
47
|
title: string;
|
|
35
48
|
sub?: string;
|
|
49
|
+
/** A short label in the card header, like `TABLE` or `ES INDEX`. */
|
|
50
|
+
pill?: string;
|
|
36
51
|
lines: string[];
|
|
52
|
+
fields: CompiledField[];
|
|
37
53
|
icon?: IconData;
|
|
38
54
|
kind?: string;
|
|
39
55
|
family?: Family;
|
|
@@ -76,6 +92,9 @@ export interface CompiledEdge {
|
|
|
76
92
|
id: string;
|
|
77
93
|
from: string;
|
|
78
94
|
to: string;
|
|
95
|
+
/** Set when the edge starts or ends on one field of an entity card. */
|
|
96
|
+
fromField?: string;
|
|
97
|
+
toField?: string;
|
|
79
98
|
label?: string;
|
|
80
99
|
kind: string;
|
|
81
100
|
both: boolean;
|
|
@@ -147,10 +166,23 @@ export interface CompiledScenario {
|
|
|
147
166
|
phases: CompiledPhase[];
|
|
148
167
|
steps: CompiledStep[];
|
|
149
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* How a diagram opens, as its author wrote it. A page's own choices (the props of `<Diagram>`) win
|
|
171
|
+
* over these. Validated by the compiler: the view and the scenario exist, and agree.
|
|
172
|
+
*/
|
|
173
|
+
export interface DiagramDefaults {
|
|
174
|
+
view?: string;
|
|
175
|
+
scenario?: string;
|
|
176
|
+
mode?: ScenarioMode;
|
|
177
|
+
sidebar?: boolean;
|
|
178
|
+
subtitles?: boolean;
|
|
179
|
+
autoplay?: boolean;
|
|
180
|
+
}
|
|
150
181
|
export interface CompiledDiagram {
|
|
151
182
|
name: string;
|
|
152
183
|
title: string;
|
|
153
184
|
descriptionHtml?: string;
|
|
185
|
+
defaults?: DiagramDefaults;
|
|
154
186
|
nodes: Record<string, CompiledNode>;
|
|
155
187
|
groups: Record<string, CompiledGroup>;
|
|
156
188
|
edges: Record<string, CompiledEdge>;
|
package/package.json
CHANGED
package/dist/chunk-ITBBPZE6.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
// src/defaults.ts
|
|
2
|
-
var BUILTIN_KINDS = {
|
|
3
|
-
client: { icon: "lucide:monitor", family: "slate" },
|
|
4
|
-
user: { icon: "lucide:user", family: "slate" },
|
|
5
|
-
ui: { icon: "lucide:layout-dashboard", family: "slate" },
|
|
6
|
-
external: { icon: "lucide:cloud", family: "slate" },
|
|
7
|
-
service: { icon: "lucide:server", family: "blue" },
|
|
8
|
-
gateway: { icon: "lucide:route", family: "blue" },
|
|
9
|
-
worker: { icon: "lucide:cog", family: "blue" },
|
|
10
|
-
container: { icon: "lucide:container", family: "blue" },
|
|
11
|
-
function: { icon: "lucide:square-function", family: "blue" },
|
|
12
|
-
database: { icon: "lucide:database", family: "green" },
|
|
13
|
-
cache: { icon: "lucide:zap", family: "green" },
|
|
14
|
-
storage: { icon: "lucide:hard-drive", family: "green" },
|
|
15
|
-
queue: { icon: "lucide:list-ordered", family: "amber" },
|
|
16
|
-
agent: { icon: "lucide:bot", family: "violet" },
|
|
17
|
-
network: { icon: "lucide:network", family: "violet" },
|
|
18
|
-
vm: { icon: "lucide:box", family: "violet" },
|
|
19
|
-
auth: { icon: "lucide:key-round", family: "teal" },
|
|
20
|
-
monitor: { icon: "lucide:activity", family: "teal" }
|
|
21
|
-
};
|
|
22
|
-
var BUILTIN_EDGE_KINDS = {
|
|
23
|
-
http: { label: "HTTP request / response", color: "ink", width: 1.5 },
|
|
24
|
-
channel: { label: "Persistent channel (websocket, gRPC)", color: "accent", width: 2.4 },
|
|
25
|
-
tunnel: { label: "Overlay tunnel", color: "tunnel", width: 5 },
|
|
26
|
-
queue: { label: "Queue / broker", color: "ok", width: 2, dash: "2 4" },
|
|
27
|
-
ws: { label: "WebSocket", color: "ink", width: 1.6, dash: "7 4" },
|
|
28
|
-
data: { label: "Data access", color: "muted", width: 1.3 }
|
|
29
|
-
};
|
|
30
|
-
var STEP_KIND_COLORS = {
|
|
31
|
-
request: "accent",
|
|
32
|
-
response: "ok",
|
|
33
|
-
error: "bad",
|
|
34
|
-
lookup: "muted",
|
|
35
|
-
event: "warn"
|
|
36
|
-
};
|
|
37
|
-
var DEFAULT_NODE_WIDTH = 178;
|
|
38
|
-
|
|
39
|
-
// src/geometry.ts
|
|
40
|
-
function polylineLength(points) {
|
|
41
|
-
let total = 0;
|
|
42
|
-
for (let i = 1; i < points.length; i++) total += dist(points[i - 1], points[i]);
|
|
43
|
-
return total;
|
|
44
|
-
}
|
|
45
|
-
function dist(a, b) {
|
|
46
|
-
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
47
|
-
}
|
|
48
|
-
function pointAt(points, d) {
|
|
49
|
-
if (points.length === 0) return { x: 0, y: 0 };
|
|
50
|
-
let left = Math.max(0, d);
|
|
51
|
-
for (let i = 1; i < points.length; i++) {
|
|
52
|
-
const a = points[i - 1];
|
|
53
|
-
const b = points[i];
|
|
54
|
-
const len = dist(a, b);
|
|
55
|
-
if (left <= len || i === points.length - 1) {
|
|
56
|
-
const t = len === 0 ? 0 : Math.min(1, left / len);
|
|
57
|
-
return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
|
|
58
|
-
}
|
|
59
|
-
left -= len;
|
|
60
|
-
}
|
|
61
|
-
return points[points.length - 1];
|
|
62
|
-
}
|
|
63
|
-
function roundedPath(points, radius = 8) {
|
|
64
|
-
if (points.length === 0) return "";
|
|
65
|
-
const first = points[0];
|
|
66
|
-
let d = `M${r(first.x)} ${r(first.y)}`;
|
|
67
|
-
for (let i = 1; i < points.length - 1; i++) {
|
|
68
|
-
const prev = points[i - 1];
|
|
69
|
-
const cur = points[i];
|
|
70
|
-
const next = points[i + 1];
|
|
71
|
-
const inLen = dist(prev, cur);
|
|
72
|
-
const outLen = dist(cur, next);
|
|
73
|
-
const rad = Math.min(radius, inLen / 2, outLen / 2);
|
|
74
|
-
if (rad < 0.5) {
|
|
75
|
-
d += `L${r(cur.x)} ${r(cur.y)}`;
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
const a = {
|
|
79
|
-
x: cur.x + (prev.x - cur.x) / inLen * rad,
|
|
80
|
-
y: cur.y + (prev.y - cur.y) / inLen * rad
|
|
81
|
-
};
|
|
82
|
-
const b = {
|
|
83
|
-
x: cur.x + (next.x - cur.x) / outLen * rad,
|
|
84
|
-
y: cur.y + (next.y - cur.y) / outLen * rad
|
|
85
|
-
};
|
|
86
|
-
d += `L${r(a.x)} ${r(a.y)}Q${r(cur.x)} ${r(cur.y)} ${r(b.x)} ${r(b.y)}`;
|
|
87
|
-
}
|
|
88
|
-
if (points.length > 1) {
|
|
89
|
-
const last = points[points.length - 1];
|
|
90
|
-
d += `L${r(last.x)} ${r(last.y)}`;
|
|
91
|
-
}
|
|
92
|
-
return d;
|
|
93
|
-
}
|
|
94
|
-
function r(n) {
|
|
95
|
-
return Math.round(n * 10) / 10;
|
|
96
|
-
}
|
|
97
|
-
function letterKey(index) {
|
|
98
|
-
let n = index;
|
|
99
|
-
let out = "";
|
|
100
|
-
do {
|
|
101
|
-
out = String.fromCharCode(65 + n % 26) + out;
|
|
102
|
-
n = Math.floor(n / 26) - 1;
|
|
103
|
-
} while (n >= 0);
|
|
104
|
-
return out;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// src/suggest.ts
|
|
108
|
-
function didYouMean(word, options) {
|
|
109
|
-
let best;
|
|
110
|
-
let bestDist = Math.max(2, Math.floor(word.length / 3)) + 1;
|
|
111
|
-
for (const o of options) {
|
|
112
|
-
const d = levenshtein(word.toLowerCase(), o.toLowerCase());
|
|
113
|
-
if (d < bestDist) {
|
|
114
|
-
best = o;
|
|
115
|
-
bestDist = d;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return best ? `Did you mean "${best}"?` : void 0;
|
|
119
|
-
}
|
|
120
|
-
function levenshtein(a, b) {
|
|
121
|
-
const row = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
122
|
-
for (let i = 1; i <= a.length; i++) {
|
|
123
|
-
let prev = row[0];
|
|
124
|
-
row[0] = i;
|
|
125
|
-
for (let j = 1; j <= b.length; j++) {
|
|
126
|
-
const tmp = row[j];
|
|
127
|
-
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
128
|
-
prev = tmp;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return row[b.length];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export {
|
|
135
|
-
BUILTIN_KINDS,
|
|
136
|
-
BUILTIN_EDGE_KINDS,
|
|
137
|
-
STEP_KIND_COLORS,
|
|
138
|
-
DEFAULT_NODE_WIDTH,
|
|
139
|
-
polylineLength,
|
|
140
|
-
dist,
|
|
141
|
-
pointAt,
|
|
142
|
-
roundedPath,
|
|
143
|
-
letterKey,
|
|
144
|
-
didYouMean
|
|
145
|
-
};
|