@the-portland-company/shell 0.1.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1353 @@
1
+ 'use strict';
2
+
3
+ var react = require('@chakra-ui/react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var clsx2 = require('clsx');
6
+ var reactRouterDom = require('react-router-dom');
7
+ var react$1 = require('react');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var clsx2__default = /*#__PURE__*/_interopDefault(clsx2);
12
+
13
+ // src/theme/index.ts
14
+
15
+ // src/theme/colors.ts
16
+ var colors = {
17
+ // Primary brand color - Politogy Red/Orange (Energy & Action)
18
+ brand: {
19
+ 50: "#fff5f0",
20
+ 100: "#ffe8dc",
21
+ 200: "#ffd0b8",
22
+ 300: "#ffb088",
23
+ 400: "#ff8c5a",
24
+ 500: "#e86a3a",
25
+ // Primary brand color - burnt orange/red
26
+ 600: "#cc5429",
27
+ 700: "#a6421f",
28
+ 800: "#803317",
29
+ 900: "#5c2410"
30
+ },
31
+ // Politogy Brand Colors
32
+ politogy: {
33
+ // Legacy Blue - kept for reference
34
+ blue: {
35
+ 50: "#e8f4fd",
36
+ 100: "#bee3f8",
37
+ 200: "#90cdf4",
38
+ 300: "#63b3ed",
39
+ 400: "#4299e1",
40
+ 500: "#3182ce",
41
+ 600: "#2b6cb0",
42
+ 700: "#2c5282",
43
+ 800: "#2a4365",
44
+ 900: "#1a365d"
45
+ },
46
+ // Primary Red/Orange - Energy & Action (main brand color)
47
+ red: {
48
+ 50: "#fff5f0",
49
+ 100: "#ffe8dc",
50
+ 200: "#ffd0b8",
51
+ 300: "#ffb088",
52
+ 400: "#ff8c5a",
53
+ 500: "#e86a3a",
54
+ 600: "#cc5429",
55
+ 700: "#a6421f",
56
+ 800: "#803317",
57
+ 900: "#5c2410"
58
+ },
59
+ // Navy - Professional & Authoritative
60
+ navy: {
61
+ 50: "#e8eef6",
62
+ 100: "#c5d4e8",
63
+ 200: "#9fb8d9",
64
+ 300: "#789cca",
65
+ 400: "#5b86be",
66
+ 500: "#3e70b2",
67
+ 600: "#325a8e",
68
+ 700: "#26446a",
69
+ 800: "#1a2e47",
70
+ 900: "#0e1823"
71
+ },
72
+ // White & Off-white
73
+ white: "#ffffff",
74
+ offWhite: "#f8fafc",
75
+ // Text colors
76
+ text: {
77
+ primary: "#1a202c",
78
+ secondary: "#4a5568",
79
+ muted: "#718096",
80
+ light: "#a0aec0"
81
+ }
82
+ },
83
+ // Semantic color tokens that will switch based on color mode
84
+ gray: {
85
+ 50: "#f7fafc",
86
+ 100: "#edf2f7",
87
+ 200: "#e2e8f0",
88
+ 300: "#cbd5e0",
89
+ 400: "#a0aec0",
90
+ 500: "#718096",
91
+ 600: "#4a5568",
92
+ 700: "#2d3748",
93
+ 800: "#1a202c",
94
+ 900: "#171923"
95
+ }
96
+ };
97
+ var semanticTokens = {
98
+ colors: {
99
+ // Text colors
100
+ "text.primary": {
101
+ default: "gray.900",
102
+ _dark: "gray.50"
103
+ },
104
+ "text.secondary": {
105
+ default: "gray.600",
106
+ _dark: "gray.400"
107
+ },
108
+ "text.muted": {
109
+ default: "gray.500",
110
+ _dark: "gray.500"
111
+ },
112
+ // Background colors
113
+ "bg.primary": {
114
+ default: "white",
115
+ _dark: "gray.800"
116
+ },
117
+ "bg.secondary": {
118
+ default: "gray.50",
119
+ _dark: "gray.900"
120
+ },
121
+ "bg.surface": {
122
+ default: "white",
123
+ _dark: "gray.700"
124
+ },
125
+ "bg.hover": {
126
+ default: "gray.50",
127
+ _dark: "gray.600"
128
+ },
129
+ // Border colors
130
+ "border.default": {
131
+ default: "gray.200",
132
+ _dark: "gray.600"
133
+ },
134
+ "border.muted": {
135
+ default: "gray.100",
136
+ _dark: "gray.700"
137
+ },
138
+ // Component specific
139
+ "card.bg": {
140
+ default: "white",
141
+ _dark: "gray.700"
142
+ },
143
+ "card.border": {
144
+ default: "gray.200",
145
+ _dark: "gray.600"
146
+ },
147
+ "input.bg": {
148
+ default: "white",
149
+ _dark: "gray.700"
150
+ },
151
+ "input.border": {
152
+ default: "gray.200",
153
+ _dark: "gray.600"
154
+ },
155
+ "input.hover": {
156
+ default: "gray.400",
157
+ _dark: "gray.500"
158
+ },
159
+ // Navigation
160
+ "nav.bg": {
161
+ default: "white",
162
+ _dark: "gray.800"
163
+ },
164
+ "nav.border": {
165
+ default: "gray.200",
166
+ _dark: "gray.700"
167
+ },
168
+ // Sidebar
169
+ "sidebar.bg": {
170
+ default: "gray.50",
171
+ _dark: "gray.900"
172
+ },
173
+ "sidebar.hover": {
174
+ default: "gray.100",
175
+ _dark: "gray.800"
176
+ },
177
+ "sidebar.active": {
178
+ default: "brand.50",
179
+ _dark: "brand.900"
180
+ },
181
+ // Status colors
182
+ "success.bg": {
183
+ default: "green.50",
184
+ _dark: "green.900"
185
+ },
186
+ "error.bg": {
187
+ default: "red.50",
188
+ _dark: "red.900"
189
+ },
190
+ "warning.bg": {
191
+ default: "yellow.50",
192
+ _dark: "yellow.900"
193
+ },
194
+ "info.bg": {
195
+ default: "blue.50",
196
+ _dark: "blue.900"
197
+ }
198
+ }
199
+ };
200
+
201
+ // src/theme/components.ts
202
+ var components = {
203
+ Button: {
204
+ baseStyle: {
205
+ fontWeight: "medium"
206
+ },
207
+ defaultProps: {
208
+ colorScheme: "brand"
209
+ },
210
+ variants: {
211
+ primary: {
212
+ bg: "brand.500",
213
+ color: "white",
214
+ _hover: {
215
+ bg: "brand.600",
216
+ _disabled: {
217
+ bg: "brand.500"
218
+ }
219
+ },
220
+ _active: {
221
+ bg: "brand.700"
222
+ }
223
+ },
224
+ secondary: {
225
+ borderWidth: "1px",
226
+ borderColor: "gray.300",
227
+ bg: "white",
228
+ color: "gray.700",
229
+ _hover: {
230
+ bg: "gray.50"
231
+ }
232
+ },
233
+ solid: (props) => {
234
+ const { colorScheme: c } = props;
235
+ if (c === "brand") {
236
+ return {
237
+ bg: "brand.500",
238
+ color: "white",
239
+ _hover: {
240
+ bg: "brand.600",
241
+ _disabled: {
242
+ bg: "brand.500"
243
+ }
244
+ },
245
+ _active: {
246
+ bg: "brand.700"
247
+ }
248
+ };
249
+ }
250
+ return {
251
+ bg: `${c}.500`,
252
+ color: "white",
253
+ _hover: {
254
+ bg: `${c}.600`,
255
+ _disabled: {
256
+ bg: `${c}.500`
257
+ }
258
+ },
259
+ _active: {
260
+ bg: `${c}.700`
261
+ }
262
+ };
263
+ },
264
+ ghost: (props) => {
265
+ const { colorScheme: c } = props;
266
+ return {
267
+ color: `${c}.600`,
268
+ _hover: {
269
+ bg: `${c}.50`
270
+ }
271
+ };
272
+ },
273
+ outline: (props) => {
274
+ const { colorScheme: c } = props;
275
+ return {
276
+ borderColor: `${c}.500`,
277
+ color: `${c}.600`,
278
+ _hover: {
279
+ bg: `${c}.50`
280
+ }
281
+ };
282
+ },
283
+ link: {
284
+ color: "brand.500",
285
+ _hover: {
286
+ color: "brand.600",
287
+ textDecoration: "underline"
288
+ }
289
+ }
290
+ }
291
+ },
292
+ Heading: {
293
+ baseStyle: {
294
+ color: "politogy.navy.800",
295
+ fontWeight: "semibold"
296
+ }
297
+ },
298
+ Card: {
299
+ baseStyle: {
300
+ container: {
301
+ bg: "card.bg",
302
+ borderWidth: "1px",
303
+ borderColor: "card.border",
304
+ borderRadius: "lg"
305
+ }
306
+ }
307
+ },
308
+ Input: {
309
+ baseStyle: {
310
+ field: {
311
+ bg: "input.bg",
312
+ borderColor: "var(--mode-input-border-color)",
313
+ _hover: {
314
+ borderColor: "var(--mode-input-hover-border-color)"
315
+ },
316
+ _focus: {
317
+ borderColor: "var(--mode-primary-color)",
318
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
319
+ }
320
+ }
321
+ },
322
+ defaultProps: {
323
+ variant: "outline"
324
+ },
325
+ variants: {
326
+ outline: {
327
+ field: {
328
+ borderColor: "var(--mode-input-border-color)",
329
+ _hover: {
330
+ borderColor: "var(--mode-input-hover-border-color)"
331
+ },
332
+ _focus: {
333
+ borderColor: "var(--mode-primary-color)",
334
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
335
+ }
336
+ }
337
+ }
338
+ }
339
+ },
340
+ NumberInput: {
341
+ defaultProps: {
342
+ variant: "outline"
343
+ },
344
+ variants: {
345
+ outline: {
346
+ field: {
347
+ borderColor: "var(--mode-input-border-color)",
348
+ _hover: {
349
+ borderColor: "var(--mode-input-hover-border-color)"
350
+ },
351
+ _focus: {
352
+ borderColor: "var(--mode-primary-color)",
353
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
354
+ }
355
+ }
356
+ }
357
+ }
358
+ },
359
+ Select: {
360
+ baseStyle: {
361
+ field: {
362
+ bg: "input.bg",
363
+ borderColor: "var(--mode-input-border-color)",
364
+ _hover: {
365
+ borderColor: "var(--mode-input-hover-border-color)"
366
+ },
367
+ _focus: {
368
+ borderColor: "var(--mode-primary-color)",
369
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
370
+ }
371
+ }
372
+ },
373
+ defaultProps: {
374
+ variant: "outline"
375
+ },
376
+ variants: {
377
+ outline: {
378
+ field: {
379
+ borderColor: "var(--mode-input-border-color)",
380
+ _hover: {
381
+ borderColor: "var(--mode-input-hover-border-color)"
382
+ },
383
+ _focus: {
384
+ borderColor: "var(--mode-primary-color)",
385
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
386
+ }
387
+ }
388
+ }
389
+ }
390
+ },
391
+ Textarea: {
392
+ baseStyle: {
393
+ bg: "input.bg",
394
+ borderColor: "var(--mode-input-border-color)",
395
+ _hover: {
396
+ borderColor: "var(--mode-input-hover-border-color)"
397
+ },
398
+ _focus: {
399
+ borderColor: "var(--mode-primary-color)",
400
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
401
+ }
402
+ },
403
+ defaultProps: {
404
+ variant: "outline"
405
+ },
406
+ variants: {
407
+ outline: {
408
+ borderColor: "var(--mode-input-border-color)",
409
+ _hover: {
410
+ borderColor: "var(--mode-input-hover-border-color)"
411
+ },
412
+ _focus: {
413
+ borderColor: "var(--mode-primary-color)",
414
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
415
+ }
416
+ }
417
+ }
418
+ },
419
+ Menu: {
420
+ baseStyle: {
421
+ list: {
422
+ bg: "bg.surface",
423
+ borderColor: "var(--mode-input-border-color)",
424
+ boxShadow: "lg"
425
+ },
426
+ item: {
427
+ bg: "transparent",
428
+ _hover: {
429
+ bg: "bg.hover"
430
+ },
431
+ _focus: {
432
+ bg: "bg.hover"
433
+ }
434
+ }
435
+ }
436
+ },
437
+ Modal: {
438
+ baseStyle: {
439
+ dialog: {
440
+ bg: "bg.surface"
441
+ },
442
+ overlay: {
443
+ bg: "blackAlpha.600"
444
+ }
445
+ }
446
+ },
447
+ Popover: {
448
+ baseStyle: {
449
+ content: {
450
+ bg: "bg.surface",
451
+ borderColor: "border.default",
452
+ boxShadow: "lg"
453
+ }
454
+ }
455
+ },
456
+ Drawer: {
457
+ baseStyle: {
458
+ dialog: {
459
+ bg: "bg.surface"
460
+ },
461
+ overlay: {
462
+ bg: "blackAlpha.600"
463
+ }
464
+ }
465
+ },
466
+ Tabs: {
467
+ baseStyle: {
468
+ root: {
469
+ width: "100%"
470
+ },
471
+ tablist: {
472
+ width: "100%",
473
+ alignItems: "flex-end",
474
+ gap: "var(--app-tab-gap)"
475
+ },
476
+ tabpanels: {
477
+ width: "100%"
478
+ },
479
+ tabpanel: {
480
+ width: "100%"
481
+ },
482
+ tab: {
483
+ minHeight: "var(--app-tab-height)",
484
+ height: "var(--app-tab-height)",
485
+ lineHeight: 1,
486
+ borderTopLeftRadius: "var(--app-tab-radius)",
487
+ borderTopRightRadius: "var(--app-tab-radius)",
488
+ borderBottomLeftRadius: 0,
489
+ borderBottomRightRadius: 0,
490
+ color: "text.secondary",
491
+ _selected: {
492
+ color: "white",
493
+ bg: "brand.500",
494
+ borderColor: "brand.500",
495
+ fontWeight: "semibold"
496
+ },
497
+ _hover: {
498
+ bg: "gray.100"
499
+ }
500
+ }
501
+ },
502
+ variants: {
503
+ enclosed: {
504
+ tab: {
505
+ color: "gray.600",
506
+ bg: "transparent",
507
+ borderColor: "gray.200",
508
+ _selected: {
509
+ color: "white",
510
+ bg: "brand.500",
511
+ borderColor: "brand.500",
512
+ borderBottomColor: "brand.500"
513
+ },
514
+ _hover: {
515
+ bg: "gray.100"
516
+ }
517
+ }
518
+ },
519
+ "enclosed-colored": {
520
+ tab: {
521
+ color: "gray.600",
522
+ _selected: {
523
+ color: "white",
524
+ bg: "brand.500"
525
+ }
526
+ }
527
+ },
528
+ "soft-rounded": {
529
+ tab: {
530
+ color: "gray.600",
531
+ _selected: {
532
+ color: "white",
533
+ bg: "brand.500"
534
+ }
535
+ }
536
+ },
537
+ "solid-rounded": {
538
+ tab: {
539
+ color: "gray.600",
540
+ _selected: {
541
+ color: "white",
542
+ bg: "brand.500"
543
+ }
544
+ }
545
+ },
546
+ line: {
547
+ tab: {
548
+ color: "gray.600",
549
+ _selected: {
550
+ color: "white",
551
+ bg: "brand.500",
552
+ borderColor: "brand.500"
553
+ },
554
+ _hover: {
555
+ bg: "gray.100"
556
+ }
557
+ }
558
+ },
559
+ unstyled: {
560
+ tab: {
561
+ // Allow inline styles to take precedence for unstyled variant
562
+ }
563
+ }
564
+ },
565
+ defaultProps: {
566
+ colorScheme: "brand"
567
+ }
568
+ },
569
+ Badge: {
570
+ baseStyle: {
571
+ borderRadius: "md",
572
+ px: 2,
573
+ py: 1,
574
+ fontWeight: "medium"
575
+ },
576
+ defaultProps: {
577
+ colorScheme: "brand"
578
+ }
579
+ },
580
+ Link: {
581
+ baseStyle: {
582
+ color: "brand.500",
583
+ _hover: {
584
+ color: "brand.600",
585
+ textDecoration: "underline"
586
+ }
587
+ }
588
+ },
589
+ Alert: {
590
+ baseStyle: {
591
+ container: {
592
+ borderRadius: "md"
593
+ }
594
+ },
595
+ variants: {
596
+ subtle: (props) => {
597
+ const { colorScheme: c } = props;
598
+ if (c === "blue" || c === "info") {
599
+ return {
600
+ container: {
601
+ bg: "blue.50"
602
+ },
603
+ icon: {
604
+ color: "blue.500"
605
+ },
606
+ title: {
607
+ color: "blue.800"
608
+ },
609
+ description: {
610
+ color: "blue.700"
611
+ }
612
+ };
613
+ }
614
+ return {};
615
+ },
616
+ "left-accent": (props) => {
617
+ const { colorScheme: c } = props;
618
+ if (c === "blue" || c === "info") {
619
+ return {
620
+ container: {
621
+ bg: "blue.50",
622
+ borderLeftColor: "blue.500"
623
+ },
624
+ icon: {
625
+ color: "blue.500"
626
+ }
627
+ };
628
+ }
629
+ return {};
630
+ },
631
+ solid: (props) => {
632
+ const { colorScheme: c } = props;
633
+ if (c === "blue" || c === "info") {
634
+ return {
635
+ container: {
636
+ bg: "blue.500",
637
+ color: "white"
638
+ }
639
+ };
640
+ }
641
+ return {};
642
+ }
643
+ }
644
+ },
645
+ Table: {
646
+ baseStyle: {
647
+ table: {
648
+ width: "100%",
649
+ borderCollapse: "collapse",
650
+ borderSpacing: "0",
651
+ borderColor: "gray.200"
652
+ },
653
+ th: {
654
+ borderColor: "gray.200",
655
+ borderBottom: "none",
656
+ bg: "gray.200",
657
+ color: "text.secondary",
658
+ fontWeight: "semibold",
659
+ px: 3,
660
+ py: 2.5,
661
+ minHeight: "44px",
662
+ height: "44px",
663
+ verticalAlign: "middle"
664
+ },
665
+ td: {
666
+ borderColor: "gray.200",
667
+ borderBottom: "none",
668
+ px: 3,
669
+ py: 2.5,
670
+ minHeight: "44px",
671
+ height: "44px",
672
+ verticalAlign: "middle"
673
+ },
674
+ tr: {
675
+ borderBottom: "none",
676
+ borderColor: "transparent",
677
+ _odd: {
678
+ bg: "white"
679
+ },
680
+ _even: {
681
+ bg: "gray.50"
682
+ },
683
+ _hover: {
684
+ bg: "gray.100"
685
+ }
686
+ },
687
+ tbody: {
688
+ tr: {
689
+ _odd: {
690
+ bg: "white"
691
+ },
692
+ _even: {
693
+ bg: "gray.50"
694
+ },
695
+ _hover: {
696
+ bg: "blue.100"
697
+ }
698
+ }
699
+ }
700
+ },
701
+ variants: {
702
+ simple: {},
703
+ striped: {}
704
+ },
705
+ defaultProps: {
706
+ variant: "striped"
707
+ }
708
+ },
709
+ Divider: {
710
+ baseStyle: {
711
+ borderColor: "border.default"
712
+ }
713
+ }
714
+ };
715
+
716
+ // src/theme/index.ts
717
+ var config = {
718
+ initialColorMode: "light",
719
+ // Always use light theme
720
+ useSystemColorMode: false
721
+ // Disable system color mode detection
722
+ };
723
+ var styles = {
724
+ global: () => ({
725
+ body: {
726
+ bg: "white",
727
+ color: "gray.900"
728
+ },
729
+ ":root": {
730
+ "--mode-primary-color": "var(--app-color-brand-500)",
731
+ "--mode-input-border-color": "var(--app-color-brand-500)",
732
+ "--mode-input-hover-border-color": "var(--app-color-brand-600)",
733
+ "--mode-input-focus-shadow-color": "var(--app-color-brand-500)"
734
+ },
735
+ // Ensure non-Chakra/native text-like inputs follow mode border colors as well.
736
+ 'input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]), textarea, select': {
737
+ borderColor: "var(--mode-input-border-color)"
738
+ },
739
+ 'input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):hover, textarea:hover, select:hover': {
740
+ borderColor: "var(--mode-input-hover-border-color)"
741
+ },
742
+ 'input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):focus, textarea:focus, select:focus': {
743
+ borderColor: "var(--mode-primary-color)",
744
+ boxShadow: "0 0 0 1px var(--mode-input-focus-shadow-color)"
745
+ }
746
+ })
747
+ };
748
+ var fonts = {
749
+ heading: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif',
750
+ body: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif',
751
+ mono: 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'
752
+ };
753
+ var politogyTheme = react.extendTheme({
754
+ config,
755
+ colors,
756
+ semanticTokens,
757
+ components,
758
+ styles,
759
+ fonts,
760
+ // Additional theme configurations
761
+ shadows: {
762
+ outline: "0 0 0 3px var(--app-color-brand-500)"
763
+ },
764
+ radii: {
765
+ none: "0",
766
+ sm: "0.125rem",
767
+ base: "0.25rem",
768
+ md: "0.375rem",
769
+ lg: "0.5rem",
770
+ xl: "0.75rem",
771
+ "2xl": "1rem",
772
+ "3xl": "1.5rem",
773
+ full: "9999px"
774
+ }
775
+ });
776
+ function Card({
777
+ title,
778
+ children,
779
+ minH,
780
+ className,
781
+ style,
782
+ ...props
783
+ }) {
784
+ return /* @__PURE__ */ jsxRuntime.jsxs(
785
+ "div",
786
+ {
787
+ className: `rounded-lg border border-slate-200 bg-white p-6 shadow-sm ${className || ""}`,
788
+ style: { minHeight: minH, ...style },
789
+ ...props,
790
+ children: [
791
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 text-lg font-semibold", children: title }),
792
+ children
793
+ ]
794
+ }
795
+ );
796
+ }
797
+ function PageContainer({
798
+ children,
799
+ maxW = "container.xl",
800
+ px,
801
+ py,
802
+ lockHeight = true
803
+ }) {
804
+ const isFullWidth = maxW === "full";
805
+ const effectivePx = isFullWidth ? 0 : px === void 0 ? 4 : Number(px);
806
+ const effectivePy = py === void 0 ? isFullWidth ? 0 : 4 : py;
807
+ const pxValue = String(effectivePx);
808
+ const pyValue = String(effectivePy);
809
+ const maxWClass = isFullWidth ? "max-w-none" : maxW === "container.xl" ? "max-w-7xl" : maxW === "container.lg" ? "max-w-6xl" : maxW === "container.md" ? "max-w-5xl" : typeof maxW === "string" && /^(\d+)px$/.test(maxW) ? "" : "max-w-7xl";
810
+ const pxClass = pxValue === "0" ? "px-0" : pxValue === "1" ? "px-1" : pxValue === "2" ? "px-2" : pxValue === "3" ? "px-3" : pxValue === "4" ? "px-4" : "px-4";
811
+ const pyClass = pyValue === "0" ? "py-0" : pyValue === "4" ? "py-4" : pyValue === "5" ? "py-5" : pyValue === "6" ? "py-6" : "py-6";
812
+ const inlineMaxWStyle = typeof maxW === "string" && /^(\d+)px$/.test(maxW) ? { maxWidth: maxW } : void 0;
813
+ return /* @__PURE__ */ jsxRuntime.jsx(
814
+ "main",
815
+ {
816
+ className: lockHeight ? "h-[calc(100vh-80px)] min-h-[calc(100vh-80px)]" : "",
817
+ style: { background: "var(--app-tab-content-bg)" },
818
+ children: /* @__PURE__ */ jsxRuntime.jsx(
819
+ "div",
820
+ {
821
+ className: clsx2__default.default(
822
+ "mx-auto w-full",
823
+ maxWClass,
824
+ pxClass,
825
+ pyClass,
826
+ lockHeight ? "h-full" : "h-auto"
827
+ ),
828
+ style: inlineMaxWStyle,
829
+ children
830
+ }
831
+ )
832
+ }
833
+ );
834
+ }
835
+ var resolveMaxWidthClass = (maxW) => {
836
+ if (maxW === "full") return "max-w-none";
837
+ if (maxW === "container.lg") return "max-w-6xl";
838
+ if (maxW === "container.md") return "max-w-5xl";
839
+ return "max-w-7xl";
840
+ };
841
+ function PageHeader({
842
+ title,
843
+ breadcrumbs = [],
844
+ actions = null,
845
+ tabBar = null,
846
+ maxW = "full",
847
+ hideSidebar = false
848
+ }) {
849
+ const maxWClass = resolveMaxWidthClass(maxW);
850
+ const titleText = typeof title === "string" ? title.trim() : "";
851
+ const normalizedTitle = titleText.toLowerCase();
852
+ const breadcrumbsWithoutCurrent = [...breadcrumbs];
853
+ const last = breadcrumbsWithoutCurrent[breadcrumbsWithoutCurrent.length - 1];
854
+ if (breadcrumbsWithoutCurrent.length > 1 && normalizedTitle && last && last.label.trim().toLowerCase() === normalizedTitle) {
855
+ breadcrumbsWithoutCurrent.pop();
856
+ }
857
+ if (!title && breadcrumbsWithoutCurrent.length === 0 && !actions && !tabBar) {
858
+ return null;
859
+ }
860
+ return /* @__PURE__ */ jsxRuntime.jsxs(
861
+ "div",
862
+ {
863
+ style: { backgroundColor: "var(--app-tab-header-bg, #888888)" },
864
+ className: clsx2__default.default("text-slate-100", tabBar ? "pt-3 pb-0" : "py-3 border-b border-gray-200", {
865
+ "md:ml-60": !hideSidebar
866
+ }),
867
+ children: [
868
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx2__default.default("w-full px-4", maxWClass), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-nowrap items-start justify-between gap-4", children: [
869
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
870
+ title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-lg font-semibold text-white", children: title }) }) : null,
871
+ breadcrumbsWithoutCurrent.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
872
+ "nav",
873
+ {
874
+ "aria-label": "Breadcrumb",
875
+ className: clsx2__default.default("min-w-0 text-slate-100", title ? "mt-1" : ""),
876
+ children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex flex-nowrap items-center gap-2 overflow-hidden text-sm text-gray-600", children: breadcrumbsWithoutCurrent.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
877
+ "li",
878
+ {
879
+ className: "flex min-w-0 flex-shrink-0 items-center gap-2",
880
+ children: [
881
+ index > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400", children: ">" }) : null,
882
+ item.href ? /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: item.href, className: "truncate text-slate-100 hover:underline", children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-slate-100", children: item.label })
883
+ ]
884
+ },
885
+ `${item.label}-${index}`
886
+ )) })
887
+ }
888
+ ) : null
889
+ ] }),
890
+ actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: actions }) : null
891
+ ] }) }),
892
+ tabBar ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "m-0 w-full px-0", style: { backgroundColor: "transparent" }, children: tabBar }) : null
893
+ ]
894
+ }
895
+ );
896
+ }
897
+ function BreadcrumbBar({
898
+ breadcrumbs = [],
899
+ actions = null,
900
+ maxW = "full"
901
+ }) {
902
+ if ((!breadcrumbs || breadcrumbs.length === 0) && !actions) {
903
+ return null;
904
+ }
905
+ const maxWClass = maxW === "full" ? "max-w-none" : maxW === "container.xl" ? "max-w-7xl" : maxW === "container.lg" ? "max-w-6xl" : maxW === "container.md" ? "max-w-5xl" : "max-w-7xl";
906
+ return /* @__PURE__ */ jsxRuntime.jsx(
907
+ "div",
908
+ {
909
+ className: "ml-0 border-b border-gray-200 px-4 py-3 md:ml-60",
910
+ style: { backgroundColor: "var(--app-tab-header-bg, #888888)" },
911
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx2__default.default("mx-auto w-full px-0", maxWClass), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-between", children: [
912
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex items-center gap-2 text-sm text-slate-100", children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-2", children: [
913
+ index > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400", children: ">" }) : null,
914
+ item.href ? /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: item.href, className: "text-slate-100 hover:underline", children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-100", children: item.label })
915
+ ] }, index)) }) }),
916
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { children: actions })
917
+ ] }) })
918
+ }
919
+ );
920
+ }
921
+ function HeaderTabBar({
922
+ items,
923
+ activeId,
924
+ onChange,
925
+ className,
926
+ ariaLabel = "Tabs"
927
+ }) {
928
+ return /* @__PURE__ */ jsxRuntime.jsx(
929
+ "div",
930
+ {
931
+ role: "tablist",
932
+ "aria-label": ariaLabel,
933
+ className: clsx2__default.default(
934
+ // Header-wide tab strip: background + bottom border only (no outer box).
935
+ "app-header-tab-bar m-0 flex w-full bg-slate-100 p-0",
936
+ "border-b border-slate-200",
937
+ className
938
+ ),
939
+ children: items.map((item, idx) => {
940
+ const isActive = item.id === activeId;
941
+ const isDisabled = Boolean(item.disabled);
942
+ return /* @__PURE__ */ jsxRuntime.jsx(
943
+ react.Tooltip,
944
+ {
945
+ label: item.label,
946
+ placement: "top",
947
+ hasArrow: true,
948
+ bg: "black",
949
+ color: "white",
950
+ isDisabled,
951
+ children: /* @__PURE__ */ jsxRuntime.jsx(
952
+ "button",
953
+ {
954
+ type: "button",
955
+ role: "tab",
956
+ "aria-selected": isActive,
957
+ "aria-label": item.label,
958
+ disabled: isDisabled,
959
+ onClick: () => onChange(item.id),
960
+ className: clsx2__default.default(
961
+ "app-header-tab-button relative inline-flex flex-1 items-center justify-center",
962
+ "transition-colors",
963
+ "rounded-none",
964
+ idx === 0 ? "rounded-tl-lg" : null,
965
+ idx === items.length - 1 ? "rounded-tr-lg" : null,
966
+ isActive ? "text-white" : "bg-transparent text-slate-600 hover:bg-white/60 hover:text-slate-900",
967
+ isDisabled ? "cursor-not-allowed opacity-50" : null
968
+ ),
969
+ style: {
970
+ background: isActive ? "var(--mode-primary-color, var(--app-btn-primary-bg))" : void 0
971
+ },
972
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center text-[14px] leading-none", children: item.icon })
973
+ }
974
+ )
975
+ },
976
+ item.id
977
+ );
978
+ })
979
+ }
980
+ );
981
+ }
982
+ var FLAG_PREFIX = ["__", "politogy", "enable"].join("");
983
+ var GLOBAL_UI_IDS_FLAG = [FLAG_PREFIX, "global", "ui", "ids"].join("_");
984
+ function isFlagEnabled(name) {
985
+ if (typeof window === "undefined") return false;
986
+ try {
987
+ const params = new URLSearchParams(window.location.search);
988
+ if (params.get(name) === "1") return true;
989
+ } catch {
990
+ }
991
+ try {
992
+ return window.localStorage.getItem(name) === "1";
993
+ } catch {
994
+ return false;
995
+ }
996
+ }
997
+ function isGlobalUiIdsEnabled() {
998
+ return isFlagEnabled(GLOBAL_UI_IDS_FLAG);
999
+ }
1000
+ var TARGET_SELECTOR = [
1001
+ "main",
1002
+ "header",
1003
+ "footer",
1004
+ "aside",
1005
+ "nav",
1006
+ "section",
1007
+ '[role="region"]',
1008
+ '[role="banner"]',
1009
+ '[role="main"]',
1010
+ '[role="navigation"]',
1011
+ '[role="complementary"]',
1012
+ "button",
1013
+ '[role="button"]',
1014
+ 'a[role="button"]',
1015
+ "input",
1016
+ "textarea",
1017
+ "select",
1018
+ '[role="combobox"]',
1019
+ '[role="listbox"]',
1020
+ '[role="option"]',
1021
+ '[role="textbox"]',
1022
+ '[role="tablist"]',
1023
+ '[role="tab"]',
1024
+ '[role="tabpanel"]',
1025
+ '[role="menu"]',
1026
+ '[role="menuitem"]',
1027
+ '[role="menuitemcheckbox"]',
1028
+ '[role="menuitemradio"]',
1029
+ "svg",
1030
+ "[data-icon]"
1031
+ ].join(",");
1032
+ function sanitizeToken(raw, fallback) {
1033
+ if (!raw) return fallback;
1034
+ const cleaned = raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
1035
+ return cleaned || fallback;
1036
+ }
1037
+ function pageToken(pathname) {
1038
+ if (!pathname || pathname === "/") return "home";
1039
+ return sanitizeToken(pathname.replace(/\//g, "-"), "page");
1040
+ }
1041
+ function inferCategory(el) {
1042
+ const role = (el.getAttribute("role") || "").toLowerCase();
1043
+ const tag = el.tagName.toLowerCase();
1044
+ if (role.includes("tab") || tag === "tabs") return "tabs";
1045
+ if (role.startsWith("menu") || role === "menu") return "menu";
1046
+ if (tag === "button" || role === "button") return "button";
1047
+ if (tag === "input" || tag === "textarea" || tag === "select" || role === "combobox")
1048
+ return "field";
1049
+ if (tag === "svg" || el.hasAttribute("data-icon")) return "icon";
1050
+ if (["main", "header", "footer", "aside", "nav", "section"].includes(tag) || ["region", "banner", "main", "navigation", "complementary"].includes(role)) {
1051
+ return "layout";
1052
+ }
1053
+ return "ui";
1054
+ }
1055
+ function inferName(el) {
1056
+ const htmlEl = el;
1057
+ return sanitizeToken(
1058
+ el.getAttribute("data-testid") || el.getAttribute("aria-label") || el.getAttribute("name") || el.getAttribute("title") || htmlEl.placeholder || htmlEl.innerText || el.getAttribute("class"),
1059
+ "item"
1060
+ );
1061
+ }
1062
+ function assignUiIds(pathname) {
1063
+ const used = /* @__PURE__ */ new Set();
1064
+ document.querySelectorAll("[id]").forEach((el) => {
1065
+ const id = el.id?.trim();
1066
+ if (id) used.add(id);
1067
+ });
1068
+ const counters = {};
1069
+ const page = pageToken(pathname);
1070
+ const elements = document.querySelectorAll(TARGET_SELECTOR);
1071
+ elements.forEach((el) => {
1072
+ const category = inferCategory(el);
1073
+ const name = inferName(el);
1074
+ const stableKey = `ui-${category}-${name}`;
1075
+ el.setAttribute("data-ui-category", category);
1076
+ el.setAttribute("data-ui-key", stableKey);
1077
+ el.setAttribute("data-ui-page", page);
1078
+ if (el.id) {
1079
+ return;
1080
+ }
1081
+ const counterKey = `${page}-${category}-${name}`;
1082
+ counters[counterKey] = (counters[counterKey] || 0) + 1;
1083
+ let nextId = `ui-${page}-${category}-${name}-${counters[counterKey]}`;
1084
+ while (used.has(nextId)) {
1085
+ counters[counterKey] += 1;
1086
+ nextId = `ui-${page}-${category}-${name}-${counters[counterKey]}`;
1087
+ }
1088
+ el.id = nextId;
1089
+ used.add(nextId);
1090
+ });
1091
+ }
1092
+ function GlobalUiIdProvider() {
1093
+ const location = reactRouterDom.useLocation();
1094
+ const enabled = isGlobalUiIdsEnabled();
1095
+ react$1.useEffect(() => {
1096
+ if (!enabled) return;
1097
+ let rafId = 0;
1098
+ const schedule = () => {
1099
+ if (rafId) return;
1100
+ rafId = window.requestAnimationFrame(() => {
1101
+ rafId = 0;
1102
+ assignUiIds(location.pathname);
1103
+ });
1104
+ };
1105
+ schedule();
1106
+ const observer = new MutationObserver(() => {
1107
+ schedule();
1108
+ });
1109
+ observer.observe(document.body, {
1110
+ subtree: true,
1111
+ childList: true,
1112
+ attributes: true,
1113
+ attributeFilter: ["role", "aria-label", "name", "title", "placeholder", "class", "data-icon"]
1114
+ });
1115
+ return () => {
1116
+ if (rafId) window.cancelAnimationFrame(rafId);
1117
+ observer.disconnect();
1118
+ };
1119
+ }, [enabled, location.pathname]);
1120
+ return null;
1121
+ }
1122
+ var ShellAuthContext = react$1.createContext(null);
1123
+ var ShellMetaContext = react$1.createContext(null);
1124
+ function toShellUser(session) {
1125
+ if (!session?.user) return null;
1126
+ const su = session.user;
1127
+ const fullName = su.user_metadata?.full_name ?? null;
1128
+ return {
1129
+ id: su.id,
1130
+ email: su.email ?? null,
1131
+ displayName: fullName ?? su.email ?? null,
1132
+ raw: su
1133
+ };
1134
+ }
1135
+ function ShellProvider({
1136
+ children,
1137
+ supabaseClient,
1138
+ currentApp,
1139
+ appRegistry,
1140
+ basename
1141
+ }) {
1142
+ const [status, setStatus] = react$1.useState("loading");
1143
+ const [session, setSession] = react$1.useState(null);
1144
+ react$1.useEffect(() => {
1145
+ let cancelled = false;
1146
+ supabaseClient.auth.getSession().then(({ data }) => {
1147
+ if (cancelled) return;
1148
+ setSession(data.session);
1149
+ setStatus(data.session ? "authenticated" : "unauthenticated");
1150
+ });
1151
+ const sub = supabaseClient.auth.onAuthStateChange((_event, newSession) => {
1152
+ setSession(newSession);
1153
+ setStatus(newSession ? "authenticated" : "unauthenticated");
1154
+ });
1155
+ return () => {
1156
+ cancelled = true;
1157
+ sub.data.subscription.unsubscribe();
1158
+ };
1159
+ }, [supabaseClient]);
1160
+ const value = react$1.useMemo(
1161
+ () => ({
1162
+ status,
1163
+ session,
1164
+ user: toShellUser(session),
1165
+ signOut: async () => {
1166
+ await supabaseClient.auth.signOut();
1167
+ }
1168
+ }),
1169
+ [status, session, supabaseClient]
1170
+ );
1171
+ const meta = react$1.useMemo(
1172
+ () => ({
1173
+ currentApp,
1174
+ appRegistry: appRegistry ?? [],
1175
+ basename: basename ?? ""
1176
+ }),
1177
+ [currentApp, appRegistry, basename]
1178
+ );
1179
+ return /* @__PURE__ */ jsxRuntime.jsx(ShellAuthContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(ShellMetaContext.Provider, { value: meta, children: /* @__PURE__ */ jsxRuntime.jsx(react.ChakraProvider, { theme: politogyTheme, children }) }) });
1180
+ }
1181
+ function useShellAuth() {
1182
+ const ctx = react$1.useContext(ShellAuthContext);
1183
+ if (!ctx) {
1184
+ throw new Error("useShellAuth must be used inside <ShellProvider>");
1185
+ }
1186
+ return ctx;
1187
+ }
1188
+ function useAppRegistry() {
1189
+ const meta = react$1.useContext(ShellMetaContext);
1190
+ if (!meta) {
1191
+ throw new Error("useAppRegistry must be used inside <ShellProvider>");
1192
+ }
1193
+ return meta.appRegistry;
1194
+ }
1195
+ function useCurrentApp() {
1196
+ const meta = react$1.useContext(ShellMetaContext);
1197
+ if (!meta) {
1198
+ throw new Error("useCurrentApp must be used inside <ShellProvider>");
1199
+ }
1200
+ return meta.currentApp;
1201
+ }
1202
+ function Header({ extrasSlot }) {
1203
+ const { user, signOut, status } = useShellAuth();
1204
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1205
+ react.Flex,
1206
+ {
1207
+ as: "header",
1208
+ align: "center",
1209
+ px: 4,
1210
+ h: "56px",
1211
+ bg: "white",
1212
+ borderBottom: "1px solid",
1213
+ borderColor: "gray.200",
1214
+ children: [
1215
+ /* @__PURE__ */ jsxRuntime.jsx(react.Heading, { size: "md", color: "brand.500", children: "politogy" }),
1216
+ /* @__PURE__ */ jsxRuntime.jsx(react.Spacer, {}),
1217
+ extrasSlot && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { mr: 3, children: extrasSlot }),
1218
+ status === "authenticated" && user && /* @__PURE__ */ jsxRuntime.jsxs(react.Menu, { children: [
1219
+ /* @__PURE__ */ jsxRuntime.jsx(react.MenuButton, { children: /* @__PURE__ */ jsxRuntime.jsx(react.Avatar, { size: "sm", name: user.displayName ?? user.email ?? "" }) }),
1220
+ /* @__PURE__ */ jsxRuntime.jsx(react.MenuList, { children: /* @__PURE__ */ jsxRuntime.jsx(react.MenuItem, { onClick: () => signOut(), children: "Sign out" }) })
1221
+ ] })
1222
+ ]
1223
+ }
1224
+ );
1225
+ }
1226
+ function Sidebar({ entries, currentApp, footerSlot }) {
1227
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1228
+ react.Box,
1229
+ {
1230
+ as: "nav",
1231
+ w: "200px",
1232
+ minH: "100%",
1233
+ bg: "gray.50",
1234
+ borderRight: "1px solid",
1235
+ borderColor: "gray.200",
1236
+ p: 3,
1237
+ display: "flex",
1238
+ flexDirection: "column",
1239
+ children: [
1240
+ /* @__PURE__ */ jsxRuntime.jsx(react.VStack, { align: "stretch", spacing: 1, children: entries.filter((e) => e.visible !== false).map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
1241
+ react.Link,
1242
+ {
1243
+ href: entry.path,
1244
+ "data-current": entry.id === currentApp,
1245
+ px: 3,
1246
+ py: 2,
1247
+ borderRadius: "md",
1248
+ fontWeight: entry.id === currentApp ? "bold" : "normal",
1249
+ bg: entry.id === currentApp ? "brand.50" : "transparent",
1250
+ _hover: { bg: "gray.100" },
1251
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { children: entry.label })
1252
+ },
1253
+ entry.id
1254
+ )) }),
1255
+ /* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: "1" }),
1256
+ footerSlot && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { pt: 3, children: footerSlot })
1257
+ ]
1258
+ }
1259
+ );
1260
+ }
1261
+ function Footer({ buildInfo }) {
1262
+ return /* @__PURE__ */ jsxRuntime.jsx(
1263
+ react.Box,
1264
+ {
1265
+ as: "footer",
1266
+ px: 4,
1267
+ py: 2,
1268
+ borderTop: "1px solid",
1269
+ borderColor: "gray.200",
1270
+ fontSize: "xs",
1271
+ color: "gray.500",
1272
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react.Text, { children: [
1273
+ "politogy ",
1274
+ buildInfo ? `\xB7 ${buildInfo}` : ""
1275
+ ] })
1276
+ }
1277
+ );
1278
+ }
1279
+ function AppLayout({
1280
+ children,
1281
+ buildInfo,
1282
+ headerExtrasSlot,
1283
+ modalsSlot,
1284
+ notificationsSlot,
1285
+ sidebarFooterSlot,
1286
+ overlaySlot
1287
+ }) {
1288
+ const currentApp = useCurrentApp();
1289
+ const entries = useAppRegistry();
1290
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { direction: "column", minH: "100vh", children: [
1291
+ /* @__PURE__ */ jsxRuntime.jsx(Header, { extrasSlot: headerExtrasSlot }),
1292
+ /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { flex: "1", minH: 0, children: [
1293
+ /* @__PURE__ */ jsxRuntime.jsx(Sidebar, { entries, currentApp, footerSlot: sidebarFooterSlot }),
1294
+ /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { as: "main", flex: "1", overflow: "auto", position: "relative", children: [
1295
+ children,
1296
+ notificationsSlot
1297
+ ] })
1298
+ ] }),
1299
+ /* @__PURE__ */ jsxRuntime.jsx(Footer, { buildInfo }),
1300
+ modalsSlot,
1301
+ overlaySlot
1302
+ ] });
1303
+ }
1304
+
1305
+ // src/sw/registerShellPrecache.ts
1306
+ async function registerShellPrecache(opts = {}) {
1307
+ if (typeof window === "undefined") return;
1308
+ if (!("serviceWorker" in navigator)) return;
1309
+ const scriptUrl = opts.scriptUrl ?? "/sw-shell.js";
1310
+ const scope = opts.scope ?? "/";
1311
+ try {
1312
+ await navigator.serviceWorker.register(scriptUrl, { scope });
1313
+ } catch (err) {
1314
+ console.warn("[shell] precache SW registration failed:", err);
1315
+ }
1316
+ }
1317
+
1318
+ // src/speculation/emitRules.ts
1319
+ function buildSpeculationRules(currentApp, registry) {
1320
+ const others = registry.filter(
1321
+ (entry) => entry.id !== currentApp && entry.visible !== false
1322
+ );
1323
+ if (others.length === 0) return null;
1324
+ const payload = {
1325
+ prerender: [
1326
+ {
1327
+ urls: others.map((entry) => entry.path),
1328
+ eagerness: "moderate"
1329
+ }
1330
+ ]
1331
+ };
1332
+ return JSON.stringify(payload);
1333
+ }
1334
+
1335
+ exports.AppLayout = AppLayout;
1336
+ exports.BreadcrumbBar = BreadcrumbBar;
1337
+ exports.Card = Card;
1338
+ exports.Footer = Footer;
1339
+ exports.GlobalUiIdProvider = GlobalUiIdProvider;
1340
+ exports.Header = Header;
1341
+ exports.HeaderTabBar = HeaderTabBar;
1342
+ exports.PageContainer = PageContainer;
1343
+ exports.PageHeader = PageHeader;
1344
+ exports.ShellProvider = ShellProvider;
1345
+ exports.Sidebar = Sidebar;
1346
+ exports.buildSpeculationRules = buildSpeculationRules;
1347
+ exports.politogyTheme = politogyTheme;
1348
+ exports.registerShellPrecache = registerShellPrecache;
1349
+ exports.useAppRegistry = useAppRegistry;
1350
+ exports.useCurrentApp = useCurrentApp;
1351
+ exports.useShellAuth = useShellAuth;
1352
+ //# sourceMappingURL=index.cjs.map
1353
+ //# sourceMappingURL=index.cjs.map