@burdenoff/microfe-tours 2026.720.1 → 2026.731.1

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.
@@ -6,132 +6,133 @@ import { useToursI18n as i } from "../i18n.js";
6
6
  import { useTourBuilder as a } from "../hooks/useTourBuilder.js";
7
7
  import { useTourPreview as o } from "../hooks/useTourPreview.js";
8
8
  import { useEffect as s } from "react";
9
- import { AlertCircle as c, ArrowLeft as l, ChevronLeft as u, ChevronRight as d, Monitor as f, Smartphone as p, Tablet as m, X as h } from "lucide-react";
10
- import { jsx as g, jsxs as _ } from "react/jsx-runtime";
11
- import { useNavigate as v, useParams as y } from "react-router-dom";
12
- import { Button as b, GlassCard as x, IllustratedEmptyState as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
9
+ import { Markdown as c } from "@burdenoff/fe-libs/shared/components";
10
+ import { AlertCircle as l, ArrowLeft as u, ChevronLeft as d, ChevronRight as f, Monitor as p, Smartphone as m, Tablet as h, X as g } from "lucide-react";
11
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
12
+ import { useNavigate as y, useParams as b } from "react-router-dom";
13
+ import { Button as x, GlassCard as S, IllustratedEmptyState as C, PagePurpose as w } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/tours/pages/TourPreviewPage.tsx
14
- function w() {
15
- let { tr: w } = i(), { tourId: T } = y(), E = v(), { basePath: D = "/" } = e(), { hasPermission: O } = n(), k = O(r.TOUR_READ), { tour: A, loadTour: j } = a(T), { devicePreview: M } = t(), { isPreviewActive: N, currentStepIndex: P, currentStep: F, totalSteps: I, canGoNext: L, canGoPrevious: R, validationResults: z, startPreview: B, stopPreview: V, nextStep: H, previousStep: U, changeDevice: W, validateForPreview: G } = o(A || void 0);
15
+ function T() {
16
+ let { tr: T } = i(), { tourId: E } = b(), D = y(), { basePath: O = "/" } = e(), { hasPermission: k } = n(), A = k(r.TOUR_READ), { tour: j, loadTour: M } = a(E), { devicePreview: N } = t(), { isPreviewActive: P, currentStepIndex: F, currentStep: I, totalSteps: L, canGoNext: R, canGoPrevious: z, validationResults: B, startPreview: V, stopPreview: H, nextStep: U, previousStep: W, changeDevice: G, validateForPreview: K } = o(j || void 0);
16
17
  if (s(() => {
17
- T && j(T);
18
- }, [T, j]), s(() => {
19
- A && G();
18
+ E && M(E);
19
+ }, [E, M]), s(() => {
20
+ j && K();
20
21
  }, [
21
- A,
22
- M,
23
- G
24
- ]), !k) return /* @__PURE__ */ g("div", {
22
+ j,
23
+ N,
24
+ K
25
+ ]), !A) return /* @__PURE__ */ _("div", {
25
26
  className: "flex items-center justify-center h-screen bg-bg-sunken",
26
- children: /* @__PURE__ */ _("div", {
27
+ children: /* @__PURE__ */ v("div", {
27
28
  className: "text-center",
28
- children: [/* @__PURE__ */ g("h2", {
29
+ children: [/* @__PURE__ */ _("h2", {
29
30
  className: "text-lg font-semibold text-text-primary mb-2",
30
- children: w("tourPreview.accessDeniedTitle")
31
- }), /* @__PURE__ */ g("p", {
31
+ children: T("tourPreview.accessDeniedTitle")
32
+ }), /* @__PURE__ */ _("p", {
32
33
  className: "text-sm text-text-secondary",
33
- children: w("tourPreview.accessDeniedMessage")
34
+ children: T("tourPreview.accessDeniedMessage")
34
35
  })]
35
36
  })
36
37
  });
37
- if (!A) return /* @__PURE__ */ g("div", {
38
+ if (!j) return /* @__PURE__ */ _("div", {
38
39
  className: "flex items-center justify-center h-screen bg-bg-sunken",
39
- children: /* @__PURE__ */ g("p", {
40
+ children: /* @__PURE__ */ _("p", {
40
41
  className: "text-text-secondary",
41
- children: w("tourPreview.loading")
42
+ children: T("tourPreview.loading")
42
43
  })
43
44
  });
44
- let K = () => {
45
- E(`${D}/${T}/edit`);
46
- }, q = {
47
- mobile: /* @__PURE__ */ g(p, { size: 20 }),
48
- tablet: /* @__PURE__ */ g(m, { size: 20 }),
49
- desktop: /* @__PURE__ */ g(f, { size: 20 })
45
+ let q = () => {
46
+ D(`${O}/${E}/edit`);
47
+ }, J = {
48
+ mobile: /* @__PURE__ */ _(m, { size: 20 }),
49
+ tablet: /* @__PURE__ */ _(h, { size: 20 }),
50
+ desktop: /* @__PURE__ */ _(p, { size: 20 })
50
51
  };
51
- return /* @__PURE__ */ _("div", {
52
+ return /* @__PURE__ */ v("div", {
52
53
  className: "flex flex-col h-screen bg-bg-sunken",
53
54
  children: [
54
- /* @__PURE__ */ _("div", {
55
+ /* @__PURE__ */ v("div", {
55
56
  className: "border-b border-border-subtle bg-bg-surface p-3 sm:p-4 flex flex-wrap items-center gap-3 sm:gap-4",
56
57
  children: [
57
- /* @__PURE__ */ g("button", {
58
+ /* @__PURE__ */ _("button", {
58
59
  type: "button",
59
- onClick: K,
60
+ onClick: q,
60
61
  className: "p-2 min-h-[44px] min-w-[44px] hover:bg-accent rounded-md",
61
- "aria-label": w("tourBuilder.goBack"),
62
- children: /* @__PURE__ */ g(l, { size: 20 })
62
+ "aria-label": T("tourBuilder.goBack"),
63
+ children: /* @__PURE__ */ _(u, { size: 20 })
63
64
  }),
64
- /* @__PURE__ */ _("div", {
65
+ /* @__PURE__ */ v("div", {
65
66
  className: "flex-1 min-w-[12rem]",
66
- children: [/* @__PURE__ */ _("h1", {
67
+ children: [/* @__PURE__ */ v("h1", {
67
68
  className: "text-base sm:text-lg font-semibold truncate",
68
69
  children: [
69
- A?.name,
70
+ j?.name,
70
71
  " - ",
71
- w("tourPreview.previewSuffix")
72
+ T("tourPreview.previewSuffix")
72
73
  ]
73
- }), N && /* @__PURE__ */ _("p", {
74
+ }), P && /* @__PURE__ */ v("p", {
74
75
  className: "text-sm text-text-secondary",
75
76
  children: [
76
- w("tourPreview.stepOf"),
77
+ T("tourPreview.stepOf"),
77
78
  " ",
78
- P + 1,
79
+ F + 1,
79
80
  " ",
80
- w("tourPreview.stepOfConnector"),
81
+ T("tourPreview.stepOfConnector"),
81
82
  " ",
82
- I
83
+ L
83
84
  ]
84
85
  })]
85
86
  }),
86
- /* @__PURE__ */ g("div", {
87
+ /* @__PURE__ */ _("div", {
87
88
  className: "flex gap-2 border border-border-subtle rounded-md overflow-hidden",
88
89
  children: [
89
90
  "mobile",
90
91
  "tablet",
91
92
  "desktop"
92
- ].map((e) => /* @__PURE__ */ g("button", {
93
+ ].map((e) => /* @__PURE__ */ _("button", {
93
94
  type: "button",
94
- onClick: () => W(e),
95
- className: `px-3 py-2 min-h-[44px] min-w-[44px] ${M === e ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-surface hover:bg-accent"}`,
96
- title: w(e === "mobile" ? "tourPreview.deviceMobile" : e === "tablet" ? "tourPreview.deviceTablet" : "tourPreview.deviceDesktop"),
97
- "aria-label": w(e === "mobile" ? "tourPreview.deviceMobile" : e === "tablet" ? "tourPreview.deviceTablet" : "tourPreview.deviceDesktop"),
98
- children: q[e]
95
+ onClick: () => G(e),
96
+ className: `px-3 py-2 min-h-[44px] min-w-[44px] ${N === e ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-surface hover:bg-accent"}`,
97
+ title: T(e === "mobile" ? "tourPreview.deviceMobile" : e === "tablet" ? "tourPreview.deviceTablet" : "tourPreview.deviceDesktop"),
98
+ "aria-label": T(e === "mobile" ? "tourPreview.deviceMobile" : e === "tablet" ? "tourPreview.deviceTablet" : "tourPreview.deviceDesktop"),
99
+ children: J[e]
99
100
  }, e))
100
101
  }),
101
- N ? /* @__PURE__ */ _(b, {
102
+ P ? /* @__PURE__ */ v(x, {
102
103
  type: "button",
103
104
  variant: "outline",
104
- onClick: V,
105
+ onClick: H,
105
106
  className: "min-h-[44px]",
106
- children: [/* @__PURE__ */ g(h, { size: 20 }), w("tourPreview.stopPreview")]
107
- }) : /* @__PURE__ */ g(b, {
107
+ children: [/* @__PURE__ */ _(g, { size: 20 }), T("tourPreview.stopPreview")]
108
+ }) : /* @__PURE__ */ _(x, {
108
109
  type: "button",
109
- onClick: B,
110
- disabled: !z?.valid,
110
+ onClick: V,
111
+ disabled: !B?.valid,
111
112
  className: "min-h-[44px]",
112
- children: w("tourPreview.startPreview")
113
+ children: T("tourPreview.startPreview")
113
114
  })
114
115
  ]
115
116
  }),
116
- /* @__PURE__ */ g("div", {
117
+ /* @__PURE__ */ _("div", {
117
118
  className: "px-3 sm:px-6 pt-3",
118
- children: /* @__PURE__ */ g(C, { children: w("tourPreview.purpose") })
119
+ children: /* @__PURE__ */ _(w, { children: T("tourPreview.purpose") })
119
120
  }),
120
- z && !z.valid && /* @__PURE__ */ g("div", {
121
+ B && !B.valid && /* @__PURE__ */ _("div", {
121
122
  className: "bg-status-error-bg/10 border-b border-status-error-border px-3 sm:px-6 py-3",
122
- children: /* @__PURE__ */ _("div", {
123
+ children: /* @__PURE__ */ v("div", {
123
124
  className: "flex items-start gap-3",
124
- children: [/* @__PURE__ */ g(c, {
125
+ children: [/* @__PURE__ */ _(l, {
125
126
  className: "text-status-error-text flex-shrink-0 mt-0.5",
126
127
  size: 20
127
- }), /* @__PURE__ */ _("div", {
128
+ }), /* @__PURE__ */ v("div", {
128
129
  className: "flex-1",
129
- children: [/* @__PURE__ */ g("h3", {
130
+ children: [/* @__PURE__ */ _("h3", {
130
131
  className: "font-semibold text-status-error-text mb-1",
131
- children: w("tourPreview.validationErrorsTitle")
132
- }), /* @__PURE__ */ g("ul", {
132
+ children: T("tourPreview.validationErrorsTitle")
133
+ }), /* @__PURE__ */ _("ul", {
133
134
  className: "list-disc list-inside space-y-1",
134
- children: z.errors.map((e) => /* @__PURE__ */ g("li", {
135
+ children: B.errors.map((e) => /* @__PURE__ */ _("li", {
135
136
  className: "text-sm text-status-error-text",
136
137
  children: e
137
138
  }, e))
@@ -139,21 +140,21 @@ function w() {
139
140
  })]
140
141
  })
141
142
  }),
142
- z && z.warnings.length > 0 && /* @__PURE__ */ g("div", {
143
+ B && B.warnings.length > 0 && /* @__PURE__ */ _("div", {
143
144
  className: "bg-warning/10 border-b border-warning px-3 sm:px-6 py-3",
144
- children: /* @__PURE__ */ _("div", {
145
+ children: /* @__PURE__ */ v("div", {
145
146
  className: "flex items-start gap-3",
146
- children: [/* @__PURE__ */ g(c, {
147
+ children: [/* @__PURE__ */ _(l, {
147
148
  className: "text-warning flex-shrink-0 mt-0.5",
148
149
  size: 20
149
- }), /* @__PURE__ */ _("div", {
150
+ }), /* @__PURE__ */ v("div", {
150
151
  className: "flex-1",
151
- children: [/* @__PURE__ */ g("h3", {
152
+ children: [/* @__PURE__ */ _("h3", {
152
153
  className: "font-semibold text-warning mb-1",
153
- children: w("tourPreview.warningsTitle")
154
- }), /* @__PURE__ */ g("ul", {
154
+ children: T("tourPreview.warningsTitle")
155
+ }), /* @__PURE__ */ _("ul", {
155
156
  className: "list-disc list-inside space-y-1",
156
- children: z.warnings.map((e) => /* @__PURE__ */ g("li", {
157
+ children: B.warnings.map((e) => /* @__PURE__ */ _("li", {
157
158
  className: "text-sm text-warning",
158
159
  children: e
159
160
  }, e))
@@ -161,77 +162,77 @@ function w() {
161
162
  })]
162
163
  })
163
164
  }),
164
- /* @__PURE__ */ g("div", {
165
+ /* @__PURE__ */ _("div", {
165
166
  className: "flex-1 flex items-center justify-center p-3 sm:p-6 overflow-auto",
166
- children: /* @__PURE__ */ g("div", {
167
- className: `bg-bg-surface border-2 rounded-lg shadow-xl overflow-hidden ${M === "mobile" ? "w-[min(375px,calc(100vw-1.5rem))] h-[667px] max-h-full" : M === "tablet" ? "w-[min(768px,calc(100vw-1.5rem))] h-[1024px] max-h-full" : "w-full max-w-[1920px] h-full max-h-[1080px]"}`,
168
- children: N && F ? /* @__PURE__ */ g("div", {
167
+ children: /* @__PURE__ */ _("div", {
168
+ className: `bg-bg-surface border-2 rounded-lg shadow-xl overflow-hidden ${N === "mobile" ? "w-[min(375px,calc(100vw-1.5rem))] h-[667px] max-h-full" : N === "tablet" ? "w-[min(768px,calc(100vw-1.5rem))] h-[1024px] max-h-full" : "w-full max-w-[1920px] h-full max-h-[1080px]"}`,
169
+ children: P && I ? /* @__PURE__ */ _("div", {
169
170
  className: "h-full flex flex-col items-center justify-center p-4 sm:p-8",
170
- children: /* @__PURE__ */ _(x, {
171
+ children: /* @__PURE__ */ v(S, {
171
172
  treatment: "glass",
172
173
  className: "max-w-md border-border-seam p-4 sm:p-6 shadow-[var(--shadow-pop)]",
173
174
  children: [
174
- /* @__PURE__ */ g("h3", {
175
+ /* @__PURE__ */ _("h3", {
175
176
  className: "text-lg font-semibold mb-3",
176
- children: F.title
177
- }),
178
- /* @__PURE__ */ g("p", {
179
- className: "text-sm text-text-secondary mb-4 whitespace-pre-wrap",
180
- children: F.content
177
+ children: I.title
181
178
  }),
182
179
  /* @__PURE__ */ _("div", {
180
+ className: "text-sm text-text-secondary mb-4 prose prose-sm max-w-none",
181
+ children: /* @__PURE__ */ _(c, { children: I.content })
182
+ }),
183
+ /* @__PURE__ */ v("div", {
183
184
  className: "flex gap-2",
184
- children: [/* @__PURE__ */ g("button", {
185
+ children: [/* @__PURE__ */ _("button", {
185
186
  type: "button",
186
- onClick: U,
187
- disabled: !R,
187
+ onClick: W,
188
+ disabled: !z,
188
189
  className: "px-3 py-2 min-h-[44px] min-w-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed",
189
- "aria-label": w("tourPreview.previous"),
190
- children: /* @__PURE__ */ g(u, { size: 16 })
191
- }), /* @__PURE__ */ g("button", {
190
+ "aria-label": T("tourPreview.previous"),
191
+ children: /* @__PURE__ */ _(d, { size: 16 })
192
+ }), /* @__PURE__ */ _("button", {
192
193
  type: "button",
193
- onClick: H,
194
- disabled: !L,
194
+ onClick: U,
195
+ disabled: !R,
195
196
  className: "flex-1 px-3 py-2 min-h-[44px] bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 disabled:opacity-50 disabled:cursor-not-allowed",
196
- children: w(L ? "tourPreview.next" : "tourPreview.finish")
197
+ children: T(R ? "tourPreview.next" : "tourPreview.finish")
197
198
  })]
198
199
  })
199
200
  ]
200
201
  })
201
- }) : /* @__PURE__ */ g("div", {
202
+ }) : /* @__PURE__ */ _("div", {
202
203
  className: "h-full flex items-center justify-center p-4",
203
- children: /* @__PURE__ */ g(S, {
204
+ children: /* @__PURE__ */ _(C, {
204
205
  illustration: "onboarding",
205
- title: w("tourPreview.readyTitle"),
206
- description: w("tourPreview.readyHint")
206
+ title: T("tourPreview.readyTitle"),
207
+ description: T("tourPreview.readyHint")
207
208
  })
208
209
  })
209
210
  })
210
211
  }),
211
- N && /* @__PURE__ */ _("div", {
212
+ P && /* @__PURE__ */ v("div", {
212
213
  className: "border-t border-border-subtle bg-bg-surface p-3 sm:p-4 flex items-center justify-center gap-3 sm:gap-4",
213
214
  children: [
214
- /* @__PURE__ */ _("button", {
215
+ /* @__PURE__ */ v("button", {
215
216
  type: "button",
216
- onClick: U,
217
- disabled: !R,
217
+ onClick: W,
218
+ disabled: !z,
218
219
  className: "px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2",
219
- children: [/* @__PURE__ */ g(u, { size: 20 }), w("tourPreview.previous")]
220
+ children: [/* @__PURE__ */ _(d, { size: 20 }), T("tourPreview.previous")]
220
221
  }),
221
- /* @__PURE__ */ _("div", {
222
+ /* @__PURE__ */ v("div", {
222
223
  className: "text-sm text-text-secondary",
223
224
  children: [
224
- P + 1,
225
+ F + 1,
225
226
  " / ",
226
- I
227
+ L
227
228
  ]
228
229
  }),
229
- /* @__PURE__ */ _("button", {
230
+ /* @__PURE__ */ v("button", {
230
231
  type: "button",
231
- onClick: H,
232
- disabled: !L,
232
+ onClick: U,
233
+ disabled: !R,
233
234
  className: "px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2",
234
- children: [w("tourPreview.nextFooter"), /* @__PURE__ */ g(d, { size: 20 })]
235
+ children: [T("tourPreview.nextFooter"), /* @__PURE__ */ _(f, { size: 20 })]
235
236
  })
236
237
  ]
237
238
  })
@@ -239,6 +240,6 @@ function w() {
239
240
  });
240
241
  }
241
242
  //#endregion
242
- export { w as TourPreviewPage };
243
+ export { T as TourPreviewPage };
243
244
 
244
245
  //# sourceMappingURL=TourPreviewPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TourPreviewPage.js","names":[],"sources":["../../../src/tours/pages/TourPreviewPage.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n ArrowLeft,\n ChevronLeft,\n ChevronRight,\n X,\n Smartphone,\n Tablet,\n Monitor,\n AlertCircle,\n} from 'lucide-react';\nimport { Button, GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useTourPreview } from '../hooks/useTourPreview';\nimport { useTourBuilder } from '../hooks/useTourBuilder';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useToursStore } from '../store/toursStore';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport { useToursI18n } from '../i18n';\n\n/**\n * Tour preview page\n * Preview tour with device simulation and validation\n */\nexport function TourPreviewPage() {\n const { tr } = useToursI18n();\n const { tourId } = useParams();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const { hasPermission } = useToursPermissionAccess();\n const canReadTour = hasPermission(TOUR_PERMISSIONS.TOUR_READ);\n const { tour, loadTour } = useTourBuilder(tourId);\n const { devicePreview } = useToursStore();\n\n const {\n isPreviewActive,\n currentStepIndex,\n currentStep,\n totalSteps,\n canGoNext,\n canGoPrevious,\n validationResults,\n startPreview,\n stopPreview,\n nextStep,\n previousStep,\n changeDevice,\n validateForPreview,\n } = useTourPreview(tour || undefined);\n\n useEffect(() => {\n if (tourId) {\n loadTour(tourId);\n }\n }, [tourId, loadTour]);\n\n useEffect(() => {\n if (tour) {\n validateForPreview();\n }\n }, [tour, devicePreview, validateForPreview]);\n\n if (!canReadTour) {\n return (\n <div className=\"flex items-center justify-center h-screen bg-bg-sunken\">\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('tourPreview.accessDeniedTitle')}\n </h2>\n <p className=\"text-sm text-text-secondary\">{tr('tourPreview.accessDeniedMessage')}</p>\n </div>\n </div>\n );\n }\n\n if (!tour) {\n return (\n <div className=\"flex items-center justify-center h-screen bg-bg-sunken\">\n <p className=\"text-text-secondary\">{tr('tourPreview.loading')}</p>\n </div>\n );\n }\n\n const handleBack = () => {\n navigate(`${basePath}/${tourId}/edit`);\n };\n\n const deviceIcons = {\n mobile: <Smartphone size={20} />,\n tablet: <Tablet size={20} />,\n desktop: <Monitor size={20} />,\n };\n\n return (\n <div className=\"flex flex-col h-screen bg-bg-sunken\">\n {/* Header */}\n <div className=\"border-b border-border-subtle bg-bg-surface p-3 sm:p-4 flex flex-wrap items-center gap-3 sm:gap-4\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"p-2 min-h-[44px] min-w-[44px] hover:bg-accent rounded-md\"\n aria-label={tr('tourBuilder.goBack')}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex-1 min-w-[12rem]\">\n <h1 className=\"text-base sm:text-lg font-semibold truncate\">\n {tour?.name} - {tr('tourPreview.previewSuffix')}\n </h1>\n {isPreviewActive && (\n <p className=\"text-sm text-text-secondary\">\n {tr('tourPreview.stepOf')} {currentStepIndex + 1} {tr('tourPreview.stepOfConnector')}{' '}\n {totalSteps}\n </p>\n )}\n </div>\n\n {/* Device Selector */}\n <div className=\"flex gap-2 border border-border-subtle rounded-md overflow-hidden\">\n {(['mobile', 'tablet', 'desktop'] as const).map((device) => (\n <button\n type=\"button\"\n key={device}\n onClick={() => changeDevice(device)}\n className={`px-3 py-2 min-h-[44px] min-w-[44px] ${\n devicePreview === device\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface hover:bg-accent'\n }`}\n title={\n device === 'mobile'\n ? tr('tourPreview.deviceMobile')\n : device === 'tablet'\n ? tr('tourPreview.deviceTablet')\n : tr('tourPreview.deviceDesktop')\n }\n aria-label={\n device === 'mobile'\n ? tr('tourPreview.deviceMobile')\n : device === 'tablet'\n ? tr('tourPreview.deviceTablet')\n : tr('tourPreview.deviceDesktop')\n }\n >\n {deviceIcons[device]}\n </button>\n ))}\n </div>\n\n {/* Preview Controls */}\n {!isPreviewActive ? (\n <Button\n type=\"button\"\n onClick={startPreview}\n disabled={!validationResults?.valid}\n className=\"min-h-[44px]\"\n >\n {tr('tourPreview.startPreview')}\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={stopPreview}\n className=\"min-h-[44px]\"\n >\n <X size={20} />\n {tr('tourPreview.stopPreview')}\n </Button>\n )}\n </div>\n\n <div className=\"px-3 sm:px-6 pt-3\">\n <PagePurpose>{tr('tourPreview.purpose')}</PagePurpose>\n </div>\n\n {/* Validation Results */}\n {validationResults && !validationResults.valid && (\n <div className=\"bg-status-error-bg/10 border-b border-status-error-border px-3 sm:px-6 py-3\">\n <div className=\"flex items-start gap-3\">\n <AlertCircle className=\"text-status-error-text flex-shrink-0 mt-0.5\" size={20} />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-status-error-text mb-1\">\n {tr('tourPreview.validationErrorsTitle')}\n </h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationResults.errors.map((error) => (\n <li key={error} className=\"text-sm text-status-error-text\">\n {error}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n )}\n\n {/* Warnings */}\n {validationResults && validationResults.warnings.length > 0 && (\n <div className=\"bg-warning/10 border-b border-warning px-3 sm:px-6 py-3\">\n <div className=\"flex items-start gap-3\">\n <AlertCircle className=\"text-warning flex-shrink-0 mt-0.5\" size={20} />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-warning mb-1\">{tr('tourPreview.warningsTitle')}</h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationResults.warnings.map((warning) => (\n <li key={warning} className=\"text-sm text-warning\">\n {warning}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n )}\n\n {/* Preview Area */}\n <div className=\"flex-1 flex items-center justify-center p-3 sm:p-6 overflow-auto\">\n <div\n className={`bg-bg-surface border-2 rounded-lg shadow-xl overflow-hidden ${\n devicePreview === 'mobile'\n ? 'w-[min(375px,calc(100vw-1.5rem))] h-[667px] max-h-full'\n : devicePreview === 'tablet'\n ? 'w-[min(768px,calc(100vw-1.5rem))] h-[1024px] max-h-full'\n : 'w-full max-w-[1920px] h-full max-h-[1080px]'\n }`}\n >\n {isPreviewActive && currentStep ? (\n <div className=\"h-full flex flex-col items-center justify-center p-4 sm:p-8\">\n {/* Simulated Tour Tooltip */}\n <GlassCard\n treatment=\"glass\"\n className=\"max-w-md border-border-seam p-4 sm:p-6 shadow-[var(--shadow-pop)]\"\n >\n <h3 className=\"text-lg font-semibold mb-3\">{currentStep.title}</h3>\n <p className=\"text-sm text-text-secondary mb-4 whitespace-pre-wrap\">\n {currentStep.content}\n </p>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={previousStep}\n disabled={!canGoPrevious}\n className=\"px-3 py-2 min-h-[44px] min-w-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed\"\n aria-label={tr('tourPreview.previous')}\n >\n <ChevronLeft size={16} />\n </button>\n <button\n type=\"button\"\n onClick={nextStep}\n disabled={!canGoNext}\n className=\"flex-1 px-3 py-2 min-h-[44px] bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {canGoNext ? tr('tourPreview.next') : tr('tourPreview.finish')}\n </button>\n </div>\n </GlassCard>\n </div>\n ) : (\n <div className=\"h-full flex items-center justify-center p-4\">\n <IllustratedEmptyState\n illustration=\"onboarding\"\n title={tr('tourPreview.readyTitle')}\n description={tr('tourPreview.readyHint')}\n />\n </div>\n )}\n </div>\n </div>\n\n {/* Footer Controls */}\n {isPreviewActive && (\n <div className=\"border-t border-border-subtle bg-bg-surface p-3 sm:p-4 flex items-center justify-center gap-3 sm:gap-4\">\n <button\n type=\"button\"\n onClick={previousStep}\n disabled={!canGoPrevious}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n <ChevronLeft size={20} />\n {tr('tourPreview.previous')}\n </button>\n <div className=\"text-sm text-text-secondary\">\n {currentStepIndex + 1} / {totalSteps}\n </div>\n <button\n type=\"button\"\n onClick={nextStep}\n disabled={!canGoNext}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n {tr('tourPreview.nextFooter')}\n <ChevronRight size={20} />\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TourPreviewPage.js","names":[],"sources":["../../../src/tours/pages/TourPreviewPage.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n ArrowLeft,\n ChevronLeft,\n ChevronRight,\n X,\n Smartphone,\n Tablet,\n Monitor,\n AlertCircle,\n} from 'lucide-react';\nimport { Markdown } from '@burdenoff/fe-libs/shared/components';\nimport { Button, GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useTourPreview } from '../hooks/useTourPreview';\nimport { useTourBuilder } from '../hooks/useTourBuilder';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useToursStore } from '../store/toursStore';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport { useToursI18n } from '../i18n';\n\n/**\n * Tour preview page\n * Preview tour with device simulation and validation\n */\nexport function TourPreviewPage() {\n const { tr } = useToursI18n();\n const { tourId } = useParams();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const { hasPermission } = useToursPermissionAccess();\n const canReadTour = hasPermission(TOUR_PERMISSIONS.TOUR_READ);\n const { tour, loadTour } = useTourBuilder(tourId);\n const { devicePreview } = useToursStore();\n\n const {\n isPreviewActive,\n currentStepIndex,\n currentStep,\n totalSteps,\n canGoNext,\n canGoPrevious,\n validationResults,\n startPreview,\n stopPreview,\n nextStep,\n previousStep,\n changeDevice,\n validateForPreview,\n } = useTourPreview(tour || undefined);\n\n useEffect(() => {\n if (tourId) {\n loadTour(tourId);\n }\n }, [tourId, loadTour]);\n\n useEffect(() => {\n if (tour) {\n validateForPreview();\n }\n }, [tour, devicePreview, validateForPreview]);\n\n if (!canReadTour) {\n return (\n <div className=\"flex items-center justify-center h-screen bg-bg-sunken\">\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('tourPreview.accessDeniedTitle')}\n </h2>\n <p className=\"text-sm text-text-secondary\">{tr('tourPreview.accessDeniedMessage')}</p>\n </div>\n </div>\n );\n }\n\n if (!tour) {\n return (\n <div className=\"flex items-center justify-center h-screen bg-bg-sunken\">\n <p className=\"text-text-secondary\">{tr('tourPreview.loading')}</p>\n </div>\n );\n }\n\n const handleBack = () => {\n navigate(`${basePath}/${tourId}/edit`);\n };\n\n const deviceIcons = {\n mobile: <Smartphone size={20} />,\n tablet: <Tablet size={20} />,\n desktop: <Monitor size={20} />,\n };\n\n return (\n <div className=\"flex flex-col h-screen bg-bg-sunken\">\n {/* Header */}\n <div className=\"border-b border-border-subtle bg-bg-surface p-3 sm:p-4 flex flex-wrap items-center gap-3 sm:gap-4\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"p-2 min-h-[44px] min-w-[44px] hover:bg-accent rounded-md\"\n aria-label={tr('tourBuilder.goBack')}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex-1 min-w-[12rem]\">\n <h1 className=\"text-base sm:text-lg font-semibold truncate\">\n {tour?.name} - {tr('tourPreview.previewSuffix')}\n </h1>\n {isPreviewActive && (\n <p className=\"text-sm text-text-secondary\">\n {tr('tourPreview.stepOf')} {currentStepIndex + 1} {tr('tourPreview.stepOfConnector')}{' '}\n {totalSteps}\n </p>\n )}\n </div>\n\n {/* Device Selector */}\n <div className=\"flex gap-2 border border-border-subtle rounded-md overflow-hidden\">\n {(['mobile', 'tablet', 'desktop'] as const).map((device) => (\n <button\n type=\"button\"\n key={device}\n onClick={() => changeDevice(device)}\n className={`px-3 py-2 min-h-[44px] min-w-[44px] ${\n devicePreview === device\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface hover:bg-accent'\n }`}\n title={\n device === 'mobile'\n ? tr('tourPreview.deviceMobile')\n : device === 'tablet'\n ? tr('tourPreview.deviceTablet')\n : tr('tourPreview.deviceDesktop')\n }\n aria-label={\n device === 'mobile'\n ? tr('tourPreview.deviceMobile')\n : device === 'tablet'\n ? tr('tourPreview.deviceTablet')\n : tr('tourPreview.deviceDesktop')\n }\n >\n {deviceIcons[device]}\n </button>\n ))}\n </div>\n\n {/* Preview Controls */}\n {!isPreviewActive ? (\n <Button\n type=\"button\"\n onClick={startPreview}\n disabled={!validationResults?.valid}\n className=\"min-h-[44px]\"\n >\n {tr('tourPreview.startPreview')}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"outline\" onClick={stopPreview} className=\"min-h-[44px]\">\n <X size={20} />\n {tr('tourPreview.stopPreview')}\n </Button>\n )}\n </div>\n\n <div className=\"px-3 sm:px-6 pt-3\">\n <PagePurpose>{tr('tourPreview.purpose')}</PagePurpose>\n </div>\n\n {/* Validation Results */}\n {validationResults && !validationResults.valid && (\n <div className=\"bg-status-error-bg/10 border-b border-status-error-border px-3 sm:px-6 py-3\">\n <div className=\"flex items-start gap-3\">\n <AlertCircle className=\"text-status-error-text flex-shrink-0 mt-0.5\" size={20} />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-status-error-text mb-1\">\n {tr('tourPreview.validationErrorsTitle')}\n </h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationResults.errors.map((error) => (\n <li key={error} className=\"text-sm text-status-error-text\">\n {error}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n )}\n\n {/* Warnings */}\n {validationResults && validationResults.warnings.length > 0 && (\n <div className=\"bg-warning/10 border-b border-warning px-3 sm:px-6 py-3\">\n <div className=\"flex items-start gap-3\">\n <AlertCircle className=\"text-warning flex-shrink-0 mt-0.5\" size={20} />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-warning mb-1\">{tr('tourPreview.warningsTitle')}</h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {validationResults.warnings.map((warning) => (\n <li key={warning} className=\"text-sm text-warning\">\n {warning}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n )}\n\n {/* Preview Area */}\n <div className=\"flex-1 flex items-center justify-center p-3 sm:p-6 overflow-auto\">\n <div\n className={`bg-bg-surface border-2 rounded-lg shadow-xl overflow-hidden ${\n devicePreview === 'mobile'\n ? 'w-[min(375px,calc(100vw-1.5rem))] h-[667px] max-h-full'\n : devicePreview === 'tablet'\n ? 'w-[min(768px,calc(100vw-1.5rem))] h-[1024px] max-h-full'\n : 'w-full max-w-[1920px] h-full max-h-[1080px]'\n }`}\n >\n {isPreviewActive && currentStep ? (\n <div className=\"h-full flex flex-col items-center justify-center p-4 sm:p-8\">\n {/* Simulated Tour Tooltip */}\n <GlassCard\n treatment=\"glass\"\n className=\"max-w-md border-border-seam p-4 sm:p-6 shadow-[var(--shadow-pop)]\"\n >\n <h3 className=\"text-lg font-semibold mb-3\">{currentStep.title}</h3>\n <div className=\"text-sm text-text-secondary mb-4 prose prose-sm max-w-none\">\n <Markdown>{currentStep.content}</Markdown>\n </div>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={previousStep}\n disabled={!canGoPrevious}\n className=\"px-3 py-2 min-h-[44px] min-w-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed\"\n aria-label={tr('tourPreview.previous')}\n >\n <ChevronLeft size={16} />\n </button>\n <button\n type=\"button\"\n onClick={nextStep}\n disabled={!canGoNext}\n className=\"flex-1 px-3 py-2 min-h-[44px] bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {canGoNext ? tr('tourPreview.next') : tr('tourPreview.finish')}\n </button>\n </div>\n </GlassCard>\n </div>\n ) : (\n <div className=\"h-full flex items-center justify-center p-4\">\n <IllustratedEmptyState\n illustration=\"onboarding\"\n title={tr('tourPreview.readyTitle')}\n description={tr('tourPreview.readyHint')}\n />\n </div>\n )}\n </div>\n </div>\n\n {/* Footer Controls */}\n {isPreviewActive && (\n <div className=\"border-t border-border-subtle bg-bg-surface p-3 sm:p-4 flex items-center justify-center gap-3 sm:gap-4\">\n <button\n type=\"button\"\n onClick={previousStep}\n disabled={!canGoPrevious}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n <ChevronLeft size={20} />\n {tr('tourPreview.previous')}\n </button>\n <div className=\"text-sm text-text-secondary\">\n {currentStepIndex + 1} / {totalSteps}\n </div>\n <button\n type=\"button\"\n onClick={nextStep}\n disabled={!canGoNext}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n >\n {tr('tourPreview.nextFooter')}\n <ChevronRight size={20} />\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA0BA,SAAgB,IAAkB;CAChC,IAAM,EAAE,UAAO,GAAc,EACvB,EAAE,cAAW,GAAW,EACxB,IAAW,GAAa,EACxB,EAAE,cAAW,QAAQ,GAAiB,EACtC,EAAE,qBAAkB,GAA0B,EAC9C,IAAc,EAAc,EAAiB,UAAU,EACvD,EAAE,SAAM,gBAAa,EAAe,EAAO,EAC3C,EAAE,qBAAkB,GAAe,EAEnC,EACJ,oBACA,qBACA,gBACA,eACA,cACA,kBACA,sBACA,iBACA,gBACA,aACA,iBACA,iBACA,0BACE,EAAe,KAAQ,KAAA,EAAU;AAcrC,KAZA,QAAgB;AACd,EAAI,KACF,EAAS,EAAO;IAEjB,CAAC,GAAQ,EAAS,CAAC,EAEtB,QAAgB;AACd,EAAI,KACF,GAAoB;IAErB;EAAC;EAAM;EAAe;EAAmB,CAAC,EAEzC,CAAC,EACH,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAG,gCAAgC;IACjC,CAAA,EACL,kBAAC,KAAD;IAAG,WAAU;cAA+B,EAAG,kCAAkC;IAAK,CAAA,CAClF;;EACF,CAAA;AAIV,KAAI,CAAC,EACH,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,KAAD;GAAG,WAAU;aAAuB,EAAG,sBAAsB;GAAK,CAAA;EAC9D,CAAA;CAIV,IAAM,UAAmB;AACvB,IAAS,GAAG,EAAS,GAAG,EAAO,OAAO;IAGlC,IAAc;EAClB,QAAQ,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;EAChC,QAAQ,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;EAC5B,SAAS,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;EAC/B;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAY,EAAG,qBAAqB;gBAEpC,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;MAChB,CAAA;KACT,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACG,GAAM;QAAK;QAAI,EAAG,4BAA4B;QAC5C;UACJ,KACC,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAG,qBAAqB;QAAC;QAAE,IAAmB;QAAE;QAAE,EAAG,8BAA8B;QAAE;QACrF;QACC;SAEF;;KAGN,kBAAC,OAAD;MAAK,WAAU;gBACX;OAAC;OAAU;OAAU;OAAU,CAAW,KAAK,MAC/C,kBAAC,UAAD;OACE,MAAK;OAEL,eAAe,EAAa,EAAO;OACnC,WAAW,uCACT,MAAkB,IACd,kDACA;OAEN,OAEM,EADJ,MAAW,WACJ,6BACH,MAAW,WACN,6BACA,4BAA4B;OAEvC,cAEM,EADJ,MAAW,WACJ,6BACH,MAAW,WACN,6BACA,4BAA4B;iBAGtC,EAAY;OACN,EAvBF,EAuBE,CACT;MACE,CAAA;KAGJ,IAUA,kBAAC,GAAD;MAAQ,MAAK;MAAS,SAAQ;MAAU,SAAS;MAAa,WAAU;gBAAxE,CACE,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA,EACd,EAAG,0BAA0B,CACvB;UAZT,kBAAC,GAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU,CAAC,GAAmB;MAC9B,WAAU;gBAET,EAAG,2BAA2B;MACxB,CAAA;KAOP;;GAEN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAA,UAAc,EAAG,sBAAsB,EAAe,CAAA;IAClD,CAAA;GAGL,KAAqB,CAAC,EAAkB,SACvC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAa,WAAU;MAA8C,MAAM;MAAM,CAAA,EACjF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,oCAAoC;OACrC,CAAA,EACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAkB,OAAO,KAAK,MAC7B,kBAAC,MAAD;QAAgB,WAAU;kBACvB;QACE,EAFI,EAEJ,CACL;OACC,CAAA,CACD;QACF;;IACF,CAAA;GAIP,KAAqB,EAAkB,SAAS,SAAS,KACxD,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAa,WAAU;MAAoC,MAAM;MAAM,CAAA,EACvE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAmC,EAAG,4BAA4B;OAAM,CAAA,EACtF,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAkB,SAAS,KAAK,MAC/B,kBAAC,MAAD;QAAkB,WAAU;kBACzB;QACE,EAFI,EAEJ,CACL;OACC,CAAA,CACD;QACF;;IACF,CAAA;GAIR,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KACE,WAAW,+DACT,MAAkB,WACd,2DACA,MAAkB,WAChB,4DACA;eAGP,KAAmB,IAClB,kBAAC,OAAD;MAAK,WAAU;gBAEb,kBAAC,GAAD;OACE,WAAU;OACV,WAAU;iBAFZ;QAIE,kBAAC,MAAD;SAAI,WAAU;mBAA8B,EAAY;SAAW,CAAA;QACnE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAA,UAAW,EAAY,SAAmB,CAAA;SACtC,CAAA;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,UAAU,CAAC;UACX,WAAU;UACV,cAAY,EAAG,uBAAuB;oBAEtC,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA;UAClB,CAAA,EACT,kBAAC,UAAD;UACE,MAAK;UACL,SAAS;UACT,UAAU,CAAC;UACX,WAAU;oBAEG,EAAZ,IAAe,qBAAyB,qBAAqB;UACvD,CAAA,CACL;;QACI;;MACR,CAAA,GAEN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD;OACE,cAAa;OACb,OAAO,EAAG,yBAAyB;OACnC,aAAa,EAAG,wBAAwB;OACxC,CAAA;MACE,CAAA;KAEJ,CAAA;IACF,CAAA;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU,CAAC;MACX,WAAU;gBAJZ,CAME,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA,EACxB,EAAG,uBAAuB,CACpB;;KACT,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,IAAmB;OAAE;OAAI;OACtB;;KACN,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU,CAAC;MACX,WAAU;gBAJZ,CAMG,EAAG,yBAAyB,EAC7B,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA,CACnB;;KACL;;GAEJ"}