@rovela-ai/sdk 0.3.10 → 0.3.11
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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function AdminBarBanner(): import("react
|
|
1
|
+
export declare function AdminBarBanner(): import("react").ReactPortal | null;
|
|
2
2
|
//# sourceMappingURL=AdminBarBanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminBarBanner.d.ts","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AdminBarBanner.d.ts","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"AAwDA,wBAAgB,cAAc,uCA+F7B"}
|
|
@@ -3,154 +3,220 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* @rovela/sdk/admin/components/AdminBarBanner
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* signed-in admin browses the public store. Customers and
|
|
8
|
-
* visitors never see it.
|
|
6
|
+
* Linear/Vercel-style admin session bar that sits above the storefront
|
|
7
|
+
* whenever a signed-in admin browses the public store. Customers and
|
|
8
|
+
* anonymous visitors never see it.
|
|
9
9
|
*
|
|
10
10
|
* Design rules:
|
|
11
11
|
*
|
|
12
|
-
* 1. Self-gating
|
|
13
|
-
* the session is loading, when there is no admin role
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* 1. Self-gating. The component takes no props and renders `null` when
|
|
13
|
+
* the session is loading, when there is no admin role, or when the
|
|
14
|
+
* user is on an `/admin/*` route. Safe to mount unconditionally at
|
|
15
|
+
* the root of a customer layout.
|
|
16
16
|
*
|
|
17
|
-
* 2.
|
|
18
|
-
*
|
|
19
|
-
* `admin-*` classes. Claude Code aggressively rewrites the storefront
|
|
20
|
-
* theme; inline styles survive every theme edit. This is intentional
|
|
21
|
-
* — the admin bar is "platform chrome" and should look identical
|
|
22
|
-
* across every merchant's store.
|
|
17
|
+
* 2. Portal-rendered to <html> (outside <body>). This anchors the bar
|
|
18
|
+
* to the viewport regardless of any body-level transform below it.
|
|
23
19
|
*
|
|
24
|
-
* 3.
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* 3. Offset the storefront without editing it. On mount we apply
|
|
21
|
+
* `margin-top: 40px` + `transform: translateZ(0)` to <body>. The
|
|
22
|
+
* transform reparents the containing block of every `position: fixed`
|
|
23
|
+
* descendant from the viewport to <body>, so sticky/fixed store
|
|
24
|
+
* headers sit *below* our bar instead of overlapping it. The banner
|
|
25
|
+
* itself lives outside <body> (in the portal root appended to
|
|
26
|
+
* <html>), so the same transform does not affect it — it stays
|
|
27
|
+
* pinned to the real viewport at `top: 0`.
|
|
28
|
+
*
|
|
29
|
+
* 4. Theme-proof styling. Inline styles + one scoped `<style>` element
|
|
30
|
+
* for pseudo-states and media queries. Storefront Tailwind/CSS edits
|
|
31
|
+
* cannot regress this.
|
|
32
|
+
*
|
|
33
|
+
* 5. Navigation-only. The bar never authorizes — clicking "Dashboard"
|
|
34
|
+
* sends a normal navigation to `/admin`, which is gated server-side
|
|
35
|
+
* by `requireAdmin()`. A deactivated admin whose JWT is still valid
|
|
36
|
+
* will land on `/admin/login`; this bar is never the gate.
|
|
28
37
|
*/
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
38
|
+
import { useEffect, useState } from 'react';
|
|
39
|
+
import { createPortal } from 'react-dom';
|
|
40
|
+
import { usePathname } from 'next/navigation';
|
|
31
41
|
import { useAdminAuth } from '../hooks/useAdminAuth';
|
|
32
42
|
import { roleLabel } from '../permissions';
|
|
33
43
|
// =============================================================================
|
|
34
|
-
//
|
|
44
|
+
// Constants
|
|
35
45
|
// =============================================================================
|
|
36
|
-
//
|
|
37
|
-
// Inline style objects keep the bar immune to storefront CSS resets, global
|
|
38
|
-
// Tailwind classes, and aggressive theme rewrites. Values match Shopify's
|
|
39
|
-
// merchant bar roughly: high-contrast dark background, 40px tall, left/right
|
|
40
|
-
// padding that respects safe areas on mobile.
|
|
41
46
|
const BAR_HEIGHT_PX = 40;
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
const PORTAL_ROOT_ID = 'rovela-admin-bar-root';
|
|
48
|
+
const STYLE_TAG_ID = 'rovela-admin-bar-style';
|
|
49
|
+
// =============================================================================
|
|
50
|
+
// Component
|
|
51
|
+
// =============================================================================
|
|
52
|
+
export function AdminBarBanner() {
|
|
53
|
+
const pathname = usePathname();
|
|
54
|
+
const { admin, isAuthenticated, isLoading } = useAdminAuth();
|
|
55
|
+
const [portalRoot, setPortalRoot] = useState(null);
|
|
56
|
+
// Visibility gate. Any change here triggers mount/unmount side-effects
|
|
57
|
+
// via the `useEffect` below.
|
|
58
|
+
const visible = !isLoading &&
|
|
59
|
+
isAuthenticated &&
|
|
60
|
+
Boolean(admin?.role) &&
|
|
61
|
+
!pathname?.startsWith('/admin');
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (typeof document === 'undefined')
|
|
64
|
+
return;
|
|
65
|
+
if (!visible)
|
|
66
|
+
return;
|
|
67
|
+
// --- 1. Portal root (child of <html>, sibling of <body>) ---
|
|
68
|
+
let root = document.getElementById(PORTAL_ROOT_ID);
|
|
69
|
+
let ownsRoot = false;
|
|
70
|
+
if (!root) {
|
|
71
|
+
root = document.createElement('div');
|
|
72
|
+
root.id = PORTAL_ROOT_ID;
|
|
73
|
+
document.documentElement.appendChild(root);
|
|
74
|
+
ownsRoot = true;
|
|
75
|
+
}
|
|
76
|
+
setPortalRoot(root);
|
|
77
|
+
// --- 2. Global stylesheet for pseudo-states + responsive behavior ---
|
|
78
|
+
let styleEl = document.getElementById(STYLE_TAG_ID);
|
|
79
|
+
let ownsStyle = false;
|
|
80
|
+
if (!styleEl) {
|
|
81
|
+
styleEl = document.createElement('style');
|
|
82
|
+
styleEl.id = STYLE_TAG_ID;
|
|
83
|
+
styleEl.textContent = GLOBAL_CSS;
|
|
84
|
+
document.head.appendChild(styleEl);
|
|
85
|
+
ownsStyle = true;
|
|
86
|
+
}
|
|
87
|
+
// --- 3. Push the storefront down + reparent fixed descendants ---
|
|
88
|
+
// Remember previous inline values so we restore precisely on unmount.
|
|
89
|
+
const prevBodyMarginTop = document.body.style.marginTop;
|
|
90
|
+
const prevBodyTransform = document.body.style.transform;
|
|
91
|
+
document.body.style.marginTop = `${BAR_HEIGHT_PX}px`;
|
|
92
|
+
// `translateZ(0)` creates a new containing block for any descendant
|
|
93
|
+
// with `position: fixed`. Combined with the body margin above, this
|
|
94
|
+
// shifts sticky/fixed store chrome out from under our bar.
|
|
95
|
+
document.body.style.transform = 'translateZ(0)';
|
|
96
|
+
return () => {
|
|
97
|
+
document.body.style.marginTop = prevBodyMarginTop;
|
|
98
|
+
document.body.style.transform = prevBodyTransform;
|
|
99
|
+
if (ownsStyle && styleEl?.parentNode) {
|
|
100
|
+
styleEl.parentNode.removeChild(styleEl);
|
|
101
|
+
}
|
|
102
|
+
if (ownsRoot && root?.parentNode) {
|
|
103
|
+
root.parentNode.removeChild(root);
|
|
104
|
+
}
|
|
105
|
+
setPortalRoot(null);
|
|
106
|
+
};
|
|
107
|
+
}, [visible]);
|
|
108
|
+
if (!visible || !portalRoot || !admin)
|
|
109
|
+
return null;
|
|
110
|
+
const role = roleLabel(admin.role).toLowerCase();
|
|
111
|
+
return createPortal(_jsx("div", { "data-rovela-admin-bar": "", style: wrapStyle, children: _jsxs("div", { style: innerStyle, children: [_jsxs("div", { style: leftGroupStyle, children: [_jsx("span", { "aria-hidden": "true", style: dotStyle }), _jsx("span", { style: labelStyle, children: "Admin session" }), _jsx("span", { "aria-hidden": "true", "data-rovela-desktop-only": "", style: dividerStyle, children: "\u00B7" }), _jsx("span", { "data-rovela-desktop-only": "", style: roleStyle, children: role })] }), _jsxs("a", { href: "/admin", "data-rovela-action": "", "aria-label": "Open admin dashboard", style: buttonStyle, children: [_jsx("span", { "data-rovela-desktop-only": "", children: "Dashboard" }), _jsx("span", { "aria-hidden": "true", style: arrowStyle, children: "\u2197" })] })] }) }), portalRoot);
|
|
112
|
+
}
|
|
113
|
+
// =============================================================================
|
|
114
|
+
// Styles
|
|
115
|
+
// =============================================================================
|
|
116
|
+
const wrapStyle = {
|
|
117
|
+
position: 'fixed',
|
|
118
|
+
top: 0,
|
|
119
|
+
left: 0,
|
|
120
|
+
right: 0,
|
|
121
|
+
height: `${BAR_HEIGHT_PX}px`,
|
|
122
|
+
// Max 32-bit signed int — safely above any storefront z-index stacking
|
|
123
|
+
// context (Intercom widgets cap at ~2147483000; we still sit above).
|
|
124
|
+
zIndex: 2147483647,
|
|
125
|
+
background: 'rgba(10, 10, 12, 0.85)',
|
|
126
|
+
backdropFilter: 'blur(12px) saturate(140%)',
|
|
127
|
+
WebkitBackdropFilter: 'blur(12px) saturate(140%)',
|
|
128
|
+
borderBottom: '1px solid rgba(255, 255, 255, 0.06)',
|
|
53
129
|
color: '#FFFFFF',
|
|
54
130
|
fontFamily: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
55
131
|
fontSize: '13px',
|
|
56
132
|
lineHeight: 1.3,
|
|
57
|
-
|
|
133
|
+
letterSpacing: '-0.005em',
|
|
58
134
|
boxSizing: 'border-box',
|
|
59
135
|
};
|
|
60
|
-
const
|
|
136
|
+
const innerStyle = {
|
|
137
|
+
maxWidth: '1280px',
|
|
138
|
+
height: '100%',
|
|
139
|
+
margin: '0 auto',
|
|
140
|
+
padding: '0 16px',
|
|
141
|
+
display: 'flex',
|
|
142
|
+
alignItems: 'center',
|
|
143
|
+
justifyContent: 'space-between',
|
|
144
|
+
gap: '12px',
|
|
145
|
+
boxSizing: 'border-box',
|
|
146
|
+
};
|
|
147
|
+
const leftGroupStyle = {
|
|
61
148
|
display: 'inline-flex',
|
|
62
149
|
alignItems: 'center',
|
|
63
150
|
gap: '8px',
|
|
64
151
|
minWidth: 0,
|
|
65
152
|
overflow: 'hidden',
|
|
66
|
-
textOverflow: 'ellipsis',
|
|
67
|
-
whiteSpace: 'nowrap',
|
|
68
153
|
};
|
|
69
154
|
const dotStyle = {
|
|
70
155
|
width: '6px',
|
|
71
156
|
height: '6px',
|
|
72
157
|
borderRadius: '9999px',
|
|
73
158
|
background: '#22C55E',
|
|
159
|
+
boxShadow: '0 0 0 0 rgba(34, 197, 94, 0.6)',
|
|
160
|
+
animation: 'rab-pulse 2.4s infinite',
|
|
74
161
|
flexShrink: 0,
|
|
75
162
|
};
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
alignItems: 'center',
|
|
79
|
-
gap: '8px',
|
|
80
|
-
flexShrink: 0,
|
|
81
|
-
};
|
|
82
|
-
const linkStyle = {
|
|
83
|
-
display: 'inline-flex',
|
|
84
|
-
alignItems: 'center',
|
|
85
|
-
gap: '6px',
|
|
86
|
-
height: '28px',
|
|
87
|
-
padding: '0 10px',
|
|
88
|
-
borderRadius: '6px',
|
|
89
|
-
fontSize: '12px',
|
|
163
|
+
const labelStyle = {
|
|
164
|
+
color: 'rgba(255, 255, 255, 0.92)',
|
|
90
165
|
fontWeight: 500,
|
|
91
|
-
color: '#0B0B0F',
|
|
92
|
-
background: '#FFFFFF',
|
|
93
|
-
textDecoration: 'none',
|
|
94
|
-
border: '1px solid #FFFFFF',
|
|
95
|
-
cursor: 'pointer',
|
|
96
166
|
whiteSpace: 'nowrap',
|
|
97
167
|
};
|
|
98
|
-
const
|
|
168
|
+
const dividerStyle = {
|
|
169
|
+
color: 'rgba(255, 255, 255, 0.3)',
|
|
170
|
+
};
|
|
171
|
+
const roleStyle = {
|
|
172
|
+
color: 'rgba(255, 255, 255, 0.55)',
|
|
173
|
+
whiteSpace: 'nowrap',
|
|
174
|
+
};
|
|
175
|
+
const buttonStyle = {
|
|
99
176
|
display: 'inline-flex',
|
|
100
177
|
alignItems: 'center',
|
|
101
178
|
gap: '6px',
|
|
102
179
|
height: '28px',
|
|
103
|
-
padding: '0
|
|
180
|
+
padding: '0 12px',
|
|
104
181
|
borderRadius: '6px',
|
|
105
|
-
fontSize: '
|
|
182
|
+
fontSize: '12.5px',
|
|
106
183
|
fontWeight: 500,
|
|
107
184
|
color: '#FFFFFF',
|
|
108
|
-
background: '
|
|
109
|
-
border: '1px solid rgba(255, 255, 255, 0.
|
|
185
|
+
background: 'rgba(255, 255, 255, 0.1)',
|
|
186
|
+
border: '1px solid rgba(255, 255, 255, 0.12)',
|
|
187
|
+
textDecoration: 'none',
|
|
110
188
|
cursor: 'pointer',
|
|
111
189
|
whiteSpace: 'nowrap',
|
|
112
|
-
fontFamily: 'inherit',
|
|
113
|
-
};
|
|
114
|
-
const roleBadgeStyle = {
|
|
115
|
-
display: 'inline-flex',
|
|
116
|
-
alignItems: 'center',
|
|
117
|
-
padding: '2px 8px',
|
|
118
|
-
borderRadius: '9999px',
|
|
119
|
-
background: 'rgba(255, 255, 255, 0.1)',
|
|
120
|
-
fontSize: '11px',
|
|
121
|
-
fontWeight: 600,
|
|
122
|
-
letterSpacing: '0.02em',
|
|
123
|
-
textTransform: 'uppercase',
|
|
124
190
|
flexShrink: 0,
|
|
191
|
+
transition: 'background 120ms ease, border-color 120ms ease',
|
|
125
192
|
};
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
193
|
+
const arrowStyle = {
|
|
194
|
+
display: 'inline-block',
|
|
195
|
+
transform: 'translateY(-0.5px)',
|
|
196
|
+
fontSize: '13px',
|
|
197
|
+
opacity: 0.9,
|
|
131
198
|
};
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const displayName = admin.name?.trim() || admin.email || 'Admin';
|
|
154
|
-
return (_jsxs("div", { role: "region", "aria-label": "Admin session", "data-rovela-admin-bar": "", style: barStyle, children: [_jsxs("div", { style: labelStyle, children: [_jsx("span", { "aria-hidden": "true", style: dotStyle }), _jsx("span", { style: roleBadgeStyle, children: roleLabel(admin.role) }), _jsxs("span", { style: nameStyle, children: ["Signed in as ", displayName] })] }), _jsxs("div", { style: actionsStyle, children: [_jsx("a", { href: "/admin", style: linkStyle, "aria-label": "Open admin dashboard", children: "Admin dashboard" }), _jsx("button", { type: "button", onClick: handleSignOut, style: ghostButtonStyle, "aria-label": "Sign out of admin", children: "Sign out" })] })] }));
|
|
199
|
+
// Scoped to `[data-rovela-admin-bar]` so we can never leak into storefront
|
|
200
|
+
// styles. Injected once per mount, removed on unmount.
|
|
201
|
+
const GLOBAL_CSS = `
|
|
202
|
+
@keyframes rab-pulse {
|
|
203
|
+
0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.55); }
|
|
204
|
+
70% { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
|
|
205
|
+
100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
|
|
206
|
+
}
|
|
207
|
+
[data-rovela-admin-bar] a[data-rovela-action]:hover {
|
|
208
|
+
background: rgba(255, 255, 255, 0.18) !important;
|
|
209
|
+
border-color: rgba(255, 255, 255, 0.2) !important;
|
|
210
|
+
}
|
|
211
|
+
[data-rovela-admin-bar] a[data-rovela-action]:focus-visible {
|
|
212
|
+
outline: 2px solid rgba(255, 255, 255, 0.6);
|
|
213
|
+
outline-offset: 2px;
|
|
214
|
+
}
|
|
215
|
+
@media (max-width: 480px) {
|
|
216
|
+
[data-rovela-admin-bar] [data-rovela-desktop-only] { display: none !important; }
|
|
217
|
+
}
|
|
218
|
+
@media (prefers-reduced-motion: reduce) {
|
|
219
|
+
[data-rovela-admin-bar] [aria-hidden="true"] { animation: none !important; }
|
|
155
220
|
}
|
|
221
|
+
`;
|
|
156
222
|
//# sourceMappingURL=AdminBarBanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminBarBanner.js","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ
|
|
1
|
+
{"version":3,"file":"AdminBarBanner.js","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,aAAa,GAAG,EAAE,CAAA;AACxB,MAAM,cAAc,GAAG,uBAAuB,CAAA;AAC9C,MAAM,YAAY,GAAG,wBAAwB,CAAA;AAE7C,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAA;IAC5D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAA;IAEtE,uEAAuE;IACvE,6BAA6B;IAC7B,MAAM,OAAO,GACX,CAAC,SAAS;QACV,eAAe;QACf,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;QACpB,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAEjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,QAAQ,KAAK,WAAW;YAAE,OAAM;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,8DAA8D;QAC9D,IAAI,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;QAClD,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YACpC,IAAI,CAAC,EAAE,GAAG,cAAc,CAAA;YACxB,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAC1C,QAAQ,GAAG,IAAI,CAAA;QACjB,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,CAAA;QAEnB,uEAAuE;QACvE,IAAI,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,YAAY,CAA4B,CAAA;QAC9E,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YACzC,OAAO,CAAC,EAAE,GAAG,YAAY,CAAA;YACzB,OAAO,CAAC,WAAW,GAAG,UAAU,CAAA;YAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAClC,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;QAED,mEAAmE;QACnE,sEAAsE;QACtE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAA;QACvD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAA;QACvD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,aAAa,IAAI,CAAA;QACpD,oEAAoE;QACpE,oEAAoE;QACpE,2DAA2D;QAC3D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,eAAe,CAAA;QAE/C,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,iBAAiB,CAAA;YACjD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,iBAAiB,CAAA;YACjD,IAAI,SAAS,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;gBACrC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YACzC,CAAC;YACD,IAAI,QAAQ,IAAI,IAAI,EAAE,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YACnC,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAElD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IAEhD,OAAO,YAAY,CACjB,uCAA2B,EAAE,EAAC,KAAK,EAAE,SAAS,YAC5C,eAAK,KAAK,EAAE,UAAU,aACpB,eAAK,KAAK,EAAE,cAAc,aACxB,8BAAkB,MAAM,EAAC,KAAK,EAAE,QAAQ,GAAI,EAC5C,eAAM,KAAK,EAAE,UAAU,8BAAsB,EAC7C,8BAAkB,MAAM,8BAA0B,EAAE,EAAC,KAAK,EAAE,YAAY,uBAEjE,EACP,2CAA+B,EAAE,EAAC,KAAK,EAAE,SAAS,YAC/C,IAAI,GACA,IACH,EAEN,aACE,IAAI,EAAC,QAAQ,wBACM,EAAE,gBACV,sBAAsB,EACjC,KAAK,EAAE,WAAW,aAElB,2CAA+B,EAAE,0BAAiB,EAClD,8BAAkB,MAAM,EAAC,KAAK,EAAE,UAAU,uBAEnC,IACL,IACA,GACF,EACN,UAAU,CACX,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAEhF,MAAM,SAAS,GAAwB;IACrC,QAAQ,EAAE,OAAO;IACjB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,GAAG,aAAa,IAAI;IAC5B,uEAAuE;IACvE,qEAAqE;IACrE,MAAM,EAAE,UAAU;IAClB,UAAU,EAAE,wBAAwB;IACpC,cAAc,EAAE,2BAA2B;IAC3C,oBAAoB,EAAE,2BAA2B;IACjD,YAAY,EAAE,qCAAqC;IACnD,KAAK,EAAE,SAAS;IAChB,UAAU,EACR,kGAAkG;IACpG,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,GAAG;IACf,aAAa,EAAE,UAAU;IACzB,SAAS,EAAE,YAAY;CACxB,CAAA;AAED,MAAM,UAAU,GAAwB;IACtC,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,eAAe;IAC/B,GAAG,EAAE,MAAM;IACX,SAAS,EAAE,YAAY;CACxB,CAAA;AAED,MAAM,cAAc,GAAwB;IAC1C,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,QAAQ;IACpB,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,QAAQ;CACnB,CAAA;AAED,MAAM,QAAQ,GAAwB;IACpC,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,QAAQ;IACtB,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,gCAAgC;IAC3C,SAAS,EAAE,yBAAyB;IACpC,UAAU,EAAE,CAAC;CACd,CAAA;AAED,MAAM,UAAU,GAAwB;IACtC,KAAK,EAAE,2BAA2B;IAClC,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,QAAQ;CACrB,CAAA;AAED,MAAM,YAAY,GAAwB;IACxC,KAAK,EAAE,0BAA0B;CAClC,CAAA;AAED,MAAM,SAAS,GAAwB;IACrC,KAAK,EAAE,2BAA2B;IAClC,UAAU,EAAE,QAAQ;CACrB,CAAA;AAED,MAAM,WAAW,GAAwB;IACvC,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,QAAQ;IACpB,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,QAAQ;IACjB,YAAY,EAAE,KAAK;IACnB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,GAAG;IACf,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,0BAA0B;IACtC,MAAM,EAAE,qCAAqC;IAC7C,cAAc,EAAE,MAAM;IACtB,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,QAAQ;IACpB,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,gDAAgD;CAC7D,CAAA;AAED,MAAM,UAAU,GAAwB;IACtC,OAAO,EAAE,cAAc;IACvB,SAAS,EAAE,oBAAoB;IAC/B,QAAQ,EAAE,MAAM;IAChB,OAAO,EAAE,GAAG;CACb,CAAA;AAED,2EAA2E;AAC3E,uDAAuD;AACvD,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;CAoBlB,CAAA"}
|