@cristianormazabal/triton-core 0.1.17 → 0.1.18
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/diagrams/triton/ds/hashmap/hashmap.d.ts +9 -9
- package/dist/diagrams/triton/ds/hashmap/hashmap.d.ts.map +1 -1
- package/dist/diagrams/triton/ds/hashmap/hashmap.js +126 -28
- package/dist/diagrams/triton/ds/hashmap/hashmap.js.map +1 -1
- package/dist/index.js +107 -19
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file diagrams/ds/hashmap/hashmap.ts — Hash map with separate chaining.
|
|
3
3
|
*
|
|
4
|
-
* A vertical strip of buckets
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* A vertical strip of buckets. Each non-empty bucket points right to a chain
|
|
5
|
+
* of key→value entries (a singly linked list), reusing the slot/pointer
|
|
6
|
+
* kernel idiom from the linked-list struct. Buckets can be numbered or labeled
|
|
7
|
+
* with arbitrary strings, and empty buckets show their configured label.
|
|
8
8
|
*
|
|
9
9
|
* Value-driven mini-syntax:
|
|
10
10
|
* hashmap
|
|
11
11
|
* title users
|
|
12
|
-
* buckets
|
|
13
|
-
* bucket
|
|
14
|
-
* bucket
|
|
15
|
-
* bucket 4: dave->4
|
|
12
|
+
* buckets name, email, phone
|
|
13
|
+
* bucket name: alice->1, bob->2 // two chained entries
|
|
14
|
+
* bucket phone: carol->3
|
|
16
15
|
*
|
|
17
16
|
* Entry separators: `,` between entries; `->`, `=>`, `:` or `=` between
|
|
18
17
|
* key and value.
|
|
@@ -23,12 +22,13 @@ export interface HashEntry {
|
|
|
23
22
|
value: string;
|
|
24
23
|
}
|
|
25
24
|
export interface HashChain {
|
|
26
|
-
index: number;
|
|
25
|
+
index: number | string;
|
|
27
26
|
entries: HashEntry[];
|
|
28
27
|
}
|
|
29
28
|
export interface HashmapDoc {
|
|
30
29
|
title?: string;
|
|
31
30
|
buckets: number;
|
|
31
|
+
bucketLabels: string[];
|
|
32
32
|
chains: HashChain[];
|
|
33
33
|
}
|
|
34
34
|
export declare function layoutHashmap(doc: HashmapDoc, theme: ResolvedTheme): LayoutResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/diagrams/triton/ds/hashmap/hashmap.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hashmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/diagrams/triton/ds/hashmap/hashmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,aAAa,EAAE,aAAa,EAAE,YAAY,EAC3C,MAAM,gCAAgC,CAAC;AAMxC,MAAM,WAAW,SAAS;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAC1D,MAAM,WAAW,SAAS;IAAG,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,EAAE,CAAC;CAAE;AAE5E,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAqID,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,GAAG,YAAY,CAkEjF;AAED,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,UAAU,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAUtG,CAAC"}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file diagrams/ds/hashmap/hashmap.ts — Hash map with separate chaining.
|
|
3
3
|
*
|
|
4
|
-
* A vertical strip of buckets
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* A vertical strip of buckets. Each non-empty bucket points right to a chain
|
|
5
|
+
* of key→value entries (a singly linked list), reusing the slot/pointer
|
|
6
|
+
* kernel idiom from the linked-list struct. Buckets can be numbered or labeled
|
|
7
|
+
* with arbitrary strings, and empty buckets show their configured label.
|
|
8
8
|
*
|
|
9
9
|
* Value-driven mini-syntax:
|
|
10
10
|
* hashmap
|
|
11
11
|
* title users
|
|
12
|
-
* buckets
|
|
13
|
-
* bucket
|
|
14
|
-
* bucket
|
|
15
|
-
* bucket 4: dave->4
|
|
12
|
+
* buckets name, email, phone
|
|
13
|
+
* bucket name: alice->1, bob->2 // two chained entries
|
|
14
|
+
* bucket phone: carol->3
|
|
16
15
|
*
|
|
17
16
|
* Entry separators: `,` between entries; `->`, `=>`, `:` or `=` between
|
|
18
17
|
* key and value.
|
|
@@ -29,9 +28,96 @@ function parseEntries(spec) {
|
|
|
29
28
|
return { key: pair, value: '' };
|
|
30
29
|
});
|
|
31
30
|
}
|
|
31
|
+
function parseBucketLabels(spec) {
|
|
32
|
+
const labels = [];
|
|
33
|
+
let current = '';
|
|
34
|
+
let inQuotes = false;
|
|
35
|
+
let escaping = false;
|
|
36
|
+
for (const ch of spec) {
|
|
37
|
+
if (escaping) {
|
|
38
|
+
current += ch;
|
|
39
|
+
escaping = false;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (inQuotes && ch === '\\') {
|
|
43
|
+
escaping = true;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (ch === '"') {
|
|
47
|
+
inQuotes = !inQuotes;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (!inQuotes && ch === ',') {
|
|
51
|
+
const label = current.trim();
|
|
52
|
+
if (label)
|
|
53
|
+
labels.push(label);
|
|
54
|
+
current = '';
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
current += ch;
|
|
58
|
+
}
|
|
59
|
+
if (inQuotes)
|
|
60
|
+
throw new Error(`Unterminated bucket label: ${spec}`);
|
|
61
|
+
const tail = current.trim();
|
|
62
|
+
if (tail)
|
|
63
|
+
labels.push(tail);
|
|
64
|
+
return labels;
|
|
65
|
+
}
|
|
66
|
+
function splitBucketDirective(spec) {
|
|
67
|
+
let inQuotes = false;
|
|
68
|
+
let escaping = false;
|
|
69
|
+
for (let i = 0; i < spec.length; i++) {
|
|
70
|
+
const ch = spec[i];
|
|
71
|
+
if (escaping) {
|
|
72
|
+
escaping = false;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (inQuotes && ch === '\\') {
|
|
76
|
+
escaping = true;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (ch === '"') {
|
|
80
|
+
inQuotes = !inQuotes;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!inQuotes && ch === ':') {
|
|
84
|
+
return { id: spec.slice(0, i).trim(), entries: spec.slice(i + 1).trim() };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
function parseBucketId(spec) {
|
|
90
|
+
const [label = ''] = parseBucketLabels(spec);
|
|
91
|
+
return /^\d+$/.test(label) ? Number(label) : label;
|
|
92
|
+
}
|
|
93
|
+
function normalizeDoc(doc) {
|
|
94
|
+
const chains = doc.chains ?? [];
|
|
95
|
+
const bucketLabels = [...(doc.bucketLabels ?? [])];
|
|
96
|
+
for (const chain of chains) {
|
|
97
|
+
if (typeof chain.index === 'string' && !bucketLabels.includes(chain.index))
|
|
98
|
+
bucketLabels.push(chain.index);
|
|
99
|
+
}
|
|
100
|
+
const maxIdx = chains.reduce((mx, c) => typeof c.index === 'number' ? Math.max(mx, c.index) : mx, -1);
|
|
101
|
+
const numericBucketCount = Math.max(doc.buckets ?? 0, maxIdx + 1, 1);
|
|
102
|
+
if (bucketLabels.length === 0) {
|
|
103
|
+
for (let i = 0; i < numericBucketCount; i++)
|
|
104
|
+
bucketLabels.push(String(i));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
while (bucketLabels.length < numericBucketCount)
|
|
108
|
+
bucketLabels.push(String(bucketLabels.length));
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
...(doc.title !== undefined ? { title: doc.title } : {}),
|
|
112
|
+
buckets: bucketLabels.length,
|
|
113
|
+
bucketLabels,
|
|
114
|
+
chains,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
32
117
|
function parse(input) {
|
|
33
118
|
let title;
|
|
34
119
|
let bucketCount;
|
|
120
|
+
let explicitBucketLabels;
|
|
35
121
|
const chains = [];
|
|
36
122
|
for (const line of lines(input)) {
|
|
37
123
|
const t = line.split(/\s+/);
|
|
@@ -43,20 +129,28 @@ function parse(input) {
|
|
|
43
129
|
continue;
|
|
44
130
|
}
|
|
45
131
|
if (t[0] === 'buckets') {
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
|
|
132
|
+
const spec = line.slice(7).trim();
|
|
133
|
+
if (!spec)
|
|
134
|
+
continue;
|
|
135
|
+
if (/^\d+$/.test(spec)) {
|
|
136
|
+
bucketCount = Number(spec);
|
|
137
|
+
explicitBucketLabels = undefined;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
explicitBucketLabels = parseBucketLabels(spec);
|
|
141
|
+
}
|
|
49
142
|
continue;
|
|
50
143
|
}
|
|
51
144
|
if (t[0] === 'bucket') {
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
chains.push({ index:
|
|
145
|
+
const parsed = splitBucketDirective(line.slice(6).trim());
|
|
146
|
+
if (parsed)
|
|
147
|
+
chains.push({ index: parseBucketId(parsed.id), entries: parseEntries(parsed.entries) });
|
|
55
148
|
}
|
|
56
149
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
150
|
+
return normalizeDoc({ title, buckets: bucketCount, bucketLabels: explicitBucketLabels, chains });
|
|
151
|
+
}
|
|
152
|
+
function bucketKey(id) {
|
|
153
|
+
return typeof id === 'number' ? `n:${id}` : `s:${id}`;
|
|
60
154
|
}
|
|
61
155
|
export function layoutHashmap(doc, theme) {
|
|
62
156
|
const { palette, typography, spacing } = theme;
|
|
@@ -64,7 +158,7 @@ export function layoutHashmap(doc, theme) {
|
|
|
64
158
|
const margin = spacing.diagramMargin;
|
|
65
159
|
const font = typography.baseFontSize;
|
|
66
160
|
const cellH = 38;
|
|
67
|
-
const idxW = 46;
|
|
161
|
+
const idxW = Math.max(46, ...doc.bucketLabels.map(label => measureText(label, font).width + 24));
|
|
68
162
|
const entryH = 30;
|
|
69
163
|
const entryGap = 30;
|
|
70
164
|
const chainGap = 36; // bucket strip → first entry
|
|
@@ -74,22 +168,26 @@ export function layoutHashmap(doc, theme) {
|
|
|
74
168
|
if (doc.title) {
|
|
75
169
|
elements.push(p.text(doc.title, margin, margin + typography.titleFontSize, typography.titleFontSize, palette.text, { weight: 'bold' }));
|
|
76
170
|
}
|
|
77
|
-
// bucket
|
|
78
|
-
const
|
|
171
|
+
// bucket label column (vertical strip)
|
|
172
|
+
const slotById = new Map();
|
|
173
|
+
const anchors = {};
|
|
79
174
|
for (let i = 0; i < doc.buckets; i++) {
|
|
80
175
|
const slot = { x: origin.x, y: origin.y + i * cellH, width: idxW, height: cellH };
|
|
81
|
-
|
|
176
|
+
const label = doc.bucketLabels[i] ?? String(i);
|
|
177
|
+
slotById.set(bucketKey(i), { row: i, bounds: slot });
|
|
178
|
+
if (!slotById.has(bucketKey(label)))
|
|
179
|
+
slotById.set(bucketKey(label), { row: i, bounds: slot });
|
|
180
|
+
anchors[`b${i}`] = { bounds: slot };
|
|
82
181
|
elements.push(p.rect(slot, palette.surface, palette.border, 1.5, { rx: 3 }));
|
|
83
|
-
elements.push(p.text(
|
|
182
|
+
elements.push(p.text(label, slot.x + slot.width / 2, slot.y + slot.height / 2 + font * 0.35, font, palette.textMuted, { anchor: 'middle', weight: 'bold' }));
|
|
84
183
|
}
|
|
85
|
-
const anchors = {};
|
|
86
|
-
slots.forEach((slot, i) => { anchors[`b${i}`] = { bounds: slot }; });
|
|
87
184
|
const chainStartX = origin.x + idxW + chainGap;
|
|
88
185
|
let maxRight = chainStartX;
|
|
89
186
|
for (const chain of doc.chains) {
|
|
90
|
-
const
|
|
91
|
-
if (!
|
|
187
|
+
const slotRef = slotById.get(bucketKey(chain.index));
|
|
188
|
+
if (!slotRef || chain.entries.length === 0)
|
|
92
189
|
continue;
|
|
190
|
+
const { bounds: slot, row } = slotRef;
|
|
93
191
|
const cy = slot.y + slot.height / 2;
|
|
94
192
|
let x = chainStartX;
|
|
95
193
|
let fromX = slot.x + slot.width;
|
|
@@ -101,7 +199,7 @@ export function layoutHashmap(doc, theme) {
|
|
|
101
199
|
elements.push(p.path(`M ${rhu(fromX)} ${rhu(cy)} L ${rhu(x - 3)} ${rhu(cy)}`, palette.primary, 1.5, { markerEnd: ARROW_ID }));
|
|
102
200
|
elements.push(p.rect(box, palette.surface, palette.border, 1.5, { rx: 4 }));
|
|
103
201
|
elements.push(p.text(label, x + w / 2, cy + font * 0.35, font, palette.text, { anchor: 'middle', weight: 'bold' }));
|
|
104
|
-
anchors[`b${
|
|
202
|
+
anchors[`b${row}e${j}`] = { bounds: box };
|
|
105
203
|
fromX = x + w;
|
|
106
204
|
x = fromX + entryGap;
|
|
107
205
|
maxRight = Math.max(maxRight, fromX);
|
|
@@ -122,7 +220,7 @@ export const hashmap = {
|
|
|
122
220
|
return { version: '1.0', metadata: {}, ...parse(input) };
|
|
123
221
|
},
|
|
124
222
|
parseYaml(input) {
|
|
125
|
-
return JSON.parse(input);
|
|
223
|
+
return { version: '1.0', metadata: {}, ...normalizeDoc(JSON.parse(input)) };
|
|
126
224
|
},
|
|
127
225
|
layout(ir, theme) {
|
|
128
226
|
return layoutHashmap(ir, theme);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashmap.js","sourceRoot":"","sources":["../../../../../../../src/diagrams/triton/ds/hashmap/hashmap.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hashmap.js","sourceRoot":"","sources":["../../../../../../../src/diagrams/triton/ds/hashmap/hashmap.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -43768,9 +43768,89 @@ function parseEntries(spec) {
|
|
|
43768
43768
|
return { key: pair, value: "" };
|
|
43769
43769
|
});
|
|
43770
43770
|
}
|
|
43771
|
+
function parseBucketLabels(spec) {
|
|
43772
|
+
const labels = [];
|
|
43773
|
+
let current = "";
|
|
43774
|
+
let inQuotes = false;
|
|
43775
|
+
let escaping = false;
|
|
43776
|
+
for (const ch of spec) {
|
|
43777
|
+
if (escaping) {
|
|
43778
|
+
current += ch;
|
|
43779
|
+
escaping = false;
|
|
43780
|
+
continue;
|
|
43781
|
+
}
|
|
43782
|
+
if (inQuotes && ch === "\\") {
|
|
43783
|
+
escaping = true;
|
|
43784
|
+
continue;
|
|
43785
|
+
}
|
|
43786
|
+
if (ch === '"') {
|
|
43787
|
+
inQuotes = !inQuotes;
|
|
43788
|
+
continue;
|
|
43789
|
+
}
|
|
43790
|
+
if (!inQuotes && ch === ",") {
|
|
43791
|
+
const label = current.trim();
|
|
43792
|
+
if (label) labels.push(label);
|
|
43793
|
+
current = "";
|
|
43794
|
+
continue;
|
|
43795
|
+
}
|
|
43796
|
+
current += ch;
|
|
43797
|
+
}
|
|
43798
|
+
if (inQuotes) throw new Error(`Unterminated bucket label: ${spec}`);
|
|
43799
|
+
const tail = current.trim();
|
|
43800
|
+
if (tail) labels.push(tail);
|
|
43801
|
+
return labels;
|
|
43802
|
+
}
|
|
43803
|
+
function splitBucketDirective(spec) {
|
|
43804
|
+
let inQuotes = false;
|
|
43805
|
+
let escaping = false;
|
|
43806
|
+
for (let i = 0; i < spec.length; i++) {
|
|
43807
|
+
const ch = spec[i];
|
|
43808
|
+
if (escaping) {
|
|
43809
|
+
escaping = false;
|
|
43810
|
+
continue;
|
|
43811
|
+
}
|
|
43812
|
+
if (inQuotes && ch === "\\") {
|
|
43813
|
+
escaping = true;
|
|
43814
|
+
continue;
|
|
43815
|
+
}
|
|
43816
|
+
if (ch === '"') {
|
|
43817
|
+
inQuotes = !inQuotes;
|
|
43818
|
+
continue;
|
|
43819
|
+
}
|
|
43820
|
+
if (!inQuotes && ch === ":") {
|
|
43821
|
+
return { id: spec.slice(0, i).trim(), entries: spec.slice(i + 1).trim() };
|
|
43822
|
+
}
|
|
43823
|
+
}
|
|
43824
|
+
return null;
|
|
43825
|
+
}
|
|
43826
|
+
function parseBucketId(spec) {
|
|
43827
|
+
const [label = ""] = parseBucketLabels(spec);
|
|
43828
|
+
return /^\d+$/.test(label) ? Number(label) : label;
|
|
43829
|
+
}
|
|
43830
|
+
function normalizeDoc(doc) {
|
|
43831
|
+
const chains = doc.chains ?? [];
|
|
43832
|
+
const bucketLabels = [...doc.bucketLabels ?? []];
|
|
43833
|
+
for (const chain of chains) {
|
|
43834
|
+
if (typeof chain.index === "string" && !bucketLabels.includes(chain.index)) bucketLabels.push(chain.index);
|
|
43835
|
+
}
|
|
43836
|
+
const maxIdx = chains.reduce((mx, c) => typeof c.index === "number" ? Math.max(mx, c.index) : mx, -1);
|
|
43837
|
+
const numericBucketCount = Math.max(doc.buckets ?? 0, maxIdx + 1, 1);
|
|
43838
|
+
if (bucketLabels.length === 0) {
|
|
43839
|
+
for (let i = 0; i < numericBucketCount; i++) bucketLabels.push(String(i));
|
|
43840
|
+
} else {
|
|
43841
|
+
while (bucketLabels.length < numericBucketCount) bucketLabels.push(String(bucketLabels.length));
|
|
43842
|
+
}
|
|
43843
|
+
return {
|
|
43844
|
+
...doc.title !== void 0 ? { title: doc.title } : {},
|
|
43845
|
+
buckets: bucketLabels.length,
|
|
43846
|
+
bucketLabels,
|
|
43847
|
+
chains
|
|
43848
|
+
};
|
|
43849
|
+
}
|
|
43771
43850
|
function parse10(input) {
|
|
43772
43851
|
let title;
|
|
43773
43852
|
let bucketCount;
|
|
43853
|
+
let explicitBucketLabels;
|
|
43774
43854
|
const chains = [];
|
|
43775
43855
|
for (const line of lines(input)) {
|
|
43776
43856
|
const t = line.split(/\s+/);
|
|
@@ -43782,18 +43862,25 @@ function parse10(input) {
|
|
|
43782
43862
|
continue;
|
|
43783
43863
|
}
|
|
43784
43864
|
if (t[0] === "buckets") {
|
|
43785
|
-
const
|
|
43786
|
-
if (
|
|
43865
|
+
const spec = line.slice(7).trim();
|
|
43866
|
+
if (!spec) continue;
|
|
43867
|
+
if (/^\d+$/.test(spec)) {
|
|
43868
|
+
bucketCount = Number(spec);
|
|
43869
|
+
explicitBucketLabels = void 0;
|
|
43870
|
+
} else {
|
|
43871
|
+
explicitBucketLabels = parseBucketLabels(spec);
|
|
43872
|
+
}
|
|
43787
43873
|
continue;
|
|
43788
43874
|
}
|
|
43789
43875
|
if (t[0] === "bucket") {
|
|
43790
|
-
const
|
|
43791
|
-
if (
|
|
43876
|
+
const parsed = splitBucketDirective(line.slice(6).trim());
|
|
43877
|
+
if (parsed) chains.push({ index: parseBucketId(parsed.id), entries: parseEntries(parsed.entries) });
|
|
43792
43878
|
}
|
|
43793
43879
|
}
|
|
43794
|
-
|
|
43795
|
-
|
|
43796
|
-
|
|
43880
|
+
return normalizeDoc({ title, buckets: bucketCount, bucketLabels: explicitBucketLabels, chains });
|
|
43881
|
+
}
|
|
43882
|
+
function bucketKey(id) {
|
|
43883
|
+
return typeof id === "number" ? `n:${id}` : `s:${id}`;
|
|
43797
43884
|
}
|
|
43798
43885
|
function layoutHashmap(doc, theme) {
|
|
43799
43886
|
const { palette, typography, spacing } = theme;
|
|
@@ -43801,7 +43888,7 @@ function layoutHashmap(doc, theme) {
|
|
|
43801
43888
|
const margin = spacing.diagramMargin;
|
|
43802
43889
|
const font = typography.baseFontSize;
|
|
43803
43890
|
const cellH = 38;
|
|
43804
|
-
const idxW = 46;
|
|
43891
|
+
const idxW = Math.max(46, ...doc.bucketLabels.map((label) => measureText(label, font).width + 24));
|
|
43805
43892
|
const entryH = 30;
|
|
43806
43893
|
const entryGap = 30;
|
|
43807
43894
|
const chainGap = 36;
|
|
@@ -43811,22 +43898,23 @@ function layoutHashmap(doc, theme) {
|
|
|
43811
43898
|
if (doc.title) {
|
|
43812
43899
|
elements.push(p.text(doc.title, margin, margin + typography.titleFontSize, typography.titleFontSize, palette.text, { weight: "bold" }));
|
|
43813
43900
|
}
|
|
43814
|
-
const
|
|
43901
|
+
const slotById = /* @__PURE__ */ new Map();
|
|
43902
|
+
const anchors = {};
|
|
43815
43903
|
for (let i = 0; i < doc.buckets; i++) {
|
|
43816
43904
|
const slot = { x: origin.x, y: origin.y + i * cellH, width: idxW, height: cellH };
|
|
43817
|
-
|
|
43905
|
+
const label = doc.bucketLabels[i] ?? String(i);
|
|
43906
|
+
slotById.set(bucketKey(i), { row: i, bounds: slot });
|
|
43907
|
+
if (!slotById.has(bucketKey(label))) slotById.set(bucketKey(label), { row: i, bounds: slot });
|
|
43908
|
+
anchors[`b${i}`] = { bounds: slot };
|
|
43818
43909
|
elements.push(p.rect(slot, palette.surface, palette.border, 1.5, { rx: 3 }));
|
|
43819
|
-
elements.push(p.text(
|
|
43910
|
+
elements.push(p.text(label, slot.x + slot.width / 2, slot.y + slot.height / 2 + font * 0.35, font, palette.textMuted, { anchor: "middle", weight: "bold" }));
|
|
43820
43911
|
}
|
|
43821
|
-
const anchors = {};
|
|
43822
|
-
slots.forEach((slot, i) => {
|
|
43823
|
-
anchors[`b${i}`] = { bounds: slot };
|
|
43824
|
-
});
|
|
43825
43912
|
const chainStartX = origin.x + idxW + chainGap;
|
|
43826
43913
|
let maxRight = chainStartX;
|
|
43827
43914
|
for (const chain of doc.chains) {
|
|
43828
|
-
const
|
|
43829
|
-
if (!
|
|
43915
|
+
const slotRef = slotById.get(bucketKey(chain.index));
|
|
43916
|
+
if (!slotRef || chain.entries.length === 0) continue;
|
|
43917
|
+
const { bounds: slot, row } = slotRef;
|
|
43830
43918
|
const cy = slot.y + slot.height / 2;
|
|
43831
43919
|
let x = chainStartX;
|
|
43832
43920
|
let fromX = slot.x + slot.width;
|
|
@@ -43837,7 +43925,7 @@ function layoutHashmap(doc, theme) {
|
|
|
43837
43925
|
elements.push(p.path(`M ${rhu(fromX)} ${rhu(cy)} L ${rhu(x - 3)} ${rhu(cy)}`, palette.primary, 1.5, { markerEnd: ARROW_ID2 }));
|
|
43838
43926
|
elements.push(p.rect(box, palette.surface, palette.border, 1.5, { rx: 4 }));
|
|
43839
43927
|
elements.push(p.text(label, x + w / 2, cy + font * 0.35, font, palette.text, { anchor: "middle", weight: "bold" }));
|
|
43840
|
-
anchors[`b${
|
|
43928
|
+
anchors[`b${row}e${j}`] = { bounds: box };
|
|
43841
43929
|
fromX = x + w;
|
|
43842
43930
|
x = fromX + entryGap;
|
|
43843
43931
|
maxRight = Math.max(maxRight, fromX);
|
|
@@ -43858,7 +43946,7 @@ var hashmap = {
|
|
|
43858
43946
|
return { version: "1.0", metadata: {}, ...parse10(input) };
|
|
43859
43947
|
},
|
|
43860
43948
|
parseYaml(input) {
|
|
43861
|
-
return JSON.parse(input);
|
|
43949
|
+
return { version: "1.0", metadata: {}, ...normalizeDoc(JSON.parse(input)) };
|
|
43862
43950
|
},
|
|
43863
43951
|
layout(ir, theme) {
|
|
43864
43952
|
return layoutHashmap(ir, theme);
|