@fayz-ai/plugin-forms 0.9.0 → 0.9.2
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/README.md +3 -3
- package/dist/{FormBuilder-7SWZQKFN.js → FormBuilder-YHJHF6HZ.js} +4 -4
- package/dist/{FormBuilder-7SWZQKFN.js.map → FormBuilder-YHJHF6HZ.js.map} +1 -1
- package/dist/{chunk-W2ZNJGQC.js → chunk-RBLXIKWB.js} +221 -8
- package/dist/chunk-RBLXIKWB.js.map +1 -0
- package/dist/components/AddDocumentDropdown.d.ts +1 -1
- package/dist/components/AddDocumentDropdown.d.ts.map +1 -1
- package/dist/components/DocumentFormDialog.d.ts.map +1 -1
- package/dist/components/DocumentSkeleton.d.ts +21 -0
- package/dist/components/DocumentSkeleton.d.ts.map +1 -0
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormViewer.d.ts.map +1 -1
- package/dist/{CustomFormsContext.d.ts → context.d.ts} +1 -1
- package/dist/context.d.ts.map +1 -0
- package/dist/data/mock.d.ts.map +1 -1
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/types.d.ts +4 -1
- package/dist/data/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -17
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-tools.d.ts.map +1 -0
- package/dist/lib/document-types.d.ts.map +1 -0
- package/dist/lib/html-text.d.ts +21 -0
- package/dist/lib/html-text.d.ts.map +1 -0
- package/dist/lib/print.d.ts.map +1 -1
- package/dist/lib/timeline-source.d.ts +10 -0
- package/dist/lib/timeline-source.d.ts.map +1 -0
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/store.d.ts +5 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/views/TemplateListView.d.ts.map +1 -1
- package/package.json +5 -7
- package/dist/CustomFormsContext.d.ts.map +0 -1
- package/dist/agent-tools.d.ts.map +0 -1
- package/dist/chunk-W2ZNJGQC.js.map +0 -1
- package/dist/document-types.d.ts.map +0 -1
- package/src/CustomFormsContext.tsx +0 -28
- package/src/agent-tools.ts +0 -73
- package/src/components/AddDocumentDropdown.tsx +0 -92
- package/src/components/BuilderCanvas.tsx +0 -87
- package/src/components/BuilderField.tsx +0 -81
- package/src/components/DocumentFormDialog.tsx +0 -155
- package/src/components/DocumentList.tsx +0 -254
- package/src/components/FieldConfigDialog.tsx +0 -243
- package/src/components/FieldPalette.tsx +0 -81
- package/src/components/FormBuilder.tsx +0 -427
- package/src/components/FormRenderer.tsx +0 -256
- package/src/components/FormViewer.tsx +0 -94
- package/src/components/PersonDocumentsWidget.tsx +0 -229
- package/src/components/TemplateSelector.tsx +0 -91
- package/src/config.ts +0 -43
- package/src/data/index.ts +0 -3
- package/src/data/mock.ts +0 -193
- package/src/data/supabase.ts +0 -408
- package/src/data/tables.ts +0 -7
- package/src/data/types.ts +0 -33
- package/src/document-types.ts +0 -51
- package/src/index.ts +0 -234
- package/src/lib/person-fields.ts +0 -67
- package/src/lib/print.ts +0 -207
- package/src/lib/tenant.ts +0 -9
- package/src/locales/en.ts +0 -95
- package/src/locales/index.ts +0 -7
- package/src/locales/pt-BR.ts +0 -95
- package/src/migrations/000_plg_rename.sql +0 -21
- package/src/migrations/001_frm_base.sql +0 -174
- package/src/migrations/002_document_archetype.sql +0 -223
- package/src/migrations/003_agent_rpcs.sql +0 -174
- package/src/migrations/index.ts +0 -610
- package/src/store.ts +0 -167
- package/src/types.ts +0 -217
- package/src/views/CustomFormsSettingsTab.tsx +0 -105
- package/src/views/TemplateListView.tsx +0 -174
- /package/dist/{agent-tools.d.ts → lib/agent-tools.d.ts} +0 -0
- /package/dist/{document-types.d.ts → lib/document-types.d.ts} +0 -0
|
@@ -4,6 +4,199 @@ import { useTranslation } from '@fayz-ai/core';
|
|
|
4
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
6
|
// src/components/FormRenderer.tsx
|
|
7
|
+
|
|
8
|
+
// src/lib/html-text.ts
|
|
9
|
+
function looksLikeHtml(value) {
|
|
10
|
+
return /<\/?[a-z][^>]*>/i.test(value);
|
|
11
|
+
}
|
|
12
|
+
var BLOCKS = "p, div, li, tr, h1, h2, h3, h4, h5, h6, blockquote, section, article";
|
|
13
|
+
var NBSP = / /g;
|
|
14
|
+
function htmlToPlainText(value) {
|
|
15
|
+
if (!value) return "";
|
|
16
|
+
if (typeof document === "undefined") {
|
|
17
|
+
return value.replace(/<br\s*\/?>/gi, "\n").replace(/<\/(p|div|li|tr|h[1-6]|blockquote)>/gi, "\n").replace(/<[^>]*>/g, "").replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&").replace(/\n{3,}/g, "\n\n").trim();
|
|
18
|
+
}
|
|
19
|
+
const el = document.createElement("div");
|
|
20
|
+
el.innerHTML = value;
|
|
21
|
+
for (const br of Array.from(el.querySelectorAll("br"))) {
|
|
22
|
+
br.replaceWith("\n");
|
|
23
|
+
}
|
|
24
|
+
for (const block of Array.from(el.querySelectorAll(BLOCKS))) {
|
|
25
|
+
block.append("\n");
|
|
26
|
+
}
|
|
27
|
+
return (el.textContent ?? "").replace(NBSP, " ").replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
28
|
+
}
|
|
29
|
+
var DROP_WITH_CONTENT = /* @__PURE__ */ new Set([
|
|
30
|
+
"script",
|
|
31
|
+
"style",
|
|
32
|
+
"iframe",
|
|
33
|
+
"object",
|
|
34
|
+
"embed",
|
|
35
|
+
"svg",
|
|
36
|
+
"math",
|
|
37
|
+
"link",
|
|
38
|
+
"meta",
|
|
39
|
+
"form",
|
|
40
|
+
"input",
|
|
41
|
+
"button",
|
|
42
|
+
"textarea",
|
|
43
|
+
"select",
|
|
44
|
+
"template",
|
|
45
|
+
"noscript"
|
|
46
|
+
]);
|
|
47
|
+
var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
48
|
+
"p",
|
|
49
|
+
"br",
|
|
50
|
+
"hr",
|
|
51
|
+
"div",
|
|
52
|
+
"span",
|
|
53
|
+
"b",
|
|
54
|
+
"strong",
|
|
55
|
+
"i",
|
|
56
|
+
"em",
|
|
57
|
+
"u",
|
|
58
|
+
"s",
|
|
59
|
+
"sub",
|
|
60
|
+
"sup",
|
|
61
|
+
"mark",
|
|
62
|
+
"small",
|
|
63
|
+
"ul",
|
|
64
|
+
"ol",
|
|
65
|
+
"li",
|
|
66
|
+
"blockquote",
|
|
67
|
+
"pre",
|
|
68
|
+
"code",
|
|
69
|
+
"h1",
|
|
70
|
+
"h2",
|
|
71
|
+
"h3",
|
|
72
|
+
"h4",
|
|
73
|
+
"h5",
|
|
74
|
+
"h6",
|
|
75
|
+
"table",
|
|
76
|
+
"thead",
|
|
77
|
+
"tbody",
|
|
78
|
+
"tfoot",
|
|
79
|
+
"tr",
|
|
80
|
+
"td",
|
|
81
|
+
"th",
|
|
82
|
+
"caption",
|
|
83
|
+
"a"
|
|
84
|
+
]);
|
|
85
|
+
var ALLOWED_ATTRS = {
|
|
86
|
+
a: /* @__PURE__ */ new Set(["href", "title"]),
|
|
87
|
+
td: /* @__PURE__ */ new Set(["colspan", "rowspan"]),
|
|
88
|
+
th: /* @__PURE__ */ new Set(["colspan", "rowspan"])
|
|
89
|
+
};
|
|
90
|
+
var SAFE_HREF = /^(https?:|mailto:|tel:)/i;
|
|
91
|
+
function cleanElement(el) {
|
|
92
|
+
for (const child of Array.from(el.children)) {
|
|
93
|
+
cleanElement(child);
|
|
94
|
+
}
|
|
95
|
+
const tag = el.tagName.toLowerCase();
|
|
96
|
+
if (DROP_WITH_CONTENT.has(tag)) {
|
|
97
|
+
el.remove();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
for (const attr of Array.from(el.attributes)) {
|
|
101
|
+
const name = attr.name.toLowerCase();
|
|
102
|
+
const allowed = ALLOWED_ATTRS[tag]?.has(name) ?? false;
|
|
103
|
+
if (!allowed) {
|
|
104
|
+
el.removeAttribute(attr.name);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (name === "href" && !SAFE_HREF.test(attr.value.trim())) {
|
|
108
|
+
el.removeAttribute(attr.name);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!ALLOWED_TAGS.has(tag)) {
|
|
112
|
+
el.replaceWith(...Array.from(el.childNodes));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (tag === "a") {
|
|
116
|
+
if (!el.getAttribute("href")) {
|
|
117
|
+
el.replaceWith(...Array.from(el.childNodes));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
el.setAttribute("target", "_blank");
|
|
121
|
+
el.setAttribute("rel", "noopener noreferrer nofollow");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function sanitizeHtml(value) {
|
|
125
|
+
if (!value) return "";
|
|
126
|
+
if (typeof DOMParser === "undefined") return "";
|
|
127
|
+
const doc = new DOMParser().parseFromString(value, "text/html");
|
|
128
|
+
for (const child of Array.from(doc.body.children)) {
|
|
129
|
+
cleanElement(child);
|
|
130
|
+
}
|
|
131
|
+
return doc.body.innerHTML;
|
|
132
|
+
}
|
|
133
|
+
function fieldRichValue(value) {
|
|
134
|
+
if (typeof value !== "string" || !value) return { text: "" };
|
|
135
|
+
if (!looksLikeHtml(value)) return { text: value };
|
|
136
|
+
const html = sanitizeHtml(value);
|
|
137
|
+
return html ? { html } : { text: htmlToPlainText(value) };
|
|
138
|
+
}
|
|
139
|
+
var RICH_TEXT_CLASS = [
|
|
140
|
+
"space-y-2",
|
|
141
|
+
"[&_p]:leading-relaxed",
|
|
142
|
+
"[&_b]:font-semibold [&_strong]:font-semibold",
|
|
143
|
+
"[&_i]:italic [&_em]:italic",
|
|
144
|
+
"[&_u]:underline",
|
|
145
|
+
"[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:leading-relaxed",
|
|
146
|
+
"[&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground",
|
|
147
|
+
"[&_a]:text-primary [&_a]:underline",
|
|
148
|
+
"[&_h1]:font-semibold [&_h2]:font-semibold [&_h3]:font-semibold",
|
|
149
|
+
"[&_table]:w-full [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1",
|
|
150
|
+
"[&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:font-medium"
|
|
151
|
+
].join(" ");
|
|
152
|
+
function ReadField({ label, children }) {
|
|
153
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
154
|
+
label && /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground", children: label }),
|
|
155
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-foreground", children })
|
|
156
|
+
] });
|
|
157
|
+
}
|
|
158
|
+
function EmptyValue() {
|
|
159
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/50", children: "\u2014" });
|
|
160
|
+
}
|
|
161
|
+
function optionLabel(field, value) {
|
|
162
|
+
if (value == null || value === "") return null;
|
|
163
|
+
const match = (field.options ?? []).find((o) => o.value === value);
|
|
164
|
+
return match?.label ?? String(value);
|
|
165
|
+
}
|
|
166
|
+
function ReadValue({ field, value }) {
|
|
167
|
+
switch (field.type) {
|
|
168
|
+
case "memo":
|
|
169
|
+
case "richtext": {
|
|
170
|
+
const rich = fieldRichValue(value);
|
|
171
|
+
return /* @__PURE__ */ jsx(ReadField, { label: field.label, children: "html" in rich ? /* @__PURE__ */ jsx("div", { className: RICH_TEXT_CLASS, dangerouslySetInnerHTML: { __html: rich.html } }) : rich.text ? /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap", children: rich.text }) : /* @__PURE__ */ jsx(EmptyValue, {}) });
|
|
172
|
+
}
|
|
173
|
+
case "date": {
|
|
174
|
+
const raw = typeof value === "string" ? value : "";
|
|
175
|
+
const date = raw ? new Date(raw) : null;
|
|
176
|
+
const text = date && !Number.isNaN(date.getTime()) ? raw.slice(0, 10).split("-").reverse().join("/") : raw;
|
|
177
|
+
return /* @__PURE__ */ jsx(ReadField, { label: field.label, children: text || /* @__PURE__ */ jsx(EmptyValue, {}) });
|
|
178
|
+
}
|
|
179
|
+
case "select":
|
|
180
|
+
case "radio": {
|
|
181
|
+
const label = optionLabel(field, value);
|
|
182
|
+
return /* @__PURE__ */ jsx(ReadField, { label: field.label, children: label ?? /* @__PURE__ */ jsx(EmptyValue, {}) });
|
|
183
|
+
}
|
|
184
|
+
case "tags": {
|
|
185
|
+
const selected = Array.isArray(value) ? value : [];
|
|
186
|
+
return /* @__PURE__ */ jsx(ReadField, { label: field.label, children: selected.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: selected.map((v) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: optionLabel(field, v) ?? v }, v)) }) : /* @__PURE__ */ jsx(EmptyValue, {}) });
|
|
187
|
+
}
|
|
188
|
+
case "checkbox":
|
|
189
|
+
return /* @__PURE__ */ jsxs(ReadField, { children: [
|
|
190
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: field.label }),
|
|
191
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: " \xB7 " }),
|
|
192
|
+
/* @__PURE__ */ jsx("span", { children: value ? "Sim" : "N\xE3o" })
|
|
193
|
+
] });
|
|
194
|
+
default: {
|
|
195
|
+
const text = value == null || value === "" ? null : String(value);
|
|
196
|
+
return /* @__PURE__ */ jsx(ReadField, { label: field.label, children: text ?? /* @__PURE__ */ jsx(EmptyValue, {}) });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
7
200
|
function FieldRenderer({
|
|
8
201
|
field,
|
|
9
202
|
value,
|
|
@@ -11,6 +204,9 @@ function FieldRenderer({
|
|
|
11
204
|
readOnly
|
|
12
205
|
}) {
|
|
13
206
|
useTranslation();
|
|
207
|
+
if (readOnly && field.type !== "title" && field.type !== "image" && field.type !== "gallery" && field.type !== "budget") {
|
|
208
|
+
return /* @__PURE__ */ jsx(ReadValue, { field, value });
|
|
209
|
+
}
|
|
14
210
|
switch (field.type) {
|
|
15
211
|
case "title":
|
|
16
212
|
return /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold pt-2 pb-1 border-b", children: field.label });
|
|
@@ -208,7 +404,7 @@ function formatDate(value) {
|
|
|
208
404
|
if (!m) return esc(value);
|
|
209
405
|
return `${m[3]}/${m[2]}/${m[1]}`;
|
|
210
406
|
}
|
|
211
|
-
function
|
|
407
|
+
function optionLabel2(field, value) {
|
|
212
408
|
const opt = (field.options ?? []).find((o) => o.value === value);
|
|
213
409
|
return esc(opt ? opt.label : value);
|
|
214
410
|
}
|
|
@@ -216,16 +412,19 @@ function renderValue(field, value) {
|
|
|
216
412
|
const empty = '<span class="empty">\u2014</span>';
|
|
217
413
|
switch (field.type) {
|
|
218
414
|
case "memo":
|
|
219
|
-
case "richtext":
|
|
220
|
-
|
|
415
|
+
case "richtext": {
|
|
416
|
+
const rich = fieldRichValue(value);
|
|
417
|
+
if ("html" in rich) return `<div class="long rich">${rich.html}</div>`;
|
|
418
|
+
return rich.text ? `<div class="long">${nl2br(rich.text)}</div>` : empty;
|
|
419
|
+
}
|
|
221
420
|
case "date":
|
|
222
421
|
return value ? formatDate(String(value)) : empty;
|
|
223
422
|
case "select":
|
|
224
423
|
case "radio":
|
|
225
|
-
return value ?
|
|
424
|
+
return value ? optionLabel2(field, value) : empty;
|
|
226
425
|
case "tags": {
|
|
227
426
|
const arr = Array.isArray(value) ? value : [];
|
|
228
|
-
return arr.length ? arr.map((v) =>
|
|
427
|
+
return arr.length ? arr.map((v) => optionLabel2(field, v)).join(", ") : empty;
|
|
229
428
|
}
|
|
230
429
|
case "checkbox":
|
|
231
430
|
return value ? "Sim" : "N\xE3o";
|
|
@@ -282,6 +481,20 @@ function buildPrintHtml(template, doc, opts = {}) {
|
|
|
282
481
|
.field .label { font-size: 9pt; text-transform: uppercase; letter-spacing: .04em; color: #666; margin-bottom: 2px; }
|
|
283
482
|
.field .value { font-size: 12pt; }
|
|
284
483
|
.field--long .value .long { white-space: normal; text-align: justify; }
|
|
484
|
+
/* Conteudo formatado (sanitizado em lib/html-text.ts). O HTML chega sem
|
|
485
|
+
class nenhuma, entao o estilo vem por tag. orphans/widows evitam que um
|
|
486
|
+
paragrafo deixe uma linha solta virando a pagina. */
|
|
487
|
+
.long.rich p { margin: 0 0 8px; orphans: 2; widows: 2; }
|
|
488
|
+
.long.rich p:last-child { margin-bottom: 0; }
|
|
489
|
+
.long.rich ul, .long.rich ol { margin: 0 0 8px; padding-left: 20px; }
|
|
490
|
+
.long.rich li { margin: 0 0 3px; }
|
|
491
|
+
.long.rich b, .long.rich strong { font-weight: 600; }
|
|
492
|
+
.long.rich blockquote { margin: 0 0 8px; padding-left: 10px; border-left: 2px solid #ccc; color: #444; }
|
|
493
|
+
.long.rich a { color: #111; text-decoration: underline; }
|
|
494
|
+
.long.rich table { width: 100%; border-collapse: collapse; margin: 0 0 8px; }
|
|
495
|
+
.long.rich td, .long.rich th { border: 1px solid #ccc; padding: 4px 6px; text-align: left; }
|
|
496
|
+
.long.rich h1, .long.rich h2, .long.rich h3,
|
|
497
|
+
.long.rich h4, .long.rich h5, .long.rich h6 { font-size: 12pt; font-weight: 600; margin: 10px 0 4px; }
|
|
285
498
|
.empty { color: #bbb; }
|
|
286
499
|
footer { margin-top: 40px; font-size: 9pt; color: #888; text-align: center; }
|
|
287
500
|
@media screen { body { background: #f3f3f3; } .page { background: #fff; max-width: 210mm; min-height: 297mm; padding: 20mm; box-shadow: 0 1px 8px rgba(0,0,0,.15); } }
|
|
@@ -343,7 +556,7 @@ function printDocument(template, doc, opts) {
|
|
|
343
556
|
printHtml(buildPrintHtml(template, doc, opts));
|
|
344
557
|
}
|
|
345
558
|
|
|
346
|
-
// src/agent-tools.ts
|
|
559
|
+
// src/lib/agent-tools.ts
|
|
347
560
|
var CATEGORY_ENUM = ["anamnesis", "evolution", "report", "contract", "general"];
|
|
348
561
|
var FIELD_SHAPE = "A field object: { type, label, required?, placeholder?, options?[] }. type \u2208 title|text|memo|richtext|date|select|radio|tags|checkbox|image|gallery|budget (title = section heading, no input). options are plain strings, only for select/radio/tags.";
|
|
349
562
|
var createOrUpdateFormTool = {
|
|
@@ -434,5 +647,5 @@ function prefillFromPerson(schema, person, existing = {}) {
|
|
|
434
647
|
}
|
|
435
648
|
|
|
436
649
|
export { FORM_BUILDER_INSTRUCTIONS, FormRenderer, PERSON_FIELD_OPTIONS, buildPrintHtml, createOrUpdateFormTool, prefillFromPerson, printDocument };
|
|
437
|
-
//# sourceMappingURL=chunk-
|
|
438
|
-
//# sourceMappingURL=chunk-
|
|
650
|
+
//# sourceMappingURL=chunk-RBLXIKWB.js.map
|
|
651
|
+
//# sourceMappingURL=chunk-RBLXIKWB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/html-text.ts","../src/components/FormRenderer.tsx","../src/lib/print.ts","../src/lib/agent-tools.ts","../src/lib/person-fields.ts"],"names":["t","optionLabel"],"mappings":";;;;;;;;AAuBO,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,OAAO,kBAAA,CAAmB,KAAK,KAAK,CAAA;AACtC;AAKA,IAAM,MAAA,GAAS,sEAAA;AAIf,IAAM,IAAA,GAAO,IAAA;AAEN,SAAS,gBAAgB,KAAA,EAAuB;AACrD,EAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAEnB,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAInC,IAAA,OAAO,MACJ,OAAA,CAAQ,cAAA,EAAgB,IAAI,CAAA,CAC5B,OAAA,CAAQ,yCAAyC,IAAI,CAAA,CACrD,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,OAAA,CAAQ,WAAW,GAAG,CAAA,CACtB,QAAQ,OAAA,EAAS,GAAG,CAAA,CACpB,OAAA,CAAQ,SAAS,GAAG,CAAA,CACpB,QAAQ,SAAA,EAAW,GAAG,EACtB,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CAGrB,OAAA,CAAQ,UAAU,GAAG,CAAA,CACrB,QAAQ,SAAA,EAAW,MAAM,EACzB,IAAA,EAAK;AAAA,EACV;AAEA,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACvC,EAAA,EAAA,CAAG,SAAA,GAAY,KAAA;AACf,EAAA,KAAA,MAAW,MAAM,KAAA,CAAM,IAAA,CAAK,GAAG,gBAAA,CAAiB,IAAI,CAAC,CAAA,EAAG;AACtD,IAAA,EAAA,CAAG,YAAY,IAAI,CAAA;AAAA,EACrB;AACA,EAAA,KAAA,MAAW,SAAS,KAAA,CAAM,IAAA,CAAK,GAAG,gBAAA,CAAiB,MAAM,CAAC,CAAA,EAAG;AAC3D,IAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AAAA,EACnB;AAEA,EAAA,OAAA,CAAQ,EAAA,CAAG,WAAA,IAAe,EAAA,EACvB,OAAA,CAAQ,MAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,WAAA,EAAa,IAAI,CAAA,CACzB,OAAA,CAAQ,SAAA,EAAW,MAAM,EACzB,IAAA,EAAK;AACV;AAgCA,IAAM,iBAAA,uBAAwB,GAAA,CAAI;AAAA,EAChC,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EACvE,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,UAAA;AAAA,EAAY,QAAA;AAAA,EAAU,UAAA;AAAA,EAAY;AAC/D,CAAC,CAAA;AAID,IAAM,YAAA,uBAAmB,GAAA,CAAI;AAAA,EAC3B,GAAA;AAAA,EAAK,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,KAAA;AAAA,EAAO,MAAA;AAAA,EACxB,GAAA;AAAA,EAAK,QAAA;AAAA,EAAU,GAAA;AAAA,EAAK,IAAA;AAAA,EAAM,GAAA;AAAA,EAAK,GAAA;AAAA,EAAK,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,OAAA;AAAA,EAC1D,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,YAAA;AAAA,EAAc,KAAA;AAAA,EAAO,MAAA;AAAA,EACvC,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAC9B,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,SAAA;AAAA,EACtD;AACF,CAAC,CAAA;AAMD,IAAM,aAAA,GAA6C;AAAA,EACjD,mBAAG,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,EAC5B,oBAAI,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,SAAS,CAAC,CAAA;AAAA,EAClC,oBAAI,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,SAAS,CAAC;AACpC,CAAA;AAEA,IAAM,SAAA,GAAY,0BAAA;AAElB,SAAS,aAAa,EAAA,EAAmB;AAEvC,EAAA,KAAA,MAAW,KAAA,IAAS,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,EAAG;AAC3C,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AAEA,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,OAAA,CAAQ,WAAA,EAAY;AAEnC,EAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC9B,IAAA,EAAA,CAAG,MAAA,EAAO;AACV,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,UAAU,CAAA,EAAG;AAC5C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,WAAA,EAAY;AACnC,IAAA,MAAM,UAAU,aAAA,CAAc,GAAG,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,IAAK,KAAA;AACjD,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,EAAA,CAAG,eAAA,CAAgB,KAAK,IAAI,CAAA;AAC5B,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,KAAS,UAAU,CAAC,SAAA,CAAU,KAAK,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,CAAA,EAAG;AACzD,MAAA,EAAA,CAAG,eAAA,CAAgB,KAAK,IAAI,CAAA;AAAA,IAC9B;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,YAAA,CAAa,GAAA,CAAI,GAAG,CAAA,EAAG;AAC1B,IAAA,EAAA,CAAG,YAAY,GAAG,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,UAAU,CAAC,CAAA;AAC3C,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,QAAQ,GAAA,EAAK;AAGf,IAAA,IAAI,CAAC,EAAA,CAAG,YAAA,CAAa,MAAM,CAAA,EAAG;AAC5B,MAAA,EAAA,CAAG,YAAY,GAAG,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,UAAU,CAAC,CAAA;AAC3C,MAAA;AAAA,IACF;AACA,IAAA,EAAA,CAAG,YAAA,CAAa,UAAU,QAAQ,CAAA;AAClC,IAAA,EAAA,CAAG,YAAA,CAAa,OAAO,8BAA8B,CAAA;AAAA,EACvD;AACF;AASO,SAAS,aAAa,KAAA,EAAuB;AAClD,EAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AACnB,EAAA,IAAI,OAAO,SAAA,KAAc,WAAA,EAAa,OAAO,EAAA;AAE7C,EAAA,MAAM,MAAM,IAAI,SAAA,EAAU,CAAE,eAAA,CAAgB,OAAO,WAAW,CAAA;AAC9D,EAAA,KAAA,MAAW,SAAS,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AACjD,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AACA,EAAA,OAAO,IAAI,IAAA,CAAK,SAAA;AAClB;AAIO,SAAS,eAAe,KAAA,EAAqD;AAClF,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,CAAC,OAAO,OAAO,EAAE,MAAM,EAAA,EAAG;AAC3D,EAAA,IAAI,CAAC,aAAA,CAAc,KAAK,GAAG,OAAO,EAAE,MAAM,KAAA,EAAM;AAChD,EAAA,MAAM,IAAA,GAAO,aAAa,KAAK,CAAA;AAC/B,EAAA,OAAO,IAAA,GAAO,EAAE,IAAA,EAAK,GAAI,EAAE,IAAA,EAAM,eAAA,CAAgB,KAAK,CAAA,EAAE;AAC1D;ACxLA,IAAM,eAAA,GAAkB;AAAA,EACtB,WAAA;AAAA,EACA,uBAAA;AAAA,EACA,8CAAA;AAAA,EACA,4BAAA;AAAA,EACA,iBAAA;AAAA,EACA,qFAAA;AAAA,EACA,iHAAA;AAAA,EACA,oCAAA;AAAA,EACA,gEAAA;AAAA,EACA,6EAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,GAAG,CAAA;AAmBV,SAAS,SAAA,CAAU,EAAE,KAAA,EAAO,QAAA,EAAS,EAAkD;AACrF,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACZ,QAAA,EAAA;AAAA,IAAA,KAAA,oBAAS,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2CAAA,EAA6C,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBAC1E,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EAA2B,QAAA,EAAS;AAAA,GAAA,EACrD,CAAA;AAEJ;AAEA,SAAS,UAAA,GAAa;AACpB,EAAA,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA2B,QAAA,EAAA,QAAA,EAAC,CAAA;AACrD;AAIA,SAAS,WAAA,CAAY,OAAqB,KAAA,EAA+B;AACvE,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,EAAA,EAAI,OAAO,IAAA;AAC1C,EAAA,MAAM,KAAA,GAAA,CAAS,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA;AACjE,EAAA,OAAO,KAAA,EAAO,KAAA,IAAS,MAAA,CAAO,KAAK,CAAA;AACrC;AAEA,SAAS,SAAA,CAAU,EAAE,KAAA,EAAO,KAAA,EAAM,EAA4C;AAC5E,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,MAAA;AAAA,IACL,KAAK,UAAA,EAAY;AAQf,MAAA,MAAM,IAAA,GAAO,eAAe,KAAK,CAAA;AACjC,MAAA,uBACE,GAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,KAAA,CAAM,KAAA,EACrB,QAAA,EAAA,MAAA,IAAU,IAAA,mBACT,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,eAAA,EAAiB,uBAAA,EAAyB,EAAE,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAK,EAAG,CAAA,GAC/E,IAAA,CAAK,IAAA,mBACP,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,IAAA,CAAK,IAAA,EAAK,CAAA,mBAE9C,GAAA,CAAC,cAAW,CAAA,EAEhB,CAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,GAAA,GAAM,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,EAAA;AAChD,MAAA,MAAM,IAAA,GAAO,GAAA,GAAM,IAAI,IAAA,CAAK,GAAG,CAAA,GAAI,IAAA;AACnC,MAAA,MAAM,IAAA,GAAO,QAAQ,CAAC,MAAA,CAAO,MAAM,IAAA,CAAK,OAAA,EAAS,CAAA,GAG7C,GAAA,CAAI,MAAM,CAAA,EAAG,EAAE,EAAE,KAAA,CAAM,GAAG,EAAE,OAAA,EAAQ,CAAE,IAAA,CAAK,GAAG,CAAA,GAC9C,GAAA;AACJ,MAAA,uBAAO,GAAA,CAAC,aAAU,KAAA,EAAO,KAAA,CAAM,OAAQ,QAAA,EAAA,IAAA,oBAAQ,GAAA,CAAC,cAAW,CAAA,EAAG,CAAA;AAAA,IAChE;AAAA,IAEA,KAAK,QAAA;AAAA,IACL,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AACtC,MAAA,uBAAO,GAAA,CAAC,aAAU,KAAA,EAAO,KAAA,CAAM,OAAQ,QAAA,EAAA,KAAA,oBAAS,GAAA,CAAC,cAAW,CAAA,EAAG,CAAA;AAAA,IACjE;AAAA,IAEA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,WAAW,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAK,QAAqB,EAAC;AAC/D,MAAA,uBACE,GAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,KAAA,CAAM,OACrB,QAAA,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,mBACjB,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACZ,QAAA,EAAA,QAAA,CAAS,IAAI,CAAC,CAAA,qBACb,GAAA,CAAC,KAAA,EAAA,EAAc,OAAA,EAAQ,WAAA,EAAY,SAAA,EAAU,SAAA,EAC1C,sBAAY,KAAA,EAAO,CAAC,CAAA,IAAK,CAAA,EAAA,EADhB,CAEZ,CACD,CAAA,EACH,CAAA,mBAEA,GAAA,CAAC,cAAW,CAAA,EAEhB,CAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,UAAA;AAIH,MAAA,4BACG,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,CAAM,KAAA,EAAM,CAAA;AAAA,wBAC3C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,QAAA,EAAG,CAAA;AAAA,wBAC3C,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,GAAQ,KAAA,GAAQ,QAAA,EAAM;AAAA,OAAA,EAC/B,CAAA;AAAA,IAGJ,SAAS;AACP,MAAA,MAAM,OAAO,KAAA,IAAS,IAAA,IAAQ,UAAU,EAAA,GAAK,IAAA,GAAO,OAAO,KAAK,CAAA;AAChE,MAAA,uBAAO,GAAA,CAAC,aAAU,KAAA,EAAO,KAAA,CAAM,OAAQ,QAAA,EAAA,IAAA,oBAAQ,GAAA,CAAC,cAAW,CAAA,EAAG,CAAA;AAAA,IAChE;AAAA;AAEJ;AAEA,SAAS,aAAA,CAAc;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAU,cAAA;AAIV,EAAA,IAAI,QAAA,IAAY,KAAA,CAAM,IAAA,KAAS,OAAA,IAAW,KAAA,CAAM,IAAA,KAAS,OAAA,IAAW,KAAA,CAAM,IAAA,KAAS,SAAA,IAAa,KAAA,CAAM,IAAA,KAAS,QAAA,EAAU;AACvH,IAAA,uBAAO,GAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAc,KAAA,EAAc,CAAA;AAAA,EAChD;AAEA,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,OAAA;AACH,MAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4CAAA,EACX,gBAAM,KAAA,EACT,CAAA;AAAA,IAGJ,KAAK,MAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,OAAQ,KAAA,IAAoB,EAAA;AAAA,YAC5B,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,YACxC,aAAa,KAAA,CAAM,WAAA;AAAA,YACnB,SAAA,EAAU,aAAA;AAAA,YACV;AAAA;AAAA;AACF,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,MAAA;AAAA,IACL,KAAK,UAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAQ,KAAA,IAAoB,EAAA;AAAA,YAC5B,UAAU,CAAC,CAAA,KAA8C,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,YAChF,aAAa,KAAA,CAAM,WAAA;AAAA,YACnB,SAAA,EAAU,uPAAA;AAAA,YACV;AAAA;AAAA;AACF,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,MAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,MAAA;AAAA,YACL,OAAQ,KAAA,IAAoB,EAAA;AAAA,YAC5B,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,YACxC,SAAA,EAAU,aAAA;AAAA,YACV;AAAA;AAAA;AACF,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,QAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,QACC,QAAA,mBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gBAAiB,QAAA,EAAA,KAAA,IAAoB,GAAA,EAAI,CAAA,mBAEtD,IAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAQ,KAAA,IAAoB,EAAA,EAAI,eAAe,QAAA,EACrD,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,aAAA,EAAA,EAAc,WAAU,aAAA,EACvB,QAAA,kBAAA,GAAA,CAAC,eAAY,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,EAAO,CAAA,EACxD,CAAA;AAAA,8BACC,aAAA,EAAA,EACG,QAAA,EAAA,CAAA,KAAA,CAAM,WAAW,EAAC,EAAG,IAAI,CAAC,GAAA,yBACzB,UAAA,EAAA,EAA2B,KAAA,EAAO,IAAI,KAAA,EACpC,QAAA,EAAA,GAAA,CAAI,SADU,GAAA,CAAI,KAErB,CACD,CAAA,EACH;AAAA,SAAA,EACF;AAAA,OAAA,EAEJ,CAAA;AAAA,IAGJ,KAAK,OAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACX,iBAAM,OAAA,IAAW,EAAC,EAAG,GAAA,CAAI,CAAC,GAAA,qBAC1B,IAAA,CAAC,OAAA,EAAA,EAAsB,WAAU,wCAAA,EAC/B,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,OAAA;AAAA,cACL,MAAM,KAAA,CAAM,EAAA;AAAA,cACZ,OAAO,GAAA,CAAI,KAAA;AAAA,cACX,OAAA,EAAS,UAAU,GAAA,CAAI,KAAA;AAAA,cACvB,QAAA,EAAU,MAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAAA,cAClC,QAAA,EAAU,QAAA;AAAA,cACV,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,cAAI,KAAA,EAAM;AAAA,SAAA,EAAA,EAV3B,GAAA,CAAI,KAWhB,CACD,CAAA,EACH;AAAA,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,eAAe,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAK,QAAqB,EAAC;AACnE,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACX,QAAA,EAAA,CAAA,KAAA,CAAM,WAAW,EAAC,EAAG,GAAA,CAAI,CAAC,GAAA,KAAQ;AAClC,UAAA,MAAM,MAAA,GAAS,YAAA,CAAa,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAC9C,UAAA,uBACE,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,SAAS,SAAA,GAAY,SAAA;AAAA,cAC9B,SAAA,EAAW,CAAA,uBAAA,EAA0B,QAAA,GAAW,qBAAA,GAAwB,EAAE,CAAA,CAAA;AAAA,cAC1E,SAAS,MAAM;AACb,gBAAA,IAAI,QAAA,EAAU;AACd,gBAAA,QAAA;AAAA,kBACE,MAAA,GACI,YAAA,CAAa,MAAA,CAAO,CAACA,EAAAA,KAAMA,EAAAA,KAAM,GAAA,CAAI,KAAK,CAAA,GAC1C,CAAC,GAAG,YAAA,EAAc,IAAI,KAAK;AAAA,iBACjC;AAAA,cACF,CAAA;AAAA,cAEC,QAAA,EAAA,GAAA,CAAI;AAAA,aAAA;AAAA,YAZA,GAAA,CAAI;AAAA,WAaX;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA,OAAA,EACF,CAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,UAAA;AACH,MAAA,uBACE,IAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,6CAAA,EACf,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,UAAA;AAAA,YACL,OAAA,EAAS,CAAC,CAAC,KAAA;AAAA,YACX,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,OAAO,CAAA;AAAA,YAC1C,QAAA,EAAU,QAAA;AAAA,YACV,SAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE;AAAA,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,OAAA;AAAA,IACL,KAAK,SAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uGAAA,EACZ,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,IAAA,KAAS,YAAY,gBAAA,GAAmB,cAAA;AAAA,UAAe;AAAA,SAAA,EAChE;AAAA,OAAA,EACF,CAAA;AAAA,IAGJ,KAAK,QAAA;AACH,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,WAAU,2BAAA,EACd,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,KAAA;AAAA,UACN,MAAM,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uGAAA,EAAwG,QAAA,EAAA,+BAAA,EAEvH;AAAA,OAAA,EACF,CAAA;AAAA,IAGJ;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEO,SAAS,aAAa,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU,UAAS,EAAsB;AACpF,EAAA,MAAM,eAAe,CAAC,GAAG,MAAA,CAAO,MAAM,EAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,GAAA,GAAM,CAAA,CAAE,OAAO,CAAA,CAAE,GAAA,GAAM,EAAE,GAAG,CAAA;AAErF,EAAA,MAAM,iBAAA,GAAoB,WAAA;AAAA,IACxB,CAAC,SAAiB,KAAA,KAAmB;AACnC,MAAA,QAAA,CAAS,EAAE,GAAG,IAAA,EAAM,CAAC,OAAO,GAAG,OAAO,CAAA;AAAA,IACxC,CAAA;AAAA,IACA,CAAC,MAAM,QAAQ;AAAA,GACjB;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,sBAAA;AAAA,MACV,KAAA,EAAO,EAAE,mBAAA,EAAqB,iBAAA,EAAkB;AAAA,MAE/C,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAC,KAAA,qBACjB,GAAA,CAAC,KAAA,EAAA,EAAmB,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA,KAAA,EAAQ,KAAA,CAAM,OAAO,IAAG,EAC/D,QAAA,kBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA;AAAA,UACpB,UAAU,CAAC,CAAA,KAAM,iBAAA,CAAkB,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,UAC9C;AAAA;AAAA,OACF,EAAA,EANQ,KAAA,CAAM,EAOhB,CACD;AAAA;AAAA,GACH;AAEJ;;;AC3XA,SAAS,IAAI,KAAA,EAAwB;AACnC,EAAA,OAAO,MAAA,CAAO,KAAA,IAAS,EAAE,CAAA,CAAE,OAAA;AAAA,IAAQ,UAAA;AAAA,IAAY,CAAC,CAAA,KAAA,CAC7C,EAAE,GAAA,EAAK,SAAS,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,QAAA,EAAU,GAAA,EAAK,OAAA,IAAU,CAAC;AAAA,GAC5E;AACF;AAEA,SAAS,MAAM,KAAA,EAAuB;AACpC,EAAA,OAAO,GAAA,CAAI,KAAK,CAAA,CAAE,OAAA,CAAQ,UAAU,OAAO,CAAA;AAC7C;AAEA,SAAS,WAAW,KAAA,EAAuB;AAEzC,EAAA,MAAM,CAAA,GAAI,0BAAA,CAA2B,IAAA,CAAK,KAAK,CAAA;AAC/C,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,GAAA,CAAI,KAAK,CAAA;AACxB,EAAA,OAAO,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA;AAChC;AAEA,SAASC,YAAAA,CAAY,OAAqB,KAAA,EAAwB;AAChE,EAAA,MAAM,GAAA,GAAA,CAAO,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA;AAC/D,EAAA,OAAO,GAAA,CAAI,GAAA,GAAM,GAAA,CAAI,KAAA,GAAQ,KAAK,CAAA;AACpC;AAGA,SAAS,WAAA,CAAY,OAAqB,KAAA,EAAwB;AAChE,EAAA,MAAM,KAAA,GAAQ,mCAAA;AACd,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,MAAA;AAAA,IACL,KAAK,UAAA,EAAY;AAQf,MAAA,MAAM,IAAA,GAAO,eAAe,KAAK,CAAA;AACjC,MAAA,IAAI,MAAA,IAAU,IAAA,EAAM,OAAO,CAAA,uBAAA,EAA0B,KAAK,IAAI,CAAA,MAAA,CAAA;AAC9D,MAAA,OAAO,KAAK,IAAA,GAAO,CAAA,kBAAA,EAAqB,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,MAAA,CAAA,GAAW,KAAA;AAAA,IACrE;AAAA,IACA,KAAK,MAAA;AACH,MAAA,OAAO,KAAA,GAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA,GAAI,KAAA;AAAA,IAC7C,KAAK,QAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,KAAA,GAAQA,YAAAA,CAAY,KAAA,EAAO,KAAK,CAAA,GAAI,KAAA;AAAA,IAC7C,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,MAAM,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,QAAQ,EAAC;AAC5C,MAAA,OAAO,GAAA,CAAI,MAAA,GACP,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAMA,YAAAA,CAAY,KAAA,EAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAC/C,KAAA;AAAA,IACN;AAAA,IACA,KAAK,UAAA;AACH,MAAA,OAAO,QAAQ,KAAA,GAAQ,QAAA;AAAA,IACzB,KAAK,OAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,QAAA;AACH,MAAA,OAAO,EAAA;AAAA;AAAA,IACT;AACE,MAAA,OAAO,KAAA,GAAQ,GAAA,CAAI,KAAK,CAAA,GAAI,KAAA;AAAA;AAElC;AAUO,SAAS,cAAA,CACd,QAAA,EACA,GAAA,EACA,IAAA,GAA0B,EAAC,EACnB;AACR,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,GAAA,CAAI,SAAS,QAAA,CAAS,IAAA;AACtD,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,CAAK,UAAA,IAAc,GAAA,CAAI,YAAY,IAAI,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA,CAAE,kBAAA,EAAoB,CAAA,CAC9F,MAAA,CAAO,OAAO,CAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,CAAC,CAAC,CAAA,CACjB,IAAA,CAAK,YAAY,CAAA;AAEpB,EAAA,MAAM,SAAS,CAAC,GAAG,SAAS,MAAA,CAAO,MAAM,EAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,GAAA,GAAM,CAAA,CAAE,OAAO,CAAA,CAAE,GAAA,GAAM,EAAE,GAAG,CAAA;AAExF,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,MAAA,CAAO,CAAC,CAAA,IAAK,EAAE,CAAC,CAAA;AAI3E,EAAA,MAAM,IAAA,GAAO,MAAA,CACV,GAAA,CAAI,CAAC,KAAA,KAAU;AACd,IAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,MAAA,OAAO,CAAA,gDAAA,EAAmD,GAAA,CAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAA,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,WAAW,WAAA,CAAY,KAAA,EAAO,IAAI,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA;AACtD,IAAA,IAAI,QAAA,KAAa,IAAI,OAAO,EAAA;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,KAAS,MAAA,IAAU,MAAM,IAAA,KAAS,UAAA;AACvD,IAAA,OAAO,CAAA,iBAAA,EAAoB,SAAS,cAAA,GAAiB,EAAE,8BAA8B,SAAA,CAAU,KAAA,CAAM,OAAO,CAAC,CAAA;AAAA,2BAAA,EACtF,GAAA,CAAI,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,2BAAA,EAChB,QAAQ,CAAA;AAAA,YAAA,CAAA;AAAA,EAEjC,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA,OAAA,EAIA,GAAA,CAAI,OAAO,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EA6CT,GAAA,CAAI,OAAO,CAAC,CAAA;AAAA,MAAA,EAChB,QAAA,GAAW,CAAA,iBAAA,EAAoB,QAAQ,CAAA,MAAA,CAAA,GAAW,EAAE;AAAA;AAAA;AAAA,MAAA,EAGpD,IAAI;AAAA;AAAA;AAAA;AAAA,OAAA,CAAA;AAKZ;AAMO,SAAS,UAAU,IAAA,EAAoB;AAC5C,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAA,CAAO,YAAA,CAAa,eAAe,MAAM,CAAA;AACzC,EAAA,MAAA,CAAO,MAAM,QAAA,GAAW,OAAA;AACxB,EAAA,MAAA,CAAO,MAAM,KAAA,GAAQ,GAAA;AACrB,EAAA,MAAA,CAAO,MAAM,MAAA,GAAS,GAAA;AACtB,EAAA,MAAA,CAAO,MAAM,KAAA,GAAQ,GAAA;AACrB,EAAA,MAAA,CAAO,MAAM,MAAA,GAAS,GAAA;AACtB,EAAA,MAAA,CAAO,MAAM,MAAA,GAAS,GAAA;AACtB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAEhC,EAAA,MAAM,UAAU,MAAM;AAEpB,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,IAAI,MAAA,CAAO,UAAA,EAAY,MAAA,CAAO,UAAA,CAAW,YAAY,MAAM,CAAA;AAAA,IAC7D,GAAG,GAAI,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,MAAM,MAAA,CAAO,aAAA;AACnB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,eAAA,IAAmB,GAAA,EAAK,QAAA;AAC5C,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,IAAA,EAAM;AACjB,IAAA,OAAA,EAAQ;AACR,IAAA;AAAA,EACF;AAEA,EAAA,IAAA,CAAK,IAAA,EAAK;AACV,EAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AACf,EAAA,IAAA,CAAK,KAAA,EAAM;AAEX,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,IAAI;AACF,MAAA,GAAA,CAAI,KAAA,EAAM;AACV,MAAA,GAAA,CAAI,KAAA,EAAM;AAAA,IACZ,CAAA,SAAE;AACA,MAAA,OAAA,EAAQ;AAAA,IACV;AAAA,EACF,CAAA;AAGA,EAAA,IAAI,IAAA,CAAK,eAAe,UAAA,EAAY;AAClC,IAAA,UAAA,CAAW,SAAS,EAAE,CAAA;AAAA,EACxB,CAAA,MAAO;AACL,IAAA,MAAA,CAAO,gBAAA,CAAiB,MAAA,EAAQ,MAAM,UAAA,CAAW,OAAA,EAAS,EAAE,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,EAC/E;AACF;AAGO,SAAS,aAAA,CACd,QAAA,EACA,GAAA,EACA,IAAA,EACM;AACN,EAAA,SAAA,CAAU,cAAA,CAAe,QAAA,EAAU,GAAA,EAAK,IAAI,CAAC,CAAA;AAC/C;;;AC1NA,IAAM,gBAAgB,CAAC,WAAA,EAAa,WAAA,EAAa,QAAA,EAAU,YAAY,SAAS,CAAA;AAEhF,IAAM,WAAA,GACJ,6PAAA;AAIK,IAAM,sBAAA,GAAuC;AAAA,EAClD,EAAA,EAAI,iCAAA;AAAA,EACJ,IAAA,EAAM,oBAAA;AAAA,EACN,WAAA,EACE,mjBAAA;AAAA,EAIF,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,QAAA,EAAU,gBAAA;AAAA,EACV,UAAA,EAAY,EAAE,OAAA,EAAS,cAAA,EAAgB,QAAQ,QAAA,EAAS;AAAA,EACxD,WAAW,EAAE,KAAA,EAAO,UAAU,IAAA,EAAM,KAAA,EAAO,KAAK,6BAAA,EAA8B;AAAA,EAC9E,QAAA,EAAU,OAAA;AAAA,EACV,WAAA,EAAa;AAAA,IACX,EAAE,OAAO,oCAAA,EAAkC;AAAA,IAC3C,EAAE,OAAO,mDAAA;AAAiD,GAC5D;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,0CAAA,EAAsC;AAAA,MAC3E,QAAA,EAAU;AAAA,QACR,IAAA,EAAM,QAAA;AAAA,QACN,IAAA,EAAM,CAAC,GAAG,aAAa,CAAA;AAAA,QACvB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,yCAAA,EAA0C;AAAA,MACtF,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,OAAA;AAAA,QACN,WAAA,EAAa,gFAA2E,WAAW,CAAA,CAAA;AAAA,QACnG,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,WAAA;AAAY,OACpD;AAAA,MACA,aAAA,EAAe;AAAA,QACb,IAAA,EAAM,OAAA;AAAA,QACN,WAAA,EAAa,8HAA8H,WAAW,CAAA,CAAA;AAAA,QACtJ,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,WAAA;AAAY;AACpD;AACF;AAEJ;AAEO,IAAM,yBAAA,GAA4B;AAAA,EACvC,yLAAA;AAAA,EACA,2HAAA;AAAA,EACA,oLAAA;AAAA,EACA,2LAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,GAAG;;;AC1DH,IAAM,oBAAA,GAAmE;AAAA,EAC9E,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,8BAAA,EAA+B;AAAA,EAC1D,EAAE,KAAA,EAAO,gBAAA,EAAkB,QAAA,EAAU,wCAAA,EAAyC;AAAA,EAC9E,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,+BAAA,EAAgC;AAAA,EAC5D,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,+BAAA,EAAgC;AAAA,EAC5D,EAAE,KAAA,EAAO,aAAA,EAAe,QAAA,EAAU,qCAAA,EAAsC;AAAA,EACxE,EAAE,KAAA,EAAO,cAAA,EAAgB,QAAA,EAAU,sCAAA,EAAuC;AAAA,EAC1E,EAAE,KAAA,EAAO,SAAA,EAAW,QAAA,EAAU,iCAAA,EAAkC;AAAA,EAChE,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,8BAAA,EAA+B;AAAA,EAC1D,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,+BAAA;AAC9B;AAEA,IAAM,OAAA,GAAU,CAAC,CAAA,KAAc,CAAA,CAAE,OAAA,CAAQ,QAAA,EAAU,CAAC,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAC/E,IAAM,OAAA,GAAU,CAAC,CAAA,KAAc,CAAA,CAAE,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA,EAAG,CAAA,KAAc,CAAA,CAAE,WAAA,EAAa,CAAA;AAGhF,SAAS,kBAAA,CACd,QACA,MAAA,EACS;AACT,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,MAAA;AAC/B,EAAA,KAAA,MAAW,GAAA,IAAO,CAAC,MAAA,EAAQ,OAAA,CAAQ,MAAM,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAC,CAAA,EAAG;AAC5D,IAAA,MAAM,CAAA,GAAI,OAAO,GAAG,CAAA;AACpB,IAAA,IAAI,CAAA,IAAK,IAAA,IAAQ,CAAA,KAAM,EAAA,EAAI,OAAO,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,iBAAA,CACd,MAAA,EACA,MAAA,EACA,QAAA,GAAoC,EAAC,EACZ;AACzB,EAAA,MAAM,IAAA,GAAgC,EAAE,GAAG,QAAA,EAAS;AACpD,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA;AAC7B,IAAA,IAAI,OAAA,IAAW,IAAA,IAAQ,OAAA,KAAY,EAAA,EAAI;AACvC,IAAA,MAAM,SAAS,KAAA,CAAM,GAAA,GAAM,mBAAmB,MAAA,EAAQ,KAAA,CAAM,GAAG,CAAA,GAAI,MAAA;AACnE,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA,GAAI,MAAA;AAAA,IACnB,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,IAAgB,IAAA,EAAM;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,EAAE,CAAA,GAAI,KAAA,CAAM,YAAA;AAAA,IACzB;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT","file":"chunk-RBLXIKWB.js","sourcesContent":["// ============================================================\n// HTML guardado num campo de formulário → texto legível\n// ============================================================\n//\n// Os campos `richtext` (e alguns `memo` vindos de importação) guardam HTML: o\n// conteúdo trazido do Feegow chega como `<p dir=\"ltr\"><b id=\"docs-internal-guid-\n// …\">Está triste, mas sabe que vai superar. </b></p>` — colado de um Google\n// Docs, com atributos e tudo.\n//\n// Isso dá dois jeitos ERRADOS de mostrar, e o produto já teve os dois:\n//\n// • escapar e imprimir → a pessoa lê `<p dir="ltr">` numa\n// ficha de atendimento. Era o que a impressão fazia.\n// • injetar como HTML → a marcação some da tela, mas o documento passa a poder\n// trazer <script>/<img onerror> de dentro do banco para dentro da página.\n// Consertar a primeira coisa caindo na segunda seria trocar um problema de\n// leitura por um de execução.\n//\n// O certo é o terceiro: extrair o TEXTO do HTML e escapar esse texto. Fica\n// legível e nada do que estava guardado é executado — o parser monta os nós, e\n// `textContent` nunca roda nenhum deles.\n\n/** Parece HTML? Uma tag de abertura ou fechamento basta. */\nexport function looksLikeHtml(value: string): boolean {\n return /<\\/?[a-z][^>]*>/i.test(value)\n}\n\n// Blocos viram quebra de linha ANTES de extrair o texto. `textContent` sozinho\n// cola os parágrafos — \"…17.07.26Está triste, mas sabe…\" — e numa evolução\n// clínica o parágrafo É a estrutura do que foi dito.\nconst BLOCKS = 'p, div, li, tr, h1, h2, h3, h4, h5, h6, blockquote, section, article'\n\n/** Espaço rígido (U+00A0): o parser decodifica ` ` para ele, mas ele não\n * quebra linha e o `trim()` não o remove. Vira espaço comum. */\nconst NBSP = / /g\n\nexport function htmlToPlainText(value: string): string {\n if (!value) return ''\n\n if (typeof document === 'undefined') {\n // Sem DOM (teste em node, render no servidor). Um \"parser\" de regex é uma\n // aproximação, e está assumido como tal: derruba as tags para não devolver\n // marcação, e não pretende estar certo para HTML arbitrário.\n return value\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/(p|div|li|tr|h[1-6]|blockquote)>/gi, '\\n')\n .replace(/<[^>]*>/g, '')\n .replace(/ /g, ' ')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n // `&` por último: antes dos outros, ele transformaria `&lt;` em\n // `<` — decodificando uma vez a mais do que o texto pedia.\n .replace(/&/g, '&')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n }\n\n const el = document.createElement('div')\n el.innerHTML = value\n for (const br of Array.from(el.querySelectorAll('br'))) {\n br.replaceWith('\\n')\n }\n for (const block of Array.from(el.querySelectorAll(BLOCKS))) {\n block.append('\\n')\n }\n\n return (el.textContent ?? '')\n .replace(NBSP, ' ')\n .replace(/[ \\t]+\\n/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n}\n\n/** Texto legível de um campo longo, seja ele HTML guardado ou texto puro. */\nexport function fieldTextValue(value: unknown): string {\n if (typeof value !== 'string') return ''\n // Um memo digitado à mão passa intacto: converter tudo faria \"a < b virou c\"\n // perder o que vem depois do `<`.\n return looksLikeHtml(value) ? htmlToPlainText(value) : value\n}\n\n// ============================================================\n// Sanitização — mostrar a FORMATAÇÃO sem executar o documento\n// ============================================================\n//\n// Texto puro resolve a legibilidade e perde o resto: negrito, parágrafo, lista.\n// Numa evolução clínica colada do Docs, o negrito costuma ser o que a\n// terapeuta destacou, e a lista é a lista. Achatar tudo é jogar fora sentido\n// que estava lá.\n//\n// Então o HTML volta a ser HTML — mas passando por uma lista de permissão. O\n// que não está nela não é \"provavelmente inofensivo\": é removido. Isso é o\n// contrário de uma lista de proibições, que só protege do que alguém lembrou\n// de proibir.\n//\n// `DOMParser` com 'text/html' monta um documento INERTE: nenhum script roda,\n// nenhuma imagem é buscada, nenhum `onerror` dispara — nem durante a análise,\n// nem enquanto caminhamos pela árvore. É por isso que a limpeza acontece aqui e\n// não com regex sobre a string, que nunca dá conta de HTML malformado (e é\n// justamente com HTML malformado que se burla um filtro de regex).\n\n/** Some com o elemento E com o conteúdo dele. Desembrulhar um <script> jogaria\n * o código para dentro do texto visível. */\nconst DROP_WITH_CONTENT = new Set([\n 'script', 'style', 'iframe', 'object', 'embed', 'svg', 'math', 'link', 'meta',\n 'form', 'input', 'button', 'textarea', 'select', 'template', 'noscript',\n])\n\n/** Some com a TAG e mantém os filhos: um `<font>` ou um `<span>` desconhecido\n * não deve levar embora a frase que estava dentro dele. */\nconst ALLOWED_TAGS = new Set([\n 'p', 'br', 'hr', 'div', 'span',\n 'b', 'strong', 'i', 'em', 'u', 's', 'sub', 'sup', 'mark', 'small',\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'table', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th', 'caption',\n 'a',\n])\n\n/** Só o que é preciso para um link funcionar. `style`, `class`, `id` e todo\n * `on*` ficam de fora — o `id=\"docs-internal-guid-…\"` que vem do Google Docs\n * é lixo de origem, e `style` é caminho para `expression()`/`url(javascript:)`\n * em motores antigos. */\nconst ALLOWED_ATTRS: Record<string, Set<string>> = {\n a: new Set(['href', 'title']),\n td: new Set(['colspan', 'rowspan']),\n th: new Set(['colspan', 'rowspan']),\n}\n\nconst SAFE_HREF = /^(https?:|mailto:|tel:)/i\n\nfunction cleanElement(el: Element): void {\n // Percorre uma CÓPIA: remover/desembrulhar filhos mexe na lista viva.\n for (const child of Array.from(el.children)) {\n cleanElement(child)\n }\n\n const tag = el.tagName.toLowerCase()\n\n if (DROP_WITH_CONTENT.has(tag)) {\n el.remove()\n return\n }\n\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase()\n const allowed = ALLOWED_ATTRS[tag]?.has(name) ?? false\n if (!allowed) {\n el.removeAttribute(attr.name)\n continue\n }\n // `href=\"javascript:…\"` é o caso clássico de atributo permitido com valor\n // que não é.\n if (name === 'href' && !SAFE_HREF.test(attr.value.trim())) {\n el.removeAttribute(attr.name)\n }\n }\n\n if (!ALLOWED_TAGS.has(tag)) {\n el.replaceWith(...Array.from(el.childNodes))\n return\n }\n\n if (tag === 'a') {\n // Um <a> que perdeu o href (era `javascript:`) continuaria azul e\n // sublinhado, prometendo um destino que não existe. Vira o texto que é.\n if (!el.getAttribute('href')) {\n el.replaceWith(...Array.from(el.childNodes))\n return\n }\n el.setAttribute('target', '_blank')\n el.setAttribute('rel', 'noopener noreferrer nofollow')\n }\n}\n\n/**\n * HTML guardado → HTML seguro de renderizar.\n *\n * Sem DOMParser (node, SSR) devolve string vazia em vez de deixar passar: quem\n * chama tem o texto puro como alternativa, e \"não consegui limpar\" nunca pode\n * virar \"então mando cru\".\n */\nexport function sanitizeHtml(value: string): string {\n if (!value) return ''\n if (typeof DOMParser === 'undefined') return ''\n\n const doc = new DOMParser().parseFromString(value, 'text/html')\n for (const child of Array.from(doc.body.children)) {\n cleanElement(child)\n }\n return doc.body.innerHTML\n}\n\n/** O campo longo pronto para exibir: `html` quando dá para formatar com\n * segurança, `text` quando não (e o chamador escapa esse). */\nexport function fieldRichValue(value: unknown): { html: string } | { text: string } {\n if (typeof value !== 'string' || !value) return { text: '' }\n if (!looksLikeHtml(value)) return { text: value }\n const html = sanitizeHtml(value)\n return html ? { html } : { text: htmlToPlainText(value) }\n}\n","import React, { useCallback } from 'react'\nimport { Input } from '@fayz-ai/ui'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@fayz-ai/ui'\nimport { Badge } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport { fieldRichValue } from '../lib/html-text'\nimport type { FormFieldDef, FormSchema } from '../types'\n\n// O HTML sanitizado chega sem `class` nenhuma (a lista de permissão derruba\n// todas), então o espaçamento e os pesos vêm daqui, pelo seletor de filho. Sem\n// isto o Tailwind zera as margens de `<p>`/`<ul>` no preflight e os parágrafos\n// do documento voltam a se colar uns nos outros.\nconst RICH_TEXT_CLASS = [\n 'space-y-2',\n '[&_p]:leading-relaxed',\n '[&_b]:font-semibold [&_strong]:font-semibold',\n '[&_i]:italic [&_em]:italic',\n '[&_u]:underline',\n '[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5 [&_li]:leading-relaxed',\n '[&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground',\n '[&_a]:text-primary [&_a]:underline',\n '[&_h1]:font-semibold [&_h2]:font-semibold [&_h3]:font-semibold',\n '[&_table]:w-full [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1',\n '[&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:font-medium',\n].join(' ')\n\ninterface FormRendererProps {\n schema: FormSchema\n data: Record<string, unknown>\n onChange: (data: Record<string, unknown>) => void\n readOnly?: boolean\n}\n\n/**\n * Leitura é uma APRESENTAÇÃO, não um formulário travado.\n *\n * `readOnly` chegava no `<input readOnly>` e parava aí: caixa, borda, cursor de\n * texto, radio marcado — pixel por pixel a mesma tela de preencher. Abrir uma\n * anamnese de fevereiro parecia estar editando a anamnese de fevereiro, e a\n * única pista do contrário era o campo não aceitar digitação. Aqui o valor vira\n * texto e some a moldura: dá para ler de cima a baixo sem confundir com um\n * rascunho aberto.\n */\nfunction ReadField({ label, children }: { label?: string; children: React.ReactNode }) {\n return (\n <div className=\"space-y-0.5\">\n {label && <p className=\"text-xs font-medium text-muted-foreground\">{label}</p>}\n <div className=\"text-sm text-foreground\">{children}</div>\n </div>\n )\n}\n\nfunction EmptyValue() {\n return <span className=\"text-muted-foreground/50\">—</span>\n}\n\n/** O rótulo escolhido, não o valor cru: um documento que mostra \"prefer_not_say\"\n * faz a pessoa traduzir de cabeça o que a tela já sabia dizer. */\nfunction optionLabel(field: FormFieldDef, value: unknown): string | null {\n if (value == null || value === '') return null\n const match = (field.options ?? []).find((o) => o.value === value)\n return match?.label ?? String(value)\n}\n\nfunction ReadValue({ field, value }: { field: FormFieldDef; value: unknown }) {\n switch (field.type) {\n case 'memo':\n case 'richtext': {\n // Formatação preservada, documento não executado: o valor passa pela\n // lista de permissão de lib/html-text.ts e volta como HTML seguro. O\n // negrito que a terapeuta aplicou continua negrito; o\n // `id=\"docs-internal-guid-…\"` que veio junto do Google Docs não sobrevive.\n //\n // Sem tag nenhuma (memo digitado à mão) é texto puro mesmo, com as\n // quebras respeitadas pelo `whitespace-pre-wrap`.\n const rich = fieldRichValue(value)\n return (\n <ReadField label={field.label}>\n {'html' in rich ? (\n <div className={RICH_TEXT_CLASS} dangerouslySetInnerHTML={{ __html: rich.html }} />\n ) : rich.text ? (\n <p className=\"whitespace-pre-wrap\">{rich.text}</p>\n ) : (\n <EmptyValue />\n )}\n </ReadField>\n )\n }\n\n case 'date': {\n const raw = typeof value === 'string' ? value : ''\n const date = raw ? new Date(raw) : null\n const text = date && !Number.isNaN(date.getTime())\n // `T00:00` faz o Date nascer em UTC e o fuso do Brasil o joga para o dia\n // anterior — daí o corte manual em vez de toLocaleDateString direto.\n ? raw.slice(0, 10).split('-').reverse().join('/')\n : raw\n return <ReadField label={field.label}>{text || <EmptyValue />}</ReadField>\n }\n\n case 'select':\n case 'radio': {\n const label = optionLabel(field, value)\n return <ReadField label={field.label}>{label ?? <EmptyValue />}</ReadField>\n }\n\n case 'tags': {\n const selected = Array.isArray(value) ? (value as string[]) : []\n return (\n <ReadField label={field.label}>\n {selected.length > 0 ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {selected.map((v) => (\n <Badge key={v} variant=\"secondary\" className=\"text-xs\">\n {optionLabel(field, v) ?? v}\n </Badge>\n ))}\n </div>\n ) : (\n <EmptyValue />\n )}\n </ReadField>\n )\n }\n\n case 'checkbox':\n // Sem rótulo próprio: o texto do checkbox JÁ é a pergunta (\"Autoriza uso\n // de imagem\"), então repeti-lo acima da resposta diria duas vezes a mesma\n // coisa.\n return (\n <ReadField>\n <span className=\"font-medium\">{field.label}</span>\n <span className=\"text-muted-foreground\"> · </span>\n <span>{value ? 'Sim' : 'Não'}</span>\n </ReadField>\n )\n\n default: {\n const text = value == null || value === '' ? null : String(value)\n return <ReadField label={field.label}>{text ?? <EmptyValue />}</ReadField>\n }\n }\n}\n\nfunction FieldRenderer({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: FormFieldDef\n value: unknown\n onChange: (value: unknown) => void\n readOnly?: boolean\n}) {\n const t = useTranslation()\n\n // Título e os blocos ainda não implementados continuam iguais nos dois modos:\n // um é estrutura do documento, os outros não têm valor para apresentar.\n if (readOnly && field.type !== 'title' && field.type !== 'image' && field.type !== 'gallery' && field.type !== 'budget') {\n return <ReadValue field={field} value={value} />\n }\n\n switch (field.type) {\n case 'title':\n return (\n <h3 className=\"text-base font-semibold pt-2 pb-1 border-b\">\n {field.label}\n </h3>\n )\n\n case 'text':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <Input\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder}\n className=\"h-9 text-sm\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'memo':\n case 'richtext':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <textarea\n value={(value as string) ?? ''}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value)}\n placeholder={field.placeholder}\n className=\"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 min-h-[100px]\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'date':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <Input\n type=\"date\"\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-9 text-sm\"\n readOnly={readOnly}\n />\n </div>\n )\n\n case 'select':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n {readOnly ? (\n <p className=\"text-sm py-1\">{(value as string) ?? '-'}</p>\n ) : (\n <Select value={(value as string) ?? ''} onValueChange={onChange}>\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue placeholder={field.placeholder ?? '...'} />\n </SelectTrigger>\n <SelectContent>\n {(field.options ?? []).map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n )\n\n case 'radio':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"space-y-1\">\n {(field.options ?? []).map((opt) => (\n <label key={opt.value} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"radio\"\n name={field.id}\n value={opt.value}\n checked={value === opt.value}\n onChange={() => onChange(opt.value)}\n disabled={readOnly}\n className=\"text-primary\"\n />\n <span className=\"text-sm\">{opt.label}</span>\n </label>\n ))}\n </div>\n </div>\n )\n\n case 'tags': {\n const selectedTags = Array.isArray(value) ? (value as string[]) : []\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex flex-wrap gap-1.5\">\n {(field.options ?? []).map((opt) => {\n const active = selectedTags.includes(opt.value)\n return (\n <Badge\n key={opt.value}\n variant={active ? 'default' : 'outline'}\n className={`cursor-pointer text-xs ${readOnly ? 'pointer-events-none' : ''}`}\n onClick={() => {\n if (readOnly) return\n onChange(\n active\n ? selectedTags.filter((t) => t !== opt.value)\n : [...selectedTags, opt.value],\n )\n }}\n >\n {opt.label}\n </Badge>\n )\n })}\n </div>\n </div>\n )\n }\n\n case 'checkbox':\n return (\n <label className=\"flex items-center gap-2 cursor-pointer py-1\">\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => onChange(e.target.checked)}\n disabled={readOnly}\n className=\"rounded border-input\"\n />\n <span className=\"text-sm font-medium\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </span>\n </label>\n )\n\n case 'image':\n case 'gallery':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground\">\n {field.type === 'gallery' ? 'Gallery upload' : 'Image upload'} — v2\n </div>\n </div>\n )\n\n case 'budget':\n return (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium block\">\n {field.label}\n {field.required && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n <div className=\"flex items-center justify-center rounded-lg border-2 border-dashed py-8 text-sm text-muted-foreground\">\n Budget / line items — v2\n </div>\n </div>\n )\n\n default:\n return null\n }\n}\n\nexport function FormRenderer({ schema, data, onChange, readOnly }: FormRendererProps) {\n const sortedFields = [...schema.fields].sort((a, b) => a.row - b.row || a.col - b.col)\n\n const handleFieldChange = useCallback(\n (fieldId: string, value: unknown) => {\n onChange({ ...data, [fieldId]: value })\n },\n [data, onChange],\n )\n\n return (\n <div\n className=\"grid gap-x-4 gap-y-3\"\n style={{ gridTemplateColumns: 'repeat(12, 1fr)' }}\n >\n {sortedFields.map((field) => (\n <div key={field.id} style={{ gridColumn: `span ${field.colSpan}` }}>\n <FieldRenderer\n field={field}\n value={data[field.id]}\n onChange={(v) => handleFieldChange(field.id, v)}\n readOnly={readOnly}\n />\n </div>\n ))}\n </div>\n )\n}\n","// ============================================================\n// PRINT / PDF — render a filled document to a printable A4 page\n// ============================================================\n//\n// Browser print-to-PDF: we build a clean, self-contained A4 HTML document from\n// the template schema + saved data, drop it into a hidden iframe, and call\n// print() on it. The browser's print dialog covers both physical printing and\n// \"Save as PDF\". No external deps.\n\nimport type { FormDocument, FormFieldDef, FormTemplate } from '../types'\nimport { fieldRichValue } from './html-text'\n\nfunction esc(value: unknown): string {\n return String(value ?? '').replace(/[&<>\"']/g, (c) =>\n ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' }[c] as string),\n )\n}\n\nfunction nl2br(value: string): string {\n return esc(value).replace(/\\r?\\n/g, '<br/>')\n}\n\nfunction formatDate(value: string): string {\n // ISO date (YYYY-MM-DD) → locale date; anything else passes through.\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value)\n if (!m) return esc(value)\n return `${m[3]}/${m[2]}/${m[1]}`\n}\n\nfunction optionLabel(field: FormFieldDef, value: unknown): string {\n const opt = (field.options ?? []).find((o) => o.value === value)\n return esc(opt ? opt.label : value)\n}\n\n/** Render one field's value as an HTML fragment for the printed page. */\nfunction renderValue(field: FormFieldDef, value: unknown): string {\n const empty = '<span class=\"empty\">—</span>'\n switch (field.type) {\n case 'memo':\n case 'richtext': {\n // Texto primeiro, escape depois. `nl2br` já escapava — e era exatamente\n // por isso que a folha impressa saía com `<p dir="ltr">`\n // no lugar da evolução do atendimento: escapar HTML guardado mostra a\n // marcação. Ver lib/html-text.ts.\n // Agora o valor passa pela lista de permissão e a folha sai formatada,\n // igual à tela. O escape continua no caminho de texto puro, que é onde\n // ele sempre foi o certo.\n const rich = fieldRichValue(value)\n if ('html' in rich) return `<div class=\"long rich\">${rich.html}</div>`\n return rich.text ? `<div class=\"long\">${nl2br(rich.text)}</div>` : empty\n }\n case 'date':\n return value ? formatDate(String(value)) : empty\n case 'select':\n case 'radio':\n return value ? optionLabel(field, value) : empty\n case 'tags': {\n const arr = Array.isArray(value) ? value : []\n return arr.length\n ? arr.map((v) => optionLabel(field, v)).join(', ')\n : empty\n }\n case 'checkbox':\n return value ? 'Sim' : 'Não'\n case 'image':\n case 'gallery':\n case 'budget':\n return '' // not meaningful on a printed contract\n default:\n return value ? esc(value) : empty\n }\n}\n\nexport interface BuildPrintOptions {\n /** Heading shown at the top of the page (defaults to the document title). */\n heading?: string\n /** Small line under the heading (e.g. person name). */\n subheading?: string\n}\n\n/** Build a full, self-contained printable HTML document. */\nexport function buildPrintHtml(\n template: FormTemplate,\n doc: FormDocument,\n opts: BuildPrintOptions = {},\n): string {\n const heading = opts.heading ?? doc.title ?? template.name\n const subParts = [opts.subheading ?? doc.personName, new Date(doc.createdAt).toLocaleDateString()]\n .filter(Boolean)\n .map((s) => esc(s))\n .join(' · ')\n\n const fields = [...template.schema.fields].sort((a, b) => a.row - b.row || a.col - b.col)\n\n const clampSpan = (n: unknown) => Math.max(1, Math.min(12, Number(n) || 12))\n\n // Mirror the builder's 12-column grid so the print keeps the authored layout\n // (side-by-side fields stay side by side). Titles span the full row.\n const body = fields\n .map((field) => {\n if (field.type === 'title') {\n return `<h2 class=\"section\" style=\"grid-column: 1 / -1\">${esc(field.label)}</h2>`\n }\n const rendered = renderValue(field, doc.data[field.id])\n if (rendered === '') return ''\n const isLong = field.type === 'memo' || field.type === 'richtext'\n return `<div class=\"field${isLong ? ' field--long' : ''}\" style=\"grid-column: span ${clampSpan(field.colSpan)}\">\n <div class=\"label\">${esc(field.label)}</div>\n <div class=\"value\">${rendered}</div>\n </div>`\n })\n .join('\\n')\n\n return `<!doctype html>\n<html lang=\"pt-BR\">\n<head>\n<meta charset=\"utf-8\"/>\n<title>${esc(heading)}</title>\n<style>\n @page { size: A4; margin: 20mm; }\n * { box-sizing: border-box; }\n html, body { margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n color: #111; font-size: 12pt; line-height: 1.5;\n -webkit-print-color-adjust: exact; print-color-adjust: exact;\n }\n .page { max-width: 170mm; margin: 0 auto; padding: 12mm 0; }\n header { border-bottom: 2px solid #111; padding-bottom: 8px; margin-bottom: 20px; }\n header h1 { font-size: 18pt; margin: 0 0 2px; }\n header .sub { font-size: 10pt; color: #555; }\n /* 12-column grid — mirrors the builder Preview (FormRenderer) so the print\n keeps the authored column layout. */\n .grid { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 16px; row-gap: 12px; align-items: start; }\n h2.section { font-size: 13pt; margin: 22px 0 4px; padding-bottom: 3px; border-bottom: 1px solid #ccc; }\n .grid > h2.section:first-child { margin-top: 4px; }\n .field { margin: 0; min-width: 0; }\n .field .label { font-size: 9pt; text-transform: uppercase; letter-spacing: .04em; color: #666; margin-bottom: 2px; }\n .field .value { font-size: 12pt; }\n .field--long .value .long { white-space: normal; text-align: justify; }\n /* Conteudo formatado (sanitizado em lib/html-text.ts). O HTML chega sem\n class nenhuma, entao o estilo vem por tag. orphans/widows evitam que um\n paragrafo deixe uma linha solta virando a pagina. */\n .long.rich p { margin: 0 0 8px; orphans: 2; widows: 2; }\n .long.rich p:last-child { margin-bottom: 0; }\n .long.rich ul, .long.rich ol { margin: 0 0 8px; padding-left: 20px; }\n .long.rich li { margin: 0 0 3px; }\n .long.rich b, .long.rich strong { font-weight: 600; }\n .long.rich blockquote { margin: 0 0 8px; padding-left: 10px; border-left: 2px solid #ccc; color: #444; }\n .long.rich a { color: #111; text-decoration: underline; }\n .long.rich table { width: 100%; border-collapse: collapse; margin: 0 0 8px; }\n .long.rich td, .long.rich th { border: 1px solid #ccc; padding: 4px 6px; text-align: left; }\n .long.rich h1, .long.rich h2, .long.rich h3,\n .long.rich h4, .long.rich h5, .long.rich h6 { font-size: 12pt; font-weight: 600; margin: 10px 0 4px; }\n .empty { color: #bbb; }\n footer { margin-top: 40px; font-size: 9pt; color: #888; text-align: center; }\n @media screen { body { background: #f3f3f3; } .page { background: #fff; max-width: 210mm; min-height: 297mm; padding: 20mm; box-shadow: 0 1px 8px rgba(0,0,0,.15); } }\n</style>\n</head>\n<body>\n <div class=\"page\">\n <header>\n <h1>${esc(heading)}</h1>\n ${subParts ? `<div class=\"sub\">${subParts}</div>` : ''}\n </header>\n <div class=\"grid\">\n ${body}\n </div>\n </div>\n</body>\n</html>`\n}\n\n/**\n * Print a prebuilt HTML document via a hidden iframe (popup-blocker safe).\n * The browser print dialog handles both printing and \"Save as PDF\".\n */\nexport function printHtml(html: string): void {\n if (typeof document === 'undefined') return\n const iframe = document.createElement('iframe')\n iframe.setAttribute('aria-hidden', 'true')\n iframe.style.position = 'fixed'\n iframe.style.right = '0'\n iframe.style.bottom = '0'\n iframe.style.width = '0'\n iframe.style.height = '0'\n iframe.style.border = '0'\n document.body.appendChild(iframe)\n\n const cleanup = () => {\n // Give the print dialog a beat before tearing the frame down.\n setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe)\n }, 1000)\n }\n\n const win = iframe.contentWindow\n const idoc = iframe.contentDocument || win?.document\n if (!win || !idoc) {\n cleanup()\n return\n }\n\n idoc.open()\n idoc.write(html)\n idoc.close()\n\n const doPrint = () => {\n try {\n win.focus()\n win.print()\n } finally {\n cleanup()\n }\n }\n\n // Wait for the frame document to be ready before printing.\n if (idoc.readyState === 'complete') {\n setTimeout(doPrint, 50)\n } else {\n iframe.addEventListener('load', () => setTimeout(doPrint, 50), { once: true })\n }\n}\n\n/** Convenience: build + print a document in one call. */\nexport function printDocument(\n template: FormTemplate,\n doc: FormDocument,\n opts?: BuildPrintOptions,\n): void {\n printHtml(buildPrintHtml(template, doc, opts))\n}\n","import type { PluginAITool } from '@fayz-ai/core'\n\n/**\n * The assistant's form-building tool. It is a SERVER-PLANE write (a pool RPC),\n * not a client-side surface mutation — so it works from any page and any\n * channel (in-app FAB, WhatsApp, MCP), and persists straight to the tenant's\n * form templates. This is the same pattern agenda/financial/marketing use.\n *\n * The builder surface (see FormBuilder) still publishes CONTEXT — which form is\n * open and its current fields with ids — so \"add an allergies field to THIS\n * form\" resolves to the right template. But the action itself is this tool.\n */\n\nconst CATEGORY_ENUM = ['anamnesis', 'evolution', 'report', 'contract', 'general'] as const\n\nconst FIELD_SHAPE =\n 'A field object: { type, label, required?, placeholder?, options?[] }. ' +\n 'type ∈ title|text|memo|richtext|date|select|radio|tags|checkbox|image|gallery|budget ' +\n '(title = section heading, no input). options are plain strings, only for select/radio/tags.'\n\nexport const createOrUpdateFormTool: PluginAITool = {\n id: 'custom_forms.createOrUpdateForm',\n name: 'createOrUpdateForm',\n description:\n 'Creates or edits a form template (anamnese, contrato, ficha…). Persisted server-side, so it works from ANY page — the user does NOT need the form builder open. ' +\n 'Omit templateId to CREATE (name required); pass templateId to EDIT an existing form. ' +\n 'Send the FULL desired field list in `fields` (replaces all fields), or `append_fields` to add to what already exists. ' +\n 'Layout is automatic — never send positions. Understand the intent and propose a sensible field set in one call rather than asking field by field. The user confirms before it is saved.',\n icon: 'FileText',\n mode: 'persist',\n limitKey: 'form_templates',\n permission: { feature: 'custom_forms', action: 'create' },\n execution: { plane: 'server', kind: 'rpc', rpc: 'agent_forms_upsert_template' },\n category: 'Forms',\n suggestions: [\n { label: 'Monte um formulário de anamnese' },\n { label: 'Adicione um campo de alergias neste formulário' },\n ],\n parameters: {\n type: 'object',\n properties: {\n templateId: {\n type: 'string',\n description: 'Existing form id to EDIT (from context or listFormTemplates). Omit to create a new form.',\n },\n name: { type: 'string', description: 'Form name — required when creating.' },\n category: {\n type: 'string',\n enum: [...CATEGORY_ENUM],\n description: 'anamnesis | evolution | report | contract | general',\n },\n description: { type: 'string', description: 'Optional short description of the form.' },\n fields: {\n type: 'array',\n description: `The FULL desired field list — REPLACES every existing field. Each item: ${FIELD_SHAPE}`,\n items: { type: 'object', description: FIELD_SHAPE },\n },\n append_fields: {\n type: 'array',\n description: `Fields to ADD to the existing form, keeping current ones. Use this for incremental edits instead of \\`fields\\`. Each item: ${FIELD_SHAPE}`,\n items: { type: 'object', description: FIELD_SHAPE },\n },\n },\n },\n}\n\nexport const FORM_BUILDER_INSTRUCTIONS = [\n 'Você está na tela do CONSTRUTOR DE FORMULÁRIOS. Para montar ou editar formulários use a tool createOrUpdateForm (ela persiste no backend e funciona mesmo fora desta tela).',\n 'O formulário aberto agora — id, nome, categoria e campos com seus ids — está no JSON da tela em contexto.',\n 'Para EDITAR este formulário, passe o templateId do contexto. Para adicionar campos mantendo os atuais, use append_fields; para redefinir tudo, use fields com a lista completa.',\n 'Ao criar do zero: entenda a intenção e proponha um conjunto de campos enxuto numa única chamada (não pergunte campo a campo). Depois confirme em uma frase o que foi montado.',\n 'Tipos de campo: title (cabeçalho de seção, sem input), text, memo (multilinha), richtext, date, select, radio, tags, checkbox, image, gallery, budget. Layout é automático.',\n].join(' ')\n","// ============================================================\n// PERSON FIELD MAPPING — prefill a document from a person record\n// ============================================================\n//\n// A template field can declare `map: '<personKey>'` (see FormFieldDef.map).\n// When a document is created from a person's profile, fields with a mapping are\n// pre-filled from that person's record. The person record reaching the widget\n// is the host app's CRUD detail `item`, keyed by the entity's field keys\n// (camelCase, e.g. `documentNumber`). We resolve tolerantly so the same mapping\n// works whether the host exposes camelCase or snake_case keys.\n\nimport type { FormSchema } from '../types'\n\n/** Curated, vertical-agnostic person keys offered in the field builder. */\nexport const PERSON_FIELD_OPTIONS: Array<{ value: string; labelKey: string }> = [\n { value: 'name', labelKey: 'customForms.personField.name' },\n { value: 'documentNumber', labelKey: 'customForms.personField.documentNumber' },\n { value: 'email', labelKey: 'customForms.personField.email' },\n { value: 'phone', labelKey: 'customForms.personField.phone' },\n { value: 'dateOfBirth', labelKey: 'customForms.personField.dateOfBirth' },\n { value: 'guardianName', labelKey: 'customForms.personField.guardianName' },\n { value: 'address', labelKey: 'customForms.personField.address' },\n { value: 'city', labelKey: 'customForms.personField.city' },\n { value: 'state', labelKey: 'customForms.personField.state' },\n]\n\nconst toSnake = (k: string) => k.replace(/[A-Z]/g, (m) => '_' + m.toLowerCase())\nconst toCamel = (k: string) => k.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n\n/** Read a person field value, tolerating camelCase/snake_case key variants. */\nexport function resolvePersonValue(\n person: Record<string, unknown> | undefined | null,\n mapKey: string | undefined,\n): unknown {\n if (!person || !mapKey) return undefined\n for (const key of [mapKey, toSnake(mapKey), toCamel(mapKey)]) {\n const v = person[key]\n if (v != null && v !== '') return v\n }\n return undefined\n}\n\n/**\n * Build the initial document data for a template. For each field, applies (in\n * priority order) an existing value, then the mapped person value, then the\n * field's static `defaultValue`. Never overwrites a value already present in\n * `existing`.\n */\nexport function prefillFromPerson(\n schema: FormSchema | undefined,\n person: Record<string, unknown> | undefined | null,\n existing: Record<string, unknown> = {},\n): Record<string, unknown> {\n const data: Record<string, unknown> = { ...existing }\n if (!schema) return data\n for (const field of schema.fields) {\n const current = data[field.id]\n if (current != null && current !== '') continue\n const mapped = field.map ? resolvePersonValue(person, field.map) : undefined\n if (mapped != null) {\n data[field.id] = mapped\n } else if (field.defaultValue != null) {\n data[field.id] = field.defaultValue\n }\n }\n return data\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddDocumentDropdown.d.ts","sourceRoot":"","sources":["../../src/components/AddDocumentDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAA;AAY5D,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"AddDocumentDropdown.d.ts","sourceRoot":"","sources":["../../src/components/AddDocumentDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAA;AAY5D,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEpF,UAAU,wBAAwB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;CAC/C;AAED,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,wBAAwB,qBAwEnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentFormDialog.d.ts","sourceRoot":"","sources":["../../src/components/DocumentFormDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;AAK/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"DocumentFormDialog.d.ts","sourceRoot":"","sources":["../../src/components/DocumentFormDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;AAK/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAY1D,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,gBAAgB,CAAC,EAAE,YAAY,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;IACvB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EAAE,eAAe,EACzB,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,MAAM,EACN,QAAQ,EACR,KAAK,EACL,OAAO,EACP,MAAM,GACP,EAAE,uBAAuB,qBAyIzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* O corpo do documento enquanto o modelo não chegou.
|
|
4
|
+
*
|
|
5
|
+
* Um spinner centralizado diz "espere" e nada mais: a área inteira colapsa numa
|
|
6
|
+
* bolinha e, quando o modelo chega, a tela salta de 40px para uma página de
|
|
7
|
+
* formulário. O esqueleto ocupa desde já a forma que vai ser preenchida — moldura,
|
|
8
|
+
* rótulo, campo — então a chegada do conteúdo troca cinza por texto no lugar onde
|
|
9
|
+
* o texto já estava.
|
|
10
|
+
*
|
|
11
|
+
* `rows` é uma aproximação e não tem como não ser: quantos campos o modelo tem é
|
|
12
|
+
* justamente o que ainda está sendo carregado. Cinco é a altura de formulário
|
|
13
|
+
* curto — erra para baixo de propósito, porque crescer ao carregar incomoda
|
|
14
|
+
* menos do que encolher.
|
|
15
|
+
*/
|
|
16
|
+
export declare function DocumentBodySkeleton({ rows }: {
|
|
17
|
+
rows?: number;
|
|
18
|
+
}): React.JSX.Element;
|
|
19
|
+
/** O cabeçalho, para quando nem o título do documento se sabe ainda. */
|
|
20
|
+
export declare function DocumentHeaderSkeleton(): React.JSX.Element;
|
|
21
|
+
//# sourceMappingURL=DocumentSkeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentSkeleton.d.ts","sourceRoot":"","sources":["../../src/components/DocumentSkeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,IAAQ,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,qBAWnE;AAED,wEAAwE;AACxE,wBAAgB,sBAAsB,sBAUrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FormRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FormRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAY1C,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,UAAU,CAAA;AAoBxD,UAAU,iBAAiB;IACzB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAuUD,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,qBA2BnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormViewer.d.ts","sourceRoot":"","sources":["../../src/components/FormViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"FormViewer.d.ts","sourceRoot":"","sources":["../../src/components/FormViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAA;AAK1D,UAAU,eAAe;IACvB,QAAQ,EAAE,YAAY,CAAA;IACtB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAA;CACrC;AASD,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,eAAe,qBA0EtF"}
|
|
@@ -12,4 +12,4 @@ export declare function CustomFormsProvider({ value, children, }: {
|
|
|
12
12
|
children: React.ReactNode;
|
|
13
13
|
}): React.FunctionComponentElement<React.ProviderProps<CustomFormsContextValue | null>>;
|
|
14
14
|
export declare function useCustomFormsContext(): CustomFormsContextValue;
|
|
15
|
-
//# sourceMappingURL=
|
|
15
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,uBAAuB,CAAA;IACjC,KAAK,EAAE,gBAAgB,CAAA;CACxB;AAID,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,uBAAuB,CAAA;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,uFAEA;AAED,wBAAgB,qBAAqB,IAAI,uBAAuB,CAI/D"}
|
package/dist/data/mock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/data/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/data/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAuBtD,wBAAgB,uBAAuB,IAAI,uBAAuB,CAwLjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAqItD,wBAAgB,2BAA2B,IAAI,uBAAuB,CAqVrE"}
|
package/dist/data/types.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { FormTemplate, FormDocument, DocumentFile, TemplateQuery, DocumentQuery, PaginatedResult, CreateTemplateInput, UpdateTemplateInput, CreateDocumentInput, UpdateDocumentInput } from '../types';
|
|
1
|
+
import type { FormTemplate, FormDocument, DocumentFile, TemplateQuery, DocumentQuery, PaginatedResult, CreateTemplateInput, UpdateTemplateInput, CreateDocumentInput, UpdateDocumentInput, TemplateUsage } from '../types';
|
|
2
2
|
export interface CustomFormsDataProvider {
|
|
3
3
|
getTemplates(query: TemplateQuery): Promise<PaginatedResult<FormTemplate>>;
|
|
4
4
|
getTemplateById(id: string): Promise<FormTemplate | null>;
|
|
5
5
|
createTemplate(input: CreateTemplateInput): Promise<FormTemplate>;
|
|
6
6
|
updateTemplate(id: string, input: UpdateTemplateInput): Promise<FormTemplate>;
|
|
7
7
|
deleteTemplate(id: string): Promise<void>;
|
|
8
|
+
/** Uso por modelo, indexado pelo id do modelo. Modelos sem nenhum documento
|
|
9
|
+
* simplesmente não aparecem no mapa. */
|
|
10
|
+
getTemplateUsage(): Promise<Record<string, TemplateUsage>>;
|
|
8
11
|
getDocuments(query: DocumentQuery): Promise<PaginatedResult<FormDocument>>;
|
|
9
12
|
getDocumentById(id: string): Promise<FormDocument | null>;
|
|
10
13
|
createDocument(input: CreateDocumentInput): Promise<FormDocument>;
|
package/dist/data/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACd,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,uBAAuB;IAEtC,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAA;IAC1E,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IACzD,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACjE,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC7E,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC;6CACyC;IACzC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;IAG1D,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAA;IAC1E,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IACzD,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACjE,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC7E,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAGzC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;IAC7D,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACnF,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PluginManifest } from '@fayz-ai/core';
|
|
2
2
|
import type { CustomFormsPluginOptions } from './config';
|
|
3
3
|
export type { CustomFormsPluginOptions };
|
|
4
|
-
export { registerDocumentTypeProvider, type DocumentTypeOption, type DocumentTypeProvider } from './document-types';
|
|
4
|
+
export { registerDocumentTypeProvider, type DocumentTypeOption, type DocumentTypeProvider } from './lib/document-types';
|
|
5
5
|
export declare function createCustomFormsPlugin(options?: CustomFormsPluginOptions): PluginManifest;
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAUnD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAUnD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AA2CxD,YAAY,EAAE,wBAAwB,EAAE,CAAA;AACxC,OAAO,EAAE,4BAA4B,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAEvH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,cAAc,CAmL1F"}
|