@c15t/dev-tools 2.0.0-rc.3 → 2.0.0-rc.5

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.
Files changed (95) hide show
  1. package/README.md +12 -1
  2. package/dist/index.cjs +2039 -953
  3. package/dist/index.js +2042 -956
  4. package/dist/react.cjs +1975 -803
  5. package/dist/react.js +1978 -806
  6. package/dist/tanstack.cjs +1862 -524
  7. package/dist/tanstack.js +1865 -527
  8. package/{dist → dist-types}/components/dropdown-menu.d.ts +0 -1
  9. package/{dist → dist-types}/components/index.d.ts +0 -1
  10. package/{dist → dist-types}/components/panel.d.ts +0 -1
  11. package/{dist → dist-types}/components/tabs.d.ts +0 -1
  12. package/{dist → dist-types}/components/ui.d.ts +8 -1
  13. package/dist-types/core/debug-bundle.d.ts +13 -0
  14. package/{dist → dist-types}/core/devtools.d.ts +0 -1
  15. package/{dist → dist-types}/core/draggable.d.ts +0 -1
  16. package/{dist → dist-types}/core/index.d.ts +0 -1
  17. package/{dist → dist-types}/core/override-storage.d.ts +1 -2
  18. package/{dist → dist-types}/core/panel-renderer.d.ts +6 -2
  19. package/{dist → dist-types}/core/renderer.d.ts +0 -1
  20. package/{dist → dist-types}/core/reset-consents.d.ts +1 -2
  21. package/{dist → dist-types}/core/state-manager.d.ts +1 -2
  22. package/{dist → dist-types}/core/store-connector.d.ts +17 -2
  23. package/dist-types/core/store-instrumentation.d.ts +12 -0
  24. package/{dist → dist-types}/index.d.ts +0 -1
  25. package/{dist → dist-types}/panels/actions.d.ts +2 -2
  26. package/{dist → dist-types}/panels/consents.d.ts +1 -2
  27. package/{dist → dist-types}/panels/dom-scanner.d.ts +1 -2
  28. package/{dist → dist-types}/panels/events.d.ts +0 -1
  29. package/{dist → dist-types}/panels/iab.d.ts +1 -2
  30. package/{dist → dist-types}/panels/index.d.ts +1 -1
  31. package/{dist → dist-types}/panels/location.d.ts +1 -2
  32. package/dist-types/panels/policy.d.ts +12 -0
  33. package/{dist → dist-types}/panels/scripts.d.ts +1 -2
  34. package/{dist → dist-types}/react.d.ts +0 -1
  35. package/{dist → dist-types}/styles/index.d.ts +0 -1
  36. package/{dist → dist-types}/tanstack.d.ts +0 -1
  37. package/{dist → dist-types}/utils/index.d.ts +1 -1
  38. package/dist-types/utils/init-source.d.ts +2 -0
  39. package/{dist → dist-types}/utils/preference-trigger.d.ts +0 -1
  40. package/dist-types/version.d.ts +1 -0
  41. package/package.json +35 -32
  42. package/CHANGELOG.md +0 -154
  43. package/dist/__tests__/components/ui.test.d.ts +0 -2
  44. package/dist/__tests__/components/ui.test.d.ts.map +0 -1
  45. package/dist/__tests__/core/override-storage.test.d.ts +0 -2
  46. package/dist/__tests__/core/override-storage.test.d.ts.map +0 -1
  47. package/dist/__tests__/core/renderer.test.d.ts +0 -2
  48. package/dist/__tests__/core/renderer.test.d.ts.map +0 -1
  49. package/dist/__tests__/core/reset-consents.test.d.ts +0 -2
  50. package/dist/__tests__/core/reset-consents.test.d.ts.map +0 -1
  51. package/dist/__tests__/core/state-manager.test.d.ts +0 -2
  52. package/dist/__tests__/core/state-manager.test.d.ts.map +0 -1
  53. package/dist/__tests__/core/store-connector.test.d.ts +0 -2
  54. package/dist/__tests__/core/store-connector.test.d.ts.map +0 -1
  55. package/dist/__tests__/panels/dom-scanner.test.d.ts +0 -2
  56. package/dist/__tests__/panels/dom-scanner.test.d.ts.map +0 -1
  57. package/dist/__tests__/panels/events.test.d.ts +0 -2
  58. package/dist/__tests__/panels/events.test.d.ts.map +0 -1
  59. package/dist/__tests__/panels/iab.test.d.ts +0 -2
  60. package/dist/__tests__/panels/iab.test.d.ts.map +0 -1
  61. package/dist/__tests__/panels/scripts.test.d.ts +0 -2
  62. package/dist/__tests__/panels/scripts.test.d.ts.map +0 -1
  63. package/dist/__tests__/utils/preference-trigger.test.d.ts +0 -2
  64. package/dist/__tests__/utils/preference-trigger.test.d.ts.map +0 -1
  65. package/dist/components/dropdown-menu.d.ts.map +0 -1
  66. package/dist/components/index.d.ts.map +0 -1
  67. package/dist/components/panel.d.ts.map +0 -1
  68. package/dist/components/tabs.d.ts.map +0 -1
  69. package/dist/components/ui.d.ts.map +0 -1
  70. package/dist/core/devtools.d.ts.map +0 -1
  71. package/dist/core/draggable.d.ts.map +0 -1
  72. package/dist/core/index.d.ts.map +0 -1
  73. package/dist/core/override-storage.d.ts.map +0 -1
  74. package/dist/core/panel-renderer.d.ts.map +0 -1
  75. package/dist/core/renderer.d.ts.map +0 -1
  76. package/dist/core/reset-consents.d.ts.map +0 -1
  77. package/dist/core/state-manager.d.ts.map +0 -1
  78. package/dist/core/store-connector.d.ts.map +0 -1
  79. package/dist/index.d.ts.map +0 -1
  80. package/dist/panels/actions.d.ts.map +0 -1
  81. package/dist/panels/consents.d.ts.map +0 -1
  82. package/dist/panels/dom-scanner.d.ts.map +0 -1
  83. package/dist/panels/events.d.ts.map +0 -1
  84. package/dist/panels/iab.d.ts.map +0 -1
  85. package/dist/panels/index.d.ts.map +0 -1
  86. package/dist/panels/location.d.ts.map +0 -1
  87. package/dist/panels/scripts.d.ts.map +0 -1
  88. package/dist/react.d.ts.map +0 -1
  89. package/dist/styles/index.d.ts.map +0 -1
  90. package/dist/tanstack.d.ts.map +0 -1
  91. package/dist/utils/index.d.ts.map +0 -1
  92. package/dist/utils/preference-trigger.d.ts.map +0 -1
  93. package/dist/version.d.ts +0 -2
  94. package/dist/version.d.ts.map +0 -1
  95. package/tsconfig.json +0 -12
package/dist/react.cjs CHANGED
@@ -261,21 +261,21 @@ var __webpack_modules__ = {
261
261
  module.id,
262
262
  `.toggle-bPZtik {
263
263
  border-radius: var(--c15t-radius-full, 9999px);
264
- background-color: var(--c15t-switch-track, #ccc);
264
+ background-color: var(--c15t-switch-track, #d9d9d9);
265
265
  cursor: pointer;
266
- width: 36px;
267
- height: 20px;
268
- transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
266
+ width: 2rem;
267
+ height: 1.25rem;
268
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
269
269
  border: none;
270
270
  align-items: center;
271
- padding: 0;
271
+ padding: .125rem;
272
272
  display: inline-flex;
273
273
  position: relative;
274
274
  }
275
275
 
276
276
  .toggle-bPZtik:focus-visible {
277
- outline: 2px solid var(--c15t-primary, #335cff);
278
- outline-offset: 2px;
277
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
278
+ outline: none;
279
279
  }
280
280
 
281
281
  .toggleActive-Ldlasg {
@@ -285,16 +285,16 @@ var __webpack_modules__ = {
285
285
  .toggleThumb-hjGfoX {
286
286
  border-radius: var(--c15t-radius-full, 9999px);
287
287
  background-color: var(--c15t-switch-thumb, #fff);
288
- width: 16px;
289
- height: 16px;
290
- transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing-spring, cubic-bezier(.34, 1.56, .64, 1));
288
+ width: .75rem;
289
+ height: .75rem;
290
+ box-shadow: 0 0 0 1px var(--c15t-border, #e3e3e3);
291
+ transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
291
292
  position: absolute;
292
293
  left: 2px;
293
- box-shadow: 0 1px 2px #0003;
294
294
  }
295
295
 
296
296
  .toggleActive-Ldlasg .toggleThumb-hjGfoX {
297
- transform: translateX(16px);
297
+ transform: translateX(1rem);
298
298
  }
299
299
 
300
300
  .toggle-bPZtik:disabled, .toggleDisabled-ZcD8nZ {
@@ -307,13 +307,14 @@ var __webpack_modules__ = {
307
307
  }
308
308
 
309
309
  .badge-yA0giZ {
310
- border-radius: var(--c15t-radius-sm, .25rem);
310
+ border-radius: var(--c15t-radius-full, 9999px);
311
311
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
312
312
  font-weight: var(--c15t-font-weight-medium, 500);
313
+ line-height: var(--c15t-line-height-tight, 1.25);
313
314
  white-space: nowrap;
315
+ justify-content: center;
314
316
  align-items: center;
315
- padding: 2px 6px;
316
- line-height: 1;
317
+ padding: .1875rem .4375rem;
317
318
  display: inline-flex;
318
319
  }
319
320
 
@@ -346,35 +347,36 @@ var __webpack_modules__ = {
346
347
  justify-content: center;
347
348
  align-items: center;
348
349
  gap: var(--c15t-space-xs, .25rem);
349
- border: 1px solid var(--c15t-border, #e3e3e3);
350
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
350
351
  border-radius: var(--c15t-radius-md, .5rem);
351
- background-color: var(--c15t-surface, #fff);
352
- min-height: 30px;
352
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
353
+ min-height: 2rem;
353
354
  color: var(--c15t-text, #171717);
354
- font-family: inherit;
355
- font-size: 12px;
355
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
356
+ font-size: var(--c15t-font-size-sm, .875rem);
356
357
  font-weight: var(--c15t-font-weight-medium, 500);
358
+ line-height: var(--c15t-line-height-tight, 1.25);
359
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
357
360
  cursor: pointer;
358
361
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
359
- padding: 5px 10px;
360
- line-height: 1;
362
+ padding: .375rem .625rem;
361
363
  display: inline-flex;
362
- box-shadow: 0 1px 1px #0000000a;
363
364
  }
364
365
 
365
366
  .btn-evRVlh:hover {
366
- background-color: var(--c15t-surface-hover, #f7f7f7);
367
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
367
368
  border-color: var(--c15t-border-hover, #c9c9c9);
368
- box-shadow: 0 2px 6px #00000014;
369
+ box-shadow: var(--c15t-shadow-md, 0 4px 12px #00000014);
369
370
  }
370
371
 
371
372
  .btn-evRVlh:focus-visible {
372
- outline: 2px solid var(--c15t-primary, #335cff);
373
- outline-offset: 1px;
373
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d), 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
374
+ outline: none;
374
375
  }
375
376
 
376
377
  .btn-evRVlh:active {
377
- box-shadow: 0 1px 2px #00000014;
378
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
379
+ transform: scale(.98);
378
380
  }
379
381
 
380
382
  .btn-evRVlh:disabled {
@@ -387,6 +389,7 @@ var __webpack_modules__ = {
387
389
  background-color: var(--c15t-primary, #335cff);
388
390
  border-color: var(--c15t-primary, #335cff);
389
391
  color: var(--c15t-text-on-primary, #fff);
392
+ box-shadow: none;
390
393
  }
391
394
 
392
395
  .btnPrimary-dA6nqY:hover {
@@ -398,6 +401,7 @@ var __webpack_modules__ = {
398
401
  background-color: var(--c15t-devtools-badge-error, #ef4343);
399
402
  border-color: var(--c15t-devtools-badge-error, #ef4343);
400
403
  color: var(--c15t-text-on-primary, #fff);
404
+ box-shadow: none;
401
405
  }
402
406
 
403
407
  .btnDanger-eDnqOX:hover {
@@ -406,10 +410,10 @@ var __webpack_modules__ = {
406
410
  }
407
411
 
408
412
  .btnSmall-TjXoqZ {
413
+ min-height: 1.75rem;
414
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
409
415
  border-radius: var(--c15t-radius-sm, .375rem);
410
- min-height: 26px;
411
- padding: 3px 8px;
412
- font-size: 11px;
416
+ padding: .25rem .5rem;
413
417
  }
414
418
 
415
419
  .btnIcon-fiYQAh {
@@ -419,19 +423,22 @@ var __webpack_modules__ = {
419
423
  }
420
424
 
421
425
  .input-IeTcCs {
422
- width: 100%;
423
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
424
- border: 1px solid var(--c15t-border, #e3e3e3);
426
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
425
427
  border-radius: var(--c15t-radius-md, .5rem);
426
- background-color: var(--c15t-surface, #fff);
428
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
429
+ width: 100%;
430
+ min-height: 2rem;
427
431
  color: var(--c15t-text, #171717);
428
- font-family: inherit;
429
- font-size: var(--c15t-font-size-sm, .875rem);
430
- transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
432
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
433
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
434
+ line-height: var(--c15t-line-height-tight, 1.25);
435
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
436
+ padding: .375rem .625rem;
431
437
  }
432
438
 
433
439
  .input-IeTcCs:focus {
434
- border-color: var(--c15t-primary, #335cff);
440
+ border-color: var(--c15t-devtools-focus-ring, #335cff);
441
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--c15t-devtools-focus-ring, #335cff) 25%, transparent);
435
442
  outline: none;
436
443
  }
437
444
 
@@ -440,30 +447,35 @@ var __webpack_modules__ = {
440
447
  }
441
448
 
442
449
  .inputSmall-pJyXcL {
443
- padding: 2px var(--c15t-space-xs, .25rem);
450
+ min-height: 1.625rem;
444
451
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
452
+ padding: .25rem .4375rem;
445
453
  }
446
454
 
447
455
  .select-byJ1WM {
448
- width: 100%;
449
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
450
- border: 1px solid var(--c15t-border, #e3e3e3);
456
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
451
457
  border-radius: var(--c15t-radius-md, .5rem);
452
- background-color: var(--c15t-surface, #fff);
458
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
459
+ width: 100%;
460
+ min-height: 2rem;
453
461
  color: var(--c15t-text, #171717);
454
- font-family: inherit;
462
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
455
463
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
464
+ line-height: var(--c15t-line-height-tight, 1.25);
456
465
  cursor: pointer;
466
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
467
+ padding: .375rem .625rem;
457
468
  }
458
469
 
459
470
  .select-byJ1WM:focus {
460
- border-color: var(--c15t-primary, #335cff);
471
+ border-color: var(--c15t-devtools-focus-ring, #335cff);
472
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--c15t-devtools-focus-ring, #335cff) 25%, transparent);
461
473
  outline: none;
462
474
  }
463
475
 
464
476
  .grid-LlrmEz {
465
477
  gap: var(--c15t-space-sm, .5rem);
466
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
478
+ padding: var(--c15t-space-md, 1rem);
467
479
  display: grid;
468
480
  }
469
481
 
@@ -476,42 +488,51 @@ var __webpack_modules__ = {
476
488
  }
477
489
 
478
490
  .gridCard-Qm5xxI {
479
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, .75rem);
480
- border: 1px solid var(--c15t-border, #e3e3e3);
481
- border-radius: var(--c15t-radius-md, .5rem);
482
- background-color: var(--c15t-surface, #fff);
483
- transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
484
491
  justify-content: space-between;
485
492
  align-items: center;
493
+ gap: var(--c15t-space-sm, .5rem);
494
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
495
+ border-radius: var(--c15t-radius-md, .5rem);
496
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
497
+ min-height: 2.75rem;
498
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
499
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
500
+ padding: .5625rem .75rem;
486
501
  display: flex;
487
502
  }
488
503
 
489
504
  .gridCard-Qm5xxI:hover {
490
505
  border-color: var(--c15t-border-hover, #c9c9c9);
506
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
491
507
  }
492
508
 
493
509
  .gridCardTitle-HjXETp {
494
510
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
495
511
  font-weight: var(--c15t-font-weight-medium, 500);
496
512
  color: var(--c15t-text, #171717);
513
+ line-height: var(--c15t-line-height-tight, 1.25);
497
514
  }
498
515
 
499
516
  .listItem-XUKGIo {
500
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-md, 1rem);
501
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
502
517
  justify-content: space-between;
503
518
  align-items: center;
519
+ gap: var(--c15t-space-sm, .5rem);
520
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
521
+ border-radius: var(--c15t-radius-md, .5rem);
522
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
523
+ margin-bottom: .375rem;
524
+ padding: .625rem .75rem;
504
525
  display: flex;
505
526
  }
506
527
 
507
528
  .listItem-XUKGIo:last-child {
508
- border-bottom: none;
529
+ margin-bottom: 0;
509
530
  }
510
531
 
511
532
  .listItemContent-WDBF1N {
512
533
  flex-direction: column;
513
534
  flex: 1;
514
- gap: 2px;
535
+ gap: .1875rem;
515
536
  min-width: 0;
516
537
  display: flex;
517
538
  }
@@ -525,6 +546,7 @@ var __webpack_modules__ = {
525
546
  .listItemDescription-E6JHyZ {
526
547
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
527
548
  color: var(--c15t-text-muted, #737373);
549
+ line-height: var(--c15t-line-height-tight, 1.25);
528
550
  text-overflow: ellipsis;
529
551
  white-space: nowrap;
530
552
  overflow: hidden;
@@ -538,8 +560,8 @@ var __webpack_modules__ = {
538
560
  }
539
561
 
540
562
  .section-a197cB {
541
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
542
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
563
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
564
+ padding: .75rem 1rem;
543
565
  }
544
566
 
545
567
  .section-a197cB:last-child {
@@ -547,9 +569,10 @@ var __webpack_modules__ = {
547
569
  }
548
570
 
549
571
  .sectionHeader-Xcljcw {
550
- margin-bottom: var(--c15t-space-sm, .5rem);
551
572
  justify-content: space-between;
552
573
  align-items: center;
574
+ gap: .5rem;
575
+ margin-bottom: .625rem;
553
576
  display: flex;
554
577
  }
555
578
 
@@ -558,47 +581,49 @@ var __webpack_modules__ = {
558
581
  font-weight: var(--c15t-font-weight-semibold, 600);
559
582
  color: var(--c15t-text-muted, #737373);
560
583
  text-transform: uppercase;
561
- letter-spacing: .5px;
584
+ letter-spacing: .04em;
562
585
  }
563
586
 
564
587
  .overrideField-keNdpJ {
565
588
  flex-direction: column;
566
- gap: 3px;
589
+ gap: .3125rem;
567
590
  margin-bottom: 0;
568
591
  display: flex;
569
592
  }
570
593
 
571
594
  .overrideLabel-ApMoTw {
595
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
596
+ font-weight: var(--c15t-font-weight-semibold, 600);
572
597
  color: var(--c15t-text-muted, #737373);
573
- font-size: 11px;
574
- font-weight: 600;
598
+ line-height: var(--c15t-line-height-tight, 1.25);
575
599
  }
576
600
 
577
601
  .overrideHint-yCfwGt {
578
- color: var(--c15t-devtools-text-muted, #737373);
579
- margin-top: 6px;
580
- font-size: 11px;
602
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
603
+ color: var(--c15t-text-muted, #737373);
604
+ line-height: var(--c15t-line-height-tight, 1.25);
605
+ margin-top: .5rem;
581
606
  }
582
607
 
583
608
  .overrideActions-imdcn7 {
584
- border-top: 1px dashed var(--c15t-border, #e3e3e3);
609
+ border-top: 1px dashed var(--c15t-devtools-border-strong, #e3e3e3);
585
610
  justify-content: space-between;
586
611
  align-items: center;
587
- gap: 8px;
588
- margin-top: 8px;
589
- padding-top: 8px;
612
+ gap: .5rem;
613
+ margin-top: .625rem;
614
+ padding-top: .625rem;
590
615
  display: flex;
591
616
  }
592
617
 
593
618
  .overrideActionButtons-gYOx1e {
594
619
  flex-wrap: wrap;
595
- gap: 6px;
620
+ gap: .375rem;
596
621
  display: flex;
597
622
  }
598
623
 
599
624
  .overrideStatus-sty_qS {
625
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
600
626
  color: var(--c15t-text-muted, #737373);
601
- font-size: 11px;
602
627
  }
603
628
 
604
629
  .overrideStatusDirty-OUdDMw {
@@ -606,9 +631,10 @@ var __webpack_modules__ = {
606
631
  }
607
632
 
608
633
  .infoRow-RlB_0h {
609
- padding: var(--c15t-space-xs, .25rem) 0;
610
634
  justify-content: space-between;
611
635
  align-items: center;
636
+ gap: .5rem;
637
+ padding: .25rem 0;
612
638
  display: flex;
613
639
  }
614
640
 
@@ -621,6 +647,7 @@ var __webpack_modules__ = {
621
647
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
622
648
  font-weight: var(--c15t-font-weight-medium, 500);
623
649
  color: var(--c15t-text, #171717);
650
+ font-variant-numeric: tabular-nums;
624
651
  font-family: ui-monospace, Cascadia Code, Source Code Pro, Menlo, Consolas, DejaVu Sans Mono, monospace;
625
652
  }
626
653
 
@@ -631,18 +658,27 @@ var __webpack_modules__ = {
631
658
  flex-direction: column;
632
659
  justify-content: center;
633
660
  align-items: center;
661
+ gap: .375rem;
634
662
  display: flex;
635
663
  }
636
664
 
637
665
  .emptyStateIcon-WHFkX8 {
666
+ opacity: .55;
638
667
  width: 32px;
639
668
  height: 32px;
640
- margin-bottom: var(--c15t-space-sm, .5rem);
641
- opacity: .5;
642
669
  }
643
670
 
644
671
  .emptyStateText-TaLvAJ {
645
672
  font-size: var(--c15t-font-size-sm, .875rem);
673
+ line-height: var(--c15t-line-height-normal, 1.5);
674
+ }
675
+
676
+ .disconnectedState-dOtZBG {
677
+ padding: var(--c15t-space-xl, 2rem);
678
+ text-align: center;
679
+ font-size: var(--c15t-font-size-sm, .875rem);
680
+ color: var(--c15t-text-muted, #737373);
681
+ line-height: var(--c15t-line-height-normal, 1.5);
646
682
  }
647
683
 
648
684
  @media (prefers-reduced-motion: reduce) {
@@ -709,7 +745,8 @@ var __webpack_modules__ = {
709
745
  infoValue: "infoValue-flMl_e",
710
746
  emptyState: "emptyState-QcmzTQ",
711
747
  emptyStateIcon: "emptyStateIcon-WHFkX8",
712
- emptyStateText: "emptyStateText-TaLvAJ"
748
+ emptyStateText: "emptyStateText-TaLvAJ",
749
+ disconnectedState: "disconnectedState-dOtZBG"
713
750
  };
714
751
  const __rspack_default_export = ___CSS_LOADER_EXPORT___;
715
752
  },
@@ -738,9 +775,9 @@ var __webpack_modules__ = {
738
775
  .floatingButton-Gw8MtJ {
739
776
  width: var(--c15t-devtools-button-size, 40px);
740
777
  height: var(--c15t-devtools-button-size, 40px);
741
- border: 1px solid var(--c15t-border, #e3e3e3);
778
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
742
779
  border-radius: var(--c15t-radius-full, 9999px);
743
- background-color: var(--c15t-surface, #fff);
780
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
744
781
  box-shadow: var(--c15t-shadow-lg, 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a);
745
782
  cursor: grab;
746
783
  z-index: var(--c15t-devtools-z-index, 99999);
@@ -768,13 +805,13 @@ var __webpack_modules__ = {
768
805
  }
769
806
 
770
807
  .floatingButton-Gw8MtJ:focus-visible {
771
- outline: 2px solid var(--c15t-primary, #335cff);
772
- outline-offset: 2px;
808
+ box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f), 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
809
+ outline: none;
773
810
  }
774
811
 
775
812
  .floatingButton-Gw8MtJ:active {
776
813
  cursor: grabbing;
777
- transform: scale(1.02);
814
+ transform: scale(.98);
778
815
  }
779
816
 
780
817
  .floatingButtonIcon-cHWefk {
@@ -815,6 +852,7 @@ var __webpack_modules__ = {
815
852
 
816
853
  .backdrop-LhVMB5 {
817
854
  background-color: var(--c15t-overlay, #00000080);
855
+ backdrop-filter: blur(1px);
818
856
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 1);
819
857
  position: fixed;
820
858
  inset: 0;
@@ -823,10 +861,10 @@ var __webpack_modules__ = {
823
861
  .panel-jtWove {
824
862
  width: var(--c15t-devtools-panel-width, 480px);
825
863
  max-height: var(--c15t-devtools-panel-max-height, 560px);
826
- background-color: var(--c15t-surface, #fff);
827
- border: 1px solid var(--c15t-border, #e3e3e3);
864
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
865
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
828
866
  border-radius: var(--c15t-radius-lg, .75rem);
829
- box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f);
867
+ box-shadow: var(--c15t-shadow-lg, 0 10px 28px #00000029);
830
868
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 2);
831
869
  flex-direction: column;
832
870
  display: flex;
@@ -859,11 +897,11 @@ var __webpack_modules__ = {
859
897
  }
860
898
 
861
899
  .header-xluoTr {
862
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
863
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
900
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
864
901
  background-color: var(--c15t-devtools-surface-muted, #f5f5f5);
865
902
  justify-content: space-between;
866
903
  align-items: center;
904
+ padding: .6875rem .875rem;
867
905
  display: flex;
868
906
  }
869
907
 
@@ -872,6 +910,7 @@ var __webpack_modules__ = {
872
910
  gap: var(--c15t-space-sm, .5rem);
873
911
  font-size: var(--c15t-font-size-sm, .875rem);
874
912
  font-weight: var(--c15t-font-weight-semibold, 600);
913
+ line-height: var(--c15t-line-height-tight, 1.25);
875
914
  color: var(--c15t-text, #171717);
876
915
  display: flex;
877
916
  }
@@ -883,9 +922,9 @@ var __webpack_modules__ = {
883
922
  }
884
923
 
885
924
  .closeButton-Yto0Nb {
886
- border-radius: var(--c15t-radius-sm, .25rem);
887
- width: 28px;
888
- height: 28px;
925
+ border-radius: var(--c15t-radius-md, .5rem);
926
+ width: 2rem;
927
+ height: 2rem;
889
928
  color: var(--c15t-text-muted, #737373);
890
929
  cursor: pointer;
891
930
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
@@ -898,13 +937,13 @@ var __webpack_modules__ = {
898
937
  }
899
938
 
900
939
  .closeButton-Yto0Nb:hover {
901
- background-color: var(--c15t-surface-hover, #f7f7f7);
940
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
902
941
  color: var(--c15t-text, #171717);
903
942
  }
904
943
 
905
944
  .closeButton-Yto0Nb:focus-visible {
906
- outline: 2px solid var(--c15t-primary, #335cff);
907
- outline-offset: 1px;
945
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
946
+ outline: none;
908
947
  }
909
948
 
910
949
  .closeButtonIcon-fVlR1I {
@@ -912,33 +951,71 @@ var __webpack_modules__ = {
912
951
  height: 16px;
913
952
  }
914
953
 
954
+ .inlineActionButton-Ky8BmN {
955
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
956
+ border-radius: var(--c15t-radius-sm, .375rem);
957
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
958
+ min-height: 1.625rem;
959
+ color: var(--c15t-text, #171717);
960
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
961
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
962
+ font-weight: var(--c15t-font-weight-medium, 500);
963
+ line-height: var(--c15t-line-height-tight, 1.25);
964
+ cursor: pointer;
965
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
966
+ justify-content: center;
967
+ align-items: center;
968
+ padding: .25rem .5rem;
969
+ display: inline-flex;
970
+ }
971
+
972
+ .inlineActionButton-Ky8BmN:hover {
973
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
974
+ border-color: var(--c15t-border-hover, #c9c9c9);
975
+ }
976
+
977
+ .inlineActionButton-Ky8BmN:focus-visible {
978
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
979
+ outline: none;
980
+ }
981
+
915
982
  .content-yDMYfG {
983
+ scrollbar-gutter: stable;
916
984
  overscroll-behavior: contain;
917
985
  -webkit-overflow-scrolling: touch;
986
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
918
987
  flex: auto;
919
988
  min-height: 200px;
920
- overflow: hidden auto;
989
+ overflow: hidden scroll;
921
990
  }
922
991
 
923
992
  .footer-ESbmwQ {
924
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-md, 1rem);
925
- border-top: 1px solid var(--c15t-border, #e3e3e3);
993
+ border-top: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
926
994
  background-color: var(--c15t-devtools-surface-muted, #f5f5f5);
927
995
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
928
996
  color: var(--c15t-text-muted, #737373);
929
997
  justify-content: space-between;
930
998
  align-items: center;
999
+ gap: .5rem;
1000
+ padding: .5rem .75rem;
931
1001
  display: flex;
932
1002
  }
933
1003
 
934
1004
  .footerStatus-rlb99A {
935
1005
  align-items: center;
936
- gap: var(--c15t-space-xs, .25rem);
1006
+ gap: .375rem;
1007
+ min-width: 0;
937
1008
  display: flex;
938
1009
  }
939
1010
 
1011
+ .footerMeta-Vdtxdk {
1012
+ opacity: .75;
1013
+ white-space: nowrap;
1014
+ }
1015
+
940
1016
  .statusDot-hYJoej {
941
1017
  border-radius: var(--c15t-radius-full, 9999px);
1018
+ flex-shrink: 0;
942
1019
  width: 6px;
943
1020
  height: 6px;
944
1021
  }
@@ -977,6 +1054,7 @@ var __webpack_modules__ = {
977
1054
  font-size: var(--c15t-font-size-sm, .875rem);
978
1055
  color: var(--c15t-text-muted, #737373);
979
1056
  max-width: 280px;
1057
+ line-height: var(--c15t-line-height-normal, 1.5);
980
1058
  }
981
1059
 
982
1060
  @media (prefers-reduced-motion: reduce) {
@@ -993,17 +1071,17 @@ var __webpack_modules__ = {
993
1071
  }
994
1072
 
995
1073
  .dropdownMenu-aKK18l {
996
- min-width: 200px;
997
- padding: var(--c15t-space-xs, .25rem);
998
- border: 1px solid var(--c15t-border, #e3e3e3);
1074
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
999
1075
  border-radius: var(--c15t-radius-lg, .75rem);
1000
- background-color: var(--c15t-surface, #fff);
1076
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1077
+ min-width: 200px;
1001
1078
  box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f);
1002
1079
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 1);
1003
1080
  opacity: 0;
1004
1081
  transform-origin: 0 100%;
1005
1082
  pointer-events: none;
1006
1083
  transition: opacity var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1)), transform var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1));
1084
+ padding: .375rem;
1007
1085
  position: fixed;
1008
1086
  transform: scale(.95)translateY(8px);
1009
1087
  }
@@ -1031,34 +1109,35 @@ var __webpack_modules__ = {
1031
1109
  }
1032
1110
 
1033
1111
  .menuItem-kBbHRP {
1034
- align-items: center;
1035
- gap: var(--c15t-space-sm, .5rem);
1036
- width: 100%;
1037
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, .75rem);
1038
1112
  border-radius: var(--c15t-radius-md, .5rem);
1113
+ width: 100%;
1039
1114
  color: var(--c15t-text, #171717);
1040
- font-size: var(--c15t-font-size-sm, .875rem);
1115
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1041
1116
  font-weight: var(--c15t-font-weight-medium, 500);
1117
+ line-height: var(--c15t-line-height-tight, 1.25);
1042
1118
  text-align: left;
1043
1119
  cursor: pointer;
1044
1120
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1045
1121
  background: none;
1046
1122
  border: none;
1123
+ align-items: center;
1124
+ gap: .625rem;
1125
+ padding: .5rem .625rem;
1047
1126
  display: flex;
1048
1127
  }
1049
1128
 
1050
1129
  .menuItem-kBbHRP:hover {
1051
- background-color: var(--c15t-surface-hover, #f2f2f2);
1130
+ background-color: var(--c15t-devtools-surface-subtle, #f2f2f2);
1052
1131
  }
1053
1132
 
1054
1133
  .menuItem-kBbHRP:focus-visible {
1055
- outline: 2px solid var(--c15t-primary, #335cff);
1056
- outline-offset: -2px;
1134
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1135
+ outline: none;
1057
1136
  }
1058
1137
 
1059
1138
  .menuItemIcon-P3pP5K {
1060
- width: 20px;
1061
- height: 20px;
1139
+ width: 1rem;
1140
+ height: 1rem;
1062
1141
  color: var(--c15t-text-muted, #737373);
1063
1142
  flex-shrink: 0;
1064
1143
  }
@@ -1071,6 +1150,7 @@ var __webpack_modules__ = {
1071
1150
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
1072
1151
  color: var(--c15t-text-muted, #737373);
1073
1152
  font-weight: var(--c15t-font-weight-normal, 400);
1153
+ margin-top: .125rem;
1074
1154
  }
1075
1155
 
1076
1156
  .menuItemContent-hBlruV {
@@ -1086,8 +1166,8 @@ var __webpack_modules__ = {
1086
1166
  .menuItemToggleTrack-gDp_f3 {
1087
1167
  background-color: var(--c15t-switch-track, #d9d9d9);
1088
1168
  border-radius: var(--c15t-radius-full, 9999px);
1089
- width: 36px;
1090
- height: 20px;
1169
+ width: 2rem;
1170
+ height: 1.25rem;
1091
1171
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1092
1172
  position: relative;
1093
1173
  }
@@ -1095,21 +1175,22 @@ var __webpack_modules__ = {
1095
1175
  .menuItemToggleThumb-ioqqyc {
1096
1176
  background-color: var(--c15t-switch-thumb, #fff);
1097
1177
  border-radius: var(--c15t-radius-full, 9999px);
1098
- width: 16px;
1099
- height: 16px;
1100
- box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000001a);
1178
+ width: .75rem;
1179
+ height: .75rem;
1180
+ box-shadow: 0 0 0 1px var(--c15t-border, #e3e3e3);
1101
1181
  transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1102
1182
  position: absolute;
1103
- top: 2px;
1183
+ top: 50%;
1104
1184
  left: 2px;
1185
+ transform: translateY(-50%);
1105
1186
  }
1106
1187
 
1107
1188
  .menuItemToggleChecked-K3BPtk .menuItemToggleTrack-gDp_f3 {
1108
- background-color: var(--c15t-switch-track-checked, #335cff);
1189
+ background-color: var(--c15t-switch-track-active, #335cff);
1109
1190
  }
1110
1191
 
1111
1192
  .menuItemToggleChecked-K3BPtk .menuItemToggleThumb-ioqqyc {
1112
- transform: translateX(16px);
1193
+ transform: translate(1rem, -50%);
1113
1194
  }
1114
1195
 
1115
1196
  .menuDivider-JIBdhU {
@@ -1145,9 +1226,11 @@ var __webpack_modules__ = {
1145
1226
  headerLogo: "headerLogo-PxJ_w1",
1146
1227
  closeButton: "closeButton-Yto0Nb",
1147
1228
  closeButtonIcon: "closeButtonIcon-fVlR1I",
1229
+ inlineActionButton: "inlineActionButton-Ky8BmN",
1148
1230
  content: "content-yDMYfG",
1149
1231
  footer: "footer-ESbmwQ",
1150
1232
  footerStatus: "footerStatus-rlb99A",
1233
+ footerMeta: "footerMeta-Vdtxdk",
1151
1234
  statusDot: "statusDot-hYJoej",
1152
1235
  statusConnected: "statusConnected-hPSUgS",
1153
1236
  statusDisconnected: "statusDisconnected-HIpcee",
@@ -1186,62 +1269,63 @@ var __webpack_modules__ = {
1186
1269
  ___CSS_LOADER_EXPORT___.push([
1187
1270
  module.id,
1188
1271
  `.tabList-IyuiBE {
1272
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
1273
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
1189
1274
  align-items: center;
1190
- gap: var(--c15t-space-xs, .25rem);
1191
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-sm, .5rem);
1192
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
1193
- background-color: var(--c15t-surface, #fff);
1194
- scrollbar-width: none;
1195
- -ms-overflow-style: none;
1196
- scroll-padding-inline-end: var(--c15t-space-sm, .5rem);
1275
+ gap: .375rem;
1276
+ padding: .75rem;
1197
1277
  display: flex;
1198
- overflow-x: auto;
1199
1278
  }
1200
1279
 
1201
- .tabList-IyuiBE:after {
1202
- content: "";
1203
- flex: 0 0 var(--c15t-space-sm, .5rem);
1204
- }
1205
-
1206
- .tabList-IyuiBE::-webkit-scrollbar {
1207
- display: none;
1280
+ .tabStrip-_KrWe4 {
1281
+ align-items: center;
1282
+ gap: var(--c15t-space-xs, .25rem);
1283
+ flex: auto;
1284
+ min-width: 0;
1285
+ display: flex;
1286
+ overflow: hidden;
1208
1287
  }
1209
1288
 
1210
1289
  .tab-yfDEqg {
1211
- align-items: center;
1212
- gap: var(--c15t-space-xs, .25rem);
1213
1290
  border-radius: var(--c15t-radius-md, .5rem);
1291
+ min-height: 1.875rem;
1214
1292
  color: var(--c15t-text-muted, #737373);
1215
- font-family: inherit;
1216
- font-size: 11px;
1293
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
1294
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1217
1295
  font-weight: var(--c15t-font-weight-medium, 500);
1296
+ line-height: var(--c15t-line-height-tight, 1.25);
1218
1297
  cursor: pointer;
1219
1298
  white-space: nowrap;
1220
- transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1299
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1221
1300
  background-color: #0000;
1222
- border: none;
1223
- padding: 3px 7px;
1301
+ border: 1px solid #0000;
1302
+ flex-shrink: 0;
1303
+ align-items: center;
1304
+ gap: .375rem;
1305
+ padding: .25rem .625rem;
1224
1306
  display: flex;
1225
1307
  }
1226
1308
 
1227
1309
  .tab-yfDEqg:hover {
1228
- background-color: var(--c15t-surface-hover, #f7f7f7);
1310
+ background-color: var(--c15t-devtools-surface-muted, #f7f7f7);
1229
1311
  color: var(--c15t-text, #171717);
1230
1312
  }
1231
1313
 
1232
1314
  .tab-yfDEqg:focus-visible {
1233
- outline: 2px solid var(--c15t-primary, #335cff);
1234
- outline-offset: 1px;
1315
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1316
+ outline: none;
1235
1317
  }
1236
1318
 
1237
1319
  .tabActive-r4hing {
1238
- background-color: var(--c15t-primary, #335cff);
1239
- color: var(--c15t-text-on-primary, #fff);
1320
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1321
+ border-color: var(--c15t-devtools-border-strong, #e3e3e3);
1322
+ color: var(--c15t-text, #171717);
1323
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
1240
1324
  }
1241
1325
 
1242
1326
  .tabActive-r4hing:hover {
1243
- background-color: var(--c15t-primary-hover, #03f);
1244
- color: var(--c15t-text-on-primary, #fff);
1327
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1328
+ color: var(--c15t-text, #171717);
1245
1329
  }
1246
1330
 
1247
1331
  .tabIcon-U9tnu0 {
@@ -1250,6 +1334,131 @@ var __webpack_modules__ = {
1250
1334
  height: 14px;
1251
1335
  }
1252
1336
 
1337
+ .tabHidden-HBXYSd {
1338
+ display: none;
1339
+ }
1340
+
1341
+ .overflowContainer-TTw9DO {
1342
+ flex-shrink: 0;
1343
+ position: relative;
1344
+ }
1345
+
1346
+ .overflowContainerHidden-sQa_XZ {
1347
+ display: none;
1348
+ }
1349
+
1350
+ .overflowButton-tKq4FF {
1351
+ border-radius: var(--c15t-radius-md, .5rem);
1352
+ width: 1.875rem;
1353
+ height: 1.875rem;
1354
+ color: var(--c15t-text-muted, #737373);
1355
+ cursor: pointer;
1356
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1357
+ background-color: #0000;
1358
+ border: 1px solid #0000;
1359
+ justify-content: center;
1360
+ align-items: center;
1361
+ padding: 0;
1362
+ display: inline-flex;
1363
+ }
1364
+
1365
+ .overflowButton-tKq4FF:hover {
1366
+ background-color: var(--c15t-devtools-surface-muted, #f7f7f7);
1367
+ color: var(--c15t-text, #171717);
1368
+ }
1369
+
1370
+ .overflowButton-tKq4FF:focus-visible {
1371
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1372
+ outline: none;
1373
+ }
1374
+
1375
+ .overflowButtonIcon-FSurfC {
1376
+ justify-content: center;
1377
+ align-items: center;
1378
+ width: 14px;
1379
+ height: 14px;
1380
+ display: inline-flex;
1381
+ }
1382
+
1383
+ .overflowMenu-TST0eZ {
1384
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
1385
+ border-radius: var(--c15t-radius-md, .5rem);
1386
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1387
+ min-width: 10rem;
1388
+ box-shadow: var(--c15t-shadow-md, 0 4px 12px #00000014);
1389
+ opacity: 0;
1390
+ transform-origin: 100% 0;
1391
+ pointer-events: none;
1392
+ z-index: 10;
1393
+ transition: opacity var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1)), transform var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1));
1394
+ flex-direction: column;
1395
+ gap: .125rem;
1396
+ padding: .3125rem;
1397
+ display: flex;
1398
+ position: absolute;
1399
+ top: calc(100% + .375rem);
1400
+ right: 0;
1401
+ transform: translateY(-4px)scale(.98);
1402
+ }
1403
+
1404
+ .overflowMenu-TST0eZ[data-state="open"] {
1405
+ opacity: 1;
1406
+ pointer-events: auto;
1407
+ transform: translateY(0)scale(1);
1408
+ }
1409
+
1410
+ .overflowItem-y5Pz7k {
1411
+ border-radius: var(--c15t-radius-sm, .375rem);
1412
+ min-height: 1.75rem;
1413
+ color: var(--c15t-text, #171717);
1414
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
1415
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1416
+ font-weight: var(--c15t-font-weight-medium, 500);
1417
+ line-height: var(--c15t-line-height-tight, 1.25);
1418
+ text-align: left;
1419
+ cursor: pointer;
1420
+ white-space: nowrap;
1421
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1422
+ background-color: #0000;
1423
+ border: none;
1424
+ align-items: center;
1425
+ gap: .5rem;
1426
+ padding: .3125rem .5rem;
1427
+ display: inline-flex;
1428
+ }
1429
+
1430
+ .overflowItem-y5Pz7k:hover {
1431
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
1432
+ }
1433
+
1434
+ .overflowItem-y5Pz7k:focus-visible {
1435
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1436
+ outline: none;
1437
+ }
1438
+
1439
+ .overflowItemActive-mzVG1T {
1440
+ background-color: var(--c15t-devtools-accent-soft, #ebefff);
1441
+ color: var(--c15t-text, #171717);
1442
+ }
1443
+
1444
+ .overflowItemDisabled-dcHX3K {
1445
+ opacity: .5;
1446
+ cursor: not-allowed;
1447
+ }
1448
+
1449
+ .overflowItemIcon-fz291V {
1450
+ flex-shrink: 0;
1451
+ justify-content: center;
1452
+ align-items: center;
1453
+ width: 14px;
1454
+ height: 14px;
1455
+ display: inline-flex;
1456
+ }
1457
+
1458
+ .overflowItemHidden-k4aawi {
1459
+ display: none;
1460
+ }
1461
+
1253
1462
  .tabDisabled-lDuv5l {
1254
1463
  opacity: .5;
1255
1464
  cursor: not-allowed;
@@ -1270,7 +1479,7 @@ var __webpack_modules__ = {
1270
1479
  }
1271
1480
 
1272
1481
  @media (prefers-reduced-motion: reduce) {
1273
- .tab-yfDEqg {
1482
+ .tab-yfDEqg, .overflowButton-tKq4FF, .overflowMenu-TST0eZ, .overflowItem-y5Pz7k {
1274
1483
  transition: none;
1275
1484
  }
1276
1485
  }
@@ -1286,9 +1495,21 @@ var __webpack_modules__ = {
1286
1495
  ]);
1287
1496
  ___CSS_LOADER_EXPORT___.locals = {
1288
1497
  tabList: "tabList-IyuiBE",
1498
+ tabStrip: "tabStrip-_KrWe4",
1289
1499
  tab: "tab-yfDEqg",
1290
1500
  tabActive: "tabActive-r4hing",
1291
1501
  tabIcon: "tabIcon-U9tnu0",
1502
+ tabHidden: "tabHidden-HBXYSd",
1503
+ overflowContainer: "overflowContainer-TTw9DO",
1504
+ overflowContainerHidden: "overflowContainerHidden-sQa_XZ",
1505
+ overflowButton: "overflowButton-tKq4FF",
1506
+ overflowButtonIcon: "overflowButtonIcon-FSurfC",
1507
+ overflowMenu: "overflowMenu-TST0eZ",
1508
+ overflowItem: "overflowItem-y5Pz7k",
1509
+ overflowItemActive: "overflowItemActive-mzVG1T",
1510
+ overflowItemDisabled: "overflowItemDisabled-dcHX3K",
1511
+ overflowItemIcon: "overflowItemIcon-fz291V",
1512
+ overflowItemHidden: "overflowItemHidden-k4aawi",
1292
1513
  tabDisabled: "tabDisabled-lDuv5l",
1293
1514
  tabPanel: "tabPanel-QKO8FX",
1294
1515
  tabPanelActive: "tabPanelActive-mrNlGE"
@@ -1312,6 +1533,15 @@ var __webpack_modules__ = {
1312
1533
  --c15t-devtools-button-size: 40px;
1313
1534
  --c15t-devtools-z-index: 99999;
1314
1535
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #f7f7f7);
1536
+ --c15t-devtools-surface-subtle: #fafafa;
1537
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #fff);
1538
+ --c15t-devtools-border-strong: var(--c15t-border, #e3e3e3);
1539
+ --c15t-devtools-code-surface: #f7f7f7;
1540
+ --c15t-devtools-accent-soft: #ebefff;
1541
+ --c15t-devtools-focus-ring: var(--c15t-primary, #335cff);
1542
+ --c15t-devtools-text-muted: var(--c15t-text-muted, #737373);
1543
+ --c15t-devtools-font-size-sm: var(--c15t-font-size-sm, .875rem);
1544
+ --c15t-surface-muted: var(--c15t-devtools-surface-muted, #f7f7f7);
1315
1545
  --c15t-devtools-font-size-xs: .75rem;
1316
1546
  --c15t-devtools-badge-success: #21c45d;
1317
1547
  --c15t-devtools-badge-success-bg: #e4fbed;
@@ -1325,8 +1555,37 @@ var __webpack_modules__ = {
1325
1555
  --c15t-devtools-badge-neutral-bg: #f0f0f0;
1326
1556
  }
1327
1557
 
1558
+ :is(:global(.c15t-light), :global(.light)) {
1559
+ --c15t-devtools-surface-muted: var(--c15t-surface-hover, #f7f7f7);
1560
+ --c15t-devtools-surface-subtle: #fafafa;
1561
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #fff);
1562
+ --c15t-devtools-border-strong: var(--c15t-border, #e3e3e3);
1563
+ --c15t-devtools-code-surface: #f7f7f7;
1564
+ --c15t-devtools-accent-soft: #ebefff;
1565
+ --c15t-devtools-badge-success-bg: #e4fbed;
1566
+ --c15t-devtools-badge-error-bg: #fde7e7;
1567
+ --c15t-devtools-badge-warning-bg: #fef7dc;
1568
+ --c15t-devtools-badge-info-bg: #dcebfe;
1569
+ --c15t-devtools-badge-neutral-bg: #f0f0f0;
1570
+ }
1571
+
1572
+ @supports (color: color-mix(in srgb, white, black)) {
1573
+ :root {
1574
+ --c15t-devtools-surface-muted: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 85%, var(--c15t-surface, #fff));
1575
+ --c15t-devtools-surface-subtle: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 55%, var(--c15t-surface, #fff));
1576
+ --c15t-devtools-border-strong: color-mix(in srgb, var(--c15t-border, #e3e3e3) 80%, var(--c15t-text-muted, #737373));
1577
+ --c15t-devtools-code-surface: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 70%, var(--c15t-surface, #fff));
1578
+ --c15t-devtools-accent-soft: color-mix(in srgb, var(--c15t-primary, #335cff) 12%, transparent);
1579
+ }
1580
+ }
1581
+
1328
1582
  :is(:global(.c15t-dark), :global(.dark)) {
1329
1583
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #292929);
1584
+ --c15t-devtools-surface-subtle: #242424;
1585
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #1a1a1a);
1586
+ --c15t-devtools-border-strong: var(--c15t-border, #3d3d3d);
1587
+ --c15t-devtools-code-surface: #212121;
1588
+ --c15t-devtools-accent-soft: #335cff33;
1330
1589
  --c15t-devtools-badge-success-bg: #21c45d33;
1331
1590
  --c15t-devtools-badge-error-bg: #ef434333;
1332
1591
  --c15t-devtools-badge-warning-bg: #f59f0a33;
@@ -1335,8 +1594,13 @@ var __webpack_modules__ = {
1335
1594
  }
1336
1595
 
1337
1596
  @media (prefers-color-scheme: dark) {
1338
- :root {
1597
+ :global(:root:not(.light):not(.c15t-light)) {
1339
1598
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #292929);
1599
+ --c15t-devtools-surface-subtle: #242424;
1600
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #1a1a1a);
1601
+ --c15t-devtools-border-strong: var(--c15t-border, #3d3d3d);
1602
+ --c15t-devtools-code-surface: #212121;
1603
+ --c15t-devtools-accent-soft: #335cff33;
1340
1604
  --c15t-devtools-badge-success-bg: #21c45d33;
1341
1605
  --c15t-devtools-badge-error-bg: #ef434333;
1342
1606
  --c15t-devtools-badge-warning-bg: #f59f0a33;
@@ -1862,7 +2126,7 @@ var __webpack_exports__ = {};
1862
2126
  type: options.type ?? 'button'
1863
2127
  });
1864
2128
  }
1865
- function span(options = {}) {
2129
+ function renderer_span(options = {}) {
1866
2130
  return createElement({
1867
2131
  ...options,
1868
2132
  tag: 'span'
@@ -1941,7 +2205,29 @@ var __webpack_exports__ = {};
1941
2205
  panel_module_options.insertStyleElement = insertStyleElement_default();
1942
2206
  injectStylesIntoStyleTag_default()(panel_module.A, panel_module_options);
1943
2207
  const styles_panel_module = panel_module.A && panel_module.A.locals ? panel_module.A.locals : void 0;
1944
- const PREFERENCE_TRIGGER_SELECTORS = '[data-c15t-trigger], [aria-label*="privacy settings"], [aria-label*="preference"]';
2208
+ function formatInitSource(source, detail) {
2209
+ const label = (()=>{
2210
+ switch(source){
2211
+ case 'ssr':
2212
+ return 'SSR Prefetch';
2213
+ case 'backend':
2214
+ return 'Backend';
2215
+ case 'backend-cache-hit':
2216
+ return 'Backend (Cache Hit)';
2217
+ case 'offline-fallback':
2218
+ return 'Offline Fallback';
2219
+ case 'offline-mode':
2220
+ return 'Offline Mode';
2221
+ case 'custom':
2222
+ return 'Custom Client';
2223
+ default:
2224
+ return '—';
2225
+ }
2226
+ })();
2227
+ return detail ? `${label} [${detail}]` : label;
2228
+ }
2229
+ const PREFERENCE_TRIGGER_SELECTORS = '[data-c15t-trigger], [aria-label*="privacy settings" i], [aria-label*="preference" i]';
2230
+ const PREVIOUS_DISPLAY_ATTR = 'data-c15t-devtools-prev-display';
1945
2231
  function detectPreferenceTrigger() {
1946
2232
  const triggers = document.querySelectorAll(PREFERENCE_TRIGGER_SELECTORS);
1947
2233
  return triggers.length > 0;
@@ -1951,7 +2237,19 @@ var __webpack_exports__ = {};
1951
2237
  }
1952
2238
  function setPreferenceTriggerVisibility(visible) {
1953
2239
  const elements = getPreferenceTriggerElements();
1954
- for (const el of elements)el.style.display = visible ? '' : 'none';
2240
+ for (const el of elements){
2241
+ if (visible) {
2242
+ const previousDisplay = el.getAttribute(PREVIOUS_DISPLAY_ATTR);
2243
+ if (null === previousDisplay) el.style.removeProperty('display');
2244
+ else {
2245
+ el.style.display = previousDisplay;
2246
+ el.removeAttribute(PREVIOUS_DISPLAY_ATTR);
2247
+ }
2248
+ continue;
2249
+ }
2250
+ if (!el.hasAttribute(PREVIOUS_DISPLAY_ATTR)) el.setAttribute(PREVIOUS_DISPLAY_ATTR, el.style.display);
2251
+ el.style.display = 'none';
2252
+ }
1955
2253
  }
1956
2254
  function getPreferenceCenterOpener(namespace = 'c15tStore') {
1957
2255
  const win = window;
@@ -1964,7 +2262,7 @@ var __webpack_exports__ = {};
1964
2262
  }
1965
2263
  return null;
1966
2264
  }
1967
- const version = '2.0.0-rc.3';
2265
+ const version = '2.0.0-rc.5';
1968
2266
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
1969
2267
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
1970
2268
  </svg>`;
@@ -2045,7 +2343,7 @@ var __webpack_exports__ = {};
2045
2343
  const labelContainer = renderer_div({
2046
2344
  className: styles_panel_module.menuItemContent ?? ''
2047
2345
  });
2048
- const label = span({
2346
+ const label = renderer_span({
2049
2347
  className: styles_panel_module.menuItemLabel ?? '',
2050
2348
  text: item.label
2051
2349
  });
@@ -2167,6 +2465,11 @@ var __webpack_exports__ = {};
2167
2465
  return styles_panel_module.positionTopLeft ?? '';
2168
2466
  }
2169
2467
  }
2468
+ function formatRetryDelay(delayMs) {
2469
+ if (null === delayMs) return 'n/a';
2470
+ if (delayMs < 1000) return `${delayMs}ms`;
2471
+ return `${(delayMs / 1000).toFixed(1)}s`;
2472
+ }
2170
2473
  function createPanel(options) {
2171
2474
  const { stateManager, storeConnector, onRenderContent, namespace = 'c15tStore', enableUnifiedMode = true } = options;
2172
2475
  let removePortal = null;
@@ -2298,7 +2601,7 @@ var __webpack_exports__ = {};
2298
2601
  }));
2299
2602
  return logoWrapper;
2300
2603
  })(),
2301
- span({
2604
+ renderer_span({
2302
2605
  text: 'c15t DevTools'
2303
2606
  })
2304
2607
  ]
@@ -2342,38 +2645,46 @@ var __webpack_exports__ = {};
2342
2645
  const isConnected = storeConnector.isConnected();
2343
2646
  const storeState = storeConnector.getState();
2344
2647
  const isLoading = storeState?.isLoadingConsentInfo ?? false;
2648
+ const diagnostics = storeConnector.getDiagnostics();
2649
+ const initSource = formatInitSource(storeState?.initDataSource ?? null, storeState?.initDataSourceDetail ?? null);
2345
2650
  const statusChildren = [
2346
- span({
2651
+ renderer_span({
2347
2652
  className: `${styles_panel_module.statusDot} ${isConnected ? styles_panel_module.statusConnected : styles_panel_module.statusDisconnected}`
2348
2653
  }),
2349
- span({
2654
+ renderer_span({
2350
2655
  text: isConnected ? 'Connected' : 'Disconnected'
2351
2656
  })
2352
2657
  ];
2353
- if (isLoading) statusChildren.push(span({
2354
- style: {
2355
- marginLeft: '4px',
2356
- opacity: '0.7'
2357
- },
2658
+ if (isLoading) statusChildren.push(renderer_span({
2659
+ className: styles_panel_module.footerMeta,
2358
2660
  text: '\u00b7 Fetching /init\u2026'
2359
2661
  }));
2662
+ else if (!isConnected) statusChildren.push(renderer_span({
2663
+ className: styles_panel_module.footerMeta,
2664
+ text: `· ${diagnostics.namespace} · retry ${diagnostics.reconnectAttempts} · next ${formatRetryDelay(diagnostics.nextRetryInMs)}`
2665
+ }));
2666
+ if (isConnected) statusChildren.push(renderer_span({
2667
+ className: styles_panel_module.footerMeta,
2668
+ text: `· Init: ${initSource}`
2669
+ }));
2360
2670
  footerElement.appendChild(renderer_div({
2361
2671
  className: styles_panel_module.footerStatus,
2362
2672
  children: statusChildren
2363
2673
  }));
2364
2674
  if (!isConnected) footerElement.appendChild(renderer_button({
2365
- className: styles_panel_module.closeButton,
2675
+ className: styles_panel_module.inlineActionButton,
2366
2676
  text: 'Retry',
2367
2677
  onClick: ()=>{
2368
2678
  storeConnector.retryConnection();
2369
2679
  }
2370
2680
  }));
2371
- footerElement.appendChild(span({
2681
+ footerElement.appendChild(renderer_span({
2372
2682
  text: `v${version}`
2373
2683
  }));
2374
2684
  }
2375
2685
  function renderErrorState(container) {
2376
2686
  clearElement(container);
2687
+ const diagnostics = storeConnector.getDiagnostics();
2377
2688
  const errorState = renderer_div({
2378
2689
  className: styles_panel_module.errorState,
2379
2690
  children: [
@@ -2395,8 +2706,25 @@ var __webpack_exports__ = {};
2395
2706
  className: styles_panel_module.errorMessage,
2396
2707
  text: 'c15t consent manager is not initialized. Make sure you have set up the ConsentManagerProvider in your app.'
2397
2708
  }),
2709
+ renderer_div({
2710
+ className: styles_panel_module.errorMessage,
2711
+ style: {
2712
+ marginTop: '4px',
2713
+ fontSize: 'var(--c15t-devtools-font-size-xs)'
2714
+ },
2715
+ text: `Namespace: ${diagnostics.namespace} · Retries: ${diagnostics.reconnectAttempts} · Next retry: ${formatRetryDelay(diagnostics.nextRetryInMs)}`
2716
+ }),
2717
+ diagnostics.lastError ? renderer_div({
2718
+ className: styles_panel_module.errorMessage,
2719
+ style: {
2720
+ marginTop: '4px',
2721
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
2722
+ color: 'var(--c15t-text-muted)'
2723
+ },
2724
+ text: `Last error: ${diagnostics.lastError}`
2725
+ }) : null,
2398
2726
  renderer_button({
2399
- className: styles_panel_module.closeButton,
2727
+ className: styles_panel_module.inlineActionButton,
2400
2728
  text: 'Retry Connection',
2401
2729
  onClick: ()=>{
2402
2730
  storeConnector.retryConnection();
@@ -2459,6 +2787,10 @@ var __webpack_exports__ = {};
2459
2787
  if (contentContainer) if (storeConnector.isConnected()) onRenderContent(contentContainer);
2460
2788
  else renderErrorState(contentContainer);
2461
2789
  });
2790
+ const unsubscribeDiagnostics = storeConnector.subscribeDiagnostics(()=>{
2791
+ updateFooter();
2792
+ if (contentContainer && !storeConnector.isConnected()) renderErrorState(contentContainer);
2793
+ });
2462
2794
  container.appendChild(floatingButton);
2463
2795
  removePortal = createPortal(container);
2464
2796
  return {
@@ -2468,6 +2800,7 @@ var __webpack_exports__ = {};
2468
2800
  destroy: ()=>{
2469
2801
  unsubscribeState();
2470
2802
  unsubscribeStore();
2803
+ unsubscribeDiagnostics();
2471
2804
  if (dropdownMenu) {
2472
2805
  dropdownMenu.destroy();
2473
2806
  dropdownMenu = null;
@@ -2500,6 +2833,11 @@ var __webpack_exports__ = {};
2500
2833
  <circle cx="12" cy="12" r="10"></circle>
2501
2834
  <line x1="2" y1="12" x2="22" y2="12"></line>
2502
2835
  <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
2836
+ </svg>`;
2837
+ const POLICY_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2838
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
2839
+ <path d="M9 12h6"></path>
2840
+ <path d="M12 9v6"></path>
2503
2841
  </svg>`;
2504
2842
  const SCRIPTS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2505
2843
  <polyline points="16 18 22 12 16 6"></polyline>
@@ -2516,6 +2854,11 @@ var __webpack_exports__ = {};
2516
2854
  const EVENTS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2517
2855
  <path d="M12 20h9"></path>
2518
2856
  <path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"></path>
2857
+ </svg>`;
2858
+ const MORE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
2859
+ <circle cx="12" cy="5" r="1.75"></circle>
2860
+ <circle cx="12" cy="12" r="1.75"></circle>
2861
+ <circle cx="12" cy="19" r="1.75"></circle>
2519
2862
  </svg>`;
2520
2863
  const TABS = [
2521
2864
  {
@@ -2523,6 +2866,11 @@ var __webpack_exports__ = {};
2523
2866
  label: 'Location',
2524
2867
  icon: LOCATION_ICON
2525
2868
  },
2869
+ {
2870
+ id: 'policy',
2871
+ label: 'Policy',
2872
+ icon: POLICY_ICON
2873
+ },
2526
2874
  {
2527
2875
  id: 'consents',
2528
2876
  label: 'Consents',
@@ -2552,12 +2900,56 @@ var __webpack_exports__ = {};
2552
2900
  function tabs_createTabs(options) {
2553
2901
  const { onTabChange, disabledTabs = [] } = options;
2554
2902
  let activeTab = options.activeTab;
2903
+ let isOverflowMenuOpen = false;
2904
+ let visibleTabIds = [];
2905
+ let hiddenTabIds = [];
2555
2906
  const tabButtons = new Map();
2907
+ const overflowButtons = new Map();
2556
2908
  const tabList = renderer_div({
2557
- className: styles_tabs_module.tabList,
2909
+ className: styles_tabs_module.tabList
2910
+ });
2911
+ const tabStrip = renderer_div({
2912
+ className: styles_tabs_module.tabStrip,
2558
2913
  role: 'tablist',
2559
2914
  ariaLabel: 'DevTools tabs'
2560
2915
  });
2916
+ tabList.appendChild(tabStrip);
2917
+ const overflowMenu = renderer_div({
2918
+ className: styles_tabs_module.overflowMenu,
2919
+ role: 'menu',
2920
+ ariaLabel: 'All tabs'
2921
+ });
2922
+ overflowMenu.dataset.state = 'closed';
2923
+ const overflowButton = renderer_button({
2924
+ className: styles_tabs_module.overflowButton,
2925
+ ariaLabel: 'More tabs',
2926
+ ariaExpanded: 'false',
2927
+ onClick: ()=>toggleOverflowMenu(),
2928
+ onKeyDown: (e)=>{
2929
+ if ('ArrowDown' === e.key || 'Enter' === e.key || ' ' === e.key) {
2930
+ e.preventDefault();
2931
+ openOverflowMenu();
2932
+ focusFirstEnabledOverflowItem();
2933
+ }
2934
+ }
2935
+ });
2936
+ overflowButton.setAttribute('aria-haspopup', 'menu');
2937
+ const overflowIcon = renderer_div({
2938
+ className: styles_tabs_module.overflowButtonIcon
2939
+ });
2940
+ overflowIcon.appendChild(createSvgElement(MORE_ICON, {
2941
+ width: 14,
2942
+ height: 14
2943
+ }));
2944
+ overflowButton.appendChild(overflowIcon);
2945
+ const overflowContainer = renderer_div({
2946
+ className: styles_tabs_module.overflowContainer,
2947
+ children: [
2948
+ overflowButton,
2949
+ overflowMenu
2950
+ ]
2951
+ });
2952
+ tabList.appendChild(overflowContainer);
2561
2953
  for (const tab of TABS){
2562
2954
  const isActive = tab.id === activeTab;
2563
2955
  const isDisabled = disabledTabs.includes(tab.id);
@@ -2571,6 +2963,7 @@ var __webpack_exports__ = {};
2571
2963
  disabled: isDisabled,
2572
2964
  onClick: ()=>{
2573
2965
  if (!isDisabled) {
2966
+ closeOverflowMenu();
2574
2967
  setActiveTab(tab.id);
2575
2968
  onTabChange(tab.id);
2576
2969
  }
@@ -2587,15 +2980,193 @@ var __webpack_exports__ = {};
2587
2980
  tabButton.appendChild(iconWrapper);
2588
2981
  tabButton.appendChild(document.createTextNode(tab.label));
2589
2982
  tabButtons.set(tab.id, tabButton);
2590
- tabList.appendChild(tabButton);
2591
- }
2592
- function handleKeyDown(e, currentTab) {
2593
- const tabIds = TABS.map((t)=>t.id);
2594
- const enabledTabIds = tabIds.filter((id)=>!disabledTabs.includes(id));
2595
- const currentIndex = enabledTabIds.indexOf(currentTab);
2596
- let newIndex = currentIndex;
2597
- switch(e.key){
2598
- case 'ArrowLeft':
2983
+ tabStrip.appendChild(tabButton);
2984
+ const overflowItem = renderer_button({
2985
+ className: `${styles_tabs_module.overflowItem} ${isActive ? styles_tabs_module.overflowItemActive : ''} ${isDisabled ? styles_tabs_module.overflowItemDisabled : ''}`,
2986
+ role: 'menuitemradio',
2987
+ ariaChecked: isActive ? 'true' : 'false',
2988
+ disabled: isDisabled,
2989
+ onClick: ()=>{
2990
+ if (!isDisabled) {
2991
+ setActiveTab(tab.id);
2992
+ onTabChange(tab.id);
2993
+ closeOverflowMenu();
2994
+ tabButtons.get(tab.id)?.focus();
2995
+ }
2996
+ },
2997
+ onKeyDown: (e)=>handleOverflowKeyDown(e, tab.id)
2998
+ });
2999
+ const overflowItemIcon = renderer_div({
3000
+ className: styles_tabs_module.overflowItemIcon
3001
+ });
3002
+ overflowItemIcon.appendChild(createSvgElement(tab.icon, {
3003
+ width: 14,
3004
+ height: 14
3005
+ }));
3006
+ overflowItem.appendChild(overflowItemIcon);
3007
+ overflowItem.appendChild(document.createTextNode(tab.label));
3008
+ overflowButtons.set(tab.id, overflowItem);
3009
+ overflowMenu.appendChild(overflowItem);
3010
+ }
3011
+ function applyActiveState(tab) {
3012
+ for (const [tabId, tabButton] of tabButtons){
3013
+ const isActive = tabId === tab;
3014
+ if (styles_tabs_module.tabActive) tabButton.classList.toggle(styles_tabs_module.tabActive, isActive);
3015
+ tabButton.setAttribute('aria-selected', isActive ? 'true' : 'false');
3016
+ tabButton.tabIndex = isActive ? 0 : -1;
3017
+ }
3018
+ for (const [tabId, overflowItem] of overflowButtons){
3019
+ const isActive = tabId === tab;
3020
+ if (styles_tabs_module.overflowItemActive) overflowItem.classList.toggle(styles_tabs_module.overflowItemActive, isActive);
3021
+ overflowItem.setAttribute('aria-checked', isActive ? 'true' : 'false');
3022
+ }
3023
+ }
3024
+ function updateVisibleTabs() {
3025
+ const allTabIds = TABS.map((t)=>t.id);
3026
+ const iabEnabled = !disabledTabs.includes('iab');
3027
+ const preferredSecondTab = iabEnabled ? 'iab' : 'consents';
3028
+ const overflowSecondTab = iabEnabled ? 'consents' : 'iab';
3029
+ const showOverflowSecondTabInStrip = activeTab === overflowSecondTab;
3030
+ const stripSecondTab = showOverflowSecondTabInStrip ? overflowSecondTab : preferredSecondTab;
3031
+ const forcedOverflowTab = showOverflowSecondTabInStrip ? preferredSecondTab : overflowSecondTab;
3032
+ const layoutTabIds = [
3033
+ 'location',
3034
+ 'policy',
3035
+ stripSecondTab,
3036
+ "scripts",
3037
+ 'actions',
3038
+ 'events',
3039
+ forcedOverflowTab
3040
+ ];
3041
+ const forcedOverflowTabIds = new Set();
3042
+ forcedOverflowTabIds.add(forcedOverflowTab);
3043
+ for (const [index, tabId] of layoutTabIds.entries()){
3044
+ const tabButton = tabButtons.get(tabId);
3045
+ if (tabButton) tabButton.style.order = String(index);
3046
+ const overflowItem = overflowButtons.get(tabId);
3047
+ if (overflowItem) overflowItem.style.order = String(index);
3048
+ }
3049
+ for (const tabId of allTabIds){
3050
+ const tabButton = tabButtons.get(tabId);
3051
+ if (tabButton && styles_tabs_module.tabHidden) tabButton.classList.remove(styles_tabs_module.tabHidden);
3052
+ }
3053
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.remove(styles_tabs_module.overflowContainerHidden);
3054
+ const stripGap = Number.parseFloat(getComputedStyle(tabStrip).gap || '0');
3055
+ const calculateVisibleTabs = (availableWidth)=>{
3056
+ if (availableWidth <= 0) return [];
3057
+ const nextVisible = [];
3058
+ let usedWidth = 0;
3059
+ for (const tabId of layoutTabIds){
3060
+ if (forcedOverflowTabIds.has(tabId)) continue;
3061
+ const tabButton = tabButtons.get(tabId);
3062
+ if (!tabButton) continue;
3063
+ const width = tabButton.getBoundingClientRect().width;
3064
+ const nextUsed = 0 === nextVisible.length ? width : usedWidth + stripGap + width;
3065
+ if (nextUsed <= availableWidth) {
3066
+ nextVisible.push(tabId);
3067
+ usedWidth = nextUsed;
3068
+ } else break;
3069
+ }
3070
+ return nextVisible;
3071
+ };
3072
+ const measureStripWidth = ()=>tabStrip.getBoundingClientRect().width;
3073
+ const showOverflowContainer = ()=>{
3074
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.remove(styles_tabs_module.overflowContainerHidden);
3075
+ };
3076
+ const hideOverflowContainer = ()=>{
3077
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.add(styles_tabs_module.overflowContainerHidden);
3078
+ };
3079
+ const measureVisibleWidth = (tabIds)=>{
3080
+ let width = 0;
3081
+ for (const [index, tabId] of tabIds.entries()){
3082
+ const tabButton = tabButtons.get(tabId);
3083
+ if (tabButton) {
3084
+ width += tabButton.getBoundingClientRect().width;
3085
+ if (index > 0) width += stripGap;
3086
+ }
3087
+ }
3088
+ return width;
3089
+ };
3090
+ if (0 === forcedOverflowTabIds.size) {
3091
+ hideOverflowContainer();
3092
+ const visibleWithoutOverflow = calculateVisibleTabs(measureStripWidth());
3093
+ if (visibleWithoutOverflow.length === layoutTabIds.length) visibleTabIds = visibleWithoutOverflow;
3094
+ else {
3095
+ showOverflowContainer();
3096
+ visibleTabIds = calculateVisibleTabs(measureStripWidth());
3097
+ }
3098
+ } else {
3099
+ showOverflowContainer();
3100
+ const withOverflow = calculateVisibleTabs(measureStripWidth());
3101
+ visibleTabIds = withOverflow.length > 0 ? withOverflow : [
3102
+ activeTab
3103
+ ];
3104
+ }
3105
+ if (!visibleTabIds.includes(activeTab) && !disabledTabs.includes(activeTab)) if (visibleTabIds.length > 0) visibleTabIds[visibleTabIds.length - 1] = activeTab;
3106
+ else visibleTabIds = [
3107
+ activeTab
3108
+ ];
3109
+ visibleTabIds = [
3110
+ ...new Set(visibleTabIds)
3111
+ ];
3112
+ const maxStripWidth = measureStripWidth();
3113
+ while(visibleTabIds.length > 1 && measureVisibleWidth(visibleTabIds) > maxStripWidth + 0.5){
3114
+ let removeIndex = visibleTabIds.length - 1;
3115
+ if (visibleTabIds[removeIndex] === activeTab) removeIndex = Math.max(0, removeIndex - 1);
3116
+ visibleTabIds.splice(removeIndex, 1);
3117
+ }
3118
+ hiddenTabIds = layoutTabIds.filter((tabId)=>!visibleTabIds.includes(tabId) || forcedOverflowTabIds.has(tabId) && tabId !== activeTab);
3119
+ for (const tabId of allTabIds){
3120
+ const tabButton = tabButtons.get(tabId);
3121
+ if (tabButton) {
3122
+ if (styles_tabs_module.tabHidden) tabButton.classList.toggle(styles_tabs_module.tabHidden, hiddenTabIds.includes(tabId));
3123
+ }
3124
+ }
3125
+ for (const tabId of allTabIds){
3126
+ const overflowItem = overflowButtons.get(tabId);
3127
+ if (overflowItem) {
3128
+ if (styles_tabs_module.overflowItemHidden) overflowItem.classList.toggle(styles_tabs_module.overflowItemHidden, !hiddenTabIds.includes(tabId));
3129
+ }
3130
+ }
3131
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.toggle(styles_tabs_module.overflowContainerHidden, 0 === hiddenTabIds.length);
3132
+ if (0 === hiddenTabIds.length) closeOverflowMenu();
3133
+ }
3134
+ function focusFirstEnabledOverflowItem() {
3135
+ const firstEnabled = hiddenTabIds.find((tabId)=>!disabledTabs.includes(tabId));
3136
+ if (firstEnabled) overflowButtons.get(firstEnabled)?.focus();
3137
+ }
3138
+ function openOverflowMenu() {
3139
+ if (isOverflowMenuOpen || 0 === hiddenTabIds.length) return;
3140
+ isOverflowMenuOpen = true;
3141
+ overflowMenu.dataset.state = 'open';
3142
+ overflowButton.setAttribute('aria-expanded', 'true');
3143
+ document.addEventListener('click', handleOutsideClick);
3144
+ document.addEventListener('keydown', handleEscapeKey);
3145
+ }
3146
+ function closeOverflowMenu() {
3147
+ if (!isOverflowMenuOpen) return;
3148
+ isOverflowMenuOpen = false;
3149
+ overflowMenu.dataset.state = 'closed';
3150
+ overflowButton.setAttribute('aria-expanded', 'false');
3151
+ document.removeEventListener('click', handleOutsideClick);
3152
+ document.removeEventListener('keydown', handleEscapeKey);
3153
+ }
3154
+ function toggleOverflowMenu() {
3155
+ if (isOverflowMenuOpen) closeOverflowMenu();
3156
+ else openOverflowMenu();
3157
+ }
3158
+ function handleOutsideClick(e) {
3159
+ if (!overflowContainer.contains(e.target)) closeOverflowMenu();
3160
+ }
3161
+ function handleEscapeKey(e) {
3162
+ if ('Escape' === e.key) closeOverflowMenu();
3163
+ }
3164
+ function handleKeyDown(e, currentTab) {
3165
+ const enabledTabIds = visibleTabIds.filter((tabId)=>!disabledTabs.includes(tabId));
3166
+ const currentIndex = enabledTabIds.indexOf(currentTab);
3167
+ let newIndex = currentIndex;
3168
+ switch(e.key){
3169
+ case 'ArrowLeft':
2599
3170
  newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabIds.length - 1;
2600
3171
  break;
2601
3172
  case 'ArrowRight':
@@ -2618,23 +3189,152 @@ var __webpack_exports__ = {};
2618
3189
  tabButtons.get(newTab)?.focus();
2619
3190
  }
2620
3191
  }
3192
+ function handleOverflowKeyDown(e, currentTab) {
3193
+ const enabledTabIds = hiddenTabIds.filter((tabId)=>!disabledTabs.includes(tabId));
3194
+ const currentIndex = enabledTabIds.indexOf(currentTab);
3195
+ if ('Escape' === e.key) {
3196
+ e.preventDefault();
3197
+ closeOverflowMenu();
3198
+ overflowButton.focus();
3199
+ return;
3200
+ }
3201
+ let newIndex = currentIndex;
3202
+ switch(e.key){
3203
+ case 'ArrowDown':
3204
+ newIndex = (currentIndex + 1) % enabledTabIds.length;
3205
+ break;
3206
+ case 'ArrowUp':
3207
+ newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabIds.length - 1;
3208
+ break;
3209
+ default:
3210
+ return;
3211
+ }
3212
+ e.preventDefault();
3213
+ const newTab = enabledTabIds[newIndex];
3214
+ if (newTab) overflowButtons.get(newTab)?.focus();
3215
+ }
2621
3216
  function setActiveTab(tab) {
2622
3217
  activeTab = tab;
2623
- for (const [tabId, tabButton] of tabButtons){
2624
- const isActive = tabId === tab;
2625
- if (styles_tabs_module.tabActive) tabButton.classList.toggle(styles_tabs_module.tabActive, isActive);
2626
- tabButton.setAttribute('aria-selected', isActive ? 'true' : 'false');
2627
- tabButton.tabIndex = isActive ? 0 : -1;
2628
- }
3218
+ applyActiveState(tab);
3219
+ updateVisibleTabs();
2629
3220
  }
3221
+ const handleWindowResize = ()=>{
3222
+ updateVisibleTabs();
3223
+ };
3224
+ let resizeObserver = null;
3225
+ if ('undefined' != typeof ResizeObserver) {
3226
+ resizeObserver = new ResizeObserver(()=>{
3227
+ updateVisibleTabs();
3228
+ });
3229
+ resizeObserver.observe(tabList);
3230
+ } else window.addEventListener('resize', handleWindowResize);
3231
+ applyActiveState(activeTab);
3232
+ requestAnimationFrame(()=>{
3233
+ updateVisibleTabs();
3234
+ });
2630
3235
  return {
2631
3236
  element: tabList,
2632
3237
  setActiveTab,
2633
3238
  destroy: ()=>{
3239
+ closeOverflowMenu();
3240
+ if (resizeObserver) {
3241
+ resizeObserver.disconnect();
3242
+ resizeObserver = null;
3243
+ } else window.removeEventListener('resize', handleWindowResize);
2634
3244
  tabButtons.clear();
3245
+ overflowButtons.clear();
2635
3246
  }
2636
3247
  };
2637
3248
  }
3249
+ function debug_bundle_createDebugBundle(payload) {
3250
+ const { namespace, devToolsState, connection, recentEvents, storeState } = payload;
3251
+ const bundle = {
3252
+ generatedAt: new Date().toISOString(),
3253
+ namespace,
3254
+ devToolsState,
3255
+ connection,
3256
+ recentEvents,
3257
+ storeState,
3258
+ overrides: storeState?.overrides ?? null,
3259
+ iab: storeState?.iab ? {
3260
+ tcString: (storeState?.iab).tcString ?? null,
3261
+ purposeCount: Object.keys((storeState?.iab).purposeConsents ?? {}).length,
3262
+ vendorCount: Object.keys((storeState?.iab).vendorConsents ?? {}).length
3263
+ } : null
3264
+ };
3265
+ return JSON.stringify(bundle, null, 2);
3266
+ }
3267
+ function debug_bundle_sanitizeStoreState(state) {
3268
+ if (!state) return null;
3269
+ try {
3270
+ return JSON.parse(JSON.stringify(state, (_key, value)=>'function' == typeof value ? void 0 : value));
3271
+ } catch {
3272
+ return {
3273
+ error: 'Unable to serialize store state'
3274
+ };
3275
+ }
3276
+ }
3277
+ function debug_bundle_downloadDebugBundle(content) {
3278
+ const blob = new Blob([
3279
+ content
3280
+ ], {
3281
+ type: 'application/json'
3282
+ });
3283
+ const url = URL.createObjectURL(blob);
3284
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
3285
+ const anchor = document.createElement('a');
3286
+ anchor.href = url;
3287
+ anchor.download = `c15t-debug-bundle-${timestamp}.json`;
3288
+ anchor.click();
3289
+ URL.revokeObjectURL(url);
3290
+ }
3291
+ const DEVTOOLS_OVERRIDES_STORAGE_KEY = 'c15t-devtools-overrides';
3292
+ function normalizeStringValue(value) {
3293
+ if ('string' != typeof value) return;
3294
+ const normalized = value.trim();
3295
+ return normalized.length > 0 ? normalized : void 0;
3296
+ }
3297
+ function normalizeBooleanValue(value) {
3298
+ return 'boolean' == typeof value ? value : void 0;
3299
+ }
3300
+ function normalizeOverrides(value) {
3301
+ if (!value || 'object' != typeof value) return null;
3302
+ const source = value;
3303
+ const overrides = {
3304
+ country: normalizeStringValue(source.country),
3305
+ region: normalizeStringValue(source.region),
3306
+ language: normalizeStringValue(source.language),
3307
+ gpc: normalizeBooleanValue(source.gpc)
3308
+ };
3309
+ return hasPersistedOverrides(overrides) ? overrides : null;
3310
+ }
3311
+ function hasPersistedOverrides(overrides) {
3312
+ return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
3313
+ }
3314
+ function override_storage_loadPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3315
+ if ('undefined' == typeof window) return null;
3316
+ try {
3317
+ const stored = localStorage.getItem(storageKey);
3318
+ if (!stored) return null;
3319
+ const parsed = JSON.parse(stored);
3320
+ return normalizeOverrides(parsed);
3321
+ } catch {
3322
+ return null;
3323
+ }
3324
+ }
3325
+ function override_storage_persistOverrides(overrides, storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3326
+ if ('undefined' == typeof window) return;
3327
+ try {
3328
+ if (!hasPersistedOverrides(overrides)) return void localStorage.removeItem(storageKey);
3329
+ localStorage.setItem(storageKey, JSON.stringify(overrides));
3330
+ } catch {}
3331
+ }
3332
+ function override_storage_clearPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3333
+ if ('undefined' == typeof window) return;
3334
+ try {
3335
+ localStorage.removeItem(storageKey);
3336
+ } catch {}
3337
+ }
2638
3338
  var components_module = __webpack_require__("../../node_modules/.bun/@rsbuild+core@1.6.12/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles/components.module.css");
2639
3339
  var components_module_options = {};
2640
3340
  components_module_options.styleTagTransform = styleTagTransform_default();
@@ -2671,7 +3371,7 @@ var __webpack_exports__ = {};
2671
3371
  info: styles_components_module.badgeInfo,
2672
3372
  neutral: styles_components_module.badgeNeutral
2673
3373
  }[variant];
2674
- return span({
3374
+ return renderer_span({
2675
3375
  className: `${styles_components_module.badge} ${variantClass}`,
2676
3376
  text
2677
3377
  });
@@ -2702,31 +3402,19 @@ var __webpack_exports__ = {};
2702
3402
  btn.appendChild(document.createTextNode(text));
2703
3403
  return btn;
2704
3404
  }
2705
- function createListItem(options) {
2706
- const { title, description, actions = [] } = options;
2707
- const content = renderer_div({
2708
- className: styles_components_module.listItemContent,
2709
- children: [
2710
- span({
2711
- className: styles_components_module.listItemTitle,
2712
- text: title
2713
- }),
2714
- description ? span({
2715
- className: styles_components_module.listItemDescription,
2716
- text: description
2717
- }) : null
2718
- ]
2719
- });
2720
- const actionsContainer = renderer_div({
2721
- className: styles_components_module.listItemActions,
2722
- children: actions
2723
- });
2724
- return renderer_div({
2725
- className: styles_components_module.listItem,
2726
- children: [
2727
- content,
2728
- actionsContainer
2729
- ]
3405
+ function createInput(options) {
3406
+ const { value, placeholder, ariaLabel, small = false, onInput } = options;
3407
+ const sizeClass = small ? styles_components_module.inputSmall : '';
3408
+ return input({
3409
+ className: `${styles_components_module.input} ${sizeClass}`.trim(),
3410
+ type: 'text',
3411
+ value,
3412
+ placeholder,
3413
+ ariaLabel,
3414
+ onInput: (event)=>{
3415
+ const target = event.target;
3416
+ onInput?.(target?.value ?? '');
3417
+ }
2730
3418
  });
2731
3419
  }
2732
3420
  function createSection(options) {
@@ -2734,7 +3422,7 @@ var __webpack_exports__ = {};
2734
3422
  const header = renderer_div({
2735
3423
  className: styles_components_module.sectionHeader,
2736
3424
  children: [
2737
- span({
3425
+ renderer_span({
2738
3426
  className: styles_components_module.sectionTitle,
2739
3427
  text: title
2740
3428
  }),
@@ -2754,11 +3442,11 @@ var __webpack_exports__ = {};
2754
3442
  return renderer_div({
2755
3443
  className: styles_components_module.infoRow,
2756
3444
  children: [
2757
- span({
3445
+ renderer_span({
2758
3446
  className: styles_components_module.infoLabel,
2759
3447
  text: label
2760
3448
  }),
2761
- span({
3449
+ renderer_span({
2762
3450
  className: styles_components_module.infoValue,
2763
3451
  text: value
2764
3452
  })
@@ -2778,7 +3466,7 @@ var __webpack_exports__ = {};
2778
3466
  }));
2779
3467
  children.push(iconWrapper);
2780
3468
  }
2781
- children.push(span({
3469
+ children.push(renderer_span({
2782
3470
  className: styles_components_module.emptyStateText,
2783
3471
  text
2784
3472
  }));
@@ -2798,7 +3486,7 @@ var __webpack_exports__ = {};
2798
3486
  function createGridCard(options) {
2799
3487
  const { title, action } = options;
2800
3488
  const children = [
2801
- span({
3489
+ renderer_span({
2802
3490
  className: styles_components_module.gridCardTitle,
2803
3491
  text: title
2804
3492
  })
@@ -2809,6 +3497,18 @@ var __webpack_exports__ = {};
2809
3497
  children
2810
3498
  });
2811
3499
  }
3500
+ function createDisconnectedState(message = 'Store not connected') {
3501
+ return renderer_div({
3502
+ className: styles_components_module.disconnectedState,
3503
+ style: {
3504
+ padding: '24px',
3505
+ textAlign: 'center',
3506
+ color: 'var(--c15t-text-muted)',
3507
+ fontSize: 'var(--c15t-devtools-font-size-sm)'
3508
+ },
3509
+ text: message
3510
+ });
3511
+ }
2812
3512
  const REFRESH_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2813
3513
  <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
2814
3514
  <path d="M21 3v5h-5"></path>
@@ -2836,19 +3536,11 @@ var __webpack_exports__ = {};
2836
3536
  <polyline points="4 17 10 11 4 5"></polyline>
2837
3537
  <line x1="12" y1="19" x2="20" y2="19"></line>
2838
3538
  </svg>`;
2839
- function actions_renderActionsPanel(container, options) {
2840
- const { getState, onResetConsents, onRefetchBanner, onShowBanner, onOpenPreferences, onCopyState } = options;
3539
+ function renderActionsPanel(container, options) {
3540
+ const { getState, onResetConsents, onRefetchBanner, onShowBanner, onOpenPreferences, onCopyState, onExportDebugBundle } = options;
2841
3541
  clearElement(container);
2842
3542
  const state = getState();
2843
- if (!state) return void container.appendChild(renderer_div({
2844
- style: {
2845
- padding: '24px',
2846
- textAlign: 'center',
2847
- color: 'var(--c15t-text-muted)',
2848
- fontSize: 'var(--c15t-devtools-font-size-sm)'
2849
- },
2850
- text: 'Store not connected'
2851
- }));
3543
+ if (!state) return void container.appendChild(createDisconnectedState());
2852
3544
  const actionCards = [
2853
3545
  createActionCard({
2854
3546
  icon: actions_EYE_ICON,
@@ -2869,6 +3561,12 @@ var __webpack_exports__ = {};
2869
3561
  icon: COPY_ICON,
2870
3562
  label: 'Copy State',
2871
3563
  onClick: onCopyState
3564
+ }),
3565
+ createActionCard({
3566
+ icon: REFRESH_ICON,
3567
+ label: 'Export Debug',
3568
+ onClick: ()=>onExportDebugBundle?.(),
3569
+ disabled: !onExportDebugBundle
2872
3570
  })
2873
3571
  ];
2874
3572
  const grid = createGrid({
@@ -2906,7 +3604,7 @@ var __webpack_exports__ = {};
2906
3604
  },
2907
3605
  children: [
2908
3606
  createIconWrapper(TERMINAL_ICON, 14),
2909
- span({
3607
+ renderer_span({
2910
3608
  style: {
2911
3609
  fontSize: 'var(--c15t-devtools-font-size-xs)',
2912
3610
  fontWeight: '600',
@@ -2929,10 +3627,10 @@ var __webpack_exports__ = {};
2929
3627
  color: 'var(--c15t-text-muted)'
2930
3628
  },
2931
3629
  children: [
2932
- span({
3630
+ renderer_span({
2933
3631
  text: `window.${getNamespace(state)}.getState()`
2934
3632
  }),
2935
- span({
3633
+ renderer_span({
2936
3634
  text: 'window.__c15tDevTools.open()'
2937
3635
  })
2938
3636
  ]
@@ -2942,7 +3640,7 @@ var __webpack_exports__ = {};
2942
3640
  container.appendChild(consoleSection);
2943
3641
  }
2944
3642
  function createActionCard(options) {
2945
- const { icon, label, onClick } = options;
3643
+ const { icon, label, onClick, disabled = false } = options;
2946
3644
  const card = renderer_div({
2947
3645
  className: styles_components_module.gridCard ?? '',
2948
3646
  style: {
@@ -2953,11 +3651,12 @@ var __webpack_exports__ = {};
2953
3651
  gap: '6px',
2954
3652
  padding: '16px 8px',
2955
3653
  cursor: 'pointer',
2956
- transition: 'background-color var(--c15t-duration-fast) var(--c15t-easing)'
3654
+ transition: 'background-color var(--c15t-duration-fast) var(--c15t-easing)',
3655
+ opacity: disabled ? '0.55' : '1'
2957
3656
  },
2958
3657
  children: [
2959
3658
  createIconWrapper(icon, 20),
2960
- span({
3659
+ renderer_span({
2961
3660
  style: {
2962
3661
  fontSize: 'var(--c15t-devtools-font-size-xs)',
2963
3662
  fontWeight: '500',
@@ -2968,13 +3667,15 @@ var __webpack_exports__ = {};
2968
3667
  })
2969
3668
  ]
2970
3669
  });
2971
- card.addEventListener('click', onClick);
2972
- card.addEventListener('mouseenter', ()=>{
2973
- card.style.backgroundColor = 'var(--c15t-surface-hover)';
2974
- });
2975
- card.addEventListener('mouseleave', ()=>{
2976
- card.style.backgroundColor = '';
2977
- });
3670
+ if (!disabled) {
3671
+ card.addEventListener('click', onClick);
3672
+ card.addEventListener('mouseenter', ()=>{
3673
+ card.style.backgroundColor = 'var(--c15t-surface-hover)';
3674
+ });
3675
+ card.addEventListener('mouseleave', ()=>{
3676
+ card.style.backgroundColor = '';
3677
+ });
3678
+ }
2978
3679
  return card;
2979
3680
  }
2980
3681
  function createIconWrapper(icon, size) {
@@ -2995,19 +3696,11 @@ var __webpack_exports__ = {};
2995
3696
  function getNamespace(state) {
2996
3697
  return state.config?.meta?.namespace || 'c15tStore';
2997
3698
  }
2998
- function consents_renderConsentsPanel(container, options) {
3699
+ function renderConsentsPanel(container, options) {
2999
3700
  const { getState, onConsentChange, onSave, onAcceptAll, onRejectAll, onReset } = options;
3000
3701
  clearElement(container);
3001
3702
  const state = getState();
3002
- if (!state) return void container.appendChild(renderer_div({
3003
- style: {
3004
- padding: '24px',
3005
- textAlign: 'center',
3006
- color: 'var(--c15t-text-muted)',
3007
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3008
- },
3009
- text: 'Store not connected'
3010
- }));
3703
+ if (!state) return void container.appendChild(createDisconnectedState());
3011
3704
  const isIabMode = 'iab' === state.model;
3012
3705
  const savedConsents = state.consents || {};
3013
3706
  const selectedConsents = state.selectedConsents || {};
@@ -3137,7 +3830,7 @@ var __webpack_exports__ = {};
3137
3830
  gap: '8px'
3138
3831
  },
3139
3832
  children: [
3140
- span({
3833
+ renderer_span({
3141
3834
  style: {
3142
3835
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3143
3836
  color: 'var(--c15t-devtools-badge-warning)'
@@ -3151,7 +3844,7 @@ var __webpack_exports__ = {};
3151
3844
  onClick: onSave
3152
3845
  })
3153
3846
  ]
3154
- }) : span({
3847
+ }) : renderer_span({
3155
3848
  style: {
3156
3849
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3157
3850
  color: 'var(--c15t-text-muted)'
@@ -3165,15 +3858,26 @@ var __webpack_exports__ = {};
3165
3858
  function formatConsentName(name) {
3166
3859
  return name.replace(/_/g, ' ').replace(/\b\w/g, (l)=>l.toUpperCase());
3167
3860
  }
3168
- let activeFilter = 'all';
3169
- let selectedEventId = null;
3170
- function events_renderEventsPanel(container, options) {
3861
+ const panelStateByContainer = new WeakMap();
3862
+ function getPanelState(container) {
3863
+ const existing = panelStateByContainer.get(container);
3864
+ if (existing) return existing;
3865
+ const initialState = {
3866
+ activeFilter: 'all',
3867
+ selectedEventId: null,
3868
+ searchQuery: ''
3869
+ };
3870
+ panelStateByContainer.set(container, initialState);
3871
+ return initialState;
3872
+ }
3873
+ function renderEventsPanel(container, options) {
3171
3874
  const { getEvents, onClear } = options;
3875
+ const panelState = getPanelState(container);
3172
3876
  clearElement(container);
3173
3877
  const allEvents = getEvents();
3174
- const events = allEvents.filter((event)=>matchesFilter(event, activeFilter));
3175
- if (!events.some((event)=>event.id === selectedEventId)) selectedEventId = events[0]?.id ?? null;
3176
- const selectedEvent = events.find((event)=>event.id === selectedEventId) ?? null;
3878
+ const events = allEvents.filter((event)=>matchesFilter(event, panelState.activeFilter)).filter((event)=>matchesSearch(event, panelState.searchQuery));
3879
+ if (!events.some((event)=>event.id === panelState.selectedEventId)) panelState.selectedEventId = events[0]?.id ?? null;
3880
+ const selectedEvent = events.find((event)=>event.id === panelState.selectedEventId) ?? null;
3177
3881
  const header = renderer_div({
3178
3882
  style: {
3179
3883
  display: 'flex',
@@ -3183,7 +3887,7 @@ var __webpack_exports__ = {};
3183
3887
  gap: '8px'
3184
3888
  },
3185
3889
  children: [
3186
- span({
3890
+ renderer_span({
3187
3891
  style: {
3188
3892
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3189
3893
  fontWeight: '600',
@@ -3209,8 +3913,8 @@ var __webpack_exports__ = {};
3209
3913
  small: true,
3210
3914
  onClick: ()=>{
3211
3915
  onClear();
3212
- selectedEventId = null;
3213
- events_renderEventsPanel(container, options);
3916
+ panelState.selectedEventId = null;
3917
+ renderEventsPanel(container, options);
3214
3918
  }
3215
3919
  })
3216
3920
  ]
@@ -3225,12 +3929,30 @@ var __webpack_exports__ = {};
3225
3929
  gap: '6px',
3226
3930
  padding: '0 16px 8px'
3227
3931
  },
3228
- children: EVENT_FILTERS.map((filter)=>createFilterButton(filter, filter === activeFilter, ()=>{
3229
- activeFilter = filter;
3230
- selectedEventId = null;
3231
- events_renderEventsPanel(container, options);
3932
+ children: EVENT_FILTERS.map((filter)=>createFilterButton(filter, filter === panelState.activeFilter, ()=>{
3933
+ panelState.activeFilter = filter;
3934
+ panelState.selectedEventId = null;
3935
+ renderEventsPanel(container, options);
3232
3936
  }))
3233
3937
  }));
3938
+ container.appendChild(renderer_div({
3939
+ style: {
3940
+ padding: '0 16px 8px'
3941
+ },
3942
+ children: [
3943
+ createInput({
3944
+ value: panelState.searchQuery,
3945
+ placeholder: 'Search events…',
3946
+ ariaLabel: 'Search events',
3947
+ small: true,
3948
+ onInput: (value)=>{
3949
+ panelState.searchQuery = value.trim().toLowerCase();
3950
+ panelState.selectedEventId = null;
3951
+ renderEventsPanel(container, options);
3952
+ }
3953
+ })
3954
+ ]
3955
+ }));
3234
3956
  const eventList = renderer_div({
3235
3957
  style: {
3236
3958
  display: 'flex',
@@ -3250,9 +3972,9 @@ var __webpack_exports__ = {};
3250
3972
  },
3251
3973
  text: 'No events match this filter'
3252
3974
  }));
3253
- else for (const event of events)eventList.appendChild(createEventItem(event, event.id === selectedEventId, ()=>{
3254
- selectedEventId = event.id;
3255
- events_renderEventsPanel(container, options);
3975
+ else for (const event of events)eventList.appendChild(createEventItem(event, event.id === panelState.selectedEventId, ()=>{
3976
+ panelState.selectedEventId = event.id;
3977
+ renderEventsPanel(container, options);
3256
3978
  }));
3257
3979
  container.appendChild(eventList);
3258
3980
  container.appendChild(createPayloadSection(selectedEvent));
@@ -3279,6 +4001,11 @@ var __webpack_exports__ = {};
3279
4001
  if ('network' === filter) return 'network' === event.type;
3280
4002
  return 'iab' === event.type;
3281
4003
  }
4004
+ function matchesSearch(event, query) {
4005
+ if (!query) return true;
4006
+ const haystack = `${event.type} ${event.message} ${JSON.stringify(event.data ?? {})}`;
4007
+ return haystack.toLowerCase().includes(query);
4008
+ }
3282
4009
  function createPayloadSection(event) {
3283
4010
  const payload = event?.data ? JSON.stringify(event.data, null, 2) : null;
3284
4011
  return renderer_div({
@@ -3331,7 +4058,7 @@ var __webpack_exports__ = {};
3331
4058
  },
3332
4059
  onClick: onSelect,
3333
4060
  children: [
3334
- span({
4061
+ renderer_span({
3335
4062
  style: {
3336
4063
  color,
3337
4064
  fontSize: '8px',
@@ -3339,7 +4066,7 @@ var __webpack_exports__ = {};
3339
4066
  },
3340
4067
  text: icon
3341
4068
  }),
3342
- span({
4069
+ renderer_span({
3343
4070
  style: {
3344
4071
  color: 'var(--c15t-text-muted)',
3345
4072
  fontFamily: 'monospace',
@@ -3348,7 +4075,7 @@ var __webpack_exports__ = {};
3348
4075
  },
3349
4076
  text: time
3350
4077
  }),
3351
- span({
4078
+ renderer_span({
3352
4079
  style: {
3353
4080
  color: 'var(--c15t-text)',
3354
4081
  flex: '1'
@@ -3416,38 +4143,15 @@ var __webpack_exports__ = {};
3416
4143
  return 'var(--c15t-text-muted)';
3417
4144
  }
3418
4145
  }
3419
- function iab_renderIabPanel(container, options) {
4146
+ const iabSearchByContainer = new WeakMap();
4147
+ function renderIabPanel(container, options) {
3420
4148
  const { getState, onSetPurposeConsent, onSetVendorConsent, onSetSpecialFeatureOptIn, onAcceptAll, onRejectAll, onSave, onReset } = options;
3421
4149
  clearElement(container);
3422
4150
  const state = getState();
3423
- if (!state) return void container.appendChild(renderer_div({
3424
- style: {
3425
- padding: '24px',
3426
- textAlign: 'center',
3427
- color: 'var(--c15t-text-muted)',
3428
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3429
- },
3430
- text: 'Store not connected'
3431
- }));
3432
- if ('iab' !== state.model) return void container.appendChild(renderer_div({
3433
- style: {
3434
- padding: '24px',
3435
- textAlign: 'center',
3436
- color: 'var(--c15t-text-muted)',
3437
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3438
- },
3439
- text: 'IAB TCF mode is not configured'
3440
- }));
4151
+ if (!state) return void container.appendChild(createDisconnectedState());
4152
+ if ('iab' !== state.model) return void container.appendChild(createDisconnectedState('IAB TCF mode is not configured'));
3441
4153
  const iabState = state.iab;
3442
- if (!iabState) return void container.appendChild(renderer_div({
3443
- style: {
3444
- padding: '24px',
3445
- textAlign: 'center',
3446
- color: 'var(--c15t-text-muted)',
3447
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3448
- },
3449
- text: 'IAB state not available'
3450
- }));
4154
+ if (!iabState) return void container.appendChild(createDisconnectedState('IAB state not available'));
3451
4155
  const tcString = iabState.tcString;
3452
4156
  const tcStringSection = createSection({
3453
4157
  title: 'TC String',
@@ -3479,9 +4183,30 @@ var __webpack_exports__ = {};
3479
4183
  });
3480
4184
  container.appendChild(tcStringSection);
3481
4185
  const gvl = iabState.gvl;
4186
+ const searchQuery = iabSearchByContainer.get(container) ?? '';
4187
+ container.appendChild(createSection({
4188
+ title: 'Filter',
4189
+ children: [
4190
+ createInput({
4191
+ value: searchQuery,
4192
+ placeholder: 'Filter purposes or vendors…',
4193
+ ariaLabel: 'Filter IAB purposes and vendors',
4194
+ small: true,
4195
+ onInput: (value)=>{
4196
+ iabSearchByContainer.set(container, value.trim().toLowerCase());
4197
+ renderIabPanel(container, options);
4198
+ }
4199
+ })
4200
+ ]
4201
+ }));
3482
4202
  const purposeConsents = iabState.purposeConsents || {};
3483
4203
  const purposes = gvl?.purposes || {};
3484
- const purposeEntries = Object.entries(purposeConsents);
4204
+ const purposeEntries = Object.entries(purposeConsents).filter(([purposeId])=>{
4205
+ if (!searchQuery) return true;
4206
+ const purposeInfo = purposes[purposeId];
4207
+ const purposeName = purposeInfo?.name || `Purpose ${purposeId}`;
4208
+ return `${purposeId} ${purposeName}`.toLowerCase().includes(searchQuery);
4209
+ });
3485
4210
  if (purposeEntries.length > 0) {
3486
4211
  const purposeList = renderer_div({
3487
4212
  style: {
@@ -3509,7 +4234,12 @@ var __webpack_exports__ = {};
3509
4234
  }
3510
4235
  const specialFeatureOptIns = iabState.specialFeatureOptIns || {};
3511
4236
  const specialFeatures = gvl?.specialFeatures || {};
3512
- const specialFeatureEntries = Object.entries(specialFeatureOptIns);
4237
+ const specialFeatureEntries = Object.entries(specialFeatureOptIns).filter(([featureId])=>{
4238
+ if (!searchQuery) return true;
4239
+ const featureInfo = specialFeatures[featureId];
4240
+ const featureName = featureInfo?.name || `Special Feature ${featureId}`;
4241
+ return `${featureId} ${featureName}`.toLowerCase().includes(searchQuery);
4242
+ });
3513
4243
  if (specialFeatureEntries.length > 0) {
3514
4244
  const specialFeatureList = renderer_div({
3515
4245
  style: {
@@ -3537,7 +4267,12 @@ var __webpack_exports__ = {};
3537
4267
  }
3538
4268
  const vendorConsents = iabState.vendorConsents || {};
3539
4269
  const vendors = gvl?.vendors || {};
3540
- const vendorEntries = Object.entries(vendorConsents);
4270
+ const vendorEntries = Object.entries(vendorConsents).filter(([vendorId])=>{
4271
+ if (!searchQuery) return true;
4272
+ const vendorInfo = vendors[vendorId];
4273
+ const vendorName = vendorInfo?.name || `Vendor ${vendorId}`;
4274
+ return `${vendorId} ${vendorName}`.toLowerCase().includes(searchQuery);
4275
+ });
3541
4276
  const iabVendors = [];
3542
4277
  const customVendors = [];
3543
4278
  for (const [vendorId, consent] of vendorEntries){
@@ -3663,7 +4398,7 @@ var __webpack_exports__ = {};
3663
4398
  borderBottom: '1px solid var(--c15t-border)'
3664
4399
  },
3665
4400
  children: [
3666
- span({
4401
+ renderer_span({
3667
4402
  style: {
3668
4403
  color: 'var(--c15t-text)',
3669
4404
  overflow: 'hidden',
@@ -3717,7 +4452,7 @@ var __webpack_exports__ = {};
3717
4452
  marginRight: '8px'
3718
4453
  },
3719
4454
  children: [
3720
- 'custom' === type ? span({
4455
+ 'custom' === type ? renderer_span({
3721
4456
  style: {
3722
4457
  fontSize: '9px',
3723
4458
  padding: '1px 4px',
@@ -3728,7 +4463,7 @@ var __webpack_exports__ = {};
3728
4463
  },
3729
4464
  text: 'CUSTOM'
3730
4465
  }) : null,
3731
- span({
4466
+ renderer_span({
3732
4467
  style: {
3733
4468
  color: 'var(--c15t-text)',
3734
4469
  overflow: 'hidden',
@@ -3756,27 +4491,23 @@ var __webpack_exports__ = {};
3756
4491
  if (text.length <= maxLength) return text;
3757
4492
  return `${text.slice(0, maxLength - 3)}...`;
3758
4493
  }
3759
- function location_renderLocationPanel(container, options) {
4494
+ function renderLocationPanel(container, options) {
3760
4495
  const { getState, onApplyOverrides, onClearOverrides } = options;
3761
4496
  clearElement(container);
3762
4497
  const state = getState();
3763
- if (!state) return void container.appendChild(renderer_div({
3764
- style: {
3765
- padding: '24px',
3766
- textAlign: 'center',
3767
- color: 'var(--c15t-text-muted)',
3768
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3769
- },
3770
- text: 'Store not connected'
3771
- }));
4498
+ if (!state) return void container.appendChild(createDisconnectedState());
3772
4499
  const locationInfo = state.locationInfo;
3773
4500
  const overrides = state.overrides;
3774
4501
  const translationConfig = state.translationConfig;
4502
+ const initData = state.lastBannerFetchData;
4503
+ const activePolicy = initData?.policy;
4504
+ const policyDecision = initData?.policyDecision;
4505
+ const initSource = formatInitSource(state.initDataSource, state.initDataSourceDetail);
3775
4506
  const gridItems = [
3776
4507
  createCompactInfoCard('Country', locationInfo?.countryCode || '—'),
3777
4508
  createCompactInfoCard('Region', locationInfo?.regionCode || '—'),
3778
- createCompactInfoCard('Jurisdiction', locationInfo?.jurisdiction || '—'),
3779
- createCompactInfoCard('Language', translationConfig?.defaultLanguage || '—')
4509
+ createCompactInfoCard('Language', translationConfig?.defaultLanguage || '—'),
4510
+ createCompactInfoCard('Init Source', initSource)
3780
4511
  ];
3781
4512
  gridItems.push(createCompactInfoCard('GPC', getEffectiveGpcLabel(overrides?.gpc)));
3782
4513
  if (state.model) gridItems.push(createCompactInfoCard('Model', getModelLabel(state.model)));
@@ -3784,7 +4515,6 @@ var __webpack_exports__ = {};
3784
4515
  columns: 3,
3785
4516
  children: gridItems
3786
4517
  });
3787
- container.appendChild(locationGrid);
3788
4518
  const initialDraft = getDraftFromOverrides(overrides);
3789
4519
  let appliedOverrides = normalizeOverrideDraft(initialDraft);
3790
4520
  let isSubmitting = false;
@@ -3808,7 +4538,7 @@ var __webpack_exports__ = {};
3808
4538
  selectOptions: GPC_OPTIONS,
3809
4539
  value: initialDraft.gpc
3810
4540
  });
3811
- const formStatus = span({
4541
+ const formStatus = renderer_span({
3812
4542
  className: styles_components_module.overrideStatus,
3813
4543
  text: 'In sync'
3814
4544
  });
@@ -3854,7 +4584,7 @@ var __webpack_exports__ = {};
3854
4584
  title: 'Override Settings',
3855
4585
  children: [
3856
4586
  overrideFieldsGrid,
3857
- span({
4587
+ renderer_span({
3858
4588
  className: styles_components_module.overrideHint,
3859
4589
  text: 'GPC override only affects opt-out or unregulated jurisdictions.'
3860
4590
  }),
@@ -3875,6 +4605,12 @@ var __webpack_exports__ = {};
3875
4605
  ]
3876
4606
  });
3877
4607
  container.appendChild(overrideSection);
4608
+ container.appendChild(locationGrid);
4609
+ container.appendChild(createActivePolicySummarySection({
4610
+ policy: activePolicy,
4611
+ policyDecision,
4612
+ policySnapshotToken: initData?.policySnapshotToken
4613
+ }));
3878
4614
  countryField.control.addEventListener('change', updateFormState);
3879
4615
  regionField.control.addEventListener('input', updateFormState);
3880
4616
  languageField.control.addEventListener('input', updateFormState);
@@ -3942,7 +4678,7 @@ var __webpack_exports__ = {};
3942
4678
  element: renderer_div({
3943
4679
  className: styles_components_module.overrideField,
3944
4680
  children: [
3945
- span({
4681
+ renderer_span({
3946
4682
  className: styles_components_module.overrideLabel,
3947
4683
  text: label
3948
4684
  }),
@@ -3963,7 +4699,7 @@ var __webpack_exports__ = {};
3963
4699
  element: renderer_div({
3964
4700
  className: styles_components_module.overrideField,
3965
4701
  children: [
3966
- span({
4702
+ renderer_span({
3967
4703
  className: styles_components_module.overrideLabel,
3968
4704
  text: label
3969
4705
  }),
@@ -4163,35 +4899,320 @@ var __webpack_exports__ = {};
4163
4899
  return 'None';
4164
4900
  }
4165
4901
  }
4166
- function createCompactInfoCard(label, value) {
4167
- return renderer_div({
4168
- className: styles_components_module.gridCard ?? '',
4169
- style: {
4170
- padding: '6px 8px',
4171
- minHeight: 'auto',
4172
- flexDirection: 'column',
4173
- alignItems: 'flex-start',
4174
- gap: '1px'
4175
- },
4902
+ function createActivePolicySummarySection(options) {
4903
+ const { policy, policyDecision, policySnapshotToken } = options;
4904
+ if (!policy && !policyDecision) return createSection({
4905
+ title: 'Active Policy',
4176
4906
  children: [
4177
- span({
4907
+ renderer_div({
4178
4908
  style: {
4179
- fontSize: 'var(--c15t-devtools-font-size-xs)',
4909
+ padding: '10px 12px',
4910
+ fontSize: 'var(--c15t-devtools-font-size-sm)',
4180
4911
  color: 'var(--c15t-text-muted)'
4181
4912
  },
4182
- text: label
4183
- }),
4184
- span({
4185
- style: {
4186
- fontSize: 'var(--c15t-font-size-sm)',
4187
- fontWeight: '500',
4188
- fontFamily: 'ui-monospace, monospace'
4913
+ text: 'No active policy matched.'
4914
+ })
4915
+ ]
4916
+ });
4917
+ const cards = [
4918
+ createCompactInfoCard('Policy ID', policy?.id ?? policyDecision?.policyId ?? '—'),
4919
+ createCompactInfoCard('Matched By', policyDecision?.matchedBy ?? '—'),
4920
+ createCompactInfoCard('Snapshot Token', policySnapshotToken ? 'present' : 'missing')
4921
+ ];
4922
+ return createSection({
4923
+ title: 'Active Policy',
4924
+ children: [
4925
+ renderer_div({
4926
+ style: {
4927
+ display: 'grid',
4928
+ gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
4929
+ gap: 'var(--c15t-space-sm, 0.5rem)'
4930
+ },
4931
+ children: cards
4932
+ }),
4933
+ renderer_span({
4934
+ className: styles_components_module.overrideHint,
4935
+ text: 'Open the Policy tab for full policy-pack diagnostics.'
4936
+ })
4937
+ ]
4938
+ });
4939
+ }
4940
+ function createCompactInfoCard(label, value) {
4941
+ return renderer_div({
4942
+ className: styles_components_module.gridCard ?? '',
4943
+ style: {
4944
+ padding: '8px 10px',
4945
+ minHeight: 'auto',
4946
+ flexDirection: 'column',
4947
+ alignItems: 'flex-start',
4948
+ gap: '2px'
4949
+ },
4950
+ children: [
4951
+ renderer_span({
4952
+ style: {
4953
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
4954
+ color: 'var(--c15t-text-muted)'
4955
+ },
4956
+ text: label
4957
+ }),
4958
+ renderer_span({
4959
+ style: {
4960
+ fontSize: 'var(--c15t-font-size-sm)',
4961
+ fontWeight: '500',
4962
+ fontFamily: 'ui-monospace, monospace'
4963
+ },
4964
+ text: value
4965
+ })
4966
+ ]
4967
+ });
4968
+ }
4969
+ function renderPolicyPanel(container, options) {
4970
+ const { getState } = options;
4971
+ clearElement(container);
4972
+ const state = getState();
4973
+ if (!state) return void container.appendChild(createDisconnectedState());
4974
+ const initData = state.lastBannerFetchData;
4975
+ const activePolicy = initData?.policy;
4976
+ const policyDecision = initData?.policyDecision;
4977
+ const initSource = formatInitSource(state.initDataSource, state.initDataSourceDetail);
4978
+ container.appendChild(createMatchTraceSection({
4979
+ policyDecision,
4980
+ policyId: activePolicy?.id ?? policyDecision?.policyId
4981
+ }));
4982
+ if (!activePolicy && !policyDecision) return void container.appendChild(createSection({
4983
+ title: 'Policy',
4984
+ children: [
4985
+ renderer_div({
4986
+ style: {
4987
+ padding: '10px 12px',
4988
+ fontSize: 'var(--c15t-devtools-font-size-sm)',
4989
+ color: 'var(--c15t-text-muted)'
4990
+ },
4991
+ text: 'No active policy matched for this request.'
4992
+ }),
4993
+ createHint(`Init Source: ${initSource}`)
4994
+ ]
4995
+ }));
4996
+ container.appendChild(createSection({
4997
+ title: 'Policy',
4998
+ children: [
4999
+ policy_createGrid(3, [
5000
+ createCard('ID', activePolicy?.id ?? policyDecision?.policyId ?? '—'),
5001
+ createCard('Model', policy_getModelLabel(activePolicy?.model)),
5002
+ createCard('Scope', getScopeModeLabel(activePolicy?.consent?.scopeMode ?? state.policyScopeMode)),
5003
+ createCard('Categories', formatList(state.policyCategories ?? activePolicy?.consent?.categories)),
5004
+ createCard('Preselected', formatList(activePolicy?.consent?.preselectedCategories)),
5005
+ createCard('Expiry', 'number' == typeof activePolicy?.consent?.expiryDays ? `${activePolicy.consent.expiryDays}d` : '—')
5006
+ ]),
5007
+ createHint(`${initSource} · ${formatFingerprint(policyDecision?.fingerprint)}`)
5008
+ ]
5009
+ }));
5010
+ const uiMode = activePolicy?.ui?.mode;
5011
+ if (uiMode && 'none' !== uiMode) {
5012
+ const bannerCards = buildSurfaceCards('Banner', activePolicy?.ui?.banner, state.policyBanner);
5013
+ const dialogCards = buildSurfaceCards('Dialog', activePolicy?.ui?.dialog, state.policyDialog);
5014
+ if (bannerCards.length > 0 || dialogCards.length > 0) container.appendChild(createSection({
5015
+ title: `UI · ${uiMode}`,
5016
+ children: [
5017
+ policy_createGrid(3, [
5018
+ ...bannerCards,
5019
+ ...dialogCards
5020
+ ])
5021
+ ]
5022
+ }));
5023
+ }
5024
+ const proofLabel = formatProofSummary(activePolicy?.proof);
5025
+ const snapshotLabel = initData?.policySnapshotToken ? 'present' : 'missing';
5026
+ container.appendChild(createSection({
5027
+ title: 'Proof & Snapshot',
5028
+ children: [
5029
+ policy_createGrid(3, [
5030
+ createCard('Proof', proofLabel),
5031
+ createCard('Snapshot', snapshotLabel),
5032
+ createCard('I18n', activePolicy?.i18n?.messageProfile ?? activePolicy?.i18n?.language ?? '—')
5033
+ ])
5034
+ ]
5035
+ }));
5036
+ }
5037
+ function buildSurfaceCards(prefix, policySurface, storeSurface) {
5038
+ const policyLayout = Array.isArray(policySurface?.layout) && 0 === policySurface.layout.length ? null : policySurface?.layout ?? null;
5039
+ const storeLayout = Array.isArray(storeSurface.layout) && 0 === storeSurface.layout.length ? null : storeSurface.layout ?? null;
5040
+ const actions = formatList(policySurface?.allowedActions ?? storeSurface.allowedActions);
5041
+ const primary = policySurface?.primaryAction ?? storeSurface.primaryAction ?? null;
5042
+ const layout = policyLayout ?? storeLayout;
5043
+ const direction = policySurface?.direction ?? storeSurface.direction ?? null;
5044
+ const profile = policySurface?.uiProfile ?? storeSurface.uiProfile ?? null;
5045
+ const scrollLock = policySurface?.scrollLock ?? storeSurface.scrollLock ?? null;
5046
+ if ('—' === actions && !primary && !layout && !direction && !profile && null === scrollLock) return [];
5047
+ const cards = [
5048
+ createCard(`${prefix} Actions`, actions)
5049
+ ];
5050
+ if (primary) cards.push(createCard(`${prefix} Primary`, primary));
5051
+ if (layout) cards.push(createCard(`${prefix} Layout`, Array.isArray(layout) ? layout.map((group)=>Array.isArray(group) ? `[${group.join(', ')}]` : group).join(' / ') : layout));
5052
+ if (direction) cards.push(createCard(`${prefix} Direction`, direction));
5053
+ if (profile) cards.push(createCard(`${prefix} Profile`, profile));
5054
+ if (null !== scrollLock) cards.push(createCard(`${prefix} Scroll Lock`, scrollLock ? 'on' : 'off'));
5055
+ return cards;
5056
+ }
5057
+ function createMatchTraceSection(options) {
5058
+ const { policyDecision, policyId } = options;
5059
+ const entries = buildTraceEntries(policyDecision, policyId);
5060
+ return createSection({
5061
+ title: 'Match Trace',
5062
+ children: [
5063
+ renderer_div({
5064
+ style: {
5065
+ display: 'grid',
5066
+ gridTemplateColumns: '1fr',
5067
+ gap: '4px'
5068
+ },
5069
+ children: entries.map((entry)=>renderer_div({
5070
+ className: styles_components_module.gridCard ?? '',
5071
+ style: {
5072
+ padding: '6px 10px',
5073
+ display: 'flex',
5074
+ alignItems: 'center',
5075
+ justifyContent: 'space-between',
5076
+ gap: '10px'
5077
+ },
5078
+ children: [
5079
+ renderer_span({
5080
+ style: {
5081
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5082
+ color: 'var(--c15t-text-muted)',
5083
+ fontFamily: 'ui-monospace, monospace'
5084
+ },
5085
+ text: entry.step
5086
+ }),
5087
+ renderer_span({
5088
+ style: {
5089
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5090
+ fontFamily: 'ui-monospace, monospace'
5091
+ },
5092
+ text: entry.result
5093
+ })
5094
+ ]
5095
+ }))
5096
+ }),
5097
+ createHint('region → country → default · fallback on geo failure · Simulate via Location tab')
5098
+ ]
5099
+ });
5100
+ }
5101
+ function buildTraceEntries(decision, policyId) {
5102
+ if (!decision) return [
5103
+ {
5104
+ step: 'decision metadata',
5105
+ result: 'UNAVAILABLE'
5106
+ }
5107
+ ];
5108
+ const country = decision.country ?? 'n/a';
5109
+ const regionKey = decision.country && decision.region ? `${decision.country}-${decision.region}` : 'n/a';
5110
+ const resolved = policyId ?? decision.policyId ?? 'unknown';
5111
+ const matched = decision.matchedBy;
5112
+ return [
5113
+ {
5114
+ step: `region(${regionKey})`,
5115
+ result: 'region' === matched ? `MATCH → ${resolved}` : 'MISS'
5116
+ },
5117
+ {
5118
+ step: `country(${country})`,
5119
+ result: 'country' === matched ? `MATCH → ${resolved}` : 'region' === matched ? 'SKIPPED' : 'MISS'
5120
+ },
5121
+ {
5122
+ step: 'fallback(geo-fail)',
5123
+ result: 'fallback' === matched ? `MATCH → ${resolved}` : 'SKIPPED'
5124
+ },
5125
+ {
5126
+ step: 'default(catch-all)',
5127
+ result: 'default' === matched ? `MATCH → ${resolved}` : 'SKIPPED'
5128
+ }
5129
+ ];
5130
+ }
5131
+ function policy_getModelLabel(model) {
5132
+ switch(model){
5133
+ case 'opt-in':
5134
+ return 'Opt-In';
5135
+ case 'opt-out':
5136
+ return 'Opt-Out';
5137
+ case 'iab':
5138
+ return 'IAB TCF';
5139
+ default:
5140
+ return 'None';
5141
+ }
5142
+ }
5143
+ function getScopeModeLabel(mode) {
5144
+ switch(mode){
5145
+ case 'strict':
5146
+ return 'Strict';
5147
+ case 'permissive':
5148
+ return 'Permissive';
5149
+ default:
5150
+ return '—';
5151
+ }
5152
+ }
5153
+ function formatList(items) {
5154
+ if (!items || 0 === items.length) return '—';
5155
+ if (items.includes('*')) return '* (all)';
5156
+ return items.join(', ');
5157
+ }
5158
+ function formatProofSummary(proof) {
5159
+ if (!proof) return '—';
5160
+ const parts = [];
5161
+ if (proof.storeIp) parts.push('IP');
5162
+ if (proof.storeUserAgent) parts.push('UA');
5163
+ if (proof.storeLanguage) parts.push('Lang');
5164
+ return parts.length > 0 ? parts.join(', ') : 'none';
5165
+ }
5166
+ function formatFingerprint(fingerprint) {
5167
+ if (!fingerprint) return 'no fingerprint';
5168
+ if (fingerprint.length <= 12) return fingerprint;
5169
+ return `${fingerprint.slice(0, 8)}…${fingerprint.slice(-4)}`;
5170
+ }
5171
+ function createCard(label, value) {
5172
+ return renderer_div({
5173
+ className: styles_components_module.gridCard ?? '',
5174
+ style: {
5175
+ padding: '8px 10px',
5176
+ minHeight: 'auto',
5177
+ flexDirection: 'column',
5178
+ alignItems: 'flex-start',
5179
+ gap: '2px'
5180
+ },
5181
+ children: [
5182
+ renderer_span({
5183
+ style: {
5184
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5185
+ color: 'var(--c15t-text-muted)'
5186
+ },
5187
+ text: label
5188
+ }),
5189
+ renderer_span({
5190
+ style: {
5191
+ fontSize: 'var(--c15t-font-size-sm)',
5192
+ fontWeight: '500',
5193
+ fontFamily: 'ui-monospace, monospace'
4189
5194
  },
4190
5195
  text: value
4191
5196
  })
4192
5197
  ]
4193
5198
  });
4194
5199
  }
5200
+ function policy_createGrid(columns, children) {
5201
+ return renderer_div({
5202
+ style: {
5203
+ display: 'grid',
5204
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
5205
+ gap: 'var(--c15t-space-sm, 0.5rem)'
5206
+ },
5207
+ children
5208
+ });
5209
+ }
5210
+ function createHint(text) {
5211
+ return renderer_span({
5212
+ className: styles_components_module.overrideHint,
5213
+ text
5214
+ });
5215
+ }
4195
5216
  const dismissedResources = new Set();
4196
5217
  function scanDOM(state) {
4197
5218
  const results = [];
@@ -4357,21 +5378,21 @@ var __webpack_exports__ = {};
4357
5378
  borderBottom: '1px solid var(--c15t-border)'
4358
5379
  },
4359
5380
  children: [
4360
- span({
5381
+ renderer_span({
4361
5382
  style: {
4362
5383
  color: iconColor,
4363
5384
  flexShrink: '0'
4364
5385
  },
4365
5386
  text: icon
4366
5387
  }),
4367
- span({
5388
+ renderer_span({
4368
5389
  style: {
4369
5390
  color: 'var(--c15t-text-muted)',
4370
5391
  flexShrink: '0'
4371
5392
  },
4372
5393
  text: `${resource.type}:`
4373
5394
  }),
4374
- span({
5395
+ renderer_span({
4375
5396
  style: {
4376
5397
  fontWeight: '500',
4377
5398
  color: 'var(--c15t-text)',
@@ -4417,23 +5438,37 @@ var __webpack_exports__ = {};
4417
5438
  <polyline points="16 18 22 12 16 6"></polyline>
4418
5439
  <polyline points="8 6 2 12 8 18"></polyline>
4419
5440
  </svg>`;
4420
- function scripts_renderScriptsPanel(container, options) {
5441
+ const scriptsSearchByContainer = new WeakMap();
5442
+ function renderScriptsPanel(container, options) {
4421
5443
  const { getState, getEvents } = options;
4422
5444
  clearElement(container);
4423
5445
  const state = getState();
4424
- if (!state) return void container.appendChild(renderer_div({
4425
- style: {
4426
- padding: '24px',
4427
- textAlign: 'center',
4428
- color: 'var(--c15t-text-muted)',
4429
- fontSize: 'var(--c15t-devtools-font-size-sm)'
4430
- },
4431
- text: 'Store not connected'
4432
- }));
5446
+ if (!state) return void container.appendChild(createDisconnectedState());
4433
5447
  const scripts = state.scripts || [];
4434
5448
  const loadedScripts = state.loadedScripts || {};
4435
5449
  const networkBlocker = state.networkBlocker;
4436
5450
  const events = getEvents?.() ?? [];
5451
+ const searchQuery = scriptsSearchByContainer.get(container) ?? '';
5452
+ const filteredScripts = scripts.filter((script)=>{
5453
+ if (!searchQuery) return true;
5454
+ const category = 'string' == typeof script.category ? script.category : JSON.stringify(script.category);
5455
+ return `${script.id} ${category}`.toLowerCase().includes(searchQuery);
5456
+ });
5457
+ if (scripts.length > 4) container.appendChild(createSection({
5458
+ title: 'Filter',
5459
+ children: [
5460
+ createInput({
5461
+ value: searchQuery,
5462
+ placeholder: "Filter scripts…",
5463
+ ariaLabel: "Filter scripts",
5464
+ small: true,
5465
+ onInput: (value)=>{
5466
+ scriptsSearchByContainer.set(container, value.trim().toLowerCase());
5467
+ renderScriptsPanel(container, options);
5468
+ }
5469
+ })
5470
+ ]
5471
+ }));
4437
5472
  if (0 === scripts.length) {
4438
5473
  const scriptsSection = createSection({
4439
5474
  title: 'Configured Scripts',
@@ -4450,10 +5485,19 @@ var __webpack_exports__ = {};
4450
5485
  style: {
4451
5486
  display: 'flex',
4452
5487
  flexDirection: 'column',
4453
- gap: '4px'
5488
+ borderTop: '1px solid var(--c15t-border)',
5489
+ borderBottom: '1px solid var(--c15t-border)'
4454
5490
  }
4455
5491
  });
4456
- for (const script of scripts){
5492
+ if (0 === filteredScripts.length) scriptsList.appendChild(renderer_div({
5493
+ style: {
5494
+ padding: '10px 0',
5495
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5496
+ color: 'var(--c15t-text-muted)'
5497
+ },
5498
+ text: "No matching scripts"
5499
+ }));
5500
+ for (const script of filteredScripts){
4457
5501
  const scriptId = script.id;
4458
5502
  const isLoaded = true === loadedScripts[scriptId];
4459
5503
  const category = script.category;
@@ -4477,17 +5521,64 @@ var __webpack_exports__ = {};
4477
5521
  text: status.charAt(0).toUpperCase() + status.slice(1),
4478
5522
  variant: statusVariant
4479
5523
  });
4480
- const item = createListItem({
4481
- title: scriptId,
4482
- description: `Category: ${categoryDisplay}`,
4483
- actions: [
4484
- badge
5524
+ const row = renderer_div({
5525
+ style: {
5526
+ display: 'flex',
5527
+ alignItems: 'center',
5528
+ justifyContent: 'space-between',
5529
+ gap: '8px',
5530
+ padding: '8px 0',
5531
+ borderBottom: '1px solid var(--c15t-border)'
5532
+ },
5533
+ children: [
5534
+ renderer_div({
5535
+ style: {
5536
+ display: 'flex',
5537
+ flexDirection: 'column',
5538
+ gap: '2px',
5539
+ minWidth: '0',
5540
+ flex: '1'
5541
+ },
5542
+ children: [
5543
+ renderer_div({
5544
+ style: {
5545
+ fontSize: 'var(--c15t-font-size-sm)',
5546
+ fontWeight: '500',
5547
+ color: 'var(--c15t-text)',
5548
+ overflow: 'hidden',
5549
+ textOverflow: 'ellipsis',
5550
+ whiteSpace: 'nowrap'
5551
+ },
5552
+ text: scriptId
5553
+ }),
5554
+ renderer_div({
5555
+ style: {
5556
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5557
+ color: 'var(--c15t-text-muted)',
5558
+ overflow: 'hidden',
5559
+ textOverflow: 'ellipsis',
5560
+ whiteSpace: 'nowrap'
5561
+ },
5562
+ text: `Category: ${categoryDisplay}`
5563
+ })
5564
+ ]
5565
+ }),
5566
+ renderer_div({
5567
+ style: {
5568
+ flexShrink: '0'
5569
+ },
5570
+ children: [
5571
+ badge
5572
+ ]
5573
+ })
4485
5574
  ]
4486
5575
  });
4487
- scriptsList.appendChild(item);
5576
+ scriptsList.appendChild(row);
4488
5577
  }
5578
+ const lastRow = scriptsList.lastElementChild;
5579
+ if (lastRow) lastRow.style.borderBottom = 'none';
4489
5580
  const scriptsSection = createSection({
4490
- title: `Configured Scripts (${scripts.length})`,
5581
+ title: `Configured Scripts (${filteredScripts.length}/${scripts.length})`,
4491
5582
  children: [
4492
5583
  scriptsList
4493
5584
  ]
@@ -4629,53 +5720,6 @@ var __webpack_exports__ = {};
4629
5720
  if (text.length <= maxLength) return text;
4630
5721
  return `${text.slice(0, maxLength - 3)}...`;
4631
5722
  }
4632
- const DEVTOOLS_OVERRIDES_STORAGE_KEY = 'c15t-devtools-overrides';
4633
- function normalizeStringValue(value) {
4634
- if ('string' != typeof value) return;
4635
- const normalized = value.trim();
4636
- return normalized.length > 0 ? normalized : void 0;
4637
- }
4638
- function normalizeBooleanValue(value) {
4639
- return 'boolean' == typeof value ? value : void 0;
4640
- }
4641
- function normalizeOverrides(value) {
4642
- if (!value || 'object' != typeof value) return null;
4643
- const source = value;
4644
- const overrides = {
4645
- country: normalizeStringValue(source.country),
4646
- region: normalizeStringValue(source.region),
4647
- language: normalizeStringValue(source.language),
4648
- gpc: normalizeBooleanValue(source.gpc)
4649
- };
4650
- return hasPersistedOverrides(overrides) ? overrides : null;
4651
- }
4652
- function hasPersistedOverrides(overrides) {
4653
- return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
4654
- }
4655
- function override_storage_loadPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4656
- if ('undefined' == typeof window) return null;
4657
- try {
4658
- const stored = localStorage.getItem(storageKey);
4659
- if (!stored) return null;
4660
- const parsed = JSON.parse(stored);
4661
- return normalizeOverrides(parsed);
4662
- } catch {
4663
- return null;
4664
- }
4665
- }
4666
- function override_storage_persistOverrides(overrides, storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4667
- if ('undefined' == typeof window) return;
4668
- try {
4669
- if (!hasPersistedOverrides(overrides)) return void localStorage.removeItem(storageKey);
4670
- localStorage.setItem(storageKey, JSON.stringify(overrides));
4671
- } catch {}
4672
- }
4673
- function override_storage_clearPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4674
- if ('undefined' == typeof window) return;
4675
- try {
4676
- localStorage.removeItem(storageKey);
4677
- } catch {}
4678
- }
4679
5723
  const STORAGE_KEYS = {
4680
5724
  C15T: 'c15t',
4681
5725
  PENDING_SYNC: 'c15t:pending-consent-sync',
@@ -4701,7 +5745,7 @@ var __webpack_exports__ = {};
4701
5745
  localStorage.removeItem(STORAGE_KEYS.EUCONSENT);
4702
5746
  } catch {}
4703
5747
  }
4704
- async function reset_consents_resetAllConsents(store, stateManager) {
5748
+ async function resetAllConsents(store, stateManager) {
4705
5749
  const storeState = store.getState();
4706
5750
  storeState.resetConsents();
4707
5751
  clearAllCookies();
@@ -4712,49 +5756,287 @@ var __webpack_exports__ = {};
4712
5756
  message: 'All consents reset (storage cleared)'
4713
5757
  });
4714
5758
  }
4715
- const STORAGE_KEY = 'c15t-devtools-events';
4716
- function loadPersistedEvents() {
4717
- if ('undefined' == typeof window) return [];
4718
- try {
4719
- const stored = sessionStorage.getItem(STORAGE_KEY);
4720
- if (stored) return JSON.parse(stored);
4721
- } catch {}
4722
- return [];
4723
- }
4724
- function persistEvents(events) {
4725
- if ('undefined' == typeof window) return;
4726
- try {
4727
- sessionStorage.setItem(STORAGE_KEY, JSON.stringify(events));
4728
- } catch {}
4729
- }
4730
- function state_manager_createStateManager(initialState = {}) {
4731
- const persistedEvents = loadPersistedEvents();
4732
- let state = {
4733
- isOpen: false,
4734
- activeTab: 'location',
4735
- position: 'bottom-right',
4736
- isConnected: false,
4737
- eventLog: persistedEvents,
4738
- maxEventLogSize: 100,
4739
- ...initialState
5759
+ function panel_renderer_createPanelRenderer(config) {
5760
+ const { storeConnector, stateManager, enableEventLogging = true, onPersistOverrides, onClearPersistedOverrides, onCopyState, onExportDebugBundle } = config;
5761
+ const getStoreState = ()=>storeConnector.getState();
5762
+ const logEvent = (type, message, data)=>{
5763
+ if (enableEventLogging) stateManager.addEvent({
5764
+ type,
5765
+ message,
5766
+ data
5767
+ });
4740
5768
  };
4741
- const listeners = new Set();
4742
- function notify(prevState) {
4743
- for (const listener of listeners)listener(state, prevState);
4744
- }
4745
- function setState(partial) {
4746
- const prevState = state;
4747
- state = {
4748
- ...state,
4749
- ...partial
4750
- };
4751
- notify(prevState);
4752
- }
4753
- return {
4754
- getState: ()=>state,
4755
- subscribe: (listener)=>{
4756
- listeners.add(listener);
4757
- return ()=>{
5769
+ const resetConsents = async ()=>{
5770
+ const store = storeConnector.getStore();
5771
+ if (store) await resetAllConsents(store, enableEventLogging ? stateManager : void 0);
5772
+ };
5773
+ const renderPanel = (container, tab)=>{
5774
+ switch(tab){
5775
+ case 'consents':
5776
+ renderConsentsPanel(container, {
5777
+ getState: getStoreState,
5778
+ onConsentChange: (name, value)=>{
5779
+ const store = storeConnector.getStore();
5780
+ if (store) {
5781
+ const consentName = String(name);
5782
+ store.getState().setSelectedConsent(consentName, value);
5783
+ logEvent('info', `${consentName} toggled to ${value} (not saved)`, {
5784
+ name: consentName,
5785
+ value
5786
+ });
5787
+ }
5788
+ },
5789
+ onSave: ()=>{
5790
+ const store = storeConnector.getStore();
5791
+ if (store) {
5792
+ store.getState().saveConsents('custom');
5793
+ logEvent('consent_save', 'Saved consent preferences');
5794
+ }
5795
+ },
5796
+ onAcceptAll: ()=>{
5797
+ const store = storeConnector.getStore();
5798
+ if (store) {
5799
+ store.getState().saveConsents('all');
5800
+ logEvent('consent_save', 'Accepted all consents');
5801
+ }
5802
+ },
5803
+ onRejectAll: ()=>{
5804
+ const store = storeConnector.getStore();
5805
+ if (store) {
5806
+ store.getState().saveConsents('necessary');
5807
+ logEvent('consent_save', 'Rejected all optional consents');
5808
+ }
5809
+ },
5810
+ onReset: resetConsents
5811
+ });
5812
+ break;
5813
+ case 'location':
5814
+ renderLocationPanel(container, {
5815
+ getState: getStoreState,
5816
+ onApplyOverrides: async (overrides)=>{
5817
+ const store = storeConnector.getStore();
5818
+ if (store) {
5819
+ await store.getState().setOverrides({
5820
+ country: overrides.country,
5821
+ region: overrides.region,
5822
+ language: overrides.language,
5823
+ gpc: overrides.gpc
5824
+ });
5825
+ logEvent('info', 'Overrides updated', {
5826
+ country: overrides.country,
5827
+ region: overrides.region,
5828
+ language: overrides.language,
5829
+ gpc: overrides.gpc
5830
+ });
5831
+ onPersistOverrides?.({
5832
+ country: overrides.country,
5833
+ region: overrides.region,
5834
+ language: overrides.language,
5835
+ gpc: overrides.gpc
5836
+ });
5837
+ }
5838
+ },
5839
+ onClearOverrides: async ()=>{
5840
+ const store = storeConnector.getStore();
5841
+ if (store) {
5842
+ await store.getState().setOverrides({
5843
+ country: void 0,
5844
+ region: void 0,
5845
+ language: void 0,
5846
+ gpc: void 0
5847
+ });
5848
+ logEvent('info', 'Overrides cleared');
5849
+ onClearPersistedOverrides?.();
5850
+ }
5851
+ }
5852
+ });
5853
+ break;
5854
+ case 'policy':
5855
+ renderPolicyPanel(container, {
5856
+ getState: getStoreState
5857
+ });
5858
+ break;
5859
+ case "scripts":
5860
+ renderScriptsPanel(container, {
5861
+ getState: getStoreState,
5862
+ getEvents: ()=>stateManager.getState().eventLog
5863
+ });
5864
+ break;
5865
+ case 'iab':
5866
+ renderIabPanel(container, {
5867
+ getState: getStoreState,
5868
+ onSetPurposeConsent: (purposeId, value)=>{
5869
+ const iab = storeConnector.getStore()?.getState().iab;
5870
+ if (!iab) return;
5871
+ iab.setPurposeConsent(purposeId, value);
5872
+ logEvent('iab', `IAB purpose ${purposeId} set to ${value}`);
5873
+ },
5874
+ onSetVendorConsent: (vendorId, value)=>{
5875
+ const iab = storeConnector.getStore()?.getState().iab;
5876
+ if (!iab) return;
5877
+ iab.setVendorConsent(vendorId, value);
5878
+ logEvent('iab', `IAB vendor ${vendorId} set to ${value}`);
5879
+ },
5880
+ onSetSpecialFeatureOptIn: (featureId, value)=>{
5881
+ const iab = storeConnector.getStore()?.getState().iab;
5882
+ if (!iab) return;
5883
+ iab.setSpecialFeatureOptIn(featureId, value);
5884
+ logEvent('iab', `IAB feature ${featureId} set to ${value}`);
5885
+ },
5886
+ onAcceptAll: ()=>{
5887
+ const iab = storeConnector.getStore()?.getState().iab;
5888
+ if (!iab) return;
5889
+ iab.acceptAll();
5890
+ logEvent('iab', 'IAB accept all selected');
5891
+ },
5892
+ onRejectAll: ()=>{
5893
+ const iab = storeConnector.getStore()?.getState().iab;
5894
+ if (!iab) return;
5895
+ iab.rejectAll();
5896
+ logEvent('iab', 'IAB reject all selected');
5897
+ },
5898
+ onSave: ()=>{
5899
+ const iab = storeConnector.getStore()?.getState().iab;
5900
+ if (!iab) return;
5901
+ iab.save().then(()=>logEvent('iab', 'IAB preferences saved')).catch((error)=>{
5902
+ logEvent('error', `Failed to save IAB preferences: ${String(error)}`);
5903
+ });
5904
+ },
5905
+ onReset: resetConsents
5906
+ });
5907
+ break;
5908
+ case 'events':
5909
+ renderEventsPanel(container, {
5910
+ getEvents: ()=>stateManager.getState().eventLog,
5911
+ onClear: ()=>{
5912
+ stateManager.clearEventLog();
5913
+ logEvent('info', 'Event log cleared');
5914
+ }
5915
+ });
5916
+ break;
5917
+ case 'actions':
5918
+ renderActionsPanel(container, {
5919
+ getState: getStoreState,
5920
+ onResetConsents: resetConsents,
5921
+ onRefetchBanner: async ()=>{
5922
+ const store = storeConnector.getStore();
5923
+ if (store) {
5924
+ await store.getState().initConsentManager();
5925
+ logEvent('info', 'Banner data refetched');
5926
+ }
5927
+ },
5928
+ onShowBanner: ()=>{
5929
+ const store = storeConnector.getStore();
5930
+ if (store) {
5931
+ store.getState().setActiveUI('banner', {
5932
+ force: true
5933
+ });
5934
+ logEvent('info', 'Banner shown');
5935
+ }
5936
+ },
5937
+ onOpenPreferences: ()=>{
5938
+ const store = storeConnector.getStore();
5939
+ if (store) {
5940
+ store.getState().setActiveUI('dialog');
5941
+ logEvent('info', 'Preferences dialog opened');
5942
+ }
5943
+ },
5944
+ onCopyState: ()=>{
5945
+ const state = getStoreState();
5946
+ if (state) if (onCopyState) {
5947
+ const result = onCopyState(state);
5948
+ if (result instanceof Promise) result.then((ok)=>{
5949
+ logEvent(ok ? 'info' : 'error', ok ? 'State copied to clipboard' : 'Failed to copy state');
5950
+ }).catch(()=>{
5951
+ logEvent('error', 'Failed to copy state');
5952
+ });
5953
+ else logEvent(result ? 'info' : 'error', result ? 'State copied to clipboard' : 'Failed to copy state');
5954
+ } else navigator.clipboard.writeText(JSON.stringify(state, null, 2)).then(()=>{
5955
+ logEvent('info', 'State copied to clipboard');
5956
+ }).catch(()=>{
5957
+ logEvent('error', 'Failed to copy state');
5958
+ });
5959
+ },
5960
+ onExportDebugBundle: onExportDebugBundle ? ()=>{
5961
+ try {
5962
+ onExportDebugBundle();
5963
+ logEvent('info', 'Debug bundle exported');
5964
+ } catch {
5965
+ logEvent('error', 'Failed to export debug bundle');
5966
+ }
5967
+ } : void 0
5968
+ });
5969
+ break;
5970
+ }
5971
+ };
5972
+ return {
5973
+ renderPanel,
5974
+ getStoreState,
5975
+ resetConsents
5976
+ };
5977
+ }
5978
+ const STORAGE_KEY = 'c15t-devtools-events';
5979
+ const ACTIVE_TAB_STORAGE_KEY = 'c15t-devtools-active-tab';
5980
+ function loadPersistedEvents() {
5981
+ if ('undefined' == typeof window) return [];
5982
+ try {
5983
+ const stored = sessionStorage.getItem(STORAGE_KEY);
5984
+ if (stored) return JSON.parse(stored);
5985
+ } catch {}
5986
+ return [];
5987
+ }
5988
+ function persistEvents(events) {
5989
+ if ('undefined' == typeof window) return;
5990
+ try {
5991
+ sessionStorage.setItem(STORAGE_KEY, JSON.stringify(events));
5992
+ } catch {}
5993
+ }
5994
+ function isDevToolsTab(value) {
5995
+ return 'consents' === value || 'location' === value || 'policy' === value || "scripts" === value || 'iab' === value || 'events' === value || 'actions' === value;
5996
+ }
5997
+ function loadPersistedActiveTab() {
5998
+ if ('undefined' == typeof window) return null;
5999
+ try {
6000
+ const stored = localStorage.getItem(ACTIVE_TAB_STORAGE_KEY);
6001
+ if (isDevToolsTab(stored)) return stored;
6002
+ } catch {}
6003
+ return null;
6004
+ }
6005
+ function persistActiveTab(tab) {
6006
+ if ('undefined' == typeof window) return;
6007
+ try {
6008
+ localStorage.setItem(ACTIVE_TAB_STORAGE_KEY, tab);
6009
+ } catch {}
6010
+ }
6011
+ function state_manager_createStateManager(initialState = {}) {
6012
+ const persistedEvents = loadPersistedEvents();
6013
+ const persistedActiveTab = loadPersistedActiveTab();
6014
+ let state = {
6015
+ isOpen: false,
6016
+ activeTab: persistedActiveTab ?? 'location',
6017
+ position: 'bottom-right',
6018
+ isConnected: false,
6019
+ eventLog: persistedEvents,
6020
+ maxEventLogSize: 100,
6021
+ ...initialState
6022
+ };
6023
+ const listeners = new Set();
6024
+ function notify(prevState) {
6025
+ for (const listener of listeners)listener(state, prevState);
6026
+ }
6027
+ function setState(partial) {
6028
+ const prevState = state;
6029
+ state = {
6030
+ ...state,
6031
+ ...partial
6032
+ };
6033
+ notify(prevState);
6034
+ }
6035
+ return {
6036
+ getState: ()=>state,
6037
+ subscribe: (listener)=>{
6038
+ listeners.add(listener);
6039
+ return ()=>{
4758
6040
  listeners.delete(listener);
4759
6041
  };
4760
6042
  },
@@ -4772,6 +6054,7 @@ var __webpack_exports__ = {};
4772
6054
  setState({
4773
6055
  activeTab: tab
4774
6056
  });
6057
+ persistActiveTab(tab);
4775
6058
  },
4776
6059
  setPosition: (position)=>{
4777
6060
  setState({
@@ -4817,22 +6100,52 @@ var __webpack_exports__ = {};
4817
6100
  let reconnectAttempts = 0;
4818
6101
  let hasNotifiedDisconnect = false;
4819
6102
  const listeners = new Set();
6103
+ const diagnosticsListeners = new Set();
6104
+ let diagnostics = {
6105
+ namespace,
6106
+ reconnectAttempts: 0,
6107
+ nextRetryInMs: null,
6108
+ lastError: null,
6109
+ isPolling: false,
6110
+ disconnectNotified: false
6111
+ };
4820
6112
  const INITIAL_RETRY_DELAY_MS = 100;
4821
6113
  const MAX_RETRY_DELAY_MS = 2000;
4822
6114
  const DISCONNECT_NOTIFY_ATTEMPTS = 5;
6115
+ function updateDiagnostics(partial, notify = true) {
6116
+ diagnostics = {
6117
+ ...diagnostics,
6118
+ ...partial
6119
+ };
6120
+ if (!notify) return;
6121
+ for (const listener of diagnosticsListeners)listener(diagnostics);
6122
+ }
4823
6123
  function clearReconnectTimer() {
4824
6124
  if (reconnectTimeout) {
4825
6125
  clearTimeout(reconnectTimeout);
4826
6126
  reconnectTimeout = null;
6127
+ updateDiagnostics({
6128
+ isPolling: false,
6129
+ nextRetryInMs: null
6130
+ });
4827
6131
  }
4828
6132
  }
4829
6133
  function resetReconnectState() {
4830
6134
  reconnectAttempts = 0;
4831
6135
  hasNotifiedDisconnect = false;
6136
+ updateDiagnostics({
6137
+ reconnectAttempts: 0,
6138
+ nextRetryInMs: null,
6139
+ lastError: null,
6140
+ disconnectNotified: false
6141
+ });
4832
6142
  }
4833
6143
  function notifyDisconnectedOnce() {
4834
6144
  if (hasNotifiedDisconnect) return;
4835
6145
  hasNotifiedDisconnect = true;
6146
+ updateDiagnostics({
6147
+ disconnectNotified: true
6148
+ });
4836
6149
  onDisconnect?.();
4837
6150
  }
4838
6151
  function tryConnect() {
@@ -4853,16 +6166,31 @@ var __webpack_exports__ = {};
4853
6166
  onConnect?.(currentState, store);
4854
6167
  clearReconnectTimer();
4855
6168
  resetReconnectState();
6169
+ updateDiagnostics({
6170
+ lastError: null
6171
+ });
4856
6172
  return true;
4857
6173
  }
6174
+ updateDiagnostics({
6175
+ lastError: `Store "${namespace}" not found on window`
6176
+ });
4858
6177
  return false;
4859
6178
  }
4860
6179
  function scheduleReconnect(immediate = false) {
4861
6180
  if (store || reconnectTimeout) return;
4862
6181
  const delay = immediate ? 0 : Math.min(INITIAL_RETRY_DELAY_MS * 2 ** Math.min(reconnectAttempts, 5), MAX_RETRY_DELAY_MS);
6182
+ updateDiagnostics({
6183
+ isPolling: true,
6184
+ nextRetryInMs: delay,
6185
+ reconnectAttempts
6186
+ });
4863
6187
  reconnectTimeout = setTimeout(()=>{
4864
6188
  reconnectTimeout = null;
4865
6189
  reconnectAttempts++;
6190
+ updateDiagnostics({
6191
+ reconnectAttempts,
6192
+ nextRetryInMs: null
6193
+ });
4866
6194
  if (tryConnect()) return;
4867
6195
  if (reconnectAttempts >= DISCONNECT_NOTIFY_ATTEMPTS) notifyDisconnectedOnce();
4868
6196
  scheduleReconnect();
@@ -4884,6 +6212,14 @@ var __webpack_exports__ = {};
4884
6212
  listeners.delete(listener);
4885
6213
  };
4886
6214
  },
6215
+ getDiagnostics: ()=>diagnostics,
6216
+ subscribeDiagnostics: (listener)=>{
6217
+ diagnosticsListeners.add(listener);
6218
+ listener(diagnostics);
6219
+ return ()=>{
6220
+ diagnosticsListeners.delete(listener);
6221
+ };
6222
+ },
4887
6223
  retryConnection: ()=>{
4888
6224
  if (store) return;
4889
6225
  resetReconnectState();
@@ -4897,6 +6233,134 @@ var __webpack_exports__ = {};
4897
6233
  }
4898
6234
  store = null;
4899
6235
  listeners.clear();
6236
+ diagnosticsListeners.clear();
6237
+ }
6238
+ };
6239
+ }
6240
+ const REGISTRY_KEY = '__c15tDevToolsInstrumentationRegistry';
6241
+ let fallbackRegistry = null;
6242
+ function getRegistry() {
6243
+ if ('undefined' == typeof window) {
6244
+ if (!fallbackRegistry) fallbackRegistry = new Map();
6245
+ return fallbackRegistry;
6246
+ }
6247
+ const host = window;
6248
+ const existing = host[REGISTRY_KEY];
6249
+ if (existing) return existing;
6250
+ const registry = new Map();
6251
+ host[REGISTRY_KEY] = registry;
6252
+ return registry;
6253
+ }
6254
+ function getBlockedRequestMessage(payload) {
6255
+ const data = payload;
6256
+ const method = 'string' == typeof data?.method ? data.method.toUpperCase() : 'REQUEST';
6257
+ const url = 'string' == typeof data?.url ? data.url : 'unknown-url';
6258
+ return `Network blocked: ${method} ${url}`;
6259
+ }
6260
+ function emitEvent(entry, event) {
6261
+ for (const listener of entry.listeners)listener(event);
6262
+ }
6263
+ function ensureNetworkBlockerWrapped(entry) {
6264
+ const blocker = entry.store.getState().networkBlocker;
6265
+ if (!blocker) return;
6266
+ if (blocker.onRequestBlocked === entry.wrappedNetworkBlockedCallback) return;
6267
+ entry.originalNetworkBlockedCallback = blocker.onRequestBlocked;
6268
+ entry.wrappedNetworkBlockedCallback = (payload)=>{
6269
+ emitEvent(entry, {
6270
+ type: 'network',
6271
+ message: getBlockedRequestMessage(payload),
6272
+ data: payload
6273
+ });
6274
+ if ('function' == typeof entry.originalNetworkBlockedCallback) entry.originalNetworkBlockedCallback(payload);
6275
+ };
6276
+ entry.store.getState().setNetworkBlocker({
6277
+ ...blocker,
6278
+ onRequestBlocked: entry.wrappedNetworkBlockedCallback
6279
+ });
6280
+ }
6281
+ function restoreInstrumentation(entry) {
6282
+ entry.stopWatchingStore?.();
6283
+ entry.stopWatchingStore = null;
6284
+ const state = entry.store.getState();
6285
+ state.setCallback('onBannerFetched', entry.originalCallbacks.onBannerFetched);
6286
+ state.setCallback('onConsentSet', entry.originalCallbacks.onConsentSet);
6287
+ state.setCallback('onError', entry.originalCallbacks.onError);
6288
+ state.setCallback('onBeforeConsentRevocationReload', entry.originalCallbacks.onBeforeConsentRevocationReload);
6289
+ const blocker = state.networkBlocker;
6290
+ if (blocker && blocker.onRequestBlocked === entry.wrappedNetworkBlockedCallback) state.setNetworkBlocker({
6291
+ ...blocker,
6292
+ onRequestBlocked: entry.originalNetworkBlockedCallback
6293
+ });
6294
+ entry.wrappedNetworkBlockedCallback = null;
6295
+ }
6296
+ function createInstrumentationEntry(store) {
6297
+ const entry = {
6298
+ store,
6299
+ listeners: new Set(),
6300
+ originalCallbacks: {
6301
+ ...store.getState().callbacks
6302
+ },
6303
+ originalNetworkBlockedCallback: store.getState().networkBlocker?.onRequestBlocked,
6304
+ wrappedNetworkBlockedCallback: null,
6305
+ stopWatchingStore: null
6306
+ };
6307
+ store.getState().setCallback('onBannerFetched', (payload)=>{
6308
+ const jurisdiction = payload.jurisdiction;
6309
+ emitEvent(entry, {
6310
+ type: 'info',
6311
+ message: `Banner fetched: ${String(jurisdiction)}`,
6312
+ data: payload
6313
+ });
6314
+ if ('function' == typeof entry.originalCallbacks.onBannerFetched) entry.originalCallbacks.onBannerFetched(payload);
6315
+ });
6316
+ store.getState().setCallback('onConsentSet', (payload)=>{
6317
+ emitEvent(entry, {
6318
+ type: 'consent_set',
6319
+ message: 'Consent preferences updated',
6320
+ data: payload
6321
+ });
6322
+ if ('function' == typeof entry.originalCallbacks.onConsentSet) entry.originalCallbacks.onConsentSet(payload);
6323
+ });
6324
+ store.getState().setCallback('onError', (payload)=>{
6325
+ const errorMessage = payload.error;
6326
+ emitEvent(entry, {
6327
+ type: 'error',
6328
+ message: `Error: ${String(errorMessage)}`,
6329
+ data: payload
6330
+ });
6331
+ if ('function' == typeof entry.originalCallbacks.onError) entry.originalCallbacks.onError(payload);
6332
+ });
6333
+ store.getState().setCallback('onBeforeConsentRevocationReload', (payload)=>{
6334
+ emitEvent(entry, {
6335
+ type: 'info',
6336
+ message: 'Consent revocation - page will reload',
6337
+ data: payload
6338
+ });
6339
+ if ('function' == typeof entry.originalCallbacks.onBeforeConsentRevocationReload) entry.originalCallbacks.onBeforeConsentRevocationReload(payload);
6340
+ });
6341
+ ensureNetworkBlockerWrapped(entry);
6342
+ entry.stopWatchingStore = store.subscribe(()=>{
6343
+ ensureNetworkBlockerWrapped(entry);
6344
+ });
6345
+ return entry;
6346
+ }
6347
+ function store_instrumentation_registerStoreInstrumentation(options) {
6348
+ const { namespace, store, onEvent } = options;
6349
+ const registry = getRegistry();
6350
+ let entry = registry.get(namespace);
6351
+ if (!entry || entry.store !== store) {
6352
+ if (entry) restoreInstrumentation(entry);
6353
+ entry = createInstrumentationEntry(store);
6354
+ registry.set(namespace, entry);
6355
+ }
6356
+ entry.listeners.add(onEvent);
6357
+ return ()=>{
6358
+ const current = registry.get(namespace);
6359
+ if (!current) return;
6360
+ current.listeners.delete(onEvent);
6361
+ if (0 === current.listeners.size) {
6362
+ restoreInstrumentation(current);
6363
+ registry.delete(namespace);
4900
6364
  }
4901
6365
  };
4902
6366
  }
@@ -4923,12 +6387,6 @@ var __webpack_exports__ = {};
4923
6387
  function persistedOverridesEqual(a, b) {
4924
6388
  return a.country === b.country && a.region === b.region && a.language === b.language && a.gpc === b.gpc;
4925
6389
  }
4926
- function getBlockedRequestMessage(payload) {
4927
- const data = payload;
4928
- const method = 'string' == typeof data?.method ? data.method.toUpperCase() : 'REQUEST';
4929
- const url = 'string' == typeof data?.url ? data.url : 'unknown-url';
4930
- return `Network blocked: ${method} ${url}`;
4931
- }
4932
6390
  function prefersReducedMotion() {
4933
6391
  return 'undefined' != typeof window && 'function' == typeof window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
4934
6392
  }
@@ -4989,74 +6447,43 @@ var __webpack_exports__ = {};
4989
6447
  destroy: clearAnimationState
4990
6448
  };
4991
6449
  }
6450
+ function createStateCopy(state) {
6451
+ return {
6452
+ consents: state.consents,
6453
+ selectedConsents: state.selectedConsents,
6454
+ consentInfo: state.consentInfo,
6455
+ locationInfo: state.locationInfo,
6456
+ model: state.model,
6457
+ overrides: state.overrides,
6458
+ scripts: state.scripts?.map((script)=>({
6459
+ id: script.id
6460
+ })),
6461
+ loadedScripts: state.loadedScripts
6462
+ };
6463
+ }
4992
6464
  function createDevTools(options = {}) {
4993
6465
  const { namespace = 'c15tStore', position = 'bottom-right', defaultOpen = false } = options;
4994
6466
  const stateManager = state_manager_createStateManager({
4995
6467
  position,
4996
6468
  isOpen: defaultOpen
4997
6469
  });
4998
- let originalCallbacks = {};
4999
- let originalNetworkBlockedCallback;
5000
- let hasWrappedNetworkBlockerCallback = false;
6470
+ let detachInstrumentation = null;
5001
6471
  const storeConnector = store_connector_createStoreConnector({
5002
6472
  namespace,
5003
- onConnect: (state, store)=>{
6473
+ onConnect: (_state, store)=>{
6474
+ detachInstrumentation?.();
6475
+ detachInstrumentation = store_instrumentation_registerStoreInstrumentation({
6476
+ namespace,
6477
+ store,
6478
+ onEvent: (event)=>{
6479
+ stateManager.addEvent(event);
6480
+ }
6481
+ });
5004
6482
  stateManager.setConnected(true);
5005
6483
  stateManager.addEvent({
5006
6484
  type: 'info',
5007
6485
  message: 'Connected to c15tStore'
5008
6486
  });
5009
- originalCallbacks = {
5010
- ...state.callbacks
5011
- };
5012
- store.getState().setCallback('onBannerFetched', (payload)=>{
5013
- stateManager.addEvent({
5014
- type: 'info',
5015
- message: `Banner fetched: ${String(payload.jurisdiction)}`,
5016
- data: payload
5017
- });
5018
- if ('function' == typeof originalCallbacks.onBannerFetched) originalCallbacks.onBannerFetched(payload);
5019
- });
5020
- store.getState().setCallback('onConsentSet', (payload)=>{
5021
- stateManager.addEvent({
5022
- type: 'consent_set',
5023
- message: 'Consent preferences updated',
5024
- data: payload
5025
- });
5026
- if ('function' == typeof originalCallbacks.onConsentSet) originalCallbacks.onConsentSet(payload);
5027
- });
5028
- store.getState().setCallback('onError', (payload)=>{
5029
- stateManager.addEvent({
5030
- type: 'error',
5031
- message: `Error: ${payload.error}`,
5032
- data: payload
5033
- });
5034
- if ('function' == typeof originalCallbacks.onError) originalCallbacks.onError(payload);
5035
- });
5036
- store.getState().setCallback('onBeforeConsentRevocationReload', (payload)=>{
5037
- stateManager.addEvent({
5038
- type: 'info',
5039
- message: 'Consent revocation - page will reload',
5040
- data: payload
5041
- });
5042
- if ('function' == typeof originalCallbacks.onBeforeConsentRevocationReload) originalCallbacks.onBeforeConsentRevocationReload(payload);
5043
- });
5044
- const currentNetworkBlocker = store.getState().networkBlocker;
5045
- if (currentNetworkBlocker && !hasWrappedNetworkBlockerCallback) {
5046
- originalNetworkBlockedCallback = currentNetworkBlocker.onRequestBlocked;
5047
- hasWrappedNetworkBlockerCallback = true;
5048
- store.getState().setNetworkBlocker({
5049
- ...currentNetworkBlocker,
5050
- onRequestBlocked: (payload)=>{
5051
- stateManager.addEvent({
5052
- type: 'network',
5053
- message: getBlockedRequestMessage(payload),
5054
- data: payload
5055
- });
5056
- if ('function' == typeof originalNetworkBlockedCallback) originalNetworkBlockedCallback(payload);
5057
- }
5058
- });
5059
- }
5060
6487
  const persistedOverrides = override_storage_loadPersistedOverrides();
5061
6488
  if (persistedOverrides) {
5062
6489
  const currentOverrides = normalizeOverridesForPersistence(store.getState().overrides);
@@ -5086,6 +6513,8 @@ var __webpack_exports__ = {};
5086
6513
  },
5087
6514
  onDisconnect: ()=>{
5088
6515
  stateManager.setConnected(false);
6516
+ detachInstrumentation?.();
6517
+ detachInstrumentation = null;
5089
6518
  stateManager.addEvent({
5090
6519
  type: 'error',
5091
6520
  message: 'Disconnected from c15tStore'
@@ -5093,6 +6522,31 @@ var __webpack_exports__ = {};
5093
6522
  },
5094
6523
  onStateChange: ()=>{}
5095
6524
  });
6525
+ const panelRenderer = panel_renderer_createPanelRenderer({
6526
+ storeConnector,
6527
+ stateManager,
6528
+ enableEventLogging: true,
6529
+ onPersistOverrides: override_storage_persistOverrides,
6530
+ onClearPersistedOverrides: override_storage_clearPersistedOverrides,
6531
+ onCopyState: async (state)=>{
6532
+ try {
6533
+ await navigator.clipboard.writeText(JSON.stringify(createStateCopy(state), null, 2));
6534
+ return true;
6535
+ } catch {
6536
+ return false;
6537
+ }
6538
+ },
6539
+ onExportDebugBundle: ()=>{
6540
+ const bundle = debug_bundle_createDebugBundle({
6541
+ namespace,
6542
+ devToolsState: stateManager.getState(),
6543
+ connection: storeConnector.getDiagnostics(),
6544
+ recentEvents: stateManager.getState().eventLog.slice(0, 100),
6545
+ storeState: debug_bundle_sanitizeStoreState(storeConnector.getState())
6546
+ });
6547
+ debug_bundle_downloadDebugBundle(bundle);
6548
+ }
6549
+ });
5096
6550
  let tabsInstance = null;
5097
6551
  const panelHeightAnimator = createPanelHeightAnimator();
5098
6552
  const panelInstance = createPanel({
@@ -5100,19 +6554,24 @@ var __webpack_exports__ = {};
5100
6554
  storeConnector,
5101
6555
  namespace,
5102
6556
  onRenderContent: (container)=>{
5103
- renderContent(container, stateManager, storeConnector);
6557
+ renderContent(container);
5104
6558
  }
5105
6559
  });
5106
- function renderContent(container, stateManager, storeConnector) {
6560
+ function renderContent(container) {
5107
6561
  const panel = container.parentElement;
5108
6562
  const previousPanelHeight = panel?.getBoundingClientRect().height ?? 0;
5109
6563
  clearElement(container);
5110
6564
  const storeState = storeConnector.getState();
5111
6565
  const disabledTabs = [];
5112
6566
  if (!storeState || 'iab' !== storeState.model) disabledTabs.push('iab');
6567
+ let currentActiveTab = stateManager.getState().activeTab;
6568
+ if (disabledTabs.includes(currentActiveTab)) {
6569
+ stateManager.setActiveTab('consents');
6570
+ currentActiveTab = 'consents';
6571
+ }
5113
6572
  if (tabsInstance) tabsInstance.destroy();
5114
6573
  tabsInstance = tabs_createTabs({
5115
- activeTab: stateManager.getState().activeTab,
6574
+ activeTab: currentActiveTab,
5116
6575
  onTabChange: (tab)=>{
5117
6576
  stateManager.setActiveTab(tab);
5118
6577
  },
@@ -5127,284 +6586,9 @@ var __webpack_exports__ = {};
5127
6586
  }
5128
6587
  });
5129
6588
  container.appendChild(panelContent);
5130
- const state = stateManager.getState();
5131
- const getStoreState = ()=>storeConnector.getState();
5132
- switch(state.activeTab){
5133
- case 'consents':
5134
- consents_renderConsentsPanel(panelContent, {
5135
- getState: getStoreState,
5136
- onConsentChange: (name, value)=>{
5137
- const store = storeConnector.getStore();
5138
- if (store) {
5139
- const consentName = String(name);
5140
- store.getState().setSelectedConsent(consentName, value);
5141
- stateManager.addEvent({
5142
- type: 'info',
5143
- message: `${consentName} toggled to ${value} (not saved)`,
5144
- data: {
5145
- name: consentName,
5146
- value
5147
- }
5148
- });
5149
- }
5150
- },
5151
- onSave: ()=>{
5152
- const store = storeConnector.getStore();
5153
- if (store) {
5154
- store.getState().saveConsents('custom');
5155
- stateManager.addEvent({
5156
- type: 'consent_save',
5157
- message: 'Saved consent preferences'
5158
- });
5159
- }
5160
- },
5161
- onAcceptAll: ()=>{
5162
- const store = storeConnector.getStore();
5163
- if (store) {
5164
- store.getState().saveConsents('all');
5165
- stateManager.addEvent({
5166
- type: 'consent_save',
5167
- message: 'Accepted all consents'
5168
- });
5169
- }
5170
- },
5171
- onRejectAll: ()=>{
5172
- const store = storeConnector.getStore();
5173
- if (store) {
5174
- store.getState().saveConsents('necessary');
5175
- stateManager.addEvent({
5176
- type: 'consent_save',
5177
- message: 'Rejected all optional consents'
5178
- });
5179
- }
5180
- },
5181
- onReset: async ()=>{
5182
- const store = storeConnector.getStore();
5183
- if (store) await reset_consents_resetAllConsents(store, stateManager);
5184
- }
5185
- });
5186
- break;
5187
- case 'location':
5188
- location_renderLocationPanel(panelContent, {
5189
- getState: getStoreState,
5190
- onApplyOverrides: async (overrides)=>{
5191
- const store = storeConnector.getStore();
5192
- if (store) {
5193
- await store.getState().setOverrides({
5194
- country: overrides.country,
5195
- region: overrides.region,
5196
- language: overrides.language,
5197
- gpc: overrides.gpc
5198
- });
5199
- override_storage_persistOverrides({
5200
- country: overrides.country,
5201
- region: overrides.region,
5202
- language: overrides.language,
5203
- gpc: overrides.gpc
5204
- });
5205
- stateManager.addEvent({
5206
- type: 'info',
5207
- message: 'Overrides updated',
5208
- data: {
5209
- country: overrides.country,
5210
- region: overrides.region,
5211
- language: overrides.language,
5212
- gpc: overrides.gpc
5213
- }
5214
- });
5215
- }
5216
- },
5217
- onClearOverrides: async ()=>{
5218
- const store = storeConnector.getStore();
5219
- if (store) {
5220
- await store.getState().setOverrides({
5221
- country: void 0,
5222
- region: void 0,
5223
- language: void 0,
5224
- gpc: void 0
5225
- });
5226
- override_storage_clearPersistedOverrides();
5227
- stateManager.addEvent({
5228
- type: 'info',
5229
- message: 'Overrides cleared'
5230
- });
5231
- }
5232
- }
5233
- });
5234
- break;
5235
- case "scripts":
5236
- scripts_renderScriptsPanel(panelContent, {
5237
- getState: getStoreState,
5238
- getEvents: ()=>stateManager.getState().eventLog
5239
- });
5240
- break;
5241
- case 'iab':
5242
- iab_renderIabPanel(panelContent, {
5243
- getState: getStoreState,
5244
- onSetPurposeConsent: (purposeId, value)=>{
5245
- const iab = storeConnector.getStore()?.getState().iab;
5246
- if (!iab) return;
5247
- iab.setPurposeConsent(purposeId, value);
5248
- stateManager.addEvent({
5249
- type: 'iab',
5250
- message: `IAB purpose ${purposeId} set to ${value}`,
5251
- data: {
5252
- purposeId,
5253
- value
5254
- }
5255
- });
5256
- },
5257
- onSetVendorConsent: (vendorId, value)=>{
5258
- const iab = storeConnector.getStore()?.getState().iab;
5259
- if (!iab) return;
5260
- iab.setVendorConsent(vendorId, value);
5261
- stateManager.addEvent({
5262
- type: 'iab',
5263
- message: `IAB vendor ${vendorId} set to ${value}`,
5264
- data: {
5265
- vendorId,
5266
- value
5267
- }
5268
- });
5269
- },
5270
- onSetSpecialFeatureOptIn: (featureId, value)=>{
5271
- const iab = storeConnector.getStore()?.getState().iab;
5272
- if (!iab) return;
5273
- iab.setSpecialFeatureOptIn(featureId, value);
5274
- stateManager.addEvent({
5275
- type: 'iab',
5276
- message: `IAB feature ${featureId} set to ${value}`,
5277
- data: {
5278
- featureId,
5279
- value
5280
- }
5281
- });
5282
- },
5283
- onAcceptAll: ()=>{
5284
- const iab = storeConnector.getStore()?.getState().iab;
5285
- if (!iab) return;
5286
- iab.acceptAll();
5287
- stateManager.addEvent({
5288
- type: 'iab',
5289
- message: 'IAB accept all selected'
5290
- });
5291
- },
5292
- onRejectAll: ()=>{
5293
- const iab = storeConnector.getStore()?.getState().iab;
5294
- if (!iab) return;
5295
- iab.rejectAll();
5296
- stateManager.addEvent({
5297
- type: 'iab',
5298
- message: 'IAB reject all selected'
5299
- });
5300
- },
5301
- onSave: ()=>{
5302
- const iab = storeConnector.getStore()?.getState().iab;
5303
- if (!iab) return;
5304
- iab.save().then(()=>{
5305
- stateManager.addEvent({
5306
- type: 'iab',
5307
- message: 'IAB preferences saved'
5308
- });
5309
- }).catch((error)=>{
5310
- stateManager.addEvent({
5311
- type: 'error',
5312
- message: `Failed to save IAB preferences: ${String(error)}`
5313
- });
5314
- });
5315
- },
5316
- onReset: async ()=>{
5317
- const store = storeConnector.getStore();
5318
- if (store) await reset_consents_resetAllConsents(store, stateManager);
5319
- }
5320
- });
5321
- break;
5322
- case 'events':
5323
- events_renderEventsPanel(panelContent, {
5324
- getEvents: ()=>stateManager.getState().eventLog,
5325
- onClear: ()=>{
5326
- stateManager.clearEventLog();
5327
- stateManager.addEvent({
5328
- type: 'info',
5329
- message: 'Event log cleared'
5330
- });
5331
- }
5332
- });
5333
- break;
5334
- case 'actions':
5335
- actions_renderActionsPanel(panelContent, {
5336
- getState: getStoreState,
5337
- onResetConsents: async ()=>{
5338
- const store = storeConnector.getStore();
5339
- if (store) await reset_consents_resetAllConsents(store, stateManager);
5340
- },
5341
- onRefetchBanner: async ()=>{
5342
- const store = storeConnector.getStore();
5343
- if (store) {
5344
- await store.getState().initConsentManager();
5345
- stateManager.addEvent({
5346
- type: 'info',
5347
- message: 'Banner data refetched'
5348
- });
5349
- }
5350
- },
5351
- onShowBanner: ()=>{
5352
- const store = storeConnector.getStore();
5353
- if (store) {
5354
- store.getState().setActiveUI('banner', {
5355
- force: true
5356
- });
5357
- stateManager.addEvent({
5358
- type: 'info',
5359
- message: 'Banner shown'
5360
- });
5361
- }
5362
- },
5363
- onOpenPreferences: ()=>{
5364
- const store = storeConnector.getStore();
5365
- if (store) {
5366
- store.getState().setActiveUI('dialog');
5367
- stateManager.addEvent({
5368
- type: 'info',
5369
- message: 'Preference center opened'
5370
- });
5371
- }
5372
- },
5373
- onCopyState: ()=>{
5374
- const state = storeConnector.getState();
5375
- if (state) {
5376
- const stateCopy = {
5377
- consents: state.consents,
5378
- consentInfo: state.consentInfo,
5379
- locationInfo: state.locationInfo,
5380
- model: state.model,
5381
- overrides: state.overrides,
5382
- scripts: state.scripts?.map((s)=>({
5383
- id: s.id
5384
- })),
5385
- loadedScripts: state.loadedScripts
5386
- };
5387
- navigator.clipboard.writeText(JSON.stringify(stateCopy, null, 2)).then(()=>{
5388
- stateManager.addEvent({
5389
- type: 'info',
5390
- message: 'State copied to clipboard'
5391
- });
5392
- }).catch(()=>{
5393
- stateManager.addEvent({
5394
- type: 'error',
5395
- message: 'Failed to copy state'
5396
- });
5397
- });
5398
- }
5399
- }
5400
- });
5401
- break;
5402
- }
6589
+ panelRenderer.renderPanel(panelContent, currentActiveTab);
5403
6590
  if (panel) panelHeightAnimator.animate(panel, previousPanelHeight);
5404
6591
  }
5405
- storeConnector.subscribe(()=>{
5406
- panelInstance.update();
5407
- });
5408
6592
  const instance = {
5409
6593
  open: ()=>stateManager.setOpen(true),
5410
6594
  close: ()=>stateManager.setOpen(false),
@@ -5418,20 +6602,8 @@ var __webpack_exports__ = {};
5418
6602
  };
5419
6603
  },
5420
6604
  destroy: ()=>{
5421
- const store = storeConnector.getStore();
5422
- if (store) {
5423
- store.getState().setCallback('onBannerFetched', originalCallbacks.onBannerFetched);
5424
- store.getState().setCallback('onConsentSet', originalCallbacks.onConsentSet);
5425
- store.getState().setCallback('onError', originalCallbacks.onError);
5426
- store.getState().setCallback('onBeforeConsentRevocationReload', originalCallbacks.onBeforeConsentRevocationReload);
5427
- if (hasWrappedNetworkBlockerCallback) {
5428
- const currentNetworkBlocker = store.getState().networkBlocker;
5429
- if (currentNetworkBlocker) store.getState().setNetworkBlocker({
5430
- ...currentNetworkBlocker,
5431
- onRequestBlocked: originalNetworkBlockedCallback
5432
- });
5433
- }
5434
- }
6605
+ detachInstrumentation?.();
6606
+ detachInstrumentation = null;
5435
6607
  panelHeightAnimator.destroy();
5436
6608
  tabsInstance?.destroy();
5437
6609
  panelInstance.destroy();