@brightsideoy/kama 1.0.0-alpha.19 → 1.0.0-alpha.20
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/content/definitions/blocks/node-list.yaml +6 -0
- package/dist/assets/{AssetEditor-CY9SjGaJ.js → AssetEditor-Dt1zCR7_.js} +1 -1
- package/dist/assets/{CmsHelp-DJSdFYVH.js → CmsHelp-DyPJLGGi.js} +1 -1
- package/dist/assets/{CmsPublisher-DBcCz-AD.js → CmsPublisher-DNLwjirk.js} +1 -1
- package/dist/assets/{EditorSplitPreview-wCnwVnnb.js → EditorSplitPreview-Cp2x0O_P.js} +1 -1
- package/dist/assets/{NodeEditor-D3tAGViP.js → NodeEditor-CiXQKXK1.js} +5 -5
- package/dist/assets/NodeEditor-pZI3gu4a.css +1 -0
- package/dist/assets/{TrashWorkspace--uFsWt53.js → TrashWorkspace-DgIg1v6t.js} +1 -1
- package/dist/assets/{index-BIES-eB_.js → index-DQ6_RmCI.js} +3 -3
- package/dist/assets/{plus-mqZr4I1D.js → plus-FQRsZBoJ.js} +1 -1
- package/dist/assets/schema-helpers-DvficKko.js +1 -0
- package/dist/assets/{useNodes-W5j_uxdQ.js → useNodes-D2-VxsxR.js} +1 -1
- package/dist/{dist-Bta0OpXl.js → dist-D_Q1y4Kh.js} +184 -119
- package/dist/index.html +4 -4
- package/dist/index.js +184 -119
- package/dist/schema-compiler.js +1 -1
- package/package.json +1 -1
- package/dist/assets/NodeEditor-DlfAHtiG.css +0 -1
- package/dist/assets/schema-helpers-1UXlO0Ye.js +0 -1
|
@@ -21117,6 +21117,13 @@ var Tb = /* @__PURE__ */ o({
|
|
|
21117
21117
|
public: !0,
|
|
21118
21118
|
allowedLinkTypes: ["tree", "node"],
|
|
21119
21119
|
rules: {}
|
|
21120
|
+
},
|
|
21121
|
+
sortBy: {
|
|
21122
|
+
label: "Sort by",
|
|
21123
|
+
type: "node-sort",
|
|
21124
|
+
default: "updatedAt_desc",
|
|
21125
|
+
public: !0,
|
|
21126
|
+
rules: {}
|
|
21120
21127
|
}
|
|
21121
21128
|
},
|
|
21122
21129
|
tabs: { access: {
|
|
@@ -22086,7 +22093,8 @@ var Tb = /* @__PURE__ */ o({
|
|
|
22086
22093
|
nodeTemplate: null,
|
|
22087
22094
|
treeTemplate: null,
|
|
22088
22095
|
channelTemplate: null,
|
|
22089
|
-
userTemplate: null
|
|
22096
|
+
userTemplate: null,
|
|
22097
|
+
treeExposedFields: ["summary"]
|
|
22090
22098
|
}, Db = Eb, Ob = {
|
|
22091
22099
|
content_schemas: "\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n type TEXT UNIQUE NOT NULL,\n schemaJson TEXT NOT NULL,\n isSystem INTEGER DEFAULT 1,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
|
|
22092
22100
|
users: "\n id TEXT PRIMARY KEY,\n email UNIQUE NOT NULL,\n name TEXT NOT NULL,\n globalRole TEXT DEFAULT 'editor',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
|
|
@@ -23450,7 +23458,8 @@ function px(e) {
|
|
|
23450
23458
|
nodeLayouts: e.nodeLayouts || {},
|
|
23451
23459
|
blockLayouts: e.blockLayouts || {},
|
|
23452
23460
|
channels: e.channels || {},
|
|
23453
|
-
taxonomies: e.taxonomies || {}
|
|
23461
|
+
taxonomies: e.taxonomies || {},
|
|
23462
|
+
treeExposedFields: e.treeExposedFields || ["summary"]
|
|
23454
23463
|
} : {
|
|
23455
23464
|
nodes: {},
|
|
23456
23465
|
trees: {},
|
|
@@ -23458,7 +23467,8 @@ function px(e) {
|
|
|
23458
23467
|
nodeLayouts: {},
|
|
23459
23468
|
blockLayouts: {},
|
|
23460
23469
|
channels: {},
|
|
23461
|
-
taxonomies: {}
|
|
23470
|
+
taxonomies: {},
|
|
23471
|
+
treeExposedFields: ["summary"]
|
|
23462
23472
|
};
|
|
23463
23473
|
}
|
|
23464
23474
|
var mx = class {
|
|
@@ -25260,7 +25270,8 @@ function Qx(e) {
|
|
|
25260
25270
|
nodeTemplate: null,
|
|
25261
25271
|
treeTemplate: null,
|
|
25262
25272
|
channelTemplate: null,
|
|
25263
|
-
userTemplate: null
|
|
25273
|
+
userTemplate: null,
|
|
25274
|
+
treeExposedFields: ["summary"]
|
|
25264
25275
|
};
|
|
25265
25276
|
let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, te = Object.keys(u).length > 0 ? u : S, O = m?.fields || {}, k = {
|
|
25266
25277
|
...p,
|
|
@@ -25533,7 +25544,15 @@ function Qx(e) {
|
|
|
25533
25544
|
let fe = _ ? {
|
|
25534
25545
|
..._,
|
|
25535
25546
|
fields: de
|
|
25536
|
-
} : null;
|
|
25547
|
+
} : null, pe = /* @__PURE__ */ new Set(["summary"]);
|
|
25548
|
+
for (let e of Object.values(k)) {
|
|
25549
|
+
let t = e.fields || e;
|
|
25550
|
+
for (let [e, n] of Object.entries(t || {})) n && typeof n == "object" && n.inTree && pe.add(e);
|
|
25551
|
+
}
|
|
25552
|
+
for (let e of Object.values(j)) {
|
|
25553
|
+
for (let [t, n] of Object.entries(e.fields || {})) n?.inTree && pe.add(t);
|
|
25554
|
+
for (let t of Object.values(e.tabs || {})) for (let [e, n] of Object.entries(t.fields || {})) n?.inTree && pe.add(e);
|
|
25555
|
+
}
|
|
25537
25556
|
return {
|
|
25538
25557
|
nodes: j,
|
|
25539
25558
|
trees: re,
|
|
@@ -25546,7 +25565,8 @@ function Qx(e) {
|
|
|
25546
25565
|
nodeTemplate: m || null,
|
|
25547
25566
|
treeTemplate: h || null,
|
|
25548
25567
|
channelTemplate: ue,
|
|
25549
|
-
userTemplate: fe
|
|
25568
|
+
userTemplate: fe,
|
|
25569
|
+
treeExposedFields: Array.from(pe)
|
|
25550
25570
|
};
|
|
25551
25571
|
}
|
|
25552
25572
|
var $x = new e(), eS = (e) => {
|
|
@@ -26035,21 +26055,30 @@ function fS(e, t) {
|
|
|
26035
26055
|
}
|
|
26036
26056
|
return !0;
|
|
26037
26057
|
}
|
|
26038
|
-
async function pS(e, t, n, r, i) {
|
|
26039
|
-
let
|
|
26040
|
-
await Promise.all(
|
|
26041
|
-
let
|
|
26042
|
-
|
|
26043
|
-
|
|
26044
|
-
|
|
26045
|
-
|
|
26046
|
-
|
|
26058
|
+
async function pS(e, t, n, r, i, a) {
|
|
26059
|
+
let o = t.filter((e) => e.componentId === "content-feed" || e.componentId === "article-list" || e.componentId === "nodeList" || e.componentId === "node-list");
|
|
26060
|
+
await Promise.all(o.map(async (t) => {
|
|
26061
|
+
let o = t.data || {}, s = o.nodeType || ["article"], c = (Array.isArray(s) ? s : String(s).split(",")).map((e) => String(e).trim()).filter(Boolean), l = {};
|
|
26062
|
+
if (a) for (let e of c) {
|
|
26063
|
+
l[e] = [];
|
|
26064
|
+
let t = a.nodes?.[e] || {}, n = { ...t.fields || {} };
|
|
26065
|
+
t.tabs && Object.values(t.tabs).forEach((e) => {
|
|
26066
|
+
Object.assign(n, e.fields || {});
|
|
26067
|
+
});
|
|
26068
|
+
for (let [t, r] of Object.entries(n)) (r.showInList || r.showInLists) && l[e].push(t);
|
|
26069
|
+
}
|
|
26070
|
+
let u = Number(o.limit) || 12, d = Number(o.offset) || 0, f = String(o.sortBy || "updatedAt_desc"), [p, m] = f.includes("_") ? f.split("_") : [f, "desc"], h = String(m).toLowerCase() === "asc" ? "ASC" : "DESC", g = String(p).replace(/[^a-zA-Z0-9_]/g, ""), _ = new URLSearchParams();
|
|
26071
|
+
_.set("nodeType", c.join(",")), _.set("limit", u.toString()), _.set("offset", (d + u).toString()), _.set("sortBy", f), n && n !== "all" && _.set("channelId", String(n));
|
|
26072
|
+
let v = `FROM content_nodes WHERE contentType IN (${c.map(() => "?").join(",")}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, y = [...c];
|
|
26073
|
+
n && n !== "all" && (v += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", y.push(Number(n) || n));
|
|
26074
|
+
let b = (/* @__PURE__ */ new Date()).toISOString();
|
|
26075
|
+
v += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", y.push(b), v += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", y.push(b);
|
|
26047
26076
|
for (let e of [
|
|
26048
26077
|
"authors",
|
|
26049
26078
|
"categories",
|
|
26050
26079
|
"tags"
|
|
26051
|
-
]) if (
|
|
26052
|
-
let t = (Array.isArray(
|
|
26080
|
+
]) if (o[e]) {
|
|
26081
|
+
let t = (Array.isArray(o[e]) ? o[e] : [o[e]]).map((e) => {
|
|
26053
26082
|
if (typeof e == "object" && e) {
|
|
26054
26083
|
if (e.key) return String(e.key);
|
|
26055
26084
|
if (e.nodeId) return String(e.nodeId);
|
|
@@ -26058,93 +26087,100 @@ async function pS(e, t, n, r, i) {
|
|
|
26058
26087
|
return String(e);
|
|
26059
26088
|
}).filter((e) => e !== "undefined" && e !== "null" && e !== "");
|
|
26060
26089
|
if (t.length > 0) {
|
|
26061
|
-
|
|
26090
|
+
_.set(e, t.join(","));
|
|
26062
26091
|
let n = t.map(() => "?").join(",");
|
|
26063
|
-
|
|
26092
|
+
v += e === "authors" ? ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${n}))` : ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${n}))`, y.push(e, ...t);
|
|
26064
26093
|
}
|
|
26065
26094
|
}
|
|
26066
|
-
let
|
|
26067
|
-
|
|
26068
|
-
let
|
|
26069
|
-
|
|
26095
|
+
let x = `ORDER BY updatedAt ${h}`;
|
|
26096
|
+
g === "createdAt" || g === "published" ? x = `ORDER BY createdAt ${h}` : g === "title" ? x = `ORDER BY LOWER(title) ${h}` : g !== "updatedAt" && g !== "" && (x = `ORDER BY json_extract(dataJson, '$.${g}') ${h}`);
|
|
26097
|
+
let S = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${v} ${x} LIMIT ? OFFSET ?`;
|
|
26098
|
+
y.push(u, d);
|
|
26070
26099
|
try {
|
|
26071
|
-
let n = await e.prepare(
|
|
26072
|
-
t.data.initialItems =
|
|
26100
|
+
let n = await e.prepare(S).all(...y), s = Array.isArray(n) ? n : n?.results || [];
|
|
26101
|
+
t.data.initialItems = s.map((e) => {
|
|
26073
26102
|
let t = {};
|
|
26074
26103
|
if (e.dataJson) try {
|
|
26075
26104
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
|
|
26076
26105
|
} catch {}
|
|
26077
|
-
|
|
26106
|
+
i && dS(t.startShowingAt, t.stopShowingAt, i);
|
|
26107
|
+
let n = {};
|
|
26108
|
+
if (a) {
|
|
26109
|
+
let r = l[e.contentType || "article"] || [];
|
|
26110
|
+
for (let e of r) t[e] !== void 0 && (n[e] = t[e]);
|
|
26111
|
+
}
|
|
26112
|
+
return {
|
|
26078
26113
|
id: e.id,
|
|
26079
26114
|
title: e.title,
|
|
26080
26115
|
slug: e.slug,
|
|
26081
26116
|
language: e.language?.trim() || r || null,
|
|
26082
26117
|
createdAt: e.createdAt,
|
|
26083
26118
|
updatedAt: e.updatedAt,
|
|
26119
|
+
...n,
|
|
26084
26120
|
excerpt: t.excerpt || "",
|
|
26085
26121
|
image: t.image || t.coverImage || null,
|
|
26086
26122
|
author: t.author || null
|
|
26087
26123
|
};
|
|
26088
|
-
}),
|
|
26124
|
+
}), o.disablePagination !== !0 && o.disablePagination !== "1" && s.length === u ? t.data.loadMoreUrl = `/api/v1/nodes?${_.toString()}` : t.data.loadMoreUrl = null;
|
|
26089
26125
|
} catch (e) {
|
|
26090
26126
|
console.error("[CMS Hydration] Failed to hydrate content feed block", e), t.data.initialItems = [], t.data.loadMoreUrl = null;
|
|
26091
26127
|
}
|
|
26092
26128
|
}));
|
|
26093
26129
|
}
|
|
26094
|
-
async function mS(e, t, n, r, i, a = !1,
|
|
26130
|
+
async function mS(e, t, n, r, i, a, o = !1, s, c) {
|
|
26095
26131
|
if (!t) return { blocks: [] };
|
|
26096
|
-
let
|
|
26097
|
-
if (!
|
|
26098
|
-
let
|
|
26099
|
-
if (
|
|
26100
|
-
let
|
|
26101
|
-
|
|
26132
|
+
let l = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT * FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), u = Array.isArray(l) ? l : l?.results || [];
|
|
26133
|
+
if (!u || u.length === 0) return { blocks: [] };
|
|
26134
|
+
let d = u.map((e) => e.contentId).filter((e) => e != null);
|
|
26135
|
+
if (d.length === 0) return { blocks: [] };
|
|
26136
|
+
let f = d.map(() => "?").join(","), p = +!!o, m = await e.prepare(`SELECT * FROM content_blocks WHERE contentId IN (${f}) AND isDraft = ? ORDER BY contentId ASC, sortOrder ASC`).all(...d, p), h = Array.isArray(m) ? m : m?.results || [], g = /* @__PURE__ */ new Map();
|
|
26137
|
+
h.forEach((e) => {
|
|
26102
26138
|
let t = String(e.contentId);
|
|
26103
|
-
|
|
26139
|
+
g.has(t) || g.set(t, []), g.get(t).push(e);
|
|
26104
26140
|
});
|
|
26105
|
-
for (let t of
|
|
26106
|
-
let n =
|
|
26141
|
+
for (let t of u) {
|
|
26142
|
+
let n = g.get(String(t.contentId)) || [];
|
|
26107
26143
|
if (n.filter((e) => e.region === r).length === 0) continue;
|
|
26108
|
-
let
|
|
26109
|
-
for (;
|
|
26110
|
-
|
|
26144
|
+
let l = /* @__PURE__ */ new Set([r]), u = !0;
|
|
26145
|
+
for (; u;) {
|
|
26146
|
+
u = !1;
|
|
26111
26147
|
for (let e of n) {
|
|
26112
|
-
if (!
|
|
26148
|
+
if (!l.has(e.region)) continue;
|
|
26113
26149
|
let t = {};
|
|
26114
26150
|
try {
|
|
26115
26151
|
t = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
|
|
26116
26152
|
} catch {}
|
|
26117
26153
|
let r = String(e.id), i = String(t.blockId || t._instanceId || t.id || e.blockId);
|
|
26118
26154
|
for (let e of n) {
|
|
26119
|
-
if (!e.region ||
|
|
26155
|
+
if (!e.region || l.has(e.region)) continue;
|
|
26120
26156
|
let t = e.region;
|
|
26121
|
-
(t.startsWith(`${r}-`) || t.startsWith(`${r}_`) || i && i !== "undefined" && i !== "null" && (t.startsWith(`${i}-`) || t.startsWith(`${i}_`) || t.startsWith(i))) && (
|
|
26157
|
+
(t.startsWith(`${r}-`) || t.startsWith(`${r}_`) || i && i !== "undefined" && i !== "null" && (t.startsWith(`${i}-`) || t.startsWith(`${i}_`) || t.startsWith(i))) && (l.add(t), u = !0);
|
|
26122
26158
|
}
|
|
26123
26159
|
}
|
|
26124
26160
|
}
|
|
26125
|
-
let
|
|
26161
|
+
let d = await Promise.all(n.filter((e) => l.has(e.region)).map(async (t) => {
|
|
26126
26162
|
let n = {};
|
|
26127
26163
|
try {
|
|
26128
26164
|
n = (typeof t.dataJson == "string" ? JSON.parse(t.dataJson) : t.dataJson) || {};
|
|
26129
26165
|
} catch {}
|
|
26130
|
-
|
|
26131
|
-
let
|
|
26132
|
-
if (!
|
|
26133
|
-
let
|
|
26134
|
-
return
|
|
26166
|
+
c && dS(n.startShowingAt, n.stopShowingAt, c);
|
|
26167
|
+
let l = n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", u = fS(n.startShowingAt, n.stopShowingAt);
|
|
26168
|
+
if (!o && (l || !u)) return null;
|
|
26169
|
+
let d = t.elementType || t.componentId || "text-block", f = i.blocks?.[d]?.fields || i.elements?.[d]?.fields || i.components?.[d]?.fields || {}, p = String(n.blockId || n._instanceId || n.id || t.blockId || t.id), m = hS(n, f);
|
|
26170
|
+
return m = await fx(e, m), m = gS(m), m = await _S(e, m, a, s), m.blockId = p, {
|
|
26135
26171
|
region: t.region || r,
|
|
26136
26172
|
block: {
|
|
26137
26173
|
instanceId: t.id,
|
|
26138
|
-
blockId:
|
|
26139
|
-
componentId:
|
|
26140
|
-
data:
|
|
26174
|
+
blockId: p,
|
|
26175
|
+
componentId: d,
|
|
26176
|
+
data: m
|
|
26141
26177
|
}
|
|
26142
26178
|
};
|
|
26143
|
-
})),
|
|
26144
|
-
for (let e of
|
|
26145
|
-
if (
|
|
26146
|
-
blocks:
|
|
26147
|
-
subRegions:
|
|
26179
|
+
})), f = {};
|
|
26180
|
+
for (let e of d) e && (f[e.region] || (f[e.region] = []), f[e.region].push(e.block));
|
|
26181
|
+
if (f[r] && f[r].length > 0) return {
|
|
26182
|
+
blocks: f[r],
|
|
26183
|
+
subRegions: f,
|
|
26148
26184
|
inheritedFromId: String(t.contentId),
|
|
26149
26185
|
inheritedFromTitle: t.title || t.slug
|
|
26150
26186
|
};
|
|
@@ -26202,8 +26238,16 @@ async function _S(e, t, n, r) {
|
|
|
26202
26238
|
if (i.size === 0 && a.size === 0) return t;
|
|
26203
26239
|
let o = /* @__PURE__ */ new Map();
|
|
26204
26240
|
if (i.size > 0) {
|
|
26205
|
-
let t = Array.from(i).map(() => "?").join(","), r = await e.prepare(`
|
|
26206
|
-
|
|
26241
|
+
let t = Array.from(i).map(() => "?").join(","), r = await e.prepare(`
|
|
26242
|
+
SELECT nodeId, path, channelId
|
|
26243
|
+
FROM node_routes
|
|
26244
|
+
WHERE nodeId IN (${t}) AND isCanonical = 1
|
|
26245
|
+
ORDER BY CASE WHEN channelId = ? THEN 0 ELSE 1 END ASC
|
|
26246
|
+
`).all(...i, n);
|
|
26247
|
+
(Array.isArray(r) ? r : r?.results || []).forEach((e) => {
|
|
26248
|
+
let t = String(e.nodeId);
|
|
26249
|
+
o.has(t) || o.set(t, e.path);
|
|
26250
|
+
});
|
|
26207
26251
|
}
|
|
26208
26252
|
let s = Array.from(a).map(() => "?").join(","), c = a.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${s})`).all(...a) : [], l = /* @__PURE__ */ new Map();
|
|
26209
26253
|
return (Array.isArray(c) ? c : c?.results || []).forEach((e) => l.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : ""))), t.replace(/<a\s+([^>]+)>/gi, (e, t) => {
|
|
@@ -26239,7 +26283,7 @@ async function vS(e, t, n, r) {
|
|
|
26239
26283
|
if (a) return yS(e, a[1], r);
|
|
26240
26284
|
if (!i) return t.href;
|
|
26241
26285
|
let o = i[1];
|
|
26242
|
-
return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ?
|
|
26286
|
+
return (await e.prepare("\n SELECT path \n FROM node_routes \n WHERE nodeId = ? AND isCanonical = 1 \n ORDER BY CASE WHEN channelId = ? THEN 0 ELSE 1 END ASC \n LIMIT 1\n ").get(Number(o), n))?.path || "#";
|
|
26243
26287
|
}
|
|
26244
26288
|
async function yS(e, t, n) {
|
|
26245
26289
|
let r = String(t), i = n.assetUrls.get(r);
|
|
@@ -26342,7 +26386,7 @@ async function wS(e) {
|
|
|
26342
26386
|
if (!m) return e.json({ error: `Channel '${p}' not found` }, 404);
|
|
26343
26387
|
let h = m.status === "disabled" || m.status === "inactive" || m.isEnabled === 0 || m.isEnabled === !1;
|
|
26344
26388
|
if (!s && h) return e.json({ error: `Channel '${m.key || p}' is currently inactive` }, 404);
|
|
26345
|
-
let g = m.id, _ = m.key || p, v = await t.prepare("
|
|
26389
|
+
let g = m.id, _ = m.key || p, v = await t.prepare("SELECT * FROM node_routes WHERE path = ? AND channelId = ? LIMIT 1").get(f, g);
|
|
26346
26390
|
if (v?.redirectUrl) return e.json({
|
|
26347
26391
|
redirect: v.redirectUrl,
|
|
26348
26392
|
isCanonical: !1
|
|
@@ -26360,9 +26404,7 @@ async function wS(e) {
|
|
|
26360
26404
|
let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(y.id, Number(c));
|
|
26361
26405
|
if (e && e.snapshotJson) try {
|
|
26362
26406
|
x = JSON.parse(e.snapshotJson), x.node && (x.node.title && (y.title = x.node.title), x.node.slug && (y.slug = x.node.slug));
|
|
26363
|
-
} catch
|
|
26364
|
-
console.error("[CMS] Failed to parse snapshotJson", e);
|
|
26365
|
-
}
|
|
26407
|
+
} catch {}
|
|
26366
26408
|
}
|
|
26367
26409
|
let S = await t.prepare(`SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${b ? "AND treeId = ?" : ""} LIMIT 1`).get(y.id, ...b ? [b] : []);
|
|
26368
26410
|
!b && S?.treeId && (b = S.treeId), b ||= "main-nav";
|
|
@@ -26395,7 +26437,23 @@ async function wS(e) {
|
|
|
26395
26437
|
return n > 0 ? e.header("Cache-Control", `public, max-age=${n}, s-maxage=${n}`) : e.header("Cache-Control", "no-cache, no-store, must-revalidate"), e.json(t);
|
|
26396
26438
|
}
|
|
26397
26439
|
}
|
|
26398
|
-
let A = S?.parentId || null
|
|
26440
|
+
let A = S?.parentId || null;
|
|
26441
|
+
if (!S && !A) {
|
|
26442
|
+
let e = f.split("/").filter(Boolean);
|
|
26443
|
+
if (e.length > 1) {
|
|
26444
|
+
e.pop();
|
|
26445
|
+
let n = "/" + e.join("/"), r = await t.prepare("SELECT nodeId FROM node_routes WHERE path = ? AND channelId = ? LIMIT 1").get(n, g);
|
|
26446
|
+
if (r?.nodeId) {
|
|
26447
|
+
let e = await t.prepare("SELECT contentId, treeId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r.nodeId);
|
|
26448
|
+
e && (A = e.contentId, b = e.treeId);
|
|
26449
|
+
}
|
|
26450
|
+
}
|
|
26451
|
+
if (!A) {
|
|
26452
|
+
let e = await t.prepare("SELECT contentId, treeId FROM tree_nodes WHERE parentId IS NULL ORDER BY sortOrder ASC LIMIT 1").get();
|
|
26453
|
+
e && (A = e.contentId, b = e.treeId);
|
|
26454
|
+
}
|
|
26455
|
+
}
|
|
26456
|
+
let ne = v?.path || (f === "" ? "/" : f), j = {
|
|
26399
26457
|
id: y.id,
|
|
26400
26458
|
title: y.title,
|
|
26401
26459
|
slug: y.slug,
|
|
@@ -26423,7 +26481,7 @@ async function wS(e) {
|
|
|
26423
26481
|
if (!s && (be || xe || Se && !Ce)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
|
|
26424
26482
|
let we = [];
|
|
26425
26483
|
if (S?.treeNodeId) {
|
|
26426
|
-
let e = await t.prepare("
|
|
26484
|
+
let e = await t.prepare("SELECT t.contentId as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC").all(S.treeNodeId, b), n = Array.isArray(e) ? e : e?.results || [], i = j.path || "", a = i === "/" ? "" : i;
|
|
26427
26485
|
we = n.map((e) => {
|
|
26428
26486
|
let t = {}, n = s && e.draftDataJson || e.dataJson;
|
|
26429
26487
|
if (!n) return null;
|
|
@@ -26486,7 +26544,7 @@ async function wS(e) {
|
|
|
26486
26544
|
for (let [e, i] of Object.entries(ke)) {
|
|
26487
26545
|
let a = Ee[e] && Ee[e].length > 0, o = !!se[e];
|
|
26488
26546
|
if (Ee[e] || (Ee[e] = [], De[e] = { isInherited: !1 }), (i?.inherit === "parent" || i?.inherit === !0 || i?.inherit === "true" || e === "header" || e === "footer") && !a && !o && A) {
|
|
26489
|
-
let i = await mS(t, A,
|
|
26547
|
+
let i = await mS(t, A, b, e, re, g, s, n, r);
|
|
26490
26548
|
if (i.blocks.length > 0 && (Ee[e] = i.blocks, De[e] = {
|
|
26491
26549
|
isInherited: !0,
|
|
26492
26550
|
inheritedFromId: i.inheritedFromId,
|
|
@@ -26498,7 +26556,7 @@ async function wS(e) {
|
|
|
26498
26556
|
});
|
|
26499
26557
|
}
|
|
26500
26558
|
}
|
|
26501
|
-
await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r)));
|
|
26559
|
+
await Promise.all(Object.keys(Ee).map((e) => pS(t, Ee[e], g, E, r, re)));
|
|
26502
26560
|
let Ae = null, je = null;
|
|
26503
26561
|
if (r.length > 0) {
|
|
26504
26562
|
je = Math.min(...r);
|
|
@@ -26559,10 +26617,9 @@ var TS = X({
|
|
|
26559
26617
|
method: "get",
|
|
26560
26618
|
path: "/{path}",
|
|
26561
26619
|
summary: "Fetch CMS Node Content",
|
|
26562
|
-
description: "Retrieves a fully hydrated CMS node along with its content blocks and inherited regions using $O(1)$ routing table lookups.",
|
|
26563
26620
|
tags: ["Public Node API"],
|
|
26564
26621
|
request: {
|
|
26565
|
-
params: X({ path: J().optional()
|
|
26622
|
+
params: X({ path: J().optional() }),
|
|
26566
26623
|
query: TS
|
|
26567
26624
|
},
|
|
26568
26625
|
responses: {
|
|
@@ -26571,11 +26628,11 @@ var TS = X({
|
|
|
26571
26628
|
content: { "application/json": { schema: DS } }
|
|
26572
26629
|
},
|
|
26573
26630
|
404: {
|
|
26574
|
-
description: "
|
|
26631
|
+
description: "Not found",
|
|
26575
26632
|
content: { "application/json": { schema: ES } }
|
|
26576
26633
|
},
|
|
26577
26634
|
500: {
|
|
26578
|
-
description: "Server error
|
|
26635
|
+
description: "Server error",
|
|
26579
26636
|
content: { "application/json": { schema: ES } }
|
|
26580
26637
|
}
|
|
26581
26638
|
}
|
|
@@ -26586,36 +26643,43 @@ var kS = new $y(), AS = X({
|
|
|
26586
26643
|
channelId: J().optional().openapi({ description: "Channel ID or key" }),
|
|
26587
26644
|
limit: Ky().min(1).max(50).default(12).openapi({ description: "Number of items (max 50)" }),
|
|
26588
26645
|
offset: Ky().min(0).default(0).openapi({ description: "Pagination offset" }),
|
|
26589
|
-
sortBy:
|
|
26590
|
-
"updatedAt",
|
|
26591
|
-
"createdAt",
|
|
26592
|
-
"title_asc"
|
|
26593
|
-
]).default("updatedAt"),
|
|
26646
|
+
sortBy: J().default("updatedAt_desc").openapi({ description: "Sort field and direction" }),
|
|
26594
26647
|
authors: G_([J(), z_(J())]).optional(),
|
|
26595
26648
|
categories: G_([J(), z_(J())]).optional(),
|
|
26596
26649
|
tags: G_([J(), z_(J())]).optional()
|
|
26597
26650
|
}), jS = async (e) => {
|
|
26598
26651
|
try {
|
|
26599
|
-
let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a =
|
|
26600
|
-
|
|
26601
|
-
|
|
26602
|
-
|
|
26603
|
-
|
|
26652
|
+
let t = e.get("db"), n = e.req.valid("query"), r = n.nodeType || "article", i = String(r).split(",").map((e) => e.trim()).filter(Boolean), a = i.map(() => "?").join(","), o = px(e.env?.BUNDLED_DEFINITIONS), s = {};
|
|
26653
|
+
for (let e of i) {
|
|
26654
|
+
s[e] = [];
|
|
26655
|
+
let t = o.nodes?.[e] || {}, n = { ...t.fields || {} };
|
|
26656
|
+
t.tabs && Object.values(t.tabs).forEach((e) => {
|
|
26657
|
+
Object.assign(n, e.fields || {});
|
|
26658
|
+
});
|
|
26659
|
+
for (let [t, r] of Object.entries(n)) (r.showInList || r.showInLists) && s[e].push(t);
|
|
26660
|
+
}
|
|
26661
|
+
let c = `FROM content_nodes WHERE contentType IN (${a}) AND isHidden = 0 AND IFNULL(status, 'published') = 'published'`, l = [...i];
|
|
26662
|
+
n.channelId && n.channelId !== "all" && (c += " AND EXISTS (SELECT 1 FROM node_channels nc WHERE nc.nodeId = content_nodes.id AND nc.channelId = ?)", l.push(Number(n.channelId) || n.channelId));
|
|
26663
|
+
let u = (/* @__PURE__ */ new Date()).toISOString();
|
|
26664
|
+
c += " AND IFNULL(json_extract(dataJson, '$.startShowingAt'), '') <= ?", l.push(u), c += " AND IFNULL(json_extract(dataJson, '$.stopShowingAt'), '9999-12-31') >= ?", l.push(u);
|
|
26665
|
+
let d = (e, t, n = !1) => {
|
|
26604
26666
|
let r = Array.isArray(t) ? t : t.split(",").map((e) => e.trim());
|
|
26605
26667
|
if (r.length === 0) return;
|
|
26606
26668
|
let i = r.map(() => "?").join(",");
|
|
26607
|
-
n ? (
|
|
26669
|
+
n ? (c += ` AND EXISTS (SELECT 1 FROM node_relations nr WHERE nr.sourceNodeId = content_nodes.id AND nr.fieldKey = ? AND nr.targetNodeId IN (${i}))`, l.push(e, ...r)) : (c += ` AND EXISTS (SELECT 1 FROM node_terms nt INNER JOIN taxonomy_terms tt ON nt.termId = tt.id WHERE nt.nodeId = content_nodes.id AND tt.taxonomy = ? AND tt.key IN (${i}))`, l.push(e, ...r));
|
|
26608
26670
|
};
|
|
26609
|
-
n.authors &&
|
|
26610
|
-
let
|
|
26611
|
-
|
|
26612
|
-
let
|
|
26613
|
-
|
|
26614
|
-
let
|
|
26671
|
+
n.authors && d("authors", n.authors, !0), n.categories && d("categories", n.categories, !1), n.tags && d("tags", n.tags, !1);
|
|
26672
|
+
let f = String(n.sortBy || "updatedAt_desc"), [p, m] = f.includes("_") ? f.split("_") : [f, "desc"], h = String(m).toLowerCase() === "asc" ? "ASC" : "DESC", g = String(p).replace(/[^a-zA-Z0-9_]/g, ""), _ = `ORDER BY updatedAt ${h}`;
|
|
26673
|
+
g === "createdAt" || g === "published" ? _ = `ORDER BY createdAt ${h}` : g === "title" ? _ = `ORDER BY LOWER(title) ${h}` : g !== "updatedAt" && g !== "" && (_ = `ORDER BY json_extract(dataJson, '$.${g}') ${h}`);
|
|
26674
|
+
let v = `SELECT id, title, slug, language, dataJson, createdAt, updatedAt ${c} ${_} LIMIT ? OFFSET ?`;
|
|
26675
|
+
l.push(n.limit, n.offset);
|
|
26676
|
+
let y = await t.prepare(v).all(...l), b = Array.isArray(y) ? y : y?.results || [], x = b.map((e) => {
|
|
26615
26677
|
let t = {};
|
|
26616
26678
|
try {
|
|
26617
26679
|
t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson || {};
|
|
26618
26680
|
} catch {}
|
|
26681
|
+
let n = {}, r = s[e.contentType || "article"] || [];
|
|
26682
|
+
for (let e of r) t[e] !== void 0 && (n[e] = t[e]);
|
|
26619
26683
|
return {
|
|
26620
26684
|
id: e.id,
|
|
26621
26685
|
title: e.title,
|
|
@@ -26623,15 +26687,16 @@ var kS = new $y(), AS = X({
|
|
|
26623
26687
|
language: e.language,
|
|
26624
26688
|
createdAt: e.createdAt,
|
|
26625
26689
|
updatedAt: e.updatedAt,
|
|
26690
|
+
...n,
|
|
26626
26691
|
excerpt: t.excerpt || "",
|
|
26627
26692
|
image: t.image || t.coverImage || null,
|
|
26628
26693
|
author: t.author || null
|
|
26629
26694
|
};
|
|
26630
26695
|
});
|
|
26631
26696
|
return e.json({
|
|
26632
|
-
items:
|
|
26633
|
-
count:
|
|
26634
|
-
rawCount:
|
|
26697
|
+
items: x,
|
|
26698
|
+
count: x.length,
|
|
26699
|
+
rawCount: b.length,
|
|
26635
26700
|
limit: n.limit,
|
|
26636
26701
|
offset: n.offset
|
|
26637
26702
|
}, 200);
|
|
@@ -26691,11 +26756,11 @@ var IS = X({ treeParam: J().openapi({ description: "The ID or key of the request
|
|
|
26691
26756
|
path: J(),
|
|
26692
26757
|
nodeType: J().optional(),
|
|
26693
26758
|
hidden: c_(),
|
|
26694
|
-
summary: J(),
|
|
26759
|
+
summary: J().optional(),
|
|
26695
26760
|
url: J().optional(),
|
|
26696
26761
|
target: J().optional(),
|
|
26697
26762
|
children: z_(zS).optional()
|
|
26698
|
-
})).openapi("TreeItem"), BS = X({
|
|
26763
|
+
}).passthrough()).openapi("TreeItem"), BS = X({
|
|
26699
26764
|
treeId: G_([c_(), J()]),
|
|
26700
26765
|
key: J(),
|
|
26701
26766
|
channelId: J(),
|
|
@@ -26753,42 +26818,42 @@ NS.openapi(VS, async (e) => {
|
|
|
26753
26818
|
let t = await p.get(m);
|
|
26754
26819
|
if (t) return e.header("X-Cache", "HIT"), e.json(t, 200);
|
|
26755
26820
|
}
|
|
26756
|
-
let g = u?.id || (l ? Number(n) : null), _ = {};
|
|
26821
|
+
let g = u?.id || (l ? Number(n) : null), _ = e.env?.BUNDLED_DEFINITIONS, v = px(_), y = v.treeExposedFields || ["summary"], b = {};
|
|
26757
26822
|
if (u && u.dataJson) try {
|
|
26758
|
-
let
|
|
26759
|
-
for (let [
|
|
26823
|
+
let e = typeof u.dataJson == "string" ? JSON.parse(u.dataJson) : u.dataJson, t = (v.trees?.[u.treeType || n] || v.trees?.site || {}).fields || {};
|
|
26824
|
+
for (let [n, r] of Object.entries(e)) t[n]?.public === !0 && (b[n] = r);
|
|
26760
26825
|
} catch (e) {
|
|
26761
26826
|
console.warn("[CMS Public Tree API] Failed to parse tree dataJson", e);
|
|
26762
26827
|
}
|
|
26763
|
-
let
|
|
26828
|
+
let x = [];
|
|
26764
26829
|
if (g !== null) {
|
|
26765
26830
|
let e = await t.prepare("\n SELECT \n t.contentId as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.startShowingAt,\n c.stopShowingAt,\n c.status,\n c.dataJson,\n c.draftDataJson,\n (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(c, g);
|
|
26766
|
-
|
|
26831
|
+
x = Array.isArray(e) ? e : e?.results || [];
|
|
26767
26832
|
}
|
|
26768
|
-
if ((!
|
|
26769
|
-
let
|
|
26770
|
-
for (let e of
|
|
26771
|
-
let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r =
|
|
26772
|
-
r ? r.push(e) :
|
|
26833
|
+
if ((!x || x.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
|
|
26834
|
+
let S = /* @__PURE__ */ new Map();
|
|
26835
|
+
for (let e of x) {
|
|
26836
|
+
let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = S.get(n);
|
|
26837
|
+
r ? r.push(e) : S.set(n, [e]);
|
|
26773
26838
|
}
|
|
26774
|
-
let
|
|
26775
|
-
for (let e of
|
|
26839
|
+
let C = /* @__PURE__ */ new Map();
|
|
26840
|
+
for (let e of x) {
|
|
26776
26841
|
let t = String(e.id), n = o && e.draftDataJson ? e.draftDataJson : e.dataJson;
|
|
26777
26842
|
if (!n) {
|
|
26778
|
-
|
|
26843
|
+
C.set(t, {});
|
|
26779
26844
|
continue;
|
|
26780
26845
|
}
|
|
26781
26846
|
try {
|
|
26782
26847
|
let e = typeof n == "string" ? JSON.parse(n) : n;
|
|
26783
|
-
|
|
26848
|
+
C.set(t, e && typeof e == "object" ? e : {});
|
|
26784
26849
|
} catch {
|
|
26785
|
-
|
|
26850
|
+
C.set(t, {});
|
|
26786
26851
|
}
|
|
26787
26852
|
}
|
|
26788
|
-
function
|
|
26853
|
+
function w(e = null, t = "") {
|
|
26789
26854
|
let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e);
|
|
26790
|
-
return (
|
|
26791
|
-
let n =
|
|
26855
|
+
return (S.get(n) || []).map((e) => {
|
|
26856
|
+
let n = C.get(String(e.id)) || {}, r = {};
|
|
26792
26857
|
for (let [e, t] of Object.entries(n)) e !== "_isTreeDraft" && e !== "_draftParentId" && e !== "isNew" && e !== "hidden" && e !== "is_hidden" && e !== "isHidden" && e !== "status" && (r[e] = t);
|
|
26793
26858
|
let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = PS(e.startShowingAt === void 0 ? n.startShowingAt : e.startShowingAt, e.stopShowingAt === void 0 ? n.stopShowingAt : e.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = !e.parentId || e.parentId === "null" || e.parentId === "", u = e.materializedPath || (l ? `/${c}` : `${t}/${c}`.replace(/\/+/g, "/")), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : f, p = {
|
|
26794
26859
|
id: e.id,
|
|
@@ -26799,24 +26864,24 @@ NS.openapi(VS, async (e) => {
|
|
|
26799
26864
|
language: d,
|
|
26800
26865
|
path: u,
|
|
26801
26866
|
nodeType: e.nodeType,
|
|
26802
|
-
hidden: a || !s ? 1 : 0
|
|
26803
|
-
summary: r.summary || ""
|
|
26867
|
+
hidden: a || !s ? 1 : 0
|
|
26804
26868
|
};
|
|
26869
|
+
for (let e of y) r[e] !== void 0 && (p[e] = r[e]);
|
|
26805
26870
|
e.nodeType === "external-link" && (r.url && (p.url = r.url), r.target && (p.target = r.target));
|
|
26806
26871
|
let m = u === "/" ? "" : u;
|
|
26807
|
-
return p.children =
|
|
26872
|
+
return p.children = w(e.id, m), p;
|
|
26808
26873
|
}).filter((e) => o || !e.hidden);
|
|
26809
26874
|
}
|
|
26810
|
-
let
|
|
26875
|
+
let T = {
|
|
26811
26876
|
treeId: u?.id || g,
|
|
26812
26877
|
key: u?.key || n,
|
|
26813
26878
|
channelId: String(i),
|
|
26814
26879
|
language: f,
|
|
26815
26880
|
label: u?.label || n,
|
|
26816
|
-
...
|
|
26817
|
-
items:
|
|
26881
|
+
...b,
|
|
26882
|
+
items: w(null)
|
|
26818
26883
|
};
|
|
26819
|
-
return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m,
|
|
26884
|
+
return !o && !h && (e.header("X-Cache", "MISS"), await FS(p, m, T, 300)), e.json(T, 200);
|
|
26820
26885
|
} catch (t) {
|
|
26821
26886
|
return console.error("[CMS Public Tree API] Error:", t), e.json({
|
|
26822
26887
|
error: "Failed to fetch public tree",
|
package/dist/index.html
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
<title>KAMA</title>
|
|
7
7
|
<link rel="icon" href="/favicon.png">
|
|
8
8
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicon.png">
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DQ6_RmCI.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-CQxWhVtr.js">
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/schema-helpers-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/useNodes-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/plus-
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/schema-helpers-DvficKko.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/useNodes-D2-VxsxR.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/plus-FQRsZBoJ.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/send-F-mJeL54.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/CmsPaneResizer-B62ZqsnE.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/user-IFlT6mYq.js">
|