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