every-json 1.0.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/PROMPT.MD +1020 -0
- package/README.md +93 -0
- package/dist/every-json.css +1 -0
- package/dist/every-json.es.js +582 -0
- package/dist/every-json.umd.js +11 -0
- package/package.json +32 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
var $ = Object.defineProperty;
|
|
2
|
+
var S = (p, e, t) => e in p ? $(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
|
|
3
|
+
var g = (p, e, t) => S(p, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class T {
|
|
5
|
+
constructor() {
|
|
6
|
+
g(this, "idCounter", 0);
|
|
7
|
+
}
|
|
8
|
+
parse(e) {
|
|
9
|
+
return this.idCounter = 0, this.parseNode("root", e, 0, "root");
|
|
10
|
+
}
|
|
11
|
+
parseNode(e, t, s, o) {
|
|
12
|
+
const r = this.getType(t), l = {
|
|
13
|
+
id: `node-${++this.idCounter}`,
|
|
14
|
+
key: e,
|
|
15
|
+
value: t,
|
|
16
|
+
type: r,
|
|
17
|
+
depth: s,
|
|
18
|
+
children: [],
|
|
19
|
+
isCollapsible: r === "object" || r === "array",
|
|
20
|
+
path: o
|
|
21
|
+
};
|
|
22
|
+
if (r === "object" && t !== null) {
|
|
23
|
+
const d = Object.keys(t);
|
|
24
|
+
l.size = d.length, l.children = d.map((n) => {
|
|
25
|
+
const i = `${o}.${n}`;
|
|
26
|
+
return this.parseNode(n, t[n], s + 1, i);
|
|
27
|
+
});
|
|
28
|
+
} else r === "array" && (l.size = t.length, l.children = t.map((d, n) => {
|
|
29
|
+
const i = `${o}[${n}]`;
|
|
30
|
+
return this.parseNode(n, d, s + 1, i);
|
|
31
|
+
}));
|
|
32
|
+
return l;
|
|
33
|
+
}
|
|
34
|
+
getType(e) {
|
|
35
|
+
return e === null ? "null" : Array.isArray(e) ? "array" : typeof e == "object" ? "object" : typeof e;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class E {
|
|
39
|
+
constructor(e, t) {
|
|
40
|
+
g(this, "container");
|
|
41
|
+
g(this, "options");
|
|
42
|
+
this.container = e, this.options = t;
|
|
43
|
+
}
|
|
44
|
+
render(e) {
|
|
45
|
+
this.container.innerHTML = "";
|
|
46
|
+
const t = this.createNodeElement(e);
|
|
47
|
+
this.container.appendChild(t);
|
|
48
|
+
}
|
|
49
|
+
createNodeElement(e) {
|
|
50
|
+
const t = document.createElement("div");
|
|
51
|
+
t.className = `json-node-wrapper depth-${e.depth} ml-${e.depth > 0 ? "4" : "0"}`;
|
|
52
|
+
const s = document.createElement("div");
|
|
53
|
+
s.className = "group flex items-center py-1 px-2 rounded hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors cursor-pointer", s.dataset.id = e.id;
|
|
54
|
+
const o = document.createElement("span");
|
|
55
|
+
o.className = `w-4 h-4 flex items-center justify-center mr-1 transition-transform duration-200 ${e.isCollapsible ? "" : "opacity-0"}`, o.innerHTML = '<i class="fa-solid fa-chevron-right text-[10px]"></i>', e.isCollapsible && o.classList.add("rotate-90"), s.appendChild(o);
|
|
56
|
+
const r = document.createElement("span");
|
|
57
|
+
r.className = "json-key mr-2", r.textContent = `${e.key}:`, s.appendChild(r);
|
|
58
|
+
const c = document.createElement("span");
|
|
59
|
+
if (e.isCollapsible) {
|
|
60
|
+
if (this.options.showTypes) {
|
|
61
|
+
const a = document.createElement("span");
|
|
62
|
+
a.className = `type-badge ml-2 ${this.getTypeColor(e.type)}`, a.textContent = e.type === "array" ? `[${e.size}]` : `{${e.size}}`, c.appendChild(a);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
const a = document.createElement("span");
|
|
66
|
+
if (a.className = `json-value-${e.type}`, a.textContent = this.formatValue(e.value, e.type), c.appendChild(a), this.options.showTypes) {
|
|
67
|
+
const l = document.createElement("span");
|
|
68
|
+
l.className = `type-badge ml-2 opacity-0 group-hover:opacity-100 transition-opacity ${this.getTypeColor(e.type)}`, l.textContent = e.type, c.appendChild(l);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (s.appendChild(c), t.appendChild(s), e.children.length > 0) {
|
|
72
|
+
const a = document.createElement("div");
|
|
73
|
+
a.className = "children-container ml-4 border-l border-gray-100 dark:border-gray-800", e.children.forEach((l) => {
|
|
74
|
+
a.appendChild(this.createNodeElement(l));
|
|
75
|
+
}), t.appendChild(a), s.addEventListener("click", (l) => {
|
|
76
|
+
l.stopPropagation();
|
|
77
|
+
const d = o.classList.toggle("rotate-90");
|
|
78
|
+
a.classList.toggle("hidden", !d);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return t;
|
|
82
|
+
}
|
|
83
|
+
formatValue(e, t) {
|
|
84
|
+
return t === "string" ? `"${e}"` : t === "null" ? "null" : String(e);
|
|
85
|
+
}
|
|
86
|
+
getTypeColor(e) {
|
|
87
|
+
switch (e) {
|
|
88
|
+
case "string":
|
|
89
|
+
return "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400";
|
|
90
|
+
case "number":
|
|
91
|
+
return "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400";
|
|
92
|
+
case "boolean":
|
|
93
|
+
return "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400";
|
|
94
|
+
case "object":
|
|
95
|
+
return "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400";
|
|
96
|
+
case "array":
|
|
97
|
+
return "bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-400";
|
|
98
|
+
default:
|
|
99
|
+
return "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
class k {
|
|
104
|
+
constructor(e, t) {
|
|
105
|
+
g(this, "container");
|
|
106
|
+
g(this, "options");
|
|
107
|
+
this.container = e, this.options = t;
|
|
108
|
+
}
|
|
109
|
+
render(e) {
|
|
110
|
+
this.container.innerHTML = "";
|
|
111
|
+
const t = document.createElement("div");
|
|
112
|
+
t.className = "w-full overflow-x-auto";
|
|
113
|
+
const s = this.createTable(e);
|
|
114
|
+
t.appendChild(s), this.container.appendChild(t), this.options;
|
|
115
|
+
}
|
|
116
|
+
createTable(e) {
|
|
117
|
+
return e.type === "array" && e.children.length > 0 && e.children[0].type === "object" ? this.renderObjectArray(e) : e.type === "array" ? this.renderSimpleArray(e) : e.type === "object" ? this.renderObjectRows(e) : this.renderSimple(e);
|
|
118
|
+
}
|
|
119
|
+
renderObjectArray(e) {
|
|
120
|
+
const t = document.createElement("table");
|
|
121
|
+
t.className = "w-full text-sm text-left border-collapse";
|
|
122
|
+
const s = /* @__PURE__ */ new Set();
|
|
123
|
+
e.children.forEach((d) => {
|
|
124
|
+
d.children.forEach((n) => {
|
|
125
|
+
s.add(String(n.key));
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
const o = Array.from(s), r = document.createElement("thead");
|
|
129
|
+
r.className = "bg-tree-bg-alt border-b border-tree-border sticky top-0";
|
|
130
|
+
const c = document.createElement("tr"), a = document.createElement("th");
|
|
131
|
+
a.className = "px-4 py-3 font-bold text-tree-text-muted uppercase tracking-wider w-10", a.textContent = "#", c.appendChild(a), o.forEach((d) => {
|
|
132
|
+
const n = document.createElement("th");
|
|
133
|
+
n.className = "px-4 py-3 font-bold text-tree-text uppercase tracking-wider text-xs", n.textContent = d, c.appendChild(n);
|
|
134
|
+
}), r.appendChild(c), t.appendChild(r);
|
|
135
|
+
const l = document.createElement("tbody");
|
|
136
|
+
return e.children.forEach((d, n) => {
|
|
137
|
+
const i = document.createElement("tr");
|
|
138
|
+
i.className = "border-b border-tree-border hover:bg-tree-bg-alt transition-colors";
|
|
139
|
+
const m = document.createElement("td");
|
|
140
|
+
m.className = "px-4 py-3 text-tree-text-muted font-mono", m.textContent = String(n), i.appendChild(m), o.forEach((h) => {
|
|
141
|
+
const u = document.createElement("td");
|
|
142
|
+
u.className = "px-4 py-3 align-top";
|
|
143
|
+
const b = d.children.find((y) => String(y.key) === h);
|
|
144
|
+
b ? u.appendChild(this.formatCellValue(b)) : (u.className += " text-tree-text-muted italic opacity-50", u.textContent = "undefined"), i.appendChild(u);
|
|
145
|
+
}), l.appendChild(i);
|
|
146
|
+
}), t.appendChild(l), t;
|
|
147
|
+
}
|
|
148
|
+
renderObjectRows(e) {
|
|
149
|
+
const t = document.createElement("table");
|
|
150
|
+
t.className = "w-full text-sm text-left border-collapse";
|
|
151
|
+
const s = document.createElement("tbody");
|
|
152
|
+
return e.children.forEach((o) => {
|
|
153
|
+
const r = document.createElement("tr");
|
|
154
|
+
r.className = "border-b border-tree-border hover:bg-tree-bg-alt transition-colors";
|
|
155
|
+
const c = document.createElement("td");
|
|
156
|
+
c.className = "px-4 py-3 font-semibold text-tree-text bg-tree-bg-alt/30 w-1/4", c.textContent = String(o.key), r.appendChild(c);
|
|
157
|
+
const a = document.createElement("td");
|
|
158
|
+
a.className = "px-4 py-3", a.appendChild(this.formatCellValue(o)), r.appendChild(a), s.appendChild(r);
|
|
159
|
+
}), t.appendChild(s), t;
|
|
160
|
+
}
|
|
161
|
+
renderSimpleArray(e) {
|
|
162
|
+
const t = document.createElement("table");
|
|
163
|
+
t.className = "w-full text-sm text-left border-collapse";
|
|
164
|
+
const s = document.createElement("tbody");
|
|
165
|
+
return e.children.forEach((o, r) => {
|
|
166
|
+
const c = document.createElement("tr");
|
|
167
|
+
c.className = "border-b border-tree-border";
|
|
168
|
+
const a = document.createElement("td");
|
|
169
|
+
a.className = "px-4 py-2 text-tree-text-muted font-mono w-10", a.textContent = `[${r}]`, c.appendChild(a);
|
|
170
|
+
const l = document.createElement("td");
|
|
171
|
+
l.className = "px-4 py-2", l.appendChild(this.formatCellValue(o)), c.appendChild(l), s.appendChild(c);
|
|
172
|
+
}), t.appendChild(s), t;
|
|
173
|
+
}
|
|
174
|
+
renderSimple(e) {
|
|
175
|
+
const t = document.createElement("div");
|
|
176
|
+
return t.className = "p-10 flex flex-col items-center justify-center text-tree-text-muted", t.innerHTML = `<span class="text-4xl mb-4 opacity-20"><i class="fa-solid fa-file-lines"></i></span> <p>This data type (${e.type}) is better viewed in Tree mode.</p>`, t;
|
|
177
|
+
}
|
|
178
|
+
formatCellValue(e) {
|
|
179
|
+
const t = document.createElement("span");
|
|
180
|
+
if (e.isCollapsible) {
|
|
181
|
+
t.className = "text-tree-text-muted italic text-xs flex flex-col gap-1";
|
|
182
|
+
const s = document.createElement("div");
|
|
183
|
+
s.className = "font-semibold opacity-70 mb-1", s.textContent = e.type === "array" ? `Array(${e.size})` : `Object(${e.size})`, t.appendChild(s);
|
|
184
|
+
const o = document.createElement("div");
|
|
185
|
+
o.className = "pl-2 border-l border-tree-border text-[10px] space-y-0.5 opacity-80";
|
|
186
|
+
const r = 5;
|
|
187
|
+
if (e.children.slice(0, r).forEach((a) => {
|
|
188
|
+
const l = document.createElement("div");
|
|
189
|
+
l.className = "truncate max-w-[200px]";
|
|
190
|
+
let d = "";
|
|
191
|
+
if (a.isCollapsible) {
|
|
192
|
+
const n = a.children.slice(0, 2).map(
|
|
193
|
+
(m) => a.type === "object" ? `${m.key}:${this.getShortValue(m)}` : this.getShortValue(m)
|
|
194
|
+
).join(", "), i = a.size || 0;
|
|
195
|
+
d = a.type === "array" ? `[${n}${i > 2 ? "..." : ""}]` : `{${n}${i > 2 ? "..." : ""}}`;
|
|
196
|
+
} else
|
|
197
|
+
d = this.getShortValue(a);
|
|
198
|
+
e.type === "object" ? l.innerHTML = `<span class="font-bold mr-1">${a.key}:</span> ${d}` : l.textContent = d, o.appendChild(l);
|
|
199
|
+
}), e.children.length > r) {
|
|
200
|
+
const a = document.createElement("div");
|
|
201
|
+
a.className = "italic opacity-50", a.textContent = `+ ${e.children.length - r} more...`, o.appendChild(a);
|
|
202
|
+
}
|
|
203
|
+
t.appendChild(o);
|
|
204
|
+
} else
|
|
205
|
+
t.className = `json-value-${e.type}`, t.textContent = e.type === "string" ? `"${e.value}"` : String(e.value);
|
|
206
|
+
return t;
|
|
207
|
+
}
|
|
208
|
+
getShortValue(e) {
|
|
209
|
+
if (e.isCollapsible)
|
|
210
|
+
return e.type === "array" ? "[...]" : "{...}";
|
|
211
|
+
const t = String(e.value);
|
|
212
|
+
return t.length > 20 ? t.substring(0, 17) + "..." : t;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function w(p) {
|
|
216
|
+
if (!p.isCollapsible) return p.value;
|
|
217
|
+
if (p.type === "array")
|
|
218
|
+
return p.children.map((t) => w(t));
|
|
219
|
+
const e = {};
|
|
220
|
+
return p.children.forEach((t) => {
|
|
221
|
+
e[t.key] = w(t);
|
|
222
|
+
}), e;
|
|
223
|
+
}
|
|
224
|
+
function v(p, e = "success") {
|
|
225
|
+
let t = document.getElementById("toast-container");
|
|
226
|
+
t || (t = document.createElement("div"), t.id = "toast-container", t.className = "fixed bottom-6 right-6 z-50 flex flex-col gap-2 pointer-events-none", document.body.appendChild(t));
|
|
227
|
+
const s = document.createElement("div");
|
|
228
|
+
s.className = `
|
|
229
|
+
min-w-[200px] px-4 py-3 rounded-lg shadow-lg text-sm font-medium
|
|
230
|
+
flex items-center space-x-3 transform translate-y-2 opacity-0 transition-all duration-300 pointer-events-auto
|
|
231
|
+
${e === "success" ? "bg-green-600 text-white" : ""}
|
|
232
|
+
${e === "error" ? "bg-red-600 text-white" : ""}
|
|
233
|
+
${e === "info" ? "bg-tree-accent text-white" : ""}
|
|
234
|
+
`;
|
|
235
|
+
const o = document.createElement("span");
|
|
236
|
+
o.innerHTML = e === "success" ? '<i class="fa-solid fa-circle-check"></i>' : e === "error" ? '<i class="fa-solid fa-circle-exclamation"></i>' : '<i class="fa-solid fa-circle-info"></i>', s.appendChild(o);
|
|
237
|
+
const r = document.createElement("span");
|
|
238
|
+
r.textContent = p, s.appendChild(r), t.appendChild(s), requestAnimationFrame(() => {
|
|
239
|
+
s.classList.remove("translate-y-2", "opacity-0");
|
|
240
|
+
}), setTimeout(() => {
|
|
241
|
+
s.classList.add("translate-y-2", "opacity-0"), setTimeout(() => s.remove(), 300);
|
|
242
|
+
}, 3e3);
|
|
243
|
+
}
|
|
244
|
+
async function L(p) {
|
|
245
|
+
try {
|
|
246
|
+
return await navigator.clipboard.writeText(p), !0;
|
|
247
|
+
} catch (e) {
|
|
248
|
+
return console.error("Failed to copy text: ", e), !1;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
class A {
|
|
252
|
+
constructor(e, t) {
|
|
253
|
+
g(this, "container");
|
|
254
|
+
g(this, "options");
|
|
255
|
+
this.container = e, this.options = t;
|
|
256
|
+
}
|
|
257
|
+
render(e) {
|
|
258
|
+
this.container.innerHTML = "";
|
|
259
|
+
const t = document.createElement("div");
|
|
260
|
+
t.className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-2", e.children.forEach((s) => {
|
|
261
|
+
t.appendChild(this.createCard(s));
|
|
262
|
+
}), this.container.appendChild(t);
|
|
263
|
+
}
|
|
264
|
+
createCard(e) {
|
|
265
|
+
const t = document.createElement("div");
|
|
266
|
+
t.className = "bg-tree-bg dark:bg-tree-bg-alt border border-tree-border rounded-2xl shadow-sm hover:shadow-md transition-all flex flex-col overflow-hidden group";
|
|
267
|
+
const s = document.createElement("div");
|
|
268
|
+
s.className = "px-5 py-4 border-b border-tree-border flex items-center justify-between bg-tree-bg-alt/30";
|
|
269
|
+
const o = document.createElement("h3");
|
|
270
|
+
if (o.className = "font-bold text-tree-text truncate", o.textContent = String(e.key).toUpperCase(), s.appendChild(o), this.options.showTypes) {
|
|
271
|
+
const n = document.createElement("span");
|
|
272
|
+
n.className = "type-badge text-[10px]", n.textContent = e.type, s.appendChild(n);
|
|
273
|
+
}
|
|
274
|
+
t.appendChild(s);
|
|
275
|
+
const r = document.createElement("div");
|
|
276
|
+
if (r.className = "p-5 flex-1 overflow-y-auto max-h-[300px] custom-scrollbar", e.isCollapsible) {
|
|
277
|
+
const n = document.createElement("div");
|
|
278
|
+
n.className = "space-y-3", e.children.forEach((i) => {
|
|
279
|
+
const m = document.createElement("div");
|
|
280
|
+
m.className = "flex flex-col gap-1";
|
|
281
|
+
const h = document.createElement("div");
|
|
282
|
+
h.className = "flex items-center justify-between";
|
|
283
|
+
const u = document.createElement("span");
|
|
284
|
+
if (u.className = "text-xs font-semibold text-tree-text-muted", u.textContent = String(i.key), h.appendChild(u), this.options.showTypes && i.isCollapsible) {
|
|
285
|
+
const y = document.createElement("span");
|
|
286
|
+
y.className = "text-[9px] px-1 bg-tree-bg-alt rounded border border-tree-border text-tree-text-muted", y.textContent = i.type === "array" ? `[${i.size}]` : `{${i.size}}`, h.appendChild(y);
|
|
287
|
+
}
|
|
288
|
+
m.appendChild(h);
|
|
289
|
+
const b = document.createElement("div");
|
|
290
|
+
if (b.className = "text-sm text-tree-text break-words", i.isCollapsible) {
|
|
291
|
+
b.className += " italic text-xs opacity-70 bg-tree-bg-alt/50 p-2 rounded border border-tree-border/50 mt-1";
|
|
292
|
+
const y = i.children.slice(0, 3).map((x) => {
|
|
293
|
+
const f = x.isCollapsible ? x.type === "array" ? "[...]" : "{...}" : String(x.value), C = f.length > 20 ? f.substring(0, 17) + "..." : f;
|
|
294
|
+
return i.type === "object" ? `<span class="font-bold opacity-60">${x.key}:</span> ${C}` : C;
|
|
295
|
+
});
|
|
296
|
+
b.innerHTML = y.join("<br>"), i.children.length > 3 && (b.innerHTML += `<div class="mt-1 opacity-40 text-[10px]">+ ${i.children.length - 3} more</div>`);
|
|
297
|
+
} else {
|
|
298
|
+
const y = document.createElement("span");
|
|
299
|
+
y.className = `json-value-${i.type}`, y.textContent = i.type === "string" ? `"${i.value}"` : String(i.value), b.appendChild(y);
|
|
300
|
+
}
|
|
301
|
+
m.appendChild(b), n.appendChild(m);
|
|
302
|
+
}), r.appendChild(n);
|
|
303
|
+
} else {
|
|
304
|
+
const n = document.createElement("div");
|
|
305
|
+
n.className = `text-lg font-mono json-value-${e.type} break-all`, n.textContent = String(e.value), r.appendChild(n);
|
|
306
|
+
}
|
|
307
|
+
t.appendChild(r);
|
|
308
|
+
const c = document.createElement("div");
|
|
309
|
+
c.className = "px-5 py-3 border-t border-tree-border bg-tree-bg-alt/10 flex items-center justify-between opacity-0 group-hover:opacity-100 transition-opacity";
|
|
310
|
+
const a = document.createElement("span");
|
|
311
|
+
a.className = "text-[10px] text-tree-text-muted", a.textContent = e.isCollapsible ? `${e.size} properties` : "primitive", c.appendChild(a);
|
|
312
|
+
const l = document.createElement("div");
|
|
313
|
+
l.className = "flex items-center space-x-2";
|
|
314
|
+
const d = document.createElement("button");
|
|
315
|
+
return d.className = "p-1.5 rounded-lg hover:bg-tree-bg-alt text-tree-text-muted hover:text-tree-accent transition-colors", d.innerHTML = '<i class="fa-regular fa-copy"></i>', d.title = "Copy as JSON", d.onclick = async () => {
|
|
316
|
+
const n = w(e);
|
|
317
|
+
await L(JSON.stringify(n, null, 2)) ? v("JSON copied to clipboard!") : v("Failed to copy JSON", "error");
|
|
318
|
+
}, l.appendChild(d), c.appendChild(l), t.appendChild(c), t;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
class j {
|
|
322
|
+
constructor(e, t = {}) {
|
|
323
|
+
g(this, "container");
|
|
324
|
+
g(this, "options");
|
|
325
|
+
this.container = e, this.options = t;
|
|
326
|
+
}
|
|
327
|
+
render(e) {
|
|
328
|
+
this.container.innerHTML = "";
|
|
329
|
+
const t = document.createElement("div");
|
|
330
|
+
t.className = "relative pl-8 pr-4 py-8";
|
|
331
|
+
const s = document.createElement("div");
|
|
332
|
+
s.className = "absolute left-4 top-0 bottom-0 w-0.5 bg-tree-border", t.appendChild(s), e.type === "array" ? e.children.forEach((o) => {
|
|
333
|
+
t.appendChild(this.createEventItem(o));
|
|
334
|
+
}) : e.children.forEach((o) => {
|
|
335
|
+
t.appendChild(this.createEventItem(o));
|
|
336
|
+
}), this.container.appendChild(t);
|
|
337
|
+
}
|
|
338
|
+
createEventItem(e) {
|
|
339
|
+
const t = document.createElement("div");
|
|
340
|
+
t.className = "relative mb-10 last:mb-0 group";
|
|
341
|
+
const s = document.createElement("div");
|
|
342
|
+
s.className = "absolute -left-[22px] top-1.5 w-3 h-3 rounded-full bg-tree-accent border-2 border-tree-bg z-10", t.appendChild(s);
|
|
343
|
+
const o = document.createElement("div");
|
|
344
|
+
o.className = "bg-tree-bg dark:bg-tree-bg-alt border border-tree-border rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow";
|
|
345
|
+
const r = document.createElement("div");
|
|
346
|
+
r.className = "flex items-center justify-between mb-3";
|
|
347
|
+
const c = document.createElement("span");
|
|
348
|
+
if (c.className = "text-xs font-bold text-tree-text tracking-wide uppercase", c.textContent = String(e.key), r.appendChild(c), this.options.showTypes) {
|
|
349
|
+
const l = document.createElement("span");
|
|
350
|
+
l.className = "type-badge", l.textContent = e.type, r.appendChild(l);
|
|
351
|
+
}
|
|
352
|
+
o.appendChild(r);
|
|
353
|
+
const a = document.createElement("div");
|
|
354
|
+
if (e.isCollapsible) {
|
|
355
|
+
a.className = "space-y-2";
|
|
356
|
+
const l = document.createElement("div");
|
|
357
|
+
l.className = "text-sm text-tree-text-muted italic opacity-60 mb-2", l.textContent = e.type === "array" ? `Array with ${e.size} items` : `Object with ${e.size} properties`, a.appendChild(l);
|
|
358
|
+
const d = document.createElement("div");
|
|
359
|
+
if (d.className = "grid grid-cols-1 sm:grid-cols-2 gap-2 mt-2", e.children.slice(0, 6).forEach((n) => {
|
|
360
|
+
const i = document.createElement("div");
|
|
361
|
+
i.className = "flex items-baseline text-xs truncate";
|
|
362
|
+
let m = "";
|
|
363
|
+
if (n.isCollapsible) {
|
|
364
|
+
const h = n.children.slice(0, 2).map(
|
|
365
|
+
(u) => n.type === "object" ? `${u.key}:${this.getShortValue(u)}` : this.getShortValue(u)
|
|
366
|
+
).join(", ");
|
|
367
|
+
m = n.type === "array" ? `[${h}...]` : `{${h}...}`;
|
|
368
|
+
} else
|
|
369
|
+
m = this.getShortValue(n);
|
|
370
|
+
e.type === "object" ? i.innerHTML = `<span class="font-bold mr-1 text-tree-text-muted">${n.key}:</span> <span class="json-value-${n.type}">${m}</span>` : i.innerHTML = `<span class="json-value-${n.type}">${m}</span>`, d.appendChild(i);
|
|
371
|
+
}), e.children.length > 6) {
|
|
372
|
+
const n = document.createElement("div");
|
|
373
|
+
n.className = "text-[10px] text-tree-text-muted mt-1 opacity-50", n.textContent = `+ ${e.children.length - 6} more items...`, d.appendChild(n);
|
|
374
|
+
}
|
|
375
|
+
a.appendChild(d);
|
|
376
|
+
} else
|
|
377
|
+
a.className = `text-sm json-value-${e.type} font-medium`, a.textContent = e.type === "string" ? `"${e.value}"` : String(e.value);
|
|
378
|
+
return o.appendChild(a), t.appendChild(o), t;
|
|
379
|
+
}
|
|
380
|
+
getShortValue(e) {
|
|
381
|
+
if (e.isCollapsible)
|
|
382
|
+
return e.type === "array" ? "[...]" : "{...}";
|
|
383
|
+
const t = String(e.value);
|
|
384
|
+
return t.length > 25 ? t.substring(0, 22) + "..." : t;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
class M {
|
|
388
|
+
constructor(e, t = {}) {
|
|
389
|
+
g(this, "container");
|
|
390
|
+
g(this, "options");
|
|
391
|
+
g(this, "svg", null);
|
|
392
|
+
g(this, "g", null);
|
|
393
|
+
// State for interactivity
|
|
394
|
+
g(this, "scale", 0.8);
|
|
395
|
+
g(this, "translateX", 400);
|
|
396
|
+
g(this, "translateY", 100);
|
|
397
|
+
g(this, "isDragging", !1);
|
|
398
|
+
g(this, "lastMouseX", 0);
|
|
399
|
+
g(this, "lastMouseY", 0);
|
|
400
|
+
this.container = e, this.options = t;
|
|
401
|
+
}
|
|
402
|
+
render(e) {
|
|
403
|
+
this.container.innerHTML = "";
|
|
404
|
+
const t = document.createElement("div");
|
|
405
|
+
t.className = "flex flex-col w-full h-[600px] min-h-[600px] relative overflow-hidden bg-tree-bg-alt rounded-2xl border border-tree-border";
|
|
406
|
+
const s = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
407
|
+
s.setAttribute("width", "100%"), s.setAttribute("height", "100%"), s.setAttribute("class", "flex-1 w-full h-full cursor-grab active:cursor-grabbing outline-none"), s.setAttribute("tabindex", "0"), this.svg = s;
|
|
408
|
+
const o = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
409
|
+
o.innerHTML = `
|
|
410
|
+
<pattern id="graph-grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
411
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="currentColor" stroke-width="0.5" class="text-tree-text/5" />
|
|
412
|
+
</pattern>
|
|
413
|
+
`, s.appendChild(o);
|
|
414
|
+
const r = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
415
|
+
r.setAttribute("width", "200%"), r.setAttribute("height", "200%"), r.setAttribute("x", "-50%"), r.setAttribute("y", "-50%"), r.setAttribute("fill", "url(#graph-grid)"), s.appendChild(r);
|
|
416
|
+
const c = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
417
|
+
c.id = "graph-content", this.g = c, s.appendChild(c), t.appendChild(s), this.container.appendChild(t), this.initInteractivity(), this.drawGraph(e), this.autoCenter(), this.updateTransform();
|
|
418
|
+
}
|
|
419
|
+
autoCenter() {
|
|
420
|
+
if (!this.container || !this.g) return;
|
|
421
|
+
const e = this.container.getBoundingClientRect();
|
|
422
|
+
this.translateX = e.width / 2, this.translateY = 100, this.scale = 0.6;
|
|
423
|
+
}
|
|
424
|
+
initInteractivity() {
|
|
425
|
+
if (!this.svg) return;
|
|
426
|
+
const e = this.svg;
|
|
427
|
+
e.addEventListener("mousedown", (t) => {
|
|
428
|
+
this.isDragging = !0, this.lastMouseX = t.clientX, this.lastMouseY = t.clientY;
|
|
429
|
+
}), window.addEventListener("mousemove", (t) => {
|
|
430
|
+
if (!this.isDragging) return;
|
|
431
|
+
const s = t.clientX - this.lastMouseX, o = t.clientY - this.lastMouseY;
|
|
432
|
+
this.translateX += s, this.translateY += o, this.lastMouseX = t.clientX, this.lastMouseY = t.clientY, this.updateTransform();
|
|
433
|
+
}), window.addEventListener("mouseup", () => {
|
|
434
|
+
this.isDragging = !1;
|
|
435
|
+
}), e.addEventListener("wheel", (t) => {
|
|
436
|
+
t.preventDefault();
|
|
437
|
+
const s = t.deltaY > 0 ? 0.9 : 1.1;
|
|
438
|
+
this.scale = Math.min(Math.max(this.scale * s, 0.2), 3), this.updateTransform();
|
|
439
|
+
}, { passive: !1 });
|
|
440
|
+
}
|
|
441
|
+
updateTransform() {
|
|
442
|
+
this.g && this.g.setAttribute("transform", `translate(${this.translateX}, ${this.translateY}) scale(${this.scale})`);
|
|
443
|
+
}
|
|
444
|
+
drawGraph(e) {
|
|
445
|
+
if (!this.g) return;
|
|
446
|
+
const t = this.g, s = [], o = [], r = [], c = (n, i) => {
|
|
447
|
+
r[i] = (r[i] || 0) + 1, n.children.forEach((m) => c(m, i + 1));
|
|
448
|
+
};
|
|
449
|
+
c(e, 0);
|
|
450
|
+
const a = Math.max(...r), l = Math.max(1200, a * 180), d = (n, i, m, h) => {
|
|
451
|
+
const u = (m + h) / 2, b = i * 200, y = { id: n.id, label: n.key, type: n.type, x: u, y: b, value: n.value, node: n };
|
|
452
|
+
if (s.push(y), n.children.length > 0) {
|
|
453
|
+
const x = (h - m) / n.children.length;
|
|
454
|
+
n.children.forEach((f, C) => {
|
|
455
|
+
const N = d(f, i + 1, m + C * x, m + (C + 1) * x);
|
|
456
|
+
o.push({ source: { x: u, y: b }, target: N });
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
return { x: u, y: b };
|
|
460
|
+
};
|
|
461
|
+
d(e, 0, -l / 2, l / 2), o.forEach((n) => {
|
|
462
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", "path"), m = n.source.y + (n.target.y - n.source.y) / 2, h = n.target.y - (n.target.y - n.source.y) / 2, u = `M ${n.source.x} ${n.source.y} C ${n.source.x} ${m}, ${n.target.x} ${h}, ${n.target.x} ${n.target.y}`;
|
|
463
|
+
i.setAttribute("d", u), i.setAttribute("stroke", "currentColor"), i.setAttribute("stroke-width", "2"), i.setAttribute("fill", "none"), i.setAttribute("class", "text-tree-border transition-colors duration-300"), t.appendChild(i);
|
|
464
|
+
}), s.forEach((n) => {
|
|
465
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
466
|
+
i.setAttribute("transform", `translate(${n.x}, ${n.y})`), i.setAttribute("class", "cursor-pointer group");
|
|
467
|
+
const m = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
468
|
+
m.setAttribute("r", "24"), m.setAttribute("class", "fill-tree-bg stroke-tree-accent stroke-2 transition-all group-hover:r-28 group-hover:stroke-[3]"), i.appendChild(m);
|
|
469
|
+
const h = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
470
|
+
if (h.setAttribute("y", "45"), h.setAttribute("text-anchor", "middle"), h.setAttribute("class", "text-[12px] fill-tree-text font-bold uppercase pointer-events-none"), h.textContent = String(n.label), i.appendChild(h), this.options.showTypes) {
|
|
471
|
+
const b = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
472
|
+
b.setAttribute("text-anchor", "middle"), b.setAttribute("dy", "5"), b.setAttribute("class", "text-[10px] font-mono font-bold fill-tree-accent pointer-events-none"), b.textContent = n.type.substring(0, 1).toUpperCase(), i.appendChild(b);
|
|
473
|
+
}
|
|
474
|
+
const u = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
475
|
+
u.setAttribute("y", "-35"), u.setAttribute("text-anchor", "middle"), u.setAttribute("class", "text-[10px] fill-tree-text-muted opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none italic"), u.textContent = n.node.isCollapsible ? `${n.node.size} items` : String(n.value), i.appendChild(u), t.appendChild(i);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const R = {
|
|
480
|
+
render(p, e, t = {}) {
|
|
481
|
+
const s = document.querySelector(p);
|
|
482
|
+
if (!s) {
|
|
483
|
+
console.error(`Container ${p} not found`);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const o = {
|
|
487
|
+
...this.currentOptions,
|
|
488
|
+
...t
|
|
489
|
+
};
|
|
490
|
+
this.currentOptions = o, o.colors && Object.entries(o.colors).forEach(([a, l]) => {
|
|
491
|
+
const d = a.startsWith("--") ? a : `--${a}`;
|
|
492
|
+
s.style.setProperty(d, l), p === "#tree-container" && document.documentElement.style.setProperty(d, l);
|
|
493
|
+
}), this.currentData = e;
|
|
494
|
+
const c = new T().parse(e);
|
|
495
|
+
this.currentRenderer = this.createRenderer(o.mode, s, o), this.currentRenderer.render(c);
|
|
496
|
+
},
|
|
497
|
+
createRenderer(p, e, t) {
|
|
498
|
+
switch (p) {
|
|
499
|
+
case "tree":
|
|
500
|
+
return new E(e, t);
|
|
501
|
+
case "table":
|
|
502
|
+
return new k(e, t);
|
|
503
|
+
case "cards":
|
|
504
|
+
return new A(e, t);
|
|
505
|
+
case "timeline":
|
|
506
|
+
return new j(e, t);
|
|
507
|
+
case "graph":
|
|
508
|
+
return new M(e, t);
|
|
509
|
+
default:
|
|
510
|
+
return new E(e, t);
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
currentRenderer: null,
|
|
514
|
+
currentData: null,
|
|
515
|
+
currentOptions: {
|
|
516
|
+
mode: "tree",
|
|
517
|
+
theme: "light",
|
|
518
|
+
showTypes: !0,
|
|
519
|
+
colors: null
|
|
520
|
+
},
|
|
521
|
+
initUI() {
|
|
522
|
+
const p = document.querySelectorAll("aside [data-mode]");
|
|
523
|
+
p.forEach((r) => {
|
|
524
|
+
r.addEventListener("click", () => {
|
|
525
|
+
const c = r.dataset.mode;
|
|
526
|
+
c && (p.forEach((a) => a.classList.remove("bg-tree-accent/10", "text-tree-accent", "font-medium")), p.forEach((a) => a.classList.add("text-tree-text-muted")), r.classList.add("bg-tree-accent/10", "text-tree-accent", "font-medium"), r.classList.remove("text-tree-text-muted"), this.currentOptions.mode = c, this.render("#tree-container", this.currentData));
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
const e = document.querySelector('[data-toggle="dark-mode"]');
|
|
530
|
+
e && e.addEventListener("click", () => {
|
|
531
|
+
const r = document.documentElement.classList.toggle("dark"), c = e.querySelector("div");
|
|
532
|
+
r ? (e.classList.replace("bg-tree-border", "bg-tree-accent"), c == null || c.classList.replace("left-1", "right-1"), document.documentElement.setAttribute("data-theme", "dark")) : (e.classList.replace("bg-tree-accent", "bg-tree-border"), c == null || c.classList.replace("right-1", "left-1"), document.documentElement.removeAttribute("data-theme"));
|
|
533
|
+
});
|
|
534
|
+
const t = document.querySelector('[data-toggle="show-types"]');
|
|
535
|
+
t && t.addEventListener("click", () => {
|
|
536
|
+
this.currentOptions.showTypes = !this.currentOptions.showTypes;
|
|
537
|
+
const r = t.querySelector("div");
|
|
538
|
+
this.currentOptions.showTypes ? (t.classList.replace("bg-tree-border", "bg-tree-accent"), r == null || r.classList.replace("left-1", "right-1")) : (t.classList.replace("bg-tree-accent", "bg-tree-border"), r == null || r.classList.replace("right-1", "left-1")), this.render("#tree-container", this.currentData), v(`Type badges ${this.currentOptions.showTypes ? "enabled" : "disabled"}`);
|
|
539
|
+
});
|
|
540
|
+
const s = document.querySelector('[data-action="import"]');
|
|
541
|
+
if (s) {
|
|
542
|
+
const r = document.createElement("input");
|
|
543
|
+
r.type = "file", r.accept = ".json", r.style.display = "none", document.body.appendChild(r), s.addEventListener("click", () => r.click()), r.addEventListener("change", (c) => {
|
|
544
|
+
var l;
|
|
545
|
+
const a = (l = c.target.files) == null ? void 0 : l[0];
|
|
546
|
+
if (a) {
|
|
547
|
+
const d = new FileReader();
|
|
548
|
+
d.onload = (n) => {
|
|
549
|
+
var i;
|
|
550
|
+
try {
|
|
551
|
+
const m = JSON.parse((i = n.target) == null ? void 0 : i.result);
|
|
552
|
+
this.render("#tree-container", m), v("JSON imported successfully!");
|
|
553
|
+
} catch {
|
|
554
|
+
v("Invalid JSON file", "error");
|
|
555
|
+
}
|
|
556
|
+
}, d.readAsText(a);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
const o = document.querySelector('input[placeholder*="Search"]');
|
|
561
|
+
o && (o.addEventListener("input", (r) => {
|
|
562
|
+
const c = r.target.value;
|
|
563
|
+
this.handleSearch(c);
|
|
564
|
+
}), window.addEventListener("keydown", (r) => {
|
|
565
|
+
(r.ctrlKey || r.metaKey) && r.key === "k" && (r.preventDefault(), o.focus());
|
|
566
|
+
}));
|
|
567
|
+
},
|
|
568
|
+
handleSearch(p) {
|
|
569
|
+
if (!p || p.length < 2) {
|
|
570
|
+
document.querySelectorAll(".highlight-match").forEach((t) => t.classList.remove("highlight-match"));
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
document.querySelectorAll(".json-node-wrapper").forEach((t) => {
|
|
574
|
+
var c;
|
|
575
|
+
const o = (((c = t.textContent) == null ? void 0 : c.toLowerCase()) || "").includes(p.toLowerCase()), r = t.querySelector(".group");
|
|
576
|
+
o && r ? r.classList.add("highlight-match") : r && r.classList.remove("highlight-match");
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
export {
|
|
581
|
+
R as default
|
|
582
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
(function(x,y){typeof exports=="object"&&typeof module<"u"?module.exports=y():typeof define=="function"&&define.amd?define(y):(x=typeof globalThis<"u"?globalThis:x||self,x.EveryJSON=y())})(this,(function(){"use strict";var j=Object.defineProperty;var M=(x,y,v)=>y in x?j(x,y,{enumerable:!0,configurable:!0,writable:!0,value:v}):x[y]=v;var g=(x,y,v)=>M(x,typeof y!="symbol"?y+"":y,v);class x{constructor(){g(this,"idCounter",0)}parse(e){return this.idCounter=0,this.parseNode("root",e,0,"root")}parseNode(e,t,s,o){const r=this.getType(t),l={id:`node-${++this.idCounter}`,key:e,value:t,type:r,depth:s,children:[],isCollapsible:r==="object"||r==="array",path:o};if(r==="object"&&t!==null){const d=Object.keys(t);l.size=d.length,l.children=d.map(n=>{const i=`${o}.${n}`;return this.parseNode(n,t[n],s+1,i)})}else r==="array"&&(l.size=t.length,l.children=t.map((d,n)=>{const i=`${o}[${n}]`;return this.parseNode(n,d,s+1,i)}));return l}getType(e){return e===null?"null":Array.isArray(e)?"array":typeof e=="object"?"object":typeof e}}class y{constructor(e,t){g(this,"container");g(this,"options");this.container=e,this.options=t}render(e){this.container.innerHTML="";const t=this.createNodeElement(e);this.container.appendChild(t)}createNodeElement(e){const t=document.createElement("div");t.className=`json-node-wrapper depth-${e.depth} ml-${e.depth>0?"4":"0"}`;const s=document.createElement("div");s.className="group flex items-center py-1 px-2 rounded hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors cursor-pointer",s.dataset.id=e.id;const o=document.createElement("span");o.className=`w-4 h-4 flex items-center justify-center mr-1 transition-transform duration-200 ${e.isCollapsible?"":"opacity-0"}`,o.innerHTML='<i class="fa-solid fa-chevron-right text-[10px]"></i>',e.isCollapsible&&o.classList.add("rotate-90"),s.appendChild(o);const r=document.createElement("span");r.className="json-key mr-2",r.textContent=`${e.key}:`,s.appendChild(r);const c=document.createElement("span");if(e.isCollapsible){if(this.options.showTypes){const a=document.createElement("span");a.className=`type-badge ml-2 ${this.getTypeColor(e.type)}`,a.textContent=e.type==="array"?`[${e.size}]`:`{${e.size}}`,c.appendChild(a)}}else{const a=document.createElement("span");if(a.className=`json-value-${e.type}`,a.textContent=this.formatValue(e.value,e.type),c.appendChild(a),this.options.showTypes){const l=document.createElement("span");l.className=`type-badge ml-2 opacity-0 group-hover:opacity-100 transition-opacity ${this.getTypeColor(e.type)}`,l.textContent=e.type,c.appendChild(l)}}if(s.appendChild(c),t.appendChild(s),e.children.length>0){const a=document.createElement("div");a.className="children-container ml-4 border-l border-gray-100 dark:border-gray-800",e.children.forEach(l=>{a.appendChild(this.createNodeElement(l))}),t.appendChild(a),s.addEventListener("click",l=>{l.stopPropagation();const d=o.classList.toggle("rotate-90");a.classList.toggle("hidden",!d)})}return t}formatValue(e,t){return t==="string"?`"${e}"`:t==="null"?"null":String(e)}getTypeColor(e){switch(e){case"string":return"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400";case"number":return"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400";case"boolean":return"bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400";case"object":return"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400";case"array":return"bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-400";default:return"bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400"}}}class v{constructor(e,t){g(this,"container");g(this,"options");this.container=e,this.options=t}render(e){this.container.innerHTML="";const t=document.createElement("div");t.className="w-full overflow-x-auto";const s=this.createTable(e);t.appendChild(s),this.container.appendChild(t),this.options}createTable(e){return e.type==="array"&&e.children.length>0&&e.children[0].type==="object"?this.renderObjectArray(e):e.type==="array"?this.renderSimpleArray(e):e.type==="object"?this.renderObjectRows(e):this.renderSimple(e)}renderObjectArray(e){const t=document.createElement("table");t.className="w-full text-sm text-left border-collapse";const s=new Set;e.children.forEach(d=>{d.children.forEach(n=>{s.add(String(n.key))})});const o=Array.from(s),r=document.createElement("thead");r.className="bg-tree-bg-alt border-b border-tree-border sticky top-0";const c=document.createElement("tr"),a=document.createElement("th");a.className="px-4 py-3 font-bold text-tree-text-muted uppercase tracking-wider w-10",a.textContent="#",c.appendChild(a),o.forEach(d=>{const n=document.createElement("th");n.className="px-4 py-3 font-bold text-tree-text uppercase tracking-wider text-xs",n.textContent=d,c.appendChild(n)}),r.appendChild(c),t.appendChild(r);const l=document.createElement("tbody");return e.children.forEach((d,n)=>{const i=document.createElement("tr");i.className="border-b border-tree-border hover:bg-tree-bg-alt transition-colors";const p=document.createElement("td");p.className="px-4 py-3 text-tree-text-muted font-mono",p.textContent=String(n),i.appendChild(p),o.forEach(h=>{const u=document.createElement("td");u.className="px-4 py-3 align-top";const b=d.children.find(f=>String(f.key)===h);b?u.appendChild(this.formatCellValue(b)):(u.className+=" text-tree-text-muted italic opacity-50",u.textContent="undefined"),i.appendChild(u)}),l.appendChild(i)}),t.appendChild(l),t}renderObjectRows(e){const t=document.createElement("table");t.className="w-full text-sm text-left border-collapse";const s=document.createElement("tbody");return e.children.forEach(o=>{const r=document.createElement("tr");r.className="border-b border-tree-border hover:bg-tree-bg-alt transition-colors";const c=document.createElement("td");c.className="px-4 py-3 font-semibold text-tree-text bg-tree-bg-alt/30 w-1/4",c.textContent=String(o.key),r.appendChild(c);const a=document.createElement("td");a.className="px-4 py-3",a.appendChild(this.formatCellValue(o)),r.appendChild(a),s.appendChild(r)}),t.appendChild(s),t}renderSimpleArray(e){const t=document.createElement("table");t.className="w-full text-sm text-left border-collapse";const s=document.createElement("tbody");return e.children.forEach((o,r)=>{const c=document.createElement("tr");c.className="border-b border-tree-border";const a=document.createElement("td");a.className="px-4 py-2 text-tree-text-muted font-mono w-10",a.textContent=`[${r}]`,c.appendChild(a);const l=document.createElement("td");l.className="px-4 py-2",l.appendChild(this.formatCellValue(o)),c.appendChild(l),s.appendChild(c)}),t.appendChild(s),t}renderSimple(e){const t=document.createElement("div");return t.className="p-10 flex flex-col items-center justify-center text-tree-text-muted",t.innerHTML=`<span class="text-4xl mb-4 opacity-20"><i class="fa-solid fa-file-lines"></i></span> <p>This data type (${e.type}) is better viewed in Tree mode.</p>`,t}formatCellValue(e){const t=document.createElement("span");if(e.isCollapsible){t.className="text-tree-text-muted italic text-xs flex flex-col gap-1";const s=document.createElement("div");s.className="font-semibold opacity-70 mb-1",s.textContent=e.type==="array"?`Array(${e.size})`:`Object(${e.size})`,t.appendChild(s);const o=document.createElement("div");o.className="pl-2 border-l border-tree-border text-[10px] space-y-0.5 opacity-80";const r=5;if(e.children.slice(0,r).forEach(a=>{const l=document.createElement("div");l.className="truncate max-w-[200px]";let d="";if(a.isCollapsible){const n=a.children.slice(0,2).map(p=>a.type==="object"?`${p.key}:${this.getShortValue(p)}`:this.getShortValue(p)).join(", "),i=a.size||0;d=a.type==="array"?`[${n}${i>2?"...":""}]`:`{${n}${i>2?"...":""}}`}else d=this.getShortValue(a);e.type==="object"?l.innerHTML=`<span class="font-bold mr-1">${a.key}:</span> ${d}`:l.textContent=d,o.appendChild(l)}),e.children.length>r){const a=document.createElement("div");a.className="italic opacity-50",a.textContent=`+ ${e.children.length-r} more...`,o.appendChild(a)}t.appendChild(o)}else t.className=`json-value-${e.type}`,t.textContent=e.type==="string"?`"${e.value}"`:String(e.value);return t}getShortValue(e){if(e.isCollapsible)return e.type==="array"?"[...]":"{...}";const t=String(e.value);return t.length>20?t.substring(0,17)+"...":t}}function $(m){if(!m.isCollapsible)return m.value;if(m.type==="array")return m.children.map(t=>$(t));const e={};return m.children.forEach(t=>{e[t.key]=$(t)}),e}function w(m,e="success"){let t=document.getElementById("toast-container");t||(t=document.createElement("div"),t.id="toast-container",t.className="fixed bottom-6 right-6 z-50 flex flex-col gap-2 pointer-events-none",document.body.appendChild(t));const s=document.createElement("div");s.className=`
|
|
2
|
+
min-w-[200px] px-4 py-3 rounded-lg shadow-lg text-sm font-medium
|
|
3
|
+
flex items-center space-x-3 transform translate-y-2 opacity-0 transition-all duration-300 pointer-events-auto
|
|
4
|
+
${e==="success"?"bg-green-600 text-white":""}
|
|
5
|
+
${e==="error"?"bg-red-600 text-white":""}
|
|
6
|
+
${e==="info"?"bg-tree-accent text-white":""}
|
|
7
|
+
`;const o=document.createElement("span");o.innerHTML=e==="success"?'<i class="fa-solid fa-circle-check"></i>':e==="error"?'<i class="fa-solid fa-circle-exclamation"></i>':'<i class="fa-solid fa-circle-info"></i>',s.appendChild(o);const r=document.createElement("span");r.textContent=m,s.appendChild(r),t.appendChild(s),requestAnimationFrame(()=>{s.classList.remove("translate-y-2","opacity-0")}),setTimeout(()=>{s.classList.add("translate-y-2","opacity-0"),setTimeout(()=>s.remove(),300)},3e3)}async function S(m){try{return await navigator.clipboard.writeText(m),!0}catch(e){return console.error("Failed to copy text: ",e),!1}}class T{constructor(e,t){g(this,"container");g(this,"options");this.container=e,this.options=t}render(e){this.container.innerHTML="";const t=document.createElement("div");t.className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-2",e.children.forEach(s=>{t.appendChild(this.createCard(s))}),this.container.appendChild(t)}createCard(e){const t=document.createElement("div");t.className="bg-tree-bg dark:bg-tree-bg-alt border border-tree-border rounded-2xl shadow-sm hover:shadow-md transition-all flex flex-col overflow-hidden group";const s=document.createElement("div");s.className="px-5 py-4 border-b border-tree-border flex items-center justify-between bg-tree-bg-alt/30";const o=document.createElement("h3");if(o.className="font-bold text-tree-text truncate",o.textContent=String(e.key).toUpperCase(),s.appendChild(o),this.options.showTypes){const n=document.createElement("span");n.className="type-badge text-[10px]",n.textContent=e.type,s.appendChild(n)}t.appendChild(s);const r=document.createElement("div");if(r.className="p-5 flex-1 overflow-y-auto max-h-[300px] custom-scrollbar",e.isCollapsible){const n=document.createElement("div");n.className="space-y-3",e.children.forEach(i=>{const p=document.createElement("div");p.className="flex flex-col gap-1";const h=document.createElement("div");h.className="flex items-center justify-between";const u=document.createElement("span");if(u.className="text-xs font-semibold text-tree-text-muted",u.textContent=String(i.key),h.appendChild(u),this.options.showTypes&&i.isCollapsible){const f=document.createElement("span");f.className="text-[9px] px-1 bg-tree-bg-alt rounded border border-tree-border text-tree-text-muted",f.textContent=i.type==="array"?`[${i.size}]`:`{${i.size}}`,h.appendChild(f)}p.appendChild(h);const b=document.createElement("div");if(b.className="text-sm text-tree-text break-words",i.isCollapsible){b.className+=" italic text-xs opacity-70 bg-tree-bg-alt/50 p-2 rounded border border-tree-border/50 mt-1";const f=i.children.slice(0,3).map(C=>{const E=C.isCollapsible?C.type==="array"?"[...]":"{...}":String(C.value),N=E.length>20?E.substring(0,17)+"...":E;return i.type==="object"?`<span class="font-bold opacity-60">${C.key}:</span> ${N}`:N});b.innerHTML=f.join("<br>"),i.children.length>3&&(b.innerHTML+=`<div class="mt-1 opacity-40 text-[10px]">+ ${i.children.length-3} more</div>`)}else{const f=document.createElement("span");f.className=`json-value-${i.type}`,f.textContent=i.type==="string"?`"${i.value}"`:String(i.value),b.appendChild(f)}p.appendChild(b),n.appendChild(p)}),r.appendChild(n)}else{const n=document.createElement("div");n.className=`text-lg font-mono json-value-${e.type} break-all`,n.textContent=String(e.value),r.appendChild(n)}t.appendChild(r);const c=document.createElement("div");c.className="px-5 py-3 border-t border-tree-border bg-tree-bg-alt/10 flex items-center justify-between opacity-0 group-hover:opacity-100 transition-opacity";const a=document.createElement("span");a.className="text-[10px] text-tree-text-muted",a.textContent=e.isCollapsible?`${e.size} properties`:"primitive",c.appendChild(a);const l=document.createElement("div");l.className="flex items-center space-x-2";const d=document.createElement("button");return d.className="p-1.5 rounded-lg hover:bg-tree-bg-alt text-tree-text-muted hover:text-tree-accent transition-colors",d.innerHTML='<i class="fa-regular fa-copy"></i>',d.title="Copy as JSON",d.onclick=async()=>{const n=$(e);await S(JSON.stringify(n,null,2))?w("JSON copied to clipboard!"):w("Failed to copy JSON","error")},l.appendChild(d),c.appendChild(l),t.appendChild(c),t}}class k{constructor(e,t={}){g(this,"container");g(this,"options");this.container=e,this.options=t}render(e){this.container.innerHTML="";const t=document.createElement("div");t.className="relative pl-8 pr-4 py-8";const s=document.createElement("div");s.className="absolute left-4 top-0 bottom-0 w-0.5 bg-tree-border",t.appendChild(s),e.type==="array"?e.children.forEach(o=>{t.appendChild(this.createEventItem(o))}):e.children.forEach(o=>{t.appendChild(this.createEventItem(o))}),this.container.appendChild(t)}createEventItem(e){const t=document.createElement("div");t.className="relative mb-10 last:mb-0 group";const s=document.createElement("div");s.className="absolute -left-[22px] top-1.5 w-3 h-3 rounded-full bg-tree-accent border-2 border-tree-bg z-10",t.appendChild(s);const o=document.createElement("div");o.className="bg-tree-bg dark:bg-tree-bg-alt border border-tree-border rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow";const r=document.createElement("div");r.className="flex items-center justify-between mb-3";const c=document.createElement("span");if(c.className="text-xs font-bold text-tree-text tracking-wide uppercase",c.textContent=String(e.key),r.appendChild(c),this.options.showTypes){const l=document.createElement("span");l.className="type-badge",l.textContent=e.type,r.appendChild(l)}o.appendChild(r);const a=document.createElement("div");if(e.isCollapsible){a.className="space-y-2";const l=document.createElement("div");l.className="text-sm text-tree-text-muted italic opacity-60 mb-2",l.textContent=e.type==="array"?`Array with ${e.size} items`:`Object with ${e.size} properties`,a.appendChild(l);const d=document.createElement("div");if(d.className="grid grid-cols-1 sm:grid-cols-2 gap-2 mt-2",e.children.slice(0,6).forEach(n=>{const i=document.createElement("div");i.className="flex items-baseline text-xs truncate";let p="";if(n.isCollapsible){const h=n.children.slice(0,2).map(u=>n.type==="object"?`${u.key}:${this.getShortValue(u)}`:this.getShortValue(u)).join(", ");p=n.type==="array"?`[${h}...]`:`{${h}...}`}else p=this.getShortValue(n);e.type==="object"?i.innerHTML=`<span class="font-bold mr-1 text-tree-text-muted">${n.key}:</span> <span class="json-value-${n.type}">${p}</span>`:i.innerHTML=`<span class="json-value-${n.type}">${p}</span>`,d.appendChild(i)}),e.children.length>6){const n=document.createElement("div");n.className="text-[10px] text-tree-text-muted mt-1 opacity-50",n.textContent=`+ ${e.children.length-6} more items...`,d.appendChild(n)}a.appendChild(d)}else a.className=`text-sm json-value-${e.type} font-medium`,a.textContent=e.type==="string"?`"${e.value}"`:String(e.value);return o.appendChild(a),t.appendChild(o),t}getShortValue(e){if(e.isCollapsible)return e.type==="array"?"[...]":"{...}";const t=String(e.value);return t.length>25?t.substring(0,22)+"...":t}}class L{constructor(e,t={}){g(this,"container");g(this,"options");g(this,"svg",null);g(this,"g",null);g(this,"scale",.8);g(this,"translateX",400);g(this,"translateY",100);g(this,"isDragging",!1);g(this,"lastMouseX",0);g(this,"lastMouseY",0);this.container=e,this.options=t}render(e){this.container.innerHTML="";const t=document.createElement("div");t.className="flex flex-col w-full h-[600px] min-h-[600px] relative overflow-hidden bg-tree-bg-alt rounded-2xl border border-tree-border";const s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width","100%"),s.setAttribute("height","100%"),s.setAttribute("class","flex-1 w-full h-full cursor-grab active:cursor-grabbing outline-none"),s.setAttribute("tabindex","0"),this.svg=s;const o=document.createElementNS("http://www.w3.org/2000/svg","defs");o.innerHTML=`
|
|
8
|
+
<pattern id="graph-grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
9
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="currentColor" stroke-width="0.5" class="text-tree-text/5" />
|
|
10
|
+
</pattern>
|
|
11
|
+
`,s.appendChild(o);const r=document.createElementNS("http://www.w3.org/2000/svg","rect");r.setAttribute("width","200%"),r.setAttribute("height","200%"),r.setAttribute("x","-50%"),r.setAttribute("y","-50%"),r.setAttribute("fill","url(#graph-grid)"),s.appendChild(r);const c=document.createElementNS("http://www.w3.org/2000/svg","g");c.id="graph-content",this.g=c,s.appendChild(c),t.appendChild(s),this.container.appendChild(t),this.initInteractivity(),this.drawGraph(e),this.autoCenter(),this.updateTransform()}autoCenter(){if(!this.container||!this.g)return;const e=this.container.getBoundingClientRect();this.translateX=e.width/2,this.translateY=100,this.scale=.6}initInteractivity(){if(!this.svg)return;const e=this.svg;e.addEventListener("mousedown",t=>{this.isDragging=!0,this.lastMouseX=t.clientX,this.lastMouseY=t.clientY}),window.addEventListener("mousemove",t=>{if(!this.isDragging)return;const s=t.clientX-this.lastMouseX,o=t.clientY-this.lastMouseY;this.translateX+=s,this.translateY+=o,this.lastMouseX=t.clientX,this.lastMouseY=t.clientY,this.updateTransform()}),window.addEventListener("mouseup",()=>{this.isDragging=!1}),e.addEventListener("wheel",t=>{t.preventDefault();const s=t.deltaY>0?.9:1.1;this.scale=Math.min(Math.max(this.scale*s,.2),3),this.updateTransform()},{passive:!1})}updateTransform(){this.g&&this.g.setAttribute("transform",`translate(${this.translateX}, ${this.translateY}) scale(${this.scale})`)}drawGraph(e){if(!this.g)return;const t=this.g,s=[],o=[],r=[],c=(n,i)=>{r[i]=(r[i]||0)+1,n.children.forEach(p=>c(p,i+1))};c(e,0);const a=Math.max(...r),l=Math.max(1200,a*180),d=(n,i,p,h)=>{const u=(p+h)/2,b=i*200,f={id:n.id,label:n.key,type:n.type,x:u,y:b,value:n.value,node:n};if(s.push(f),n.children.length>0){const C=(h-p)/n.children.length;n.children.forEach((E,N)=>{const A=d(E,i+1,p+N*C,p+(N+1)*C);o.push({source:{x:u,y:b},target:A})})}return{x:u,y:b}};d(e,0,-l/2,l/2),o.forEach(n=>{const i=document.createElementNS("http://www.w3.org/2000/svg","path"),p=n.source.y+(n.target.y-n.source.y)/2,h=n.target.y-(n.target.y-n.source.y)/2,u=`M ${n.source.x} ${n.source.y} C ${n.source.x} ${p}, ${n.target.x} ${h}, ${n.target.x} ${n.target.y}`;i.setAttribute("d",u),i.setAttribute("stroke","currentColor"),i.setAttribute("stroke-width","2"),i.setAttribute("fill","none"),i.setAttribute("class","text-tree-border transition-colors duration-300"),t.appendChild(i)}),s.forEach(n=>{const i=document.createElementNS("http://www.w3.org/2000/svg","g");i.setAttribute("transform",`translate(${n.x}, ${n.y})`),i.setAttribute("class","cursor-pointer group");const p=document.createElementNS("http://www.w3.org/2000/svg","circle");p.setAttribute("r","24"),p.setAttribute("class","fill-tree-bg stroke-tree-accent stroke-2 transition-all group-hover:r-28 group-hover:stroke-[3]"),i.appendChild(p);const h=document.createElementNS("http://www.w3.org/2000/svg","text");if(h.setAttribute("y","45"),h.setAttribute("text-anchor","middle"),h.setAttribute("class","text-[12px] fill-tree-text font-bold uppercase pointer-events-none"),h.textContent=String(n.label),i.appendChild(h),this.options.showTypes){const b=document.createElementNS("http://www.w3.org/2000/svg","text");b.setAttribute("text-anchor","middle"),b.setAttribute("dy","5"),b.setAttribute("class","text-[10px] font-mono font-bold fill-tree-accent pointer-events-none"),b.textContent=n.type.substring(0,1).toUpperCase(),i.appendChild(b)}const u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("y","-35"),u.setAttribute("text-anchor","middle"),u.setAttribute("class","text-[10px] fill-tree-text-muted opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none italic"),u.textContent=n.node.isCollapsible?`${n.node.size} items`:String(n.value),i.appendChild(u),t.appendChild(i)})}}return{render(m,e,t={}){const s=document.querySelector(m);if(!s){console.error(`Container ${m} not found`);return}const o={...this.currentOptions,...t};this.currentOptions=o,o.colors&&Object.entries(o.colors).forEach(([a,l])=>{const d=a.startsWith("--")?a:`--${a}`;s.style.setProperty(d,l),m==="#tree-container"&&document.documentElement.style.setProperty(d,l)}),this.currentData=e;const c=new x().parse(e);this.currentRenderer=this.createRenderer(o.mode,s,o),this.currentRenderer.render(c)},createRenderer(m,e,t){switch(m){case"tree":return new y(e,t);case"table":return new v(e,t);case"cards":return new T(e,t);case"timeline":return new k(e,t);case"graph":return new L(e,t);default:return new y(e,t)}},currentRenderer:null,currentData:null,currentOptions:{mode:"tree",theme:"light",showTypes:!0,colors:null},initUI(){const m=document.querySelectorAll("aside [data-mode]");m.forEach(r=>{r.addEventListener("click",()=>{const c=r.dataset.mode;c&&(m.forEach(a=>a.classList.remove("bg-tree-accent/10","text-tree-accent","font-medium")),m.forEach(a=>a.classList.add("text-tree-text-muted")),r.classList.add("bg-tree-accent/10","text-tree-accent","font-medium"),r.classList.remove("text-tree-text-muted"),this.currentOptions.mode=c,this.render("#tree-container",this.currentData))})});const e=document.querySelector('[data-toggle="dark-mode"]');e&&e.addEventListener("click",()=>{const r=document.documentElement.classList.toggle("dark"),c=e.querySelector("div");r?(e.classList.replace("bg-tree-border","bg-tree-accent"),c==null||c.classList.replace("left-1","right-1"),document.documentElement.setAttribute("data-theme","dark")):(e.classList.replace("bg-tree-accent","bg-tree-border"),c==null||c.classList.replace("right-1","left-1"),document.documentElement.removeAttribute("data-theme"))});const t=document.querySelector('[data-toggle="show-types"]');t&&t.addEventListener("click",()=>{this.currentOptions.showTypes=!this.currentOptions.showTypes;const r=t.querySelector("div");this.currentOptions.showTypes?(t.classList.replace("bg-tree-border","bg-tree-accent"),r==null||r.classList.replace("left-1","right-1")):(t.classList.replace("bg-tree-accent","bg-tree-border"),r==null||r.classList.replace("right-1","left-1")),this.render("#tree-container",this.currentData),w(`Type badges ${this.currentOptions.showTypes?"enabled":"disabled"}`)});const s=document.querySelector('[data-action="import"]');if(s){const r=document.createElement("input");r.type="file",r.accept=".json",r.style.display="none",document.body.appendChild(r),s.addEventListener("click",()=>r.click()),r.addEventListener("change",c=>{var l;const a=(l=c.target.files)==null?void 0:l[0];if(a){const d=new FileReader;d.onload=n=>{var i;try{const p=JSON.parse((i=n.target)==null?void 0:i.result);this.render("#tree-container",p),w("JSON imported successfully!")}catch{w("Invalid JSON file","error")}},d.readAsText(a)}})}const o=document.querySelector('input[placeholder*="Search"]');o&&(o.addEventListener("input",r=>{const c=r.target.value;this.handleSearch(c)}),window.addEventListener("keydown",r=>{(r.ctrlKey||r.metaKey)&&r.key==="k"&&(r.preventDefault(),o.focus())}))},handleSearch(m){if(!m||m.length<2){document.querySelectorAll(".highlight-match").forEach(t=>t.classList.remove("highlight-match"));return}document.querySelectorAll(".json-node-wrapper").forEach(t=>{var c;const o=(((c=t.textContent)==null?void 0:c.toLowerCase())||"").includes(m.toLowerCase()),r=t.querySelector(".group");o&&r?r.classList.add("highlight-match"):r&&r.classList.remove("highlight-match")})}}}));
|