@webx-ui/module-blog 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,535 @@
1
+ import { defineComponent as me, useTemplateRef as ye, ref as J, computed as c, watch as ge, openBlock as o, createElementBlock as E, createVNode as s, unref as t, withCtx as i, createBlock as d, createTextVNode as v, toDisplayString as b, createCommentVNode as h, createElementVNode as f, Fragment as _e, renderList as xe, normalizeClass as ke } from "vue";
2
+ import { useRoute as we, useRouter as qe } from "vue-router";
3
+ import { useAdmin as ze, useTranslate as K, useErrorText as We, rowMenuWidth as $e, WxListScreen as Ce, WxRowMenu as Q, WxDate as X, WxAddressNote as Be, WxFilterChips as Te } from "@webx-ui/module-admin";
4
+ import { useElementWidth as Se, createModal as Ae, WxTable as Ne, WxEntityCard as Ve, WxBadge as W, WxIcon as C, WxText as Y, WxTooltip as Re, WxFormItem as F, WxSelect as M, WxButton as Ee, toast as B, confirm as Fe } from "@webx-ui/core";
5
+ import { c as Me, u as Pe, _ as Ue, a as De } from "./index-DqN5h0Ej.js";
6
+ const Ie = ["src"], Le = { class: "wx-articles__name" }, Oe = { class: "wx-articles__name-text" }, je = { class: "wx-articles__title" }, Ge = { class: "wx-articles__address" }, He = { class: "wx-articles__chips" }, Je = { class: "wx-articles__state" }, Z = 640, Ke = /* @__PURE__ */ me({
7
+ __name: "ArticlesPage",
8
+ props: {
9
+ base: { default: "/blog" }
10
+ },
11
+ setup(ee) {
12
+ const le = ee, T = ze(), m = Me(T), r = we(), y = qe();
13
+ Pe();
14
+ const a = K("webx-blog"), P = K("webx-admin"), U = We(), D = ye("root"), I = Se(D), S = J(null), A = J(!0), ae = Ae(Ue), L = c(() => T.can("blog.articles.manage")), O = c(
15
+ () => T.state.manifest?.modules.find((e) => e.id === "articles")?.title ?? a("module.articles")
16
+ ), x = c({
17
+ get: () => typeof r.query.view == "string" ? r.query.view : "",
18
+ set: (e) => {
19
+ y.replace({
20
+ query: { ...r.query, view: e === "" ? void 0 : String(e), page: void 0 }
21
+ });
22
+ }
23
+ }), p = c(() => x.value === "trashed"), u = c(() => ({
24
+ q: typeof r.query.q == "string" ? r.query.q : "",
25
+ rubric: N(r.query.rubric),
26
+ tag: N(r.query.tag),
27
+ author: N(r.query.author),
28
+ sort: typeof r.query.sort == "string" ? r.query.sort : null,
29
+ page: Number(r.query.page ?? 1) || 1
30
+ }));
31
+ function N(e) {
32
+ return typeof e == "string" && e !== "" && Number(e) || null;
33
+ }
34
+ const te = c(() => [
35
+ { value: "", label: a("panel.view-all") },
36
+ { value: "published", label: a("panel.view-published") },
37
+ { value: "scheduled", label: a("panel.view-scheduled") },
38
+ { value: "draft", label: a("panel.view-draft") },
39
+ { value: "unpublished", label: a("panel.view-unpublished") },
40
+ { value: "trashed", label: a("panel.bin"), icon: "trash" }
41
+ ]), g = c(() => S.value?.filters ?? { rubrics: [], tags: [], authors: [] }), ne = c(() => I.value > 0 && I.value < Z), ie = c(() => ne.value ? [{ key: "card", label: "" }] : [
42
+ { key: "cover", label: "", width: 68 },
43
+ /* The one that takes what the others leave, and the only one without a number. */
44
+ { key: "title", label: a("panel.column-title"), minWidth: 220 },
45
+ { key: "rubrics", label: a("panel.column-rubrics"), width: 190, hideBelow: 1e3 },
46
+ { key: "author", label: a("panel.column-author"), width: 160, hideBelow: 1200 },
47
+ {
48
+ key: "date",
49
+ label: p.value ? a("panel.column-deleted") : a("panel.column-date"),
50
+ width: 120,
51
+ hideBelow: 700,
52
+ // "today at 16:22" is three words the table will break over two lines given half a
53
+ // chance, and a date read down a column has to be one line to be read at all.
54
+ cellClass: "wx-articles__when"
55
+ },
56
+ { key: "status", label: a("panel.column-status"), width: 170 },
57
+ { key: "actions", label: "", width: $e, align: "right" }
58
+ ]), se = c(() => u.value.q !== "" ? a("panel.empty-search") : p.value ? a("panel.empty-bin") : a("panel.empty")), V = c(() => {
59
+ const e = [], n = g.value.rubrics.find((z) => z.id === u.value.rubric);
60
+ n && e.push({
61
+ key: "rubric",
62
+ label: `${a("panel.filter-rubric")}: ${n.title}`,
63
+ clear: () => _("rubric", void 0)
64
+ });
65
+ const l = g.value.tags.find((z) => z.id === u.value.tag);
66
+ l && e.push({
67
+ key: "tag",
68
+ label: `${a("panel.filter-tag")}: ${l.title}`,
69
+ clear: () => _("tag", void 0)
70
+ });
71
+ const q = g.value.authors.find((z) => z.id === u.value.author);
72
+ return q && e.push({
73
+ key: "author",
74
+ label: `${a("panel.filter-author")}: ${q.title}`,
75
+ clear: () => _("author", void 0)
76
+ }), e;
77
+ });
78
+ function re() {
79
+ y.replace({
80
+ query: {
81
+ ...r.query,
82
+ rubric: void 0,
83
+ tag: void 0,
84
+ author: void 0,
85
+ page: void 0
86
+ }
87
+ });
88
+ }
89
+ async function k(e) {
90
+ A.value = !0;
91
+ try {
92
+ S.value = await m.articles({
93
+ q: e?.search ?? u.value.q,
94
+ status: p.value ? "" : x.value,
95
+ trashed: p.value,
96
+ rubric: u.value.rubric,
97
+ tag: u.value.tag,
98
+ author: u.value.author,
99
+ sort: e?.sort ? `${e.sort.order === "desc" ? "-" : ""}${e.sort.key}` : null,
100
+ page: e?.page ?? u.value.page,
101
+ per_page: e?.perPage
102
+ });
103
+ } catch (n) {
104
+ B.danger(U(n));
105
+ } finally {
106
+ A.value = !1;
107
+ }
108
+ }
109
+ function ue(e) {
110
+ const n = {
111
+ ...r.query,
112
+ q: e.search === "" ? void 0 : e.search,
113
+ sort: e.sort === null ? void 0 : `${e.sort.order === "desc" ? "-" : ""}${e.sort.key}`,
114
+ page: e.page === 1 ? void 0 : String(e.page)
115
+ };
116
+ y.replace({ query: n }), k(e);
117
+ }
118
+ function _(e, n) {
119
+ y.replace({
120
+ query: {
121
+ ...r.query,
122
+ [e]: typeof n == "number" ? String(n) : void 0,
123
+ page: void 0
124
+ }
125
+ });
126
+ }
127
+ ge(
128
+ [x, () => u.value.rubric, () => u.value.tag, () => u.value.author],
129
+ () => {
130
+ k();
131
+ }
132
+ ), k();
133
+ function R(e) {
134
+ const n = `${le.base}/articles/${e.id}`;
135
+ y.resolve(n).matched.length > 0 && y.push({ path: n, query: { ...r.query } });
136
+ }
137
+ async function oe() {
138
+ const e = await ae({});
139
+ e && (await k(), R(e));
140
+ }
141
+ function j(e) {
142
+ if (!L.value) return [];
143
+ if (p.value)
144
+ return [
145
+ {
146
+ key: "restore",
147
+ icon: "refresh",
148
+ label: a("panel.restore"),
149
+ run: () => {
150
+ be(e);
151
+ }
152
+ }
153
+ ];
154
+ const n = [
155
+ { key: "open", icon: "edit", label: a("panel.open"), run: () => R(e) }
156
+ ];
157
+ return e.url && e.status !== "draft" && n.push({
158
+ key: "site",
159
+ icon: "external-link",
160
+ label: a("panel.open-on-site"),
161
+ href: e.url
162
+ }), e.path !== null && n.push({
163
+ key: "copy",
164
+ icon: "copy",
165
+ label: a("panel.copy-address"),
166
+ run: () => {
167
+ he(e);
168
+ }
169
+ }), n.push({
170
+ key: "pin",
171
+ icon: "star",
172
+ label: e.pinned ? a("panel.unpin") : a("panel.pin"),
173
+ run: () => {
174
+ pe(e, !e.pinned);
175
+ }
176
+ }), n.push(
177
+ e.status === "published" || e.status === "modified" || e.status === "scheduled" ? {
178
+ key: "unpublish",
179
+ icon: "eye-off",
180
+ label: a("panel.unpublish"),
181
+ run: () => {
182
+ de(e);
183
+ }
184
+ } : {
185
+ key: "publish",
186
+ icon: "upload",
187
+ label: a("panel.publish"),
188
+ run: () => {
189
+ ce(e);
190
+ }
191
+ }
192
+ ), n.push({
193
+ key: "delete",
194
+ icon: "trash",
195
+ label: a("panel.delete"),
196
+ danger: !0,
197
+ run: () => {
198
+ ve(e);
199
+ }
200
+ }), n;
201
+ }
202
+ async function ce(e) {
203
+ await w(() => m.publish(e.id), a("panel.published"));
204
+ }
205
+ async function de(e) {
206
+ await w(() => m.unpublish(e.id), a("panel.unpublished-done"));
207
+ }
208
+ async function pe(e, n) {
209
+ await w(
210
+ () => m.save(e.id, { values: { pinned: n }, revision: e.revision }),
211
+ a(n ? "panel.pinned-done" : "panel.unpinned")
212
+ );
213
+ }
214
+ async function ve(e) {
215
+ await Fe({
216
+ title: a("panel.delete-title", { title: e.title }),
217
+ message: a("panel.delete-text"),
218
+ confirmText: a("panel.delete"),
219
+ cancelText: a("panel.cancel"),
220
+ tone: "danger"
221
+ }) && await w(() => m.remove(e.id), a("panel.deleted"));
222
+ }
223
+ async function be(e) {
224
+ await w(() => m.restore(e.id), a("panel.restored"));
225
+ }
226
+ async function w(e, n) {
227
+ try {
228
+ await e(), B.success(n);
229
+ } catch (l) {
230
+ B.danger(U(l));
231
+ } finally {
232
+ await k();
233
+ }
234
+ }
235
+ async function he(e) {
236
+ if (e.url)
237
+ try {
238
+ await navigator.clipboard.writeText(e.url), B.success(a("panel.address-copied"));
239
+ } catch {
240
+ }
241
+ }
242
+ function G(e) {
243
+ return e === "published" || e === "modified" ? "success" : e === "scheduled" ? "warning" : "default";
244
+ }
245
+ function H(e) {
246
+ return p.value ? "—" : e.path === null ? a("panel.no-address") : `/${e.path}`;
247
+ }
248
+ function $(e) {
249
+ return p.value ? e.deleted_at : e.published_at;
250
+ }
251
+ const fe = c(
252
+ () => L.value ? [{ key: "new", label: a("panel.new"), icon: "plus", primary: !0, run: () => {
253
+ oe();
254
+ } }] : []
255
+ );
256
+ return (e, n) => (o(), E("div", {
257
+ ref_key: "root",
258
+ ref: D,
259
+ class: "wx-articles"
260
+ }, [
261
+ s(t(Ce), {
262
+ view: x.value,
263
+ "onUpdate:view": n[3] || (n[3] = (l) => x.value = l),
264
+ title: O.value,
265
+ views: te.value,
266
+ actions: fe.value
267
+ }, {
268
+ default: i(() => [
269
+ s(t(Ne), {
270
+ data: S.value,
271
+ columns: ie.value,
272
+ "row-key": "id",
273
+ searchable: "",
274
+ clickable: !p.value,
275
+ hover: !p.value,
276
+ flush: "",
277
+ loading: A.value,
278
+ layout: "fixed",
279
+ "cards-below": Z,
280
+ "filters-count": V.value.length,
281
+ "filters-label": t(P)("filters.title"),
282
+ "search-placeholder": t(a)("panel.search"),
283
+ "empty-text": se.value,
284
+ "aria-label": O.value,
285
+ onRowClick: R,
286
+ onStateChange: ue
287
+ }, {
288
+ filters: i(() => [
289
+ s(t(F), {
290
+ label: t(a)("panel.filter-rubric")
291
+ }, {
292
+ default: i(() => [
293
+ s(t(M), {
294
+ "model-value": u.value.rubric,
295
+ options: g.value.rubrics.map((l) => ({ value: l.id, label: l.title })),
296
+ placeholder: t(a)("panel.any-rubric"),
297
+ clearable: "",
298
+ size: "sm",
299
+ "onUpdate:modelValue": n[0] || (n[0] = (l) => _("rubric", l))
300
+ }, null, 8, ["model-value", "options", "placeholder"])
301
+ ]),
302
+ _: 1
303
+ }, 8, ["label"]),
304
+ s(t(F), {
305
+ label: t(a)("panel.filter-tag")
306
+ }, {
307
+ default: i(() => [
308
+ s(t(M), {
309
+ "model-value": u.value.tag,
310
+ options: g.value.tags.map((l) => ({ value: l.id, label: l.title })),
311
+ placeholder: t(a)("panel.any-tag"),
312
+ clearable: "",
313
+ filterable: "",
314
+ size: "sm",
315
+ "onUpdate:modelValue": n[1] || (n[1] = (l) => _("tag", l))
316
+ }, null, 8, ["model-value", "options", "placeholder"])
317
+ ]),
318
+ _: 1
319
+ }, 8, ["label"]),
320
+ s(t(F), {
321
+ label: t(a)("panel.filter-author")
322
+ }, {
323
+ default: i(() => [
324
+ s(t(M), {
325
+ "model-value": u.value.author,
326
+ options: g.value.authors.map((l) => ({ value: l.id, label: l.title })),
327
+ placeholder: t(a)("panel.any-author"),
328
+ clearable: "",
329
+ size: "sm",
330
+ "onUpdate:modelValue": n[2] || (n[2] = (l) => _("author", l))
331
+ }, null, 8, ["model-value", "options", "placeholder"])
332
+ ]),
333
+ _: 1
334
+ }, 8, ["label"]),
335
+ V.value.length > 0 ? (o(), d(t(Ee), {
336
+ key: 0,
337
+ variant: "text",
338
+ size: "sm",
339
+ block: "",
340
+ onClick: re
341
+ }, {
342
+ icon: i(() => [
343
+ s(t(C), { name: "close" })
344
+ ]),
345
+ default: i(() => [
346
+ v(" " + b(t(P)("filters.reset")), 1)
347
+ ]),
348
+ _: 1
349
+ })) : h("", !0)
350
+ ]),
351
+ applied: i(() => [
352
+ s(t(Te), { filters: V.value }, null, 8, ["filters"])
353
+ ]),
354
+ "cell-cover": i(({ row: l }) => [
355
+ f("span", {
356
+ class: ke(["wx-articles__cover", { "is-empty": !l.cover }])
357
+ }, [
358
+ l.cover?.thumb ? (o(), E("img", {
359
+ key: 0,
360
+ src: l.cover.thumb,
361
+ alt: "",
362
+ loading: "lazy"
363
+ }, null, 8, Ie)) : (o(), d(t(C), {
364
+ key: 1,
365
+ name: "image",
366
+ size: "sm"
367
+ }))
368
+ ], 2)
369
+ ]),
370
+ "cell-title": i(({ row: l }) => [
371
+ f("div", Le, [
372
+ l.pinned ? (o(), d(t(Re), {
373
+ key: 0,
374
+ content: t(a)("panel.pinned")
375
+ }, {
376
+ default: i(() => [
377
+ s(t(C), {
378
+ class: "wx-articles__pin",
379
+ name: "star",
380
+ size: "sm"
381
+ })
382
+ ]),
383
+ _: 1
384
+ }, 8, ["content"])) : h("", !0),
385
+ f("div", Oe, [
386
+ f("span", je, b(l.title), 1),
387
+ f("span", Ge, [
388
+ v(b(H(l)) + " ", 1),
389
+ p.value ? h("", !0) : (o(), d(t(Be), {
390
+ key: 0,
391
+ locale: l.address_locale
392
+ }, null, 8, ["locale"]))
393
+ ])
394
+ ])
395
+ ])
396
+ ]),
397
+ "cell-rubrics": i(({ row: l }) => [
398
+ f("span", He, [
399
+ (o(!0), E(_e, null, xe(l.rubrics, (q) => (o(), d(t(W), {
400
+ key: q.id,
401
+ size: "sm",
402
+ round: ""
403
+ }, {
404
+ default: i(() => [
405
+ v(b(q.title), 1)
406
+ ]),
407
+ _: 2
408
+ }, 1024))), 128))
409
+ ])
410
+ ]),
411
+ "cell-author": i(({ row: l }) => [
412
+ s(t(Y), {
413
+ size: "sm",
414
+ tone: "muted",
415
+ truncate: ""
416
+ }, {
417
+ default: i(() => [
418
+ v(b(l.author ? l.author.name : "—"), 1)
419
+ ]),
420
+ _: 2
421
+ }, 1024)
422
+ ]),
423
+ "cell-date": i(({ row: l }) => [
424
+ $(l) ? (o(), d(t(X), {
425
+ key: 0,
426
+ value: $(l),
427
+ compact: ""
428
+ }, null, 8, ["value"])) : (o(), d(t(Y), {
429
+ key: 1,
430
+ size: "sm",
431
+ tone: "muted"
432
+ }, {
433
+ default: i(() => [...n[4] || (n[4] = [
434
+ v("—", -1)
435
+ ])]),
436
+ _: 1
437
+ }))
438
+ ]),
439
+ "cell-status": i(({ row: l }) => [
440
+ f("span", Je, [
441
+ s(t(W), {
442
+ type: G(l.status),
443
+ dot: "",
444
+ size: "sm"
445
+ }, {
446
+ default: i(() => [
447
+ v(b(t(a)(`panel.status-${l.status}`)), 1)
448
+ ]),
449
+ _: 2
450
+ }, 1032, ["type"]),
451
+ l.status === "modified" ? (o(), d(t(W), {
452
+ key: 0,
453
+ type: "primary",
454
+ size: "sm",
455
+ round: ""
456
+ }, {
457
+ default: i(() => [
458
+ v(b(t(a)("panel.edits")), 1)
459
+ ]),
460
+ _: 1
461
+ })) : h("", !0)
462
+ ])
463
+ ]),
464
+ "cell-card": i(({ row: l }) => [
465
+ s(t(Ve), {
466
+ class: "wx-articles__entity",
467
+ variant: "plain",
468
+ title: l.title,
469
+ image: l.cover?.thumb ?? void 0,
470
+ "image-size": "56px",
471
+ "title-lines": 2,
472
+ subtitle: H(l)
473
+ }, {
474
+ title: i(() => [
475
+ l.pinned ? (o(), d(t(C), {
476
+ key: 0,
477
+ class: "wx-articles__pin",
478
+ name: "star",
479
+ size: "sm"
480
+ })) : h("", !0),
481
+ v(" " + b(l.title), 1)
482
+ ]),
483
+ meta: i(() => [
484
+ l.rubrics[0] ? (o(), d(t(W), {
485
+ key: 0,
486
+ size: "sm",
487
+ round: ""
488
+ }, {
489
+ default: i(() => [
490
+ v(b(l.rubrics[0].title), 1)
491
+ ]),
492
+ _: 2
493
+ }, 1024)) : h("", !0),
494
+ s(t(W), {
495
+ type: G(l.status),
496
+ dot: "",
497
+ size: "sm"
498
+ }, {
499
+ default: i(() => [
500
+ v(b(t(a)(`panel.status-${l.status}`)), 1)
501
+ ]),
502
+ _: 2
503
+ }, 1032, ["type"]),
504
+ $(l) ? (o(), d(t(X), {
505
+ key: 1,
506
+ value: $(l)
507
+ }, null, 8, ["value"])) : h("", !0)
508
+ ]),
509
+ _: 2
510
+ }, 1032, ["title", "image", "subtitle"])
511
+ ]),
512
+ "card-actions": i(({ row: l }) => [
513
+ s(t(Q), {
514
+ actions: j(l),
515
+ label: l.title
516
+ }, null, 8, ["actions", "label"])
517
+ ]),
518
+ "cell-actions": i(({ row: l }) => [
519
+ s(t(Q), {
520
+ actions: j(l),
521
+ label: l.title
522
+ }, null, 8, ["actions", "label"])
523
+ ]),
524
+ _: 1
525
+ }, 8, ["data", "columns", "clickable", "hover", "loading", "filters-count", "filters-label", "search-placeholder", "empty-text", "aria-label"])
526
+ ]),
527
+ _: 1
528
+ }, 8, ["view", "title", "views", "actions"])
529
+ ], 512));
530
+ }
531
+ }), ll = /* @__PURE__ */ De(Ke, [["__scopeId", "data-v-5dfe798a"]]);
532
+ export {
533
+ ll as default
534
+ };
535
+ //# sourceMappingURL=ArticlesPage-CI-Nwhpy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArticlesPage-CI-Nwhpy.js","sources":["../src/ArticlesPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useTemplateRef, watch } from 'vue'\nimport { useRoute, useRouter, type LocationQueryRaw } from 'vue-router'\nimport {\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxListScreen,\n WxFilterChips,\n rowMenuWidth,\n WxRowMenu,\n type AppliedFilter,\n type RowAction,\n type ScreenAction,\n WxAddressNote,\n} from '@webx-ui/module-admin'\nimport {\n confirm,\n createModal,\n toast,\n useElementWidth,\n WxBadge,\n WxButton,\n WxEntityCard,\n WxFormItem,\n WxIcon,\n WxSelect,\n WxTable,\n WxText,\n WxTooltip,\n type TabItem,\n type TableColumn,\n type TableState,\n type TabValue,\n} from '@webx-ui/core'\nimport ArticleCreateDialog from './ArticleCreateDialog.vue'\nimport { createBlogApi } from './api'\nimport { useBlogMessages } from './i18n'\nimport type { ArticleRow, ArticleStatus, ArticlesPage } from './types'\n\n/**\n * The section: a page of articles with the filters of §10 over it.\n *\n * A paginator rather than a tree, which is the whole difference from `Pages`: articles all sit\n * at the same depth and there are a hundred of them, so the screen is twenty rows, a filter bar\n * and a page number.\n *\n * Below {@link CARDS} the row becomes a card, and the card is not the table's own stack of\n * labelled lines: at 375px five of those are four hundred pixels for one article. It is the\n * cover on the left and everything else beside it, which is 96px and ten articles on a screen\n * instead of two (§10). The table draws whatever columns it is given, so the switch is made\n * here — one column at that width, seven above it — and both halves agree on the number because\n * it is the same constant.\n */\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/blog' })\n\n/** Where the row stops being a row. Below it the table draws cards and this screen draws one. */\nconst CARDS = 640\n\nconst context = useAdmin()\nconst api = createBlogApi(context)\nconst route = useRoute()\nconst router = useRouter()\nuseBlogMessages()\n\nconst t = useTranslate('webx-blog')\n/* The two words a list needs as soon as it has filters belong to the panel, not to the blog. */\nconst admin = useTranslate('webx-admin')\n/* Not the server's `message`: the panel says how a request failed in its own words. */\nconst message = useErrorText()\n\nconst root = useTemplateRef<HTMLElement>('root')\nconst width = useElementWidth(root)\n\nconst page = ref<ArticlesPage | null>(null)\nconst loading = ref(true)\n\nconst create = createModal<ArticleRow, Record<string, never>>(ArticleCreateDialog)\n\nconst canManage = computed(() => context.can('blog.articles.manage'))\n\nconst title = computed(\n () =>\n context.state.manifest?.modules.find((module) => module.id === 'articles')?.title ??\n t('module.articles'),\n)\n\n/**\n * Everything the list is looking at lives in the address.\n *\n * Coming back from an article has to land on the same filter and the same page, or the section\n * costs the reader their place every time they open something.\n */\nconst view = computed<TabValue>({\n get: () => (typeof route.query.view === 'string' ? route.query.view : ''),\n set: (value) => {\n // A new view is a new list: the page it was on belongs to the view it was on.\n void router.replace({\n query: { ...route.query, view: value === '' ? undefined : String(value), page: undefined },\n })\n },\n})\n\nconst inBin = computed(() => view.value === 'trashed')\n\nconst query = computed(() => ({\n q: typeof route.query.q === 'string' ? route.query.q : '',\n rubric: number(route.query.rubric),\n tag: number(route.query.tag),\n author: number(route.query.author),\n sort: typeof route.query.sort === 'string' ? route.query.sort : null,\n page: Number(route.query.page ?? 1) || 1,\n}))\n\nfunction number(value: unknown): number | null {\n return typeof value === 'string' && value !== '' ? Number(value) || null : null\n}\n\n/** The views of the same list, as tabs over the card. The bin rides in the same row (§10). */\nconst views = computed<TabItem[]>(() => [\n { value: '', label: t('panel.view-all') },\n { value: 'published', label: t('panel.view-published') },\n { value: 'scheduled', label: t('panel.view-scheduled') },\n { value: 'draft', label: t('panel.view-draft') },\n { value: 'unpublished', label: t('panel.view-unpublished') },\n { value: 'trashed', label: t('panel.bin'), icon: 'trash' },\n])\n\nconst filters = computed(() => page.value?.filters ?? { rubrics: [], tags: [], authors: [] })\n\nconst asCards = computed(() => width.value > 0 && width.value < CARDS)\n\n/**\n * Seven columns, or one.\n *\n * Every column but the title carries a width and the table is laid out `fixed`, so the ones\n * that drop below a breakpoint give what they had to the title rather than to whichever cell\n * happened to hold the longest string. They go in the order they can be spared — who wrote it,\n * then where it belongs, then when — and what is left at the bottom is the cover, the title and\n * the state, which is what identifies an article and what an editor is looking for.\n */\nconst columns = computed<TableColumn<ArticleRow>[]>(() => {\n if (asCards.value) {\n return [{ key: 'card', label: '' }]\n }\n\n return [\n { key: 'cover', label: '', width: 68 },\n /* The one that takes what the others leave, and the only one without a number. */\n { key: 'title', label: t('panel.column-title'), minWidth: 220 },\n { key: 'rubrics', label: t('panel.column-rubrics'), width: 190, hideBelow: 1000 },\n { key: 'author', label: t('panel.column-author'), width: 160, hideBelow: 1200 },\n {\n key: 'date',\n label: inBin.value ? t('panel.column-deleted') : t('panel.column-date'),\n width: 120,\n hideBelow: 700,\n // \"today at 16:22\" is three words the table will break over two lines given half a\n // chance, and a date read down a column has to be one line to be read at all.\n cellClass: 'wx-articles__when',\n },\n { key: 'status', label: t('panel.column-status'), width: 170 },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n ]\n})\n\nconst emptyText = computed(() => {\n if (query.value.q !== '') return t('panel.empty-search')\n\n return inBin.value ? t('panel.empty-bin') : t('panel.empty')\n})\n\n/**\n * What the three dropdowns are set to, said in the reader's words.\n *\n * They live behind the funnel now, and a shut panel says nothing about itself: a list narrowed\n * by something nobody can see is a list that looks wrong. The chips are the answer, and taking\n * one off is the same `narrow()` the dropdown itself calls.\n */\nconst applied = computed<AppliedFilter[]>(() => {\n const chips: AppliedFilter[] = []\n\n const rubric = filters.value.rubrics.find((item) => item.id === query.value.rubric)\n if (rubric) {\n chips.push({\n key: 'rubric',\n label: `${t('panel.filter-rubric')}: ${rubric.title}`,\n clear: () => narrow('rubric', undefined),\n })\n }\n\n const tag = filters.value.tags.find((item) => item.id === query.value.tag)\n if (tag) {\n chips.push({\n key: 'tag',\n label: `${t('panel.filter-tag')}: ${tag.title}`,\n clear: () => narrow('tag', undefined),\n })\n }\n\n const author = filters.value.authors.find((item) => item.id === query.value.author)\n if (author) {\n chips.push({\n key: 'author',\n label: `${t('panel.filter-author')}: ${author.title}`,\n clear: () => narrow('author', undefined),\n })\n }\n\n return chips\n})\n\n/** All three at once, from inside the panel they were set in. */\nfunction clearFilters(): void {\n void router.replace({\n query: {\n ...route.query,\n rubric: undefined,\n tag: undefined,\n author: undefined,\n page: undefined,\n },\n })\n}\n\nasync function load(state?: TableState): Promise<void> {\n loading.value = true\n\n try {\n page.value = await api.articles({\n q: state?.search ?? query.value.q,\n status: inBin.value ? '' : (view.value as ArticleStatus | ''),\n trashed: inBin.value,\n rubric: query.value.rubric,\n tag: query.value.tag,\n author: query.value.author,\n sort: state?.sort ? `${state.sort.order === 'desc' ? '-' : ''}${state.sort.key}` : null,\n page: state?.page ?? query.value.page,\n per_page: state?.perPage,\n })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\n/**\n * The table reports everything it knows in one event, and that is the one place the address is\n * written from — so a page, a sort and a search all survive opening an article and coming back,\n * and none of them has its own half of the bookkeeping.\n */\nfunction onState(state: TableState): void {\n const wanted: LocationQueryRaw = {\n ...route.query,\n q: state.search === '' ? undefined : state.search,\n sort:\n state.sort === null\n ? undefined\n : `${state.sort.order === 'desc' ? '-' : ''}${state.sort.key}`,\n page: state.page === 1 ? undefined : String(state.page),\n }\n\n void router.replace({ query: wanted })\n void load(state)\n}\n\n/** One of the three dropdowns moved: a new list, from its first page. */\nfunction narrow(name: 'rubric' | 'tag' | 'author', value: unknown): void {\n void router.replace({\n query: {\n ...route.query,\n [name]: typeof value === 'number' ? String(value) : undefined,\n page: undefined,\n },\n })\n}\n\n/* One source per value, not one getter returning an array: `query` is rebuilt on every change of\n the address, so an array is new each time and the watcher would fire on a page turn too —\n a second request, without `per_page`, racing the one `onState` already sent. */\nwatch(\n [view, () => query.value.rubric, () => query.value.tag, () => query.value.author],\n () => void load(),\n)\n\nvoid load()\n\n/**\n * The editor of an article arrives with session C; until it does, the row opens nothing rather\n * than pushing the router at a route that is not there.\n *\n * The bin never reaches here: the table is told the rows lead nowhere, and it withholds the\n * click along with the pointer and the highlight (CLAUDE.md §4).\n */\nfunction open(article: ArticleRow): void {\n const path = `${props.base}/articles/${article.id}`\n\n if (router.resolve(path).matched.length > 0) void router.push({ path, query: { ...route.query } })\n}\n\n/** A new article: the dialog asks for a title, the list shows it as a draft, the editor opens. */\nasync function add(): Promise<void> {\n const article = await create({})\n\n if (!article) return\n\n await load()\n open(article)\n}\n\nfunction actionsFor(article: ArticleRow): RowAction[] {\n if (!canManage.value) return []\n\n if (inBin.value) {\n return [\n {\n key: 'restore',\n icon: 'refresh',\n label: t('panel.restore'),\n run: () => void restore(article),\n },\n ]\n }\n\n const actions: RowAction[] = [\n { key: 'open', icon: 'edit', label: t('panel.open'), run: () => open(article) },\n ]\n\n if (article.url && article.status !== 'draft') {\n actions.push({\n key: 'site',\n icon: 'external-link',\n label: t('panel.open-on-site'),\n href: article.url,\n })\n }\n\n if (article.path !== null) {\n actions.push({\n key: 'copy',\n icon: 'copy',\n label: t('panel.copy-address'),\n run: () => void copyAddress(article),\n })\n }\n\n actions.push({\n key: 'pin',\n icon: 'star',\n label: article.pinned ? t('panel.unpin') : t('panel.pin'),\n run: () => void setPinned(article, !article.pinned),\n })\n\n actions.push(\n article.status === 'published' ||\n article.status === 'modified' ||\n article.status === 'scheduled'\n ? {\n key: 'unpublish',\n icon: 'eye-off',\n label: t('panel.unpublish'),\n run: () => void unpublish(article),\n }\n : {\n key: 'publish',\n icon: 'upload',\n label: t('panel.publish'),\n run: () => void publish(article),\n },\n )\n\n actions.push({\n key: 'delete',\n icon: 'trash',\n label: t('panel.delete'),\n danger: true,\n run: () => void remove(article),\n })\n\n return actions\n}\n\nasync function publish(article: ArticleRow): Promise<void> {\n await run(() => api.publish(article.id), t('panel.published'))\n}\n\nasync function unpublish(article: ArticleRow): Promise<void> {\n await run(() => api.unpublish(article.id), t('panel.unpublished-done'))\n}\n\nasync function setPinned(article: ArticleRow, pinned: boolean): Promise<void> {\n await run(\n () => api.save(article.id, { values: { pinned }, revision: article.revision }),\n pinned ? t('panel.pinned-done') : t('panel.unpinned'),\n )\n}\n\nasync function remove(article: ArticleRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-title', { title: article.title }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n await run(() => api.remove(article.id), t('panel.deleted'))\n}\n\nasync function restore(article: ArticleRow): Promise<void> {\n await run(() => api.restore(article.id), t('panel.restored'))\n}\n\n/** One request, one sentence about it, and the list as the server now sees it. */\nasync function run(request: () => Promise<unknown>, said: string): Promise<void> {\n try {\n await request()\n toast.success(said)\n } catch (error) {\n toast.danger(message(error))\n } finally {\n // Either way: a refused publication has left the row saying what it was, and one that\n // worked has changed an order the answer does not carry row by row.\n await load()\n }\n}\n\nasync function copyAddress(article: ArticleRow): Promise<void> {\n if (!article.url) return\n\n try {\n await navigator.clipboard.writeText(article.url)\n toast.success(t('panel.address-copied'))\n } catch {\n // A browser that refuses the clipboard without a gesture it trusts; the address is on\n // screen and can be copied from there.\n }\n}\n\n/**\n * Live and live-with-edits are the same green: the article is on the site, and what is waiting\n * beside it is said by a chip of its own rather than by a different colour. An editor scanning\n * the column is asking \"is this up\", and two greens answer it once.\n */\nfunction badge(status: ArticleStatus): 'default' | 'success' | 'warning' | 'danger' {\n if (status === 'published' || status === 'modified') return 'success'\n if (status === 'scheduled') return 'warning'\n\n return 'default'\n}\n\n/** The address under the title, and the two different nothings that can stand there instead. */\nfunction address(article: ArticleRow): string {\n if (inBin.value) return '—'\n\n return article.path === null ? t('panel.no-address') : `/${article.path}`\n}\n\n/** The date a row is about: when it was published, or when it was deleted in the bin. */\nfunction dateOf(article: ArticleRow): string | null {\n return inBin.value ? article.deleted_at : article.published_at\n}\n\n/* What the section offers. Declared, because on a phone the head folds it into the ···. */\nconst actions = computed<ScreenAction[]>(() =>\n canManage.value\n ? [{ key: 'new', label: t('panel.new'), icon: 'plus', primary: true, run: () => void add() }]\n : [],\n)\n</script>\n\n<template>\n <div ref=\"root\" class=\"wx-articles\">\n <wx-list-screen v-model:view=\"view\" :title=\"title\" :views=\"views\" :actions=\"actions\">\n <wx-table\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n :clickable=\"!inBin\"\n :hover=\"!inBin\"\n flush\n :loading=\"loading\"\n layout=\"fixed\"\n :cards-below=\"CARDS\"\n :filters-count=\"applied.length\"\n :filters-label=\"admin('filters.title')\"\n :search-placeholder=\"t('panel.search')\"\n :empty-text=\"emptyText\"\n :aria-label=\"title\"\n @row-click=\"open\"\n @state-change=\"onState\"\n >\n <!--\n The three dropdowns live behind the funnel, and what they are set to comes back as\n chips beside it. Standing open they were three controls of chrome above the first\n article, and on a phone — where the table stacks everything in its head into a column —\n three lines of it before any data.\n -->\n <template #filters>\n <wx-form-item :label=\"t('panel.filter-rubric')\">\n <wx-select\n :model-value=\"query.rubric\"\n :options=\"filters.rubrics.map((item) => ({ value: item.id, label: item.title }))\"\n :placeholder=\"t('panel.any-rubric')\"\n clearable\n size=\"sm\"\n @update:model-value=\"(value: unknown) => narrow('rubric', value)\"\n />\n </wx-form-item>\n\n <wx-form-item :label=\"t('panel.filter-tag')\">\n <wx-select\n :model-value=\"query.tag\"\n :options=\"filters.tags.map((item) => ({ value: item.id, label: item.title }))\"\n :placeholder=\"t('panel.any-tag')\"\n clearable\n filterable\n size=\"sm\"\n @update:model-value=\"(value: unknown) => narrow('tag', value)\"\n />\n </wx-form-item>\n\n <wx-form-item :label=\"t('panel.filter-author')\">\n <wx-select\n :model-value=\"query.author\"\n :options=\"filters.authors.map((item) => ({ value: item.id, label: item.title }))\"\n :placeholder=\"t('panel.any-author')\"\n clearable\n size=\"sm\"\n @update:model-value=\"(value: unknown) => narrow('author', value)\"\n />\n </wx-form-item>\n\n <!-- Taking all of them off belongs with the fields it resets: beside the chips it\n reads as one more chip, and it is the only control there that does not take\n exactly one filter away. -->\n <wx-button v-if=\"applied.length > 0\" variant=\"text\" size=\"sm\" block @click=\"clearFilters\">\n <template #icon><wx-icon name=\"close\" /></template>\n {{ admin('filters.reset') }}\n </wx-button>\n </template>\n\n <template #applied>\n <wx-filter-chips :filters=\"applied\" />\n </template>\n\n <template #cell-cover=\"{ row }\">\n <span class=\"wx-articles__cover\" :class=\"{ 'is-empty': !row.cover }\">\n <img v-if=\"row.cover?.thumb\" :src=\"row.cover.thumb\" alt=\"\" loading=\"lazy\" />\n <wx-icon v-else name=\"image\" size=\"sm\" />\n </span>\n </template>\n\n <template #cell-title=\"{ row }\">\n <div class=\"wx-articles__name\">\n <wx-tooltip v-if=\"row.pinned\" :content=\"t('panel.pinned')\">\n <wx-icon class=\"wx-articles__pin\" name=\"star\" size=\"sm\" />\n </wx-tooltip>\n <div class=\"wx-articles__name-text\">\n <span class=\"wx-articles__title\">{{ row.title }}</span>\n <!-- An article in the bin holds no address — the registry let it go when it went\n in — and \"the address appears when it is published\" would be a promise about\n something nobody can publish without bringing it back first. -->\n <span class=\"wx-articles__address\">\n {{ address(row) }}\n <wx-address-note v-if=\"!inBin\" :locale=\"row.address_locale\" />\n </span>\n </div>\n </div>\n </template>\n\n <template #cell-rubrics=\"{ row }\">\n <span class=\"wx-articles__chips\">\n <wx-badge v-for=\"rubric in row.rubrics\" :key=\"rubric.id\" size=\"sm\" round>\n {{ rubric.title }}\n </wx-badge>\n </span>\n </template>\n\n <template #cell-author=\"{ row }\">\n <wx-text size=\"sm\" tone=\"muted\" truncate>\n {{ row.author ? row.author.name : '—' }}\n </wx-text>\n </template>\n\n <template #cell-date=\"{ row }\">\n <wx-date v-if=\"dateOf(row)\" :value=\"dateOf(row)\" compact />\n <wx-text v-else size=\"sm\" tone=\"muted\">—</wx-text>\n </template>\n\n <template #cell-status=\"{ row }\">\n <span class=\"wx-articles__state\">\n <wx-badge :type=\"badge(row.status)\" dot size=\"sm\">\n {{ t(`panel.status-${row.status}`) }}\n </wx-badge>\n <!-- What is waiting, said beside the state rather than instead of it: the article\n is on the site, and there is something that is not. -->\n <wx-badge v-if=\"row.status === 'modified'\" type=\"primary\" size=\"sm\" round>\n {{ t('panel.edits') }}\n </wx-badge>\n </span>\n </template>\n\n <!--\n The card: the cover on the left, everything else beside it. One field and no label,\n because the table's own stack of \"Title: … / Author: … / Date: …\" is five lines and\n four hundred pixels for one article (§10).\n -->\n <!--\n `WxEntityCard`, `plain` so that the box around it stays the table's own: a picture, a\n name, its address under it and a row of facts is exactly what the component is, and\n writing that by hand once per section is how five sections end up with five different\n cards.\n -->\n <template #cell-card=\"{ row }\">\n <wx-entity-card\n class=\"wx-articles__entity\"\n variant=\"plain\"\n :title=\"row.title\"\n :image=\"row.cover?.thumb ?? undefined\"\n image-size=\"56px\"\n :title-lines=\"2\"\n :subtitle=\"address(row)\"\n >\n <template #title>\n <wx-icon v-if=\"row.pinned\" class=\"wx-articles__pin\" name=\"star\" size=\"sm\" />\n {{ row.title }}\n </template>\n\n <template #meta>\n <wx-badge v-if=\"row.rubrics[0]\" size=\"sm\" round>{{ row.rubrics[0].title }}</wx-badge>\n <wx-badge :type=\"badge(row.status)\" dot size=\"sm\">\n {{ t(`panel.status-${row.status}`) }}\n </wx-badge>\n <wx-date v-if=\"dateOf(row)\" :value=\"dateOf(row)\" />\n </template>\n </wx-entity-card>\n </template>\n\n <!--\n The menu goes in the card's own top strip, beside the checkbox: that line is there\n either way as soon as rows can be picked, and a `···` inside the entity takes width\n off a title that is already one line short.\n -->\n <template #card-actions=\"{ row }\">\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"row.title\" />\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"row.title\" />\n </template>\n </wx-table>\n </wx-list-screen>\n </div>\n</template>\n\n<style scoped>\n/* The list screen inside it lays the screen out; this only keeps a wide table from pushing the\n column it sits in. */\n.wx-articles {\n min-width: 0;\n}\n\n/*\n * The cover is the picture's box, never the picture: `<img>` has `min-width: auto`, which is\n * its natural width, so a 1600px photograph would take the column and the ones beside it\n * (CLAUDE.md §4).\n */\n.wx-articles__cover {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 32px;\n overflow: hidden;\n /* The smallest step in the scale, and what `WxEntityCard` gives its own thumbnail: on a box\n 32px tall the next one up is 12, which is over a third of it. */\n border-radius: var(--wx-radius-xs);\n background: var(--wx-bg-subtle);\n color: var(--wx-text-muted);\n}\n\n.wx-articles__cover.is-empty {\n border: 1px dashed var(--wx-border-default);\n background: var(--wx-bg-surface);\n}\n\n.wx-articles__cover img {\n width: 100%;\n height: 100%;\n min-width: 0;\n object-fit: cover;\n}\n\n.wx-articles__name {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-articles__name-text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-articles__pin {\n flex: none;\n color: var(--wx-color-primary);\n}\n\n.wx-articles__title {\n overflow: hidden;\n font-weight: var(--wx-font-weight-medium);\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.wx-articles__address {\n overflow: hidden;\n color: var(--wx-text-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.wx-articles__chips,\n.wx-articles__state {\n display: flex;\n align-items: center;\n gap: var(--wx-space-4);\n min-width: 0;\n overflow: hidden;\n}\n\n/* `:deep()` because the cell is the table's element and the class is ours — a scoped rule\n would be looking for our attribute on somebody else's markup (CLAUDE.md §4). */\n.wx-articles :deep(.wx-articles__when) {\n white-space: nowrap;\n}\n</style>\n"],"names":["CARDS","props","__props","context","useAdmin","api","createBlogApi","route","useRoute","router","useRouter","useBlogMessages","t","useTranslate","admin","message","useErrorText","root","useTemplateRef","width","useElementWidth","page","ref","loading","create","createModal","ArticleCreateDialog","canManage","computed","title","module","view","value","inBin","query","number","views","filters","asCards","columns","rowMenuWidth","emptyText","applied","chips","rubric","item","narrow","tag","author","clearFilters","load","state","error","toast","onState","wanted","name","watch","open","article","path","add","actionsFor","restore","actions","copyAddress","setPinned","unpublish","publish","remove","run","pinned","confirm","request","said","badge","status","address","dateOf","_createElementBlock","_createVNode","_unref","WxListScreen","$event","WxTable","WxFormItem","WxSelect","_cache","_createBlock","WxButton","WxIcon","_createTextVNode","WxFilterChips","_withCtx","row","_createElementVNode","_normalizeClass","_hoisted_2","WxTooltip","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","WxAddressNote","_hoisted_6","_openBlock","_Fragment","_renderList","WxBadge","WxText","WxDate","_hoisted_7","WxEntityCard","WxRowMenu"],"mappings":";;;;;6PA0DMA,IAAQ;;;;;;AAHd,UAAMC,KAAQC,IAKRC,IAAUC,GAAA,GACVC,IAAMC,GAAcH,CAAO,GAC3BI,IAAQC,GAAA,GACRC,IAASC,GAAA;AACf,IAAAC,GAAA;AAEA,UAAMC,IAAIC,EAAa,WAAW,GAE5BC,IAAQD,EAAa,YAAY,GAEjCE,IAAUC,GAAA,GAEVC,IAAOC,GAA4B,MAAM,GACzCC,IAAQC,GAAgBH,CAAI,GAE5BI,IAAOC,EAAyB,IAAI,GACpCC,IAAUD,EAAI,EAAI,GAElBE,KAASC,GAA+CC,EAAmB,GAE3EC,IAAYC,EAAS,MAAMzB,EAAQ,IAAI,sBAAsB,CAAC,GAE9D0B,IAAQD;AAAA,MACZ,MACEzB,EAAQ,MAAM,UAAU,QAAQ,KAAK,CAAC2B,MAAWA,EAAO,OAAO,UAAU,GAAG,SAC5ElB,EAAE,iBAAiB;AAAA,IAAA,GASjBmB,IAAOH,EAAmB;AAAA,MAC9B,KAAK,MAAO,OAAOrB,EAAM,MAAM,QAAS,WAAWA,EAAM,MAAM,OAAO;AAAA,MACtE,KAAK,CAACyB,MAAU;AAEd,QAAKvB,EAAO,QAAQ;AAAA,UAClB,OAAO,EAAE,GAAGF,EAAM,OAAO,MAAMyB,MAAU,KAAK,SAAY,OAAOA,CAAK,GAAG,MAAM,OAAA;AAAA,QAAU,CAC1F;AAAA,MACH;AAAA,IAAA,CACD,GAEKC,IAAQL,EAAS,MAAMG,EAAK,UAAU,SAAS,GAE/CG,IAAQN,EAAS,OAAO;AAAA,MAC5B,GAAG,OAAOrB,EAAM,MAAM,KAAM,WAAWA,EAAM,MAAM,IAAI;AAAA,MACvD,QAAQ4B,EAAO5B,EAAM,MAAM,MAAM;AAAA,MACjC,KAAK4B,EAAO5B,EAAM,MAAM,GAAG;AAAA,MAC3B,QAAQ4B,EAAO5B,EAAM,MAAM,MAAM;AAAA,MACjC,MAAM,OAAOA,EAAM,MAAM,QAAS,WAAWA,EAAM,MAAM,OAAO;AAAA,MAChE,MAAM,OAAOA,EAAM,MAAM,QAAQ,CAAC,KAAK;AAAA,IAAA,EACvC;AAEF,aAAS4B,EAAOH,GAA+B;AAC7C,aAAO,OAAOA,KAAU,YAAYA,MAAU,MAAK,OAAOA,CAAK,KAAK;AAAA,IACtE;AAGA,UAAMI,KAAQR,EAAoB,MAAM;AAAA,MACtC,EAAE,OAAO,IAAI,OAAOhB,EAAE,gBAAgB,EAAA;AAAA,MACtC,EAAE,OAAO,aAAa,OAAOA,EAAE,sBAAsB,EAAA;AAAA,MACrD,EAAE,OAAO,aAAa,OAAOA,EAAE,sBAAsB,EAAA;AAAA,MACrD,EAAE,OAAO,SAAS,OAAOA,EAAE,kBAAkB,EAAA;AAAA,MAC7C,EAAE,OAAO,eAAe,OAAOA,EAAE,wBAAwB,EAAA;AAAA,MACzD,EAAE,OAAO,WAAW,OAAOA,EAAE,WAAW,GAAG,MAAM,QAAA;AAAA,IAAQ,CAC1D,GAEKyB,IAAUT,EAAS,MAAMP,EAAK,OAAO,WAAW,EAAE,SAAS,CAAA,GAAI,MAAM,CAAA,GAAI,SAAS,CAAA,GAAI,GAEtFiB,KAAUV,EAAS,MAAMT,EAAM,QAAQ,KAAKA,EAAM,QAAQnB,CAAK,GAW/DuC,KAAUX,EAAoC,MAC9CU,GAAQ,QACH,CAAC,EAAE,KAAK,QAAQ,OAAO,IAAI,IAG7B;AAAA,MACL,EAAE,KAAK,SAAS,OAAO,IAAI,OAAO,GAAA;AAAA;AAAA,MAElC,EAAE,KAAK,SAAS,OAAO1B,EAAE,oBAAoB,GAAG,UAAU,IAAA;AAAA,MAC1D,EAAE,KAAK,WAAW,OAAOA,EAAE,sBAAsB,GAAG,OAAO,KAAK,WAAW,IAAA;AAAA,MAC3E,EAAE,KAAK,UAAU,OAAOA,EAAE,qBAAqB,GAAG,OAAO,KAAK,WAAW,KAAA;AAAA,MACzE;AAAA,QACE,KAAK;AAAA,QACL,OAAOqB,EAAM,QAAQrB,EAAE,sBAAsB,IAAIA,EAAE,mBAAmB;AAAA,QACtE,OAAO;AAAA,QACP,WAAW;AAAA;AAAA;AAAA,QAGX,WAAW;AAAA,MAAA;AAAA,MAEb,EAAE,KAAK,UAAU,OAAOA,EAAE,qBAAqB,GAAG,OAAO,IAAA;AAAA,MACzD,EAAE,KAAK,WAAW,OAAO,IAAI,OAAO4B,IAAc,OAAO,QAAA;AAAA,IAAQ,CAEpE,GAEKC,KAAYb,EAAS,MACrBM,EAAM,MAAM,MAAM,KAAWtB,EAAE,oBAAoB,IAEhDqB,EAAM,QAAQrB,EAAE,iBAAiB,IAAIA,EAAE,aAAa,CAC5D,GASK8B,IAAUd,EAA0B,MAAM;AAC9C,YAAMe,IAAyB,CAAA,GAEzBC,IAASP,EAAQ,MAAM,QAAQ,KAAK,CAACQ,MAASA,EAAK,OAAOX,EAAM,MAAM,MAAM;AAClF,MAAIU,KACFD,EAAM,KAAK;AAAA,QACT,KAAK;AAAA,QACL,OAAO,GAAG/B,EAAE,qBAAqB,CAAC,KAAKgC,EAAO,KAAK;AAAA,QACnD,OAAO,MAAME,EAAO,UAAU,MAAS;AAAA,MAAA,CACxC;AAGH,YAAMC,IAAMV,EAAQ,MAAM,KAAK,KAAK,CAACQ,MAASA,EAAK,OAAOX,EAAM,MAAM,GAAG;AACzE,MAAIa,KACFJ,EAAM,KAAK;AAAA,QACT,KAAK;AAAA,QACL,OAAO,GAAG/B,EAAE,kBAAkB,CAAC,KAAKmC,EAAI,KAAK;AAAA,QAC7C,OAAO,MAAMD,EAAO,OAAO,MAAS;AAAA,MAAA,CACrC;AAGH,YAAME,IAASX,EAAQ,MAAM,QAAQ,KAAK,CAACQ,MAASA,EAAK,OAAOX,EAAM,MAAM,MAAM;AAClF,aAAIc,KACFL,EAAM,KAAK;AAAA,QACT,KAAK;AAAA,QACL,OAAO,GAAG/B,EAAE,qBAAqB,CAAC,KAAKoC,EAAO,KAAK;AAAA,QACnD,OAAO,MAAMF,EAAO,UAAU,MAAS;AAAA,MAAA,CACxC,GAGIH;AAAA,IACT,CAAC;AAGD,aAASM,KAAqB;AAC5B,MAAKxC,EAAO,QAAQ;AAAA,QAClB,OAAO;AAAA,UACL,GAAGF,EAAM;AAAA,UACT,QAAQ;AAAA,UACR,KAAK;AAAA,UACL,QAAQ;AAAA,UACR,MAAM;AAAA,QAAA;AAAA,MACR,CACD;AAAA,IACH;AAEA,mBAAe2C,EAAKC,GAAmC;AACrD,MAAA5B,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAAF,EAAK,QAAQ,MAAMhB,EAAI,SAAS;AAAA,UAC9B,GAAG8C,GAAO,UAAUjB,EAAM,MAAM;AAAA,UAChC,QAAQD,EAAM,QAAQ,KAAMF,EAAK;AAAA,UACjC,SAASE,EAAM;AAAA,UACf,QAAQC,EAAM,MAAM;AAAA,UACpB,KAAKA,EAAM,MAAM;AAAA,UACjB,QAAQA,EAAM,MAAM;AAAA,UACpB,MAAMiB,GAAO,OAAO,GAAGA,EAAM,KAAK,UAAU,SAAS,MAAM,EAAE,GAAGA,EAAM,KAAK,GAAG,KAAK;AAAA,UACnF,MAAMA,GAAO,QAAQjB,EAAM,MAAM;AAAA,UACjC,UAAUiB,GAAO;AAAA,QAAA,CAClB;AAAA,MACH,SAASC,GAAO;AACd,QAAAC,EAAM,OAAOtC,EAAQqC,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAA7B,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAOA,aAAS+B,GAAQH,GAAyB;AACxC,YAAMI,IAA2B;AAAA,QAC/B,GAAGhD,EAAM;AAAA,QACT,GAAG4C,EAAM,WAAW,KAAK,SAAYA,EAAM;AAAA,QAC3C,MACEA,EAAM,SAAS,OACX,SACA,GAAGA,EAAM,KAAK,UAAU,SAAS,MAAM,EAAE,GAAGA,EAAM,KAAK,GAAG;AAAA,QAChE,MAAMA,EAAM,SAAS,IAAI,SAAY,OAAOA,EAAM,IAAI;AAAA,MAAA;AAGxD,MAAK1C,EAAO,QAAQ,EAAE,OAAO8C,GAAQ,GAChCL,EAAKC,CAAK;AAAA,IACjB;AAGA,aAASL,EAAOU,GAAmCxB,GAAsB;AACvE,MAAKvB,EAAO,QAAQ;AAAA,QAClB,OAAO;AAAA,UACL,GAAGF,EAAM;AAAA,UACT,CAACiD,CAAI,GAAG,OAAOxB,KAAU,WAAW,OAAOA,CAAK,IAAI;AAAA,UACpD,MAAM;AAAA,QAAA;AAAA,MACR,CACD;AAAA,IACH;AAKA,IAAAyB;AAAA,MACE,CAAC1B,GAAM,MAAMG,EAAM,MAAM,QAAQ,MAAMA,EAAM,MAAM,KAAK,MAAMA,EAAM,MAAM,MAAM;AAAA,MAChF,MAAA;AAAM,QAAKgB,EAAA;AAAA;AAAA,IAAK,GAGbA,EAAA;AASL,aAASQ,EAAKC,GAA2B;AACvC,YAAMC,IAAO,GAAG3D,GAAM,IAAI,aAAa0D,EAAQ,EAAE;AAEjD,MAAIlD,EAAO,QAAQmD,CAAI,EAAE,QAAQ,SAAS,KAAQnD,EAAO,KAAK,EAAE,MAAAmD,GAAM,OAAO,EAAE,GAAGrD,EAAM,MAAA,GAAS;AAAA,IACnG;AAGA,mBAAesD,KAAqB;AAClC,YAAMF,IAAU,MAAMnC,GAAO,EAAE;AAE/B,MAAKmC,MAEL,MAAMT,EAAA,GACNQ,EAAKC,CAAO;AAAA,IACd;AAEA,aAASG,EAAWH,GAAkC;AACpD,UAAI,CAAChC,EAAU,MAAO,QAAO,CAAA;AAE7B,UAAIM,EAAM;AACR,eAAO;AAAA,UACL;AAAA,YACE,KAAK;AAAA,YACL,MAAM;AAAA,YACN,OAAOrB,EAAE,eAAe;AAAA,YACxB,KAAK,MAAA;AAAM,cAAKmD,GAAQJ,CAAO;AAAA;AAAA,UAAA;AAAA,QACjC;AAIJ,YAAMK,IAAuB;AAAA,QAC3B,EAAE,KAAK,QAAQ,MAAM,QAAQ,OAAOpD,EAAE,YAAY,GAAG,KAAK,MAAM8C,EAAKC,CAAO,EAAA;AAAA,MAAE;AAGhF,aAAIA,EAAQ,OAAOA,EAAQ,WAAW,WACpCK,EAAQ,KAAK;AAAA,QACX,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAOpD,EAAE,oBAAoB;AAAA,QAC7B,MAAM+C,EAAQ;AAAA,MAAA,CACf,GAGCA,EAAQ,SAAS,QACnBK,EAAQ,KAAK;AAAA,QACX,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAOpD,EAAE,oBAAoB;AAAA,QAC7B,KAAK,MAAA;AAAM,UAAKqD,GAAYN,CAAO;AAAA;AAAA,MAAA,CACpC,GAGHK,EAAQ,KAAK;AAAA,QACX,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAOL,EAAQ,SAAS/C,EAAE,aAAa,IAAIA,EAAE,WAAW;AAAA,QACxD,KAAK,MAAA;AAAM,UAAKsD,GAAUP,GAAS,CAACA,EAAQ,MAAM;AAAA;AAAA,MAAA,CACnD,GAEDK,EAAQ;AAAA,QACNL,EAAQ,WAAW,eACjBA,EAAQ,WAAW,cACnBA,EAAQ,WAAW,cACjB;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAO/C,EAAE,iBAAiB;AAAA,UAC1B,KAAK,MAAA;AAAM,YAAKuD,GAAUR,CAAO;AAAA;AAAA,QAAA,IAEnC;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAO/C,EAAE,eAAe;AAAA,UACxB,KAAK,MAAA;AAAM,YAAKwD,GAAQT,CAAO;AAAA;AAAA,QAAA;AAAA,MACjC,GAGNK,EAAQ,KAAK;AAAA,QACX,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAOpD,EAAE,cAAc;AAAA,QACvB,QAAQ;AAAA,QACR,KAAK,MAAA;AAAM,UAAKyD,GAAOV,CAAO;AAAA;AAAA,MAAA,CAC/B,GAEMK;AAAAA,IACT;AAEA,mBAAeI,GAAQT,GAAoC;AACzD,YAAMW,EAAI,MAAMjE,EAAI,QAAQsD,EAAQ,EAAE,GAAG/C,EAAE,iBAAiB,CAAC;AAAA,IAC/D;AAEA,mBAAeuD,GAAUR,GAAoC;AAC3D,YAAMW,EAAI,MAAMjE,EAAI,UAAUsD,EAAQ,EAAE,GAAG/C,EAAE,wBAAwB,CAAC;AAAA,IACxE;AAEA,mBAAesD,GAAUP,GAAqBY,GAAgC;AAC5E,YAAMD;AAAA,QACJ,MAAMjE,EAAI,KAAKsD,EAAQ,IAAI,EAAE,QAAQ,EAAE,QAAAY,KAAU,UAAUZ,EAAQ,UAAU;AAAA,QACpE/C,EAAT2D,IAAW,sBAAyB,gBAAN;AAAA,MAAsB;AAAA,IAExD;AAEA,mBAAeF,GAAOV,GAAoC;AASxD,MARe,MAAMa,GAAQ;AAAA,QAC3B,OAAO5D,EAAE,sBAAsB,EAAE,OAAO+C,EAAQ,OAAO;AAAA,QACvD,SAAS/C,EAAE,mBAAmB;AAAA,QAC9B,aAAaA,EAAE,cAAc;AAAA,QAC7B,YAAYA,EAAE,cAAc;AAAA,QAC5B,MAAM;AAAA,MAAA,CACP,KAID,MAAM0D,EAAI,MAAMjE,EAAI,OAAOsD,EAAQ,EAAE,GAAG/C,EAAE,eAAe,CAAC;AAAA,IAC5D;AAEA,mBAAemD,GAAQJ,GAAoC;AACzD,YAAMW,EAAI,MAAMjE,EAAI,QAAQsD,EAAQ,EAAE,GAAG/C,EAAE,gBAAgB,CAAC;AAAA,IAC9D;AAGA,mBAAe0D,EAAIG,GAAiCC,GAA6B;AAC/E,UAAI;AACF,cAAMD,EAAA,GACNpB,EAAM,QAAQqB,CAAI;AAAA,MACpB,SAAStB,GAAO;AACd,QAAAC,EAAM,OAAOtC,EAAQqC,CAAK,CAAC;AAAA,MAC7B,UAAA;AAGE,cAAMF,EAAA;AAAA,MACR;AAAA,IACF;AAEA,mBAAee,GAAYN,GAAoC;AAC7D,UAAKA,EAAQ;AAEb,YAAI;AACF,gBAAM,UAAU,UAAU,UAAUA,EAAQ,GAAG,GAC/CN,EAAM,QAAQzC,EAAE,sBAAsB,CAAC;AAAA,QACzC,QAAQ;AAAA,QAGR;AAAA,IACF;AAOA,aAAS+D,EAAMC,GAAqE;AAClF,aAAIA,MAAW,eAAeA,MAAW,aAAmB,YACxDA,MAAW,cAAoB,YAE5B;AAAA,IACT;AAGA,aAASC,EAAQlB,GAA6B;AAC5C,aAAI1B,EAAM,QAAc,MAEjB0B,EAAQ,SAAS,OAAO/C,EAAE,kBAAkB,IAAI,IAAI+C,EAAQ,IAAI;AAAA,IACzE;AAGA,aAASmB,EAAOnB,GAAoC;AAClD,aAAO1B,EAAM,QAAQ0B,EAAQ,aAAaA,EAAQ;AAAA,IACpD;AAGA,UAAMK,KAAUpC;AAAA,MAAyB,MACvCD,EAAU,QACN,CAAC,EAAE,KAAK,OAAO,OAAOf,EAAE,WAAW,GAAG,MAAM,QAAQ,SAAS,IAAM,KAAK;AAAM,QAAKiD,GAAA;AAAA,QAAI,CAAG,IAC1F,CAAA;AAAA,IAAC;2BAKLkB,EAsLM,OAAA;AAAA,eAtLG;AAAA,MAAJ,KAAI9D;AAAA,MAAO,OAAM;AAAA,IAAA;MACpB+D,EAoLiBC,EAAAC,EAAA,GAAA;AAAA,QApLO,MAAMnD,EAAA;AAAA,gDAAAA,EAAI,QAAAoD;AAAA,QAAG,OAAOtD,EAAA;AAAA,QAAQ,OAAOO,GAAA;AAAA,QAAQ,SAAS4B,GAAA;AAAA,MAAA;mBAC1E,MAkLW;AAAA,UAlLXgB,EAkLWC,EAAAG,EAAA,GAAA;AAAA,YAjLR,MAAM/D,EAAA;AAAA,YACN,SAASkB,GAAA;AAAA,YACV,WAAQ;AAAA,YACR,YAAA;AAAA,YACC,YAAYN,EAAA;AAAA,YACZ,QAAQA,EAAA;AAAA,YACT,OAAA;AAAA,YACC,SAASV,EAAA;AAAA,YACV,QAAO;AAAA,YACN,eAAavB;AAAA,YACb,iBAAe0C,EAAA,MAAQ;AAAA,YACvB,iBAAeuC,EAAAnE,CAAA,EAAK,eAAA;AAAA,YACpB,sBAAoBmE,EAAArE,CAAA,EAAC,cAAA;AAAA,YACrB,cAAY6B,GAAA;AAAA,YACZ,cAAYZ,EAAA;AAAA,YACZ,YAAW6B;AAAA,YACX,eAAcJ;AAAA,UAAA;YAQJ,WACT,MASe;AAAA,cATf0B,EASeC,EAAAI,CAAA,GAAA;AAAA,gBATA,OAAOJ,EAAArE,CAAA,EAAC,qBAAA;AAAA,cAAA;2BACrB,MAOE;AAAA,kBAPFoE,EAOEC,EAAAK,CAAA,GAAA;AAAA,oBANC,eAAapD,EAAA,MAAM;AAAA,oBACnB,SAASG,EAAA,MAAQ,QAAQ,IAAG,CAAEQ,OAAI,EAAA,OAAeA,EAAK,IAAE,OAASA,EAAK,QAAK;AAAA,oBAC3E,aAAaoC,EAAArE,CAAA,EAAC,kBAAA;AAAA,oBACf,WAAA;AAAA,oBACA,MAAK;AAAA,oBACJ,uBAAkB2E,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAGvD,MAAmBc,YAAiBd,CAAK;AAAA,kBAAA;;;;cAInEgD,EAUeC,EAAAI,CAAA,GAAA;AAAA,gBAVA,OAAOJ,EAAArE,CAAA,EAAC,kBAAA;AAAA,cAAA;2BACrB,MAQE;AAAA,kBARFoE,EAQEC,EAAAK,CAAA,GAAA;AAAA,oBAPC,eAAapD,EAAA,MAAM;AAAA,oBACnB,SAASG,EAAA,MAAQ,KAAK,IAAG,CAAEQ,OAAI,EAAA,OAAeA,EAAK,IAAE,OAASA,EAAK,QAAK;AAAA,oBACxE,aAAaoC,EAAArE,CAAA,EAAC,eAAA;AAAA,oBACf,WAAA;AAAA,oBACA,YAAA;AAAA,oBACA,MAAK;AAAA,oBACJ,uBAAkB2E,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAGvD,MAAmBc,SAAcd,CAAK;AAAA,kBAAA;;;;cAIhEgD,EASeC,EAAAI,CAAA,GAAA;AAAA,gBATA,OAAOJ,EAAArE,CAAA,EAAC,qBAAA;AAAA,cAAA;2BACrB,MAOE;AAAA,kBAPFoE,EAOEC,EAAAK,CAAA,GAAA;AAAA,oBANC,eAAapD,EAAA,MAAM;AAAA,oBACnB,SAASG,EAAA,MAAQ,QAAQ,IAAG,CAAEQ,OAAI,EAAA,OAAeA,EAAK,IAAE,OAASA,EAAK,QAAK;AAAA,oBAC3E,aAAaoC,EAAArE,CAAA,EAAC,kBAAA;AAAA,oBACf,WAAA;AAAA,oBACA,MAAK;AAAA,oBACJ,uBAAkB2E,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAGvD,MAAmBc,YAAiBd,CAAK;AAAA,kBAAA;;;;cAOlDU,EAAA,MAAQ,SAAM,UAA/B8C,EAGYP,EAAAQ,EAAA,GAAA;AAAA;gBAHyB,SAAQ;AAAA,gBAAO,MAAK;AAAA,gBAAK,OAAA;AAAA,gBAAO,SAAOxC;AAAA,cAAA;gBAC/D,QAAK,MAAwB;AAAA,kBAAxB+B,EAAwBC,EAAAS,CAAA,GAAA,EAAf,MAAK,SAAO;AAAA,gBAAA;2BAAc,MACnD;AAAA,kBADmDC,EAAA,QAChDV,EAAAnE,CAAA,EAAK,eAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;YAID,WACT,MAAsC;AAAA,cAAtCkE,EAAsCC,EAAAW,EAAA,GAAA,EAApB,SAASlD,EAAA,SAAO,MAAA,GAAA,CAAA,SAAA,CAAA;AAAA,YAAA;YAGzB,cAAUmD,EACnB,CAGO,EAJgB,KAAAC,QAAG;AAAA,cAC1BC,EAGO,QAAA;AAAA,gBAHD,OAAKC,GAAA,CAAC,sBAAoB,EAAA,YAAA,CAAwBF,EAAI,OAAK,CAAA;AAAA,cAAA;gBACpDA,EAAI,OAAO,cAAtBf,EAA4E,OAAA;AAAA;kBAA9C,KAAKe,EAAI,MAAM;AAAA,kBAAO,KAAI;AAAA,kBAAG,SAAQ;AAAA,gBAAA,yBACnEN,EAAyCP,EAAAS,CAAA,GAAA;AAAA;kBAAzB,MAAK;AAAA,kBAAQ,MAAK;AAAA,gBAAA;;;YAI3B,cAAUG,EACnB,CAcM,EAfiB,KAAAC,QAAG;AAAA,cAC1BC,EAcM,OAdNE,IAcM;AAAA,gBAbcH,EAAI,eAAtBN,EAEaP,EAAAiB,EAAA,GAAA;AAAA;kBAFkB,SAASjB,EAAArE,CAAA,EAAC,cAAA;AAAA,gBAAA;6BACvC,MAA0D;AAAA,oBAA1DoE,EAA0DC,EAAAS,CAAA,GAAA;AAAA,sBAAjD,OAAM;AAAA,sBAAmB,MAAK;AAAA,sBAAO,MAAK;AAAA,oBAAA;;;;gBAErDK,EASM,OATNI,IASM;AAAA,kBARJJ,EAAuD,QAAvDK,IAAuDC,EAAnBP,EAAI,KAAK,GAAA,CAAA;AAAA,kBAI7CC,EAGO,QAHPO,IAGO;AAAA,wBAFFzB,EAAQiB,CAAG,CAAA,IAAI,KAClB,CAAA;AAAA,oBAAwB7D,EAAA,0BAAxBuD,EAA8DP,EAAAsB,EAAA,GAAA;AAAA;sBAA9B,QAAQT,EAAI;AAAA,oBAAA;;;;;YAMzC,gBAAYD,EACrB,CAIO,EALkB,KAAAC,QAAG;AAAA,cAC5BC,EAIO,QAJPS,IAIO;AAAA,iBAHLC,EAAA,EAAA,GAAA1B,EAEW2B,IAAA,MAAAC,GAFgBb,EAAI,UAAdlD,YAAjB4C,EAEWP,EAAA2B,CAAA,GAAA;AAAA,kBAF8B,KAAKhE,EAAO;AAAA,kBAAI,MAAK;AAAA,kBAAK,OAAA;AAAA,gBAAA;6BACjE,MAAkB;AAAA,oBAAf+C,EAAAU,EAAAzD,EAAO,KAAK,GAAA,CAAA;AAAA,kBAAA;;;;;YAKV,eAAWiD,EACpB,CAEU,EAHc,KAAAC,QAAG;AAAA,cAC3Bd,EAEUC,EAAA4B,CAAA,GAAA;AAAA,gBAFD,MAAK;AAAA,gBAAK,MAAK;AAAA,gBAAQ,UAAA;AAAA,cAAA;2BAC9B,MAAwC;AAAA,kBAArClB,EAAAU,EAAAP,EAAI,SAASA,EAAI,OAAO,OAAI,GAAA,GAAA,CAAA;AAAA,gBAAA;;;;YAIxB,aAASD,EAClB,CAA2D,EADrC,KAAAC,QAAG;AAAA,cACVhB,EAAOgB,CAAG,UAAzBN,EAA2DP,EAAA6B,CAAA,GAAA;AAAA;gBAA9B,OAAOhC,EAAOgB,CAAG;AAAA,gBAAG,SAAA;AAAA,cAAA,gCACjDN,EAAkDP,EAAA4B,CAAA,GAAA;AAAA;gBAAlC,MAAK;AAAA,gBAAK,MAAK;AAAA,cAAA;2BAAQ,MAAC,CAAA,GAAAtB,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,oBAAD,KAAC,EAAA;AAAA,gBAAA;;;;YAG/B,eAAWM,EACpB,CASO,EAViB,KAAAC,QAAG;AAAA,cAC3BC,EASO,QATPgB,IASO;AAAA,gBARL/B,EAEWC,EAAA2B,CAAA,GAAA;AAAA,kBAFA,MAAMjC,EAAMmB,EAAI,MAAM;AAAA,kBAAG,KAAA;AAAA,kBAAI,MAAK;AAAA,gBAAA;6BAC3C,MAAqC;AAAA,wBAAlCb,EAAArE,CAAA,EAAC,gBAAiBkF,EAAI,MAAM,EAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;gBAIjBA,EAAI,WAAM,mBAA1BN,EAEWP,EAAA2B,CAAA,GAAA;AAAA;kBAFgC,MAAK;AAAA,kBAAU,MAAK;AAAA,kBAAK,OAAA;AAAA,gBAAA;6BAClE,MAAsB;AAAA,wBAAnB3B,EAAArE,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;;;YAgBC,aAASiF,EAClB,CAqBiB,EAtBK,KAAAC,QAAG;AAAA,cACzBd,EAqBiBC,EAAA+B,EAAA,GAAA;AAAA,gBApBf,OAAM;AAAA,gBACN,SAAQ;AAAA,gBACP,OAAOlB,EAAI;AAAA,gBACX,OAAOA,EAAI,OAAO,SAAS;AAAA,gBAC5B,cAAW;AAAA,gBACV,eAAa;AAAA,gBACb,UAAUjB,EAAQiB,CAAG;AAAA,cAAA;gBAEX,SACT,MAA4E;AAAA,kBAA7DA,EAAI,eAAnBN,EAA4EP,EAAAS,CAAA,GAAA;AAAA;oBAAjD,OAAM;AAAA,oBAAmB,MAAK;AAAA,oBAAO,MAAK;AAAA,kBAAA;oBAAO,MAC5EW,EAAGP,EAAI,KAAK,GAAA,CAAA;AAAA,gBAAA;gBAGH,QACT,MAAqF;AAAA,kBAArEA,EAAI,QAAO,CAAA,UAA3BN,EAAqFP,EAAA2B,CAAA,GAAA;AAAA;oBAArD,MAAK;AAAA,oBAAK,OAAA;AAAA,kBAAA;+BAAM,MAA0B;AAAA,0BAAvBd,EAAI,QAAO,CAAA,EAAI,KAAK,GAAA,CAAA;AAAA,oBAAA;;;kBACvEd,EAEWC,EAAA2B,CAAA,GAAA;AAAA,oBAFA,MAAMjC,EAAMmB,EAAI,MAAM;AAAA,oBAAG,KAAA;AAAA,oBAAI,MAAK;AAAA,kBAAA;+BAC3C,MAAqC;AAAA,0BAAlCb,EAAArE,CAAA,EAAC,gBAAiBkF,EAAI,MAAM,EAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;kBAElBhB,EAAOgB,CAAG,UAAzBN,EAAmDP,EAAA6B,CAAA,GAAA;AAAA;oBAAtB,OAAOhC,EAAOgB,CAAG;AAAA,kBAAA;;;;;YAUzC,gBAAYD,EACrB,CAA6D,EADpC,KAAAC,QAAG;AAAA,cAC5Bd,EAA6DC,EAAAgC,CAAA,GAAA;AAAA,gBAA/C,SAASnD,EAAWgC,CAAG;AAAA,gBAAI,OAAOA,EAAI;AAAA,cAAA;;YAG3C,gBAAYD,EACrB,CAA6D,EADpC,KAAAC,QAAG;AAAA,cAC5Bd,EAA6DC,EAAAgC,CAAA,GAAA;AAAA,gBAA/C,SAASnD,EAAWgC,CAAG;AAAA,gBAAI,OAAOA,EAAI;AAAA,cAAA;;;;;;;;;;"}