hotwire-native-dev-tools 0.1.0-rc.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
1
  var $ = Object.defineProperty;
2
- var x = (i) => {
2
+ var L = (i) => {
3
3
  throw TypeError(i);
4
4
  };
5
5
  var I = (i, t, e) => t in i ? $(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
- var l = (i, t, e) => I(i, typeof t != "symbol" ? t + "" : t, e), F = (i, t, e) => t.has(i) || x("Cannot " + e);
7
- var b = (i, t, e) => (F(i, t, "read from private field"), e ? e.call(i) : t.get(i)), g = (i, t, e) => t.has(i) ? x("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e);
8
- const H = () => `
6
+ var l = (i, t, e) => I(i, typeof t != "symbol" ? t + "" : t, e), F = (i, t, e) => t.has(i) || L("Cannot " + e);
7
+ var b = (i, t, e) => (F(i, t, "read from private field"), e ? e.call(i) : t.get(i)), g = (i, t, e) => t.has(i) ? L("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e);
8
+ const M = () => `
9
9
  :host {
10
10
  all: initial;
11
11
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
@@ -30,7 +30,7 @@ const H = () => `
30
30
  margin: 0;
31
31
  }
32
32
 
33
- button {
33
+ button, label, .toggle-label {
34
34
  user-select: none;
35
35
  -webkit-user-select: none;
36
36
  -webkit-tap-highlight-color: transparent;
@@ -97,6 +97,7 @@ const H = () => `
97
97
  .dropdown-content label {
98
98
  color: black;
99
99
  width: 100%;
100
+ margin: 0;
100
101
  border: none;
101
102
  display: flex;
102
103
  align-items: center;
@@ -268,6 +269,11 @@ const H = () => `
268
269
  color: #ED4E4C;
269
270
  }
270
271
 
272
+ .bottom-sheet .tab-action-bars {
273
+ /* Fixes a 1px gap that can appear between .tab-action-bar and .tablist on Android devices */
274
+ margin-top: -1px;
275
+ }
276
+
271
277
  .bottom-sheet .tab-action-bar {
272
278
  display: none;
273
279
  justify-content: space-between;
@@ -304,6 +310,7 @@ const H = () => `
304
310
  border: none;
305
311
  outline: none;
306
312
  padding: 14px 16px;
313
+ margin: 0;
307
314
  font-size: 0.8em;
308
315
  }
309
316
 
@@ -312,9 +319,15 @@ const H = () => `
312
319
  color: white;
313
320
  }
314
321
 
322
+ .tablist .tablink-settings {
323
+ background-color: inherit;
324
+ }
325
+
315
326
  .tab-contents {
316
327
  height: 100%;
317
328
  overflow: scroll;
329
+ /* Fixes a 1px gap that can appear between .tab-action-bar and .tab-contents on Android devices */
330
+ margin-top: -1px;
318
331
  }
319
332
 
320
333
  .outer-tab-content {
@@ -673,16 +686,16 @@ const H = () => `
673
686
  width: 80%;
674
687
  }
675
688
  `;
676
- var u, m, v;
677
- class M {
689
+ var m, u, v;
690
+ class H {
678
691
  constructor() {
679
692
  l(this, "printWarning", (t, e = !0, ...o) => {
680
693
  e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
681
694
  });
682
695
  l(this, "checkForWarnings", () => {
683
- b(this, u).call(this), b(this, m).call(this), b(this, v).call(this);
696
+ b(this, m).call(this), b(this, u).call(this), b(this, v).call(this);
684
697
  });
685
- g(this, u, () => {
698
+ g(this, m, () => {
686
699
  var t;
687
700
  window.Turbo ? ((t = window.Turbo) == null ? void 0 : t.session.drive) === !1 && setTimeout(() => {
688
701
  var e;
@@ -691,7 +704,7 @@ class M {
691
704
  window.Turbo || this.printWarning("Turbo is not detected. Hotwire Native will not work correctly without Turbo");
692
705
  }, 1e3);
693
706
  });
694
- g(this, m, () => {
707
+ g(this, u, () => {
695
708
  const t = this.turboFrameIds;
696
709
  t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
697
710
  this.printWarning(`Multiple Turbo Frames with the same ID '${o}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`);
@@ -713,7 +726,7 @@ class M {
713
726
  return Array.from(document.querySelectorAll("turbo-frame")).map((t) => t.id);
714
727
  }
715
728
  }
716
- u = new WeakMap(), m = new WeakMap(), v = new WeakMap();
729
+ m = new WeakMap(), u = new WeakMap(), v = new WeakMap();
717
730
  const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], d = (i, t) => {
718
731
  let e = JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}");
719
732
  e[i] = t, localStorage.setItem("hotwire-native-dev-tools", JSON.stringify(e));
@@ -725,7 +738,7 @@ const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
725
738
  debug: !0,
726
739
  info: !0,
727
740
  log: !0
728
- }, N = (i, t) => {
741
+ }, z = (i, t) => {
729
742
  const e = y();
730
743
  return e[i] = t, d("consoleFilterLevels", e), e;
731
744
  }, p = (i, t) => {
@@ -734,7 +747,7 @@ const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
734
747
  const s = () => i.apply(void 0, o);
735
748
  clearTimeout(e), e = setTimeout(s, t);
736
749
  };
737
- }, { userAgent: E } = window.navigator, z = /iOS/.test(E), A = /Android/.test(E), S = () => z ? "ios" : A ? "android" : "unknown", D = () => {
750
+ }, { userAgent: E } = window.navigator, A = /iOS/.test(E), N = /Android/.test(E), S = () => A ? "ios" : N ? "android" : "unknown", D = () => {
738
751
  switch (S()) {
739
752
  case "android":
740
753
  return "Android";
@@ -875,7 +888,7 @@ class J {
875
888
  const o = e.dataset.tabId;
876
889
  this.devTools.state.setActiveTab(o), this.updateTabView(o);
877
890
  });
878
- this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(c("bottomSheetHeight")) || 50;
891
+ this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(c("bottomSheetHeight")) || 55;
879
892
  }
880
893
  render() {
881
894
  this.createBottomSheet(), this.sheetContent = this.bottomSheet.querySelector(".content"), this.sheetOverlay = this.bottomSheet.querySelector(".sheet-overlay"), this.addEventListeners();
@@ -900,7 +913,7 @@ class J {
900
913
  <button class="tablink ${e === "tab-console-logs" ? "active" : ""}" data-tab-id="tab-console-logs">Console</button>
901
914
  <button class="tablink ${e === "tab-event-logs" ? "active" : ""}" data-tab-id="tab-event-logs">Events</button>
902
915
  <button class="tablink ${e === "tab-native-stack" ? "active" : ""} d-none" data-tab-id="tab-native-stack">Stack</button>
903
- <div class="dropdown d-flex">
916
+ <div class="tablink-settings dropdown d-flex">
904
917
  <button class="dropdown-trigger tablink-dropdown">${X}</button>
905
918
  <div class="dropdown-content settings-dropdown">
906
919
  <button class="btn-switch-to-single-tab-sheet" data-tab-id="single-tab-settings">Settings</button>
@@ -997,12 +1010,18 @@ class J {
997
1010
  <h3 class="ms-1">Settings</h3>
998
1011
  </div>
999
1012
  <div class="mb-3">
1000
- <label for="bottom-sheet-height"> Bottom Sheet Height</label>
1001
- <input type="range" id="bottom-sheet-height" class="w-100" min="10" max="100" value="${this.sheetHeight}" step="1" />
1013
+ <label for="bottom-sheet-height-setting"> Bottom Sheet Height</label>
1014
+ <input type="range" id="bottom-sheet-height-setting" class="w-100" min="10" max="100" value="${this.sheetHeight}" step="1" list="bottom-sheet-height-setting-markers" />
1015
+ <datalist id="bottom-sheet-height-setting-markers">
1016
+ <option value="55"></option>
1017
+ </datalist>
1002
1018
  </div>
1003
1019
  <div class="mb-4">
1004
- <label for="font-size-input"> Font Size</label>
1005
- <input id="font-size-input" type="number" inputmode="numeric" class="w-100" value="${c("fontSize") || 16}" />
1020
+ <label for="font-size-setting"> Font Size</label>
1021
+ <input type="range" id="font-size-setting" class="w-100" min="8" max="24" value="${c("fontSize") || 16}" step="1" list="font-size-setting-markers" />
1022
+ <datalist id="font-size-setting-markers">
1023
+ <option value="16"></option>
1024
+ </datalist>
1006
1025
  </div>
1007
1026
  <div class="mb-3">
1008
1027
  <label class="toggle">
@@ -1096,7 +1115,7 @@ class J {
1096
1115
  `;
1097
1116
  }
1098
1117
  nativeViewStackHTML(t) {
1099
- var L;
1118
+ var x;
1100
1119
  const e = ["UINavigationController", "NavigatorHost"].includes(t.type), o = t.type === "UITabBarController", s = ["VisitableViewController", "HotwireWebFragment", "BackStackEntry"].includes(t.type), r = `viewstack-card ${t.url === this.currentUrl ? "current-view" : ""} ${e ? "main-view" : s ? "hotwire-view" : o ? "tab-container" : "non-identified-view"}`, a = "viewstack-" + Math.random().toString(16).slice(2), w = t.url ? `<div class="view-url">
1101
1120
  ${(() => {
1102
1121
  try {
@@ -1112,7 +1131,7 @@ class J {
1112
1131
  } catch {
1113
1132
  return t.pathConfigurationProperties;
1114
1133
  }
1115
- })(), T = k ? `<pre class="view-path-configuration">${k}</pre>` : "", B = (L = t.children) != null && L.length ? `<div class="child-container">
1134
+ })(), T = k ? `<pre class="view-path-configuration">${k}</pre>` : "", B = (x = t.children) != null && x.length ? `<div class="child-container">
1116
1135
  ${t.children.map((h) => this.nativeViewStackHTML(h)).join("")}
1117
1136
  </div>` : "";
1118
1137
  return `
@@ -1199,20 +1218,20 @@ class J {
1199
1218
  const e = t.closest("input[type='checkbox']");
1200
1219
  if (!e) return;
1201
1220
  const o = e.dataset.consoleFilter, s = e.checked;
1202
- N(o, s), this.renderConsoleLogs();
1221
+ z(o, s), this.renderConsoleLogs();
1203
1222
  }), this.bottomSheet.querySelector(".btn-search-console").addEventListener("click", () => {
1204
1223
  const t = this.bottomSheet.querySelector(".console-search");
1205
1224
  t.classList.toggle("d-none"), t.querySelector("input").focus();
1206
1225
  }), this.bottomSheet.querySelector(".console-search-input").addEventListener("input", (t) => {
1207
1226
  this.devTools.state.setConsoleSearchValue(t.target.value.toLowerCase()), this.renderConsoleLogs();
1208
- }), this.bottomSheet.querySelector("#bottom-sheet-height").addEventListener("change", (t) => {
1227
+ }), this.bottomSheet.querySelector("#bottom-sheet-height-setting").addEventListener("change", (t) => {
1209
1228
  const e = t.target.value;
1210
1229
  this.sheetHeight = parseInt(e), d("bottomSheetHeight", e), this.updateSheetHeight(e);
1211
1230
  }), this.bottomSheet.querySelector("#console-error-animation-setting").addEventListener("change", (t) => {
1212
1231
  d("errorAnimationEnabled", t.target.checked);
1213
- }), this.bottomSheet.querySelector("#font-size-input").addEventListener("change", (t) => {
1214
- const e = t.target.value;
1215
- d("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1232
+ }), this.bottomSheet.querySelector("#font-size-setting").addEventListener("change", (t) => {
1233
+ let e = t.target.value;
1234
+ e = Math.max(8, Math.min(24, e)), d("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1216
1235
  }), this.bottomSheet.querySelector("#auto-open-setting").addEventListener("change", (t) => {
1217
1236
  d("autoOpen", t.target.checked);
1218
1237
  }), this.bottomSheet.querySelector(".pin-bottom-sheet").addEventListener("click", () => {
@@ -1402,13 +1421,13 @@ class Z {
1402
1421
  l(this, "injectCSSToShadowRoot", async () => {
1403
1422
  if (this.shadowRoot.querySelector("style")) return;
1404
1423
  const t = document.createElement("style");
1405
- t.textContent = H(), this.shadowRoot.appendChild(t);
1424
+ t.textContent = M(), this.shadowRoot.appendChild(t);
1406
1425
  });
1407
1426
  this.options = {
1408
1427
  enabled: !0,
1409
1428
  reset: !1,
1410
1429
  ...t
1411
- }, this.options.enabled && (this.options.reset && q(), this.state = new G(), this.bubble = new U(this), this.bottomSheet = new J(this), this.nativeBridge = new K(this), this.diagnosticsChecker = new M(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1430
+ }, this.options.enabled && (this.options.reset && q(), this.state = new G(), this.bubble = new U(this), this.bottomSheet = new J(this), this.nativeBridge = new K(this), this.diagnosticsChecker = new H(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1412
1431
  }
1413
1432
  // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page
1414
1433
  setup() {
@@ -1 +1 @@
1
- {"version":3,"file":"hotwire-native-dev-tools.es.js","sources":["../src/assets/DevToolsStyling.css.js","../src/lib/DiagnosticsChecker.js","../src/utils/settings.js","../src/utils/utils.js","../src/assets/icons.js","../src/components/FloatingBubble.js","../src/components/BottomSheet.js","../src/lib/DevToolsState.js","../src/lib/NativeBridge.js","../src/DevTools.js","../src/index.js"],"sourcesContent":["// Ideally, we would use a dedicated CSS file, but I dind't find a good way to load the styles from a dedicated CSS file.\n// So we just use a function that returns the CSS content as a string.\n// For better syntax highlighting, you can set the language to CSS in the editor for this file.\nexport const cssContent = () => {\n return `\n :host {\n all: initial;\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\" !important;\n --font-size: 16px;\n font-size: var(--font-size) !important;\n }\n\n * {\n box-sizing: border-box;\n }\n\n p, span, h1, h2, h3, h4, h5, h6, div, a, button, input, label {\n font-size: inherit;\n }\n\n\n a {\n color: white;\n }\n\n h1, h2, h3, h4, h5, h6 {\n margin: 0;\n }\n\n button {\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n input {\n display: block;\n padding: 3px;\n box-sizing: border-box;\n border: 1px solid #ccc;\n border-radius: 4px;\n }\n\n input:focus {\n outline: none;\n }\n\n .btn-icon {\n background-color: transparent;\n border: none;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n height: 100%;\n }\n\n .btn-icon svg {\n width: 1rem;\n height: 1rem;\n fill: white;\n }\n\n /* Dropdown */\n .dropdown-content {\n display: none;\n position: absolute;\n z-index: 1000;\n background: white;\n border: 1px solid #ddd;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n min-width: 200px;\n max-width: 300px;\n opacity: 0;\n transform: scale(0.9);\n transition: opacity 0.2s, transform 0.2s;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .dropdown-content.dropdown-open {\n display: block;\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .dropdown-content > * {\n padding: 12px;\n }\n\n .dropdown-content button,\n .dropdown-content label {\n color: black;\n width: 100%;\n border: none;\n display: flex;\n align-items: center;\n }\n\n .dropdown-content button:not(:first-child) {\n border-top: 1px solid #cecdcd;\n }\n\n .settings-dropdown {\n right: 0;\n top: 2rem;\n }\n\n /* Floating bubble */\n #floating-bubble {\n display: flex;\n background-color: hsl(0deg 0% 0% / 60%);\n border-radius: 50%;\n touch-action: none;\n user-select: none;\n z-index: 10000000;\n position: fixed;\n top: 10px;\n left: 10px;\n\n /* Remove tap highlight on iOS */\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n\n /* Keep width, height, and border in sync with bubbleSize in FloatingBubble.js */\n width: 4.75rem;\n height: 4.75rem;\n border: 0.3rem solid rgba(136, 136, 136, 0.5);\n }\n\n #floating-bubble svg {\n transform: scale(0.6);\n fill: #b1b1b1;\n }\n\n #floating-bubble .animation-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 1;\n }\n\n #floating-bubble .error-border {\n position: absolute;\n top: -30px;\n left: -30px;\n width: calc(100% + 60px);\n height: calc(100% + 60px);\n border-radius: 50%;\n }\n\n #floating-bubble .error-border circle {\n transform-origin: center;\n transform: rotate(-90deg);\n }\n\n #floating-bubble .error-border circle.animate {\n animation: error-border-progress 0.8s ease-out forwards;\n }\n\n #floating-bubble .animation-container.fade-out {\n animation: fade-out 0.4s ease-out forwards;\n }\n\n /*\n The \"stroke-dasharray\" defines the start of the animation\n The value is calculated by the formula: 2 * Math.PI * radius\n In this case: 2 * Math.PI * 90 = 565\n */\n @keyframes error-border-progress {\n from {\n stroke-dashoffset: 565;\n }\n to {\n stroke-dashoffset: 0;\n }\n }\n\n @keyframes fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n\n /* Bottom Sheet */\n .bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n max-height: 100%;\n display: flex;\n opacity: 0;\n pointer-events: none;\n align-items: center;\n flex-direction: column;\n justify-content: flex-end;\n transition: 0.1s linear;\n z-index: 10000001;\n }\n\n .bottom-sheet .sheet-overlay.active {\n position: fixed;\n top: 0;\n left: 0;\n z-index: -1;\n width: 100%;\n height: 100%;\n opacity: 0.2;\n background: #000;\n }\n\n .bottom-sheet .content {\n width: 100%;\n height: 40vh;\n position: relative;\n color: white;\n transform: translateY(100%);\n border-radius: 12px 12px 0 0;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.03);\n transition: 0.3s ease;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry {\n border-bottom: 1px solid #6c6c6c;\n white-space: collapse;\n }\n\n .bottom-sheet .log-entry-icon svg {\n width: 1rem;\n fill: white;\n }\n\n .bottom-sheet.show {\n opacity: 1;\n pointer-events: auto;\n }\n\n .bottom-sheet.show .content {\n transform: translateY(0%);\n }\n\n .bottom-sheet.dragging .content {\n transition: none;\n }\n .bottom-sheet.fullscreen .content {\n border-radius: 0;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry-message.warn {\n color: #f39c12;\n }\n\n .bottom-sheet .log-entry-message.error {\n color: #ED4E4C;\n }\n\n .bottom-sheet .tab-action-bar {\n display: none;\n justify-content: space-between;\n background-color: rgb(49, 54, 63);\n padding: 0.5rem;\n padding-right: 1rem;\n padding-left: 1rem;\n }\n\n .bottom-sheet .tab-action-bar.active {\n display: flex;\n }\n\n .bottom-sheet .tab-action-bar button:active svg {\n fill: #6c6c6c;\n }\n\n .bottom-sheet .btn-clear-tab,\n .bottom-sheet .btn-reload-tab {\n margin-left: auto;\n }\n\n /* Bottom Sheet Tabs */\n .tablist {\n display: flex;\n overflow: hidden;\n background-color: #EEEEEE;\n }\n\n .tablist .tablink {\n color: black;\n background-color: inherit;\n width: 100%;\n border: none;\n outline: none;\n padding: 14px 16px;\n font-size: 0.8em;\n }\n\n .tablist .tablink.active {\n background-color: #31363f;\n color: white;\n }\n\n .tab-contents {\n height: 100%;\n overflow: scroll;\n }\n\n .outer-tab-content {\n display: none;\n border-top: none;\n height: 100%;\n overflow: scroll;\n background-color: hsl(0deg 0% 0% / 80%);\n backdrop-filter: blur(3px) saturate(100%);\n -webkit-backdrop-filter: blur(3px) saturate(100%);\n padding-bottom: 7em;\n }\n .outer-tab-content.active {\n display: block;\n }\n .inner-tab-content {\n padding: 1rem;\n overflow-x: auto;\n white-space: nowrap;\n }\n .single-tab-content .inner-tab-content {\n white-space: normal;\n }\n\n .tab-empty-content {\n display: flex;\n justify-content: center;\n flex-direction: column;\n align-items: center;\n padding: 1em;\n }\n\n .bottom-sheet .tablink-dropdown {\n background: inherit;\n border: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n width: 2rem;\n }\n\n .bottom-sheet .tablink-dropdown svg {\n width: 1rem;\n height: 1rem;\n fill: #121212;\n }\n\n .bottom-sheet .tablink-dropdown:active {\n background-color: #31363f;\n }\n .bottom-sheet .tablink-dropdown:active svg {\n fill: white;\n }\n\n /* Bottom Sheet Stack Visualization */\n .bottom-sheet .viewstack-card {\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 10px;\n margin: 10px 0;\n background: white;\n color: black;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: auto;\n }\n\n .bottom-sheet .viewstack-card.current-view {\n border: 2px solid #f1f208;\n }\n\n .bottom-sheet .tab-container {\n background: #EEEEEE;\n }\n\n .bottom-sheet .main-view {\n border-color: #4e6080;\n background: #31363F;\n }\n\n .bottom-sheet .hotwire-view {\n border-color: #6db1b5;\n background: #76ABAE;\n }\n\n .bottom-sheet .child-container {\n margin-left: 30px;\n position: relative;\n }\n\n .bottom-sheet .child-container::before {\n content: \"\";\n position: absolute;\n left: -15px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #ddd;\n }\n\n .bottom-sheet .view-title {\n display: flex;\n align-items: center;\n gap: 0.5em;\n\n font-weight: bold;\n color: white;\n margin-bottom: 5px;\n }\n\n .bottom-sheet .view-title-details {\n color: #efefef;\n font-size: 0.6em;\n }\n\n .bottom-sheet .tab-container .view-title-details {\n color: #6c6c6c;\n }\n\n .bottom-sheet .view-url {\n color: #000000;\n font-size: 0.9em;\n margin-top: 5px;\n word-break: break-all;\n }\n\n .bottom-sheet .non-identified-view {\n background: #EEEEEE;\n }\n .bottom-sheet .non-identified-view .view-title-details,\n .bottom-sheet .non-identified-view .view-title {\n color: #6c6c6c;\n }\n\n .bottom-sheet .viewstack-card pre {\n font-size: 0.8em;\n }\n\n /* Bottom Sheet Bridge Components */\n .bottom-sheet .bridge-components-collapse-btn {\n background: none;\n border: none;\n color: white;\n width: 100%;\n text-align: left;\n border-bottom: 1px solid #eee;\n padding: 0.5em 0em;\n font-size: 0.9em;\n }\n\n .tab-content-bridge-components {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 0.5em 0em;\n }\n\n .tab-content-bridge-components .bridge-component {\n position: relative;\n padding-left: 15px;\n }\n\n .tab-content-bridge-components .bridge-component::before {\n content: \"•\";\n color: #eee;\n font-size: 1.5em;\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n }\n .tab-content-bridge-components .bridge-component.connected::before {\n color: #5cff00\n }\n\n /* Collapsibles */\n .collapse-target {\n display: none;\n }\n\n .collapse-target.active {\n display: block;\n }\n\n .collapse:not(.no-chevron):after {\n content: '\\\\25BC';\n font-size: 13px;\n color: #777;\n float: right;\n margin-left: 5px;\n }\n\n .collapse:not(.no-chevron).active:after {\n content: \"\\\\25B2\";\n }\n\n /* Custom checkbox toggles */\n .toggle {\n display: inline-block;\n user-select: none;\n }\n\n .toggle-switch {\n display: inline-block;\n background: #ccc;\n border-radius: 16px;\n width: 29px;\n height: 16px;\n position: relative;\n vertical-align: middle;\n transition: background 0.15s;\n }\n .toggle-switch:before,\n .toggle-switch:after {\n content: \"\";\n }\n .toggle-switch:before {\n display: block;\n background: linear-gradient(to bottom, #fff 0%, #eee 100%);\n border-radius: 50%;\n width: 12px;\n height: 12px;\n position: absolute;\n top: 2px;\n left: 2px;\n transition: left 0.15s;\n }\n .toggle-checkbox:checked + .toggle-switch {\n background: #56c080;\n }\n .toggle-checkbox:checked + .toggle-switch:before {\n left: 15px;\n }\n\n .toggle-checkbox {\n position: absolute;\n visibility: hidden;\n }\n\n .toggle-label {\n position: relative;\n margin-left: 3px;\n top: 2px;\n }\n\n /* Utility classes */\n .d-none {\n display: none;\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-ellipsis {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .break-word {\n word-break: break-word;\n }\n\n .d-flex {\n display: flex;\n }\n\n .flex-column {\n flex-direction: column;\n }\n\n .justify-content-between {\n justify-content: space-between;\n }\n\n .justify-content-end {\n justify-content: flex-end;\n }\n\n .align-items-center {\n align-items: center;\n }\n\n .flex-grow-1 {\n flex-grow: 1;\n }\n\n .border-bottom {\n border-bottom: 1px solid #c5c1c1;\n }\n\n .no-wrap {\n overflow: hidden;\n white-space: nowrap;\n }\n\n .white-space-collapse {\n white-space: collapse;\n }\n\n .overflow-auto {\n overflow: auto;\n }\n\n .mt-1 {\n margin-top: 0.25rem;\n }\n\n .mt-2 {\n margin-top: 0.5rem;\n }\n\n .mt-4 {\n margin-top: 1.5rem;\n }\n\n .ms-1 {\n margin-left: 0.25rem;\n }\n\n .mb-2 {\n margin-bottom: 0.5rem;\n }\n\n .mb-3 {\n margin-bottom: 1rem;\n }\n\n .mb-4 {\n margin-bottom: 1.5rem;\n }\n\n .gap-1 {\n gap: 0.25rem;\n }\n\n .gap-3 {\n gap: 1rem;\n }\n\n .pb-2 {\n padding-bottom: 0.5rem;\n }\n\n .pt-2 {\n padding-top: 0.5rem;\n }\n\n .w-100 {\n width: 100%;\n }\n\n .w-80 {\n width: 80%;\n }\n `\n}\n","export default class DiagnosticsChecker {\n constructor() {\n this.printedWarnings = []\n }\n\n printWarning = (message, once = true, ...extraArgs) => {\n if (once && this.printedWarnings.includes(message)) return\n\n console.warn(`DevTools: ${message}`, ...extraArgs)\n this.printedWarnings.push(message)\n }\n\n checkForWarnings = () => {\n this.#checkForTurboDrive()\n this.#checkForDuplicatedTurboFrames()\n this.#checkTurboPermanentElements()\n }\n\n #checkForTurboDrive = () => {\n if (!window.Turbo) {\n // Since it's possible that the DevTools are loaded before Turbo, we need to wait a bit to check if Turbo is loaded\n setTimeout(() => {\n if (!window.Turbo) {\n this.printWarning(\"Turbo is not detected. Hotwire Native will not work correctly without Turbo\")\n }\n }, 1000)\n } else if (window.Turbo?.session.drive === false) {\n setTimeout(() => {\n if (window.Turbo?.session.drive === false) {\n this.printWarning(\"Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive\")\n }\n }, 1000)\n }\n }\n\n #checkForDuplicatedTurboFrames = () => {\n const turboFramesIds = this.turboFrameIds\n const duplicatedIds = turboFramesIds.filter((id, index) => turboFramesIds.indexOf(id) !== index)\n\n duplicatedIds.forEach((id) => {\n this.printWarning(`Multiple Turbo Frames with the same ID '${id}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`)\n })\n }\n\n #checkTurboPermanentElements = () => {\n const turboPermanentElements = document.querySelectorAll(\"[data-turbo-permanent]\")\n if (turboPermanentElements.length === 0) return\n\n turboPermanentElements.forEach((element) => {\n const id = element.id\n if (id === \"\") {\n const message = `Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n\n const idIsDuplicated = id && document.querySelectorAll(`#${id}`).length > 1\n if (idIsDuplicated) {\n const message = `Turbo Permanent Element with ID '${id}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n })\n }\n\n get turboFrameIds() {\n return Array.from(document.querySelectorAll(\"turbo-frame\")).map((turboFrame) => turboFrame.id)\n }\n}\n","export const getSettings = (key) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n return settings[key]\n}\n\nexport const saveSettings = (key, value) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n settings[key] = value\n\n localStorage.setItem(\"hotwire-native-dev-tools\", JSON.stringify(settings))\n}\n\nexport const resetSettings = () => {\n localStorage.removeItem(\"hotwire-native-dev-tools\")\n}\n\nexport const getConsoleFilterLevels = () => {\n const consoleFilterLevels = getSettings(\"consoleFilterLevels\") || {\n warn: true,\n error: true,\n debug: true,\n info: true,\n log: true,\n }\n\n return consoleFilterLevels\n}\n\nexport const saveConsoleFilterLevels = (key, value) => {\n const consoleFilterLevels = getConsoleFilterLevels()\n consoleFilterLevels[key] = value\n saveSettings(\"consoleFilterLevels\", consoleFilterLevels)\n return consoleFilterLevels\n}\n","export const debounce = (fn, delay) => {\n let timeoutId = null\n\n return (...args) => {\n const callback = () => fn.apply(this, args)\n clearTimeout(timeoutId)\n timeoutId = setTimeout(callback, delay)\n }\n}\n\nconst { userAgent } = window.navigator\nexport const isIosApp = /iOS/.test(userAgent)\nexport const isAndroidApp = /Android/.test(userAgent)\n\nexport const platform = () => {\n if (isIosApp) {\n return \"ios\"\n } else if (isAndroidApp) {\n return \"android\"\n }\n return \"unknown\"\n}\n\nexport const formattedPlatform = () => {\n switch (platform()) {\n case \"android\":\n return \"Android\"\n case \"ios\":\n return \"iOS\"\n default:\n return \"<unknown>\"\n }\n}\n","export const hotwireIcon = `\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 294 320\">\n <g transform=\"matrix(1,0,0,1,-28.38,-15.268)\">\n <g transform=\"matrix(1,0,0,1,-462.157,-144.417)\">\n <path d=\"M783.777,159.685L683.006,262.542L765.948,268.939L622.459,394.208L690.389,396.4L490.537,479.149L569.424,402.053L511.312,400.203L639.22,296.093L533.548,287.812L783.777,159.685Z\"/>\n </g>\n </g>\n </svg>\n`\n\nexport const arrowUp = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71L280 392c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-214.1-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z\"/>\n </svg>\n`\n\nexport const arrowDown = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 297c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 120c0-13.3 10.7-24 24-24s24 10.7 24 24l0 214.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 409c-9.4 9.4-24.6 9.4-33.9 0L127 297z\"/>\n </svg>\n`\n\nexport const arrowLeft = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\"/>\n </svg>\n`\n\nexport const trash = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z\"/>\n </svg>\n`\n\nexport const rotate = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z\"/>\n </svg>\n`\n\nexport const questionMark = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n`\n\nexport const search = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z\"/>\n </svg>\n`\n\nexport const filter = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M3.9 54.9C10.5 40.9 24.5 32 40 32l432 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9 320 448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z\"/>\n </svg>\n`\n\nexport const threeDotsVertical = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\"/>\n </svg>\n`\n","import { getSettings, saveSettings } from \"../utils/settings\"\nimport { debounce } from \"../utils/utils\"\nimport { hotwireIcon } from \"../assets/icons\"\n\nexport default class FloatingBubble {\n constructor(devTools) {\n this.devTools = devTools\n this.bubbleSize = 4.75 * 16 + 0.3 * 16 // 4.75rem + 0.3rem border\n this.minVisible = this.bubbleSize * 0.5 // Keep 50% of the bubble visible at all times\n this.currentlyDragging = false\n }\n\n render = debounce(() => {\n this.setPosition()\n this.createDragItem()\n this.setTranslate(this.initialX, this.initialY, this.dragItem)\n this.addEventListeners()\n }, 50)\n\n setPosition() {\n this.settingKey = window.innerWidth < window.innerHeight ? \"bubblePosPortrait\" : \"bubblePosLandscape\"\n\n // Get stored position or use default (bottom right corner)\n const defaultPos = { x: window.innerWidth - 100, y: window.innerHeight - 100 }\n const { x: startX, y: startY } = getSettings(this.settingKey) || defaultPos\n\n this.currentX = this.initialX = this.xOffset = startX\n this.currentY = this.initialY = this.yOffset = startY\n }\n\n createDragItem() {\n const existingBubble = this.devTools.shadowRoot?.getElementById(\"floating-bubble\")\n if (existingBubble) {\n this.dragItem = existingBubble\n return\n }\n\n this.dragItem = document.createElement(\"div\")\n this.dragItem.id = \"floating-bubble\"\n this.dragItem.innerHTML = hotwireIcon\n this.devTools.shadowRoot.appendChild(this.dragItem)\n }\n\n addEventListeners() {\n if (this.dragItem.hasEventListeners) return\n this.dragItem.addEventListener(\"click\", this.click.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchend\", this.dragEnd.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchmove\", this.drag.bind(this), { passive: true })\n this.dragItem.hasEventListeners = true\n }\n\n click(event) {\n if (this.clickCallback) {\n this.clickCallback(event)\n }\n }\n\n animateErrorBorder = debounce(() => {\n if (!this.dragItem) return\n if (getSettings(\"errorAnimationEnabled\") === false) return\n\n let errorBorder = this.dragItem.querySelector(\".error-border\")\n let circleElement = this.dragItem.querySelector(\".error-border circle\")\n\n if (errorBorder) {\n errorBorder.remove()\n }\n\n const animationContainer = document.createElement(\"div\")\n animationContainer.className = \"animation-container\"\n animationContainer.innerHTML = `\n <svg viewBox=\"0 0 180 180\" xmlns=\"http://www.w3.org/2000/svg\" class=\"error-border\">\n <defs>\n <linearGradient id=\"errorGradient\" gradientTransform=\"rotate(45)\">\n <stop offset=\"0%\" stop-color=\"#e4241a\" />\n <stop offset=\"50%\" stop-color=\"#dd1f15\" />\n <stop offset=\"100%\" stop-color=\"#f6160a\" />\n </linearGradient>\n </defs>\n <circle cx=\"90\" cy=\"90\" r=\"90\" fill=\"none\" stroke=\"url(#errorGradient)\" stroke-width=\"21\"\n stroke-dasharray=\"565\" stroke-dashoffset=\"565\" stroke-linecap=\"round\" />\n </svg>\n `\n\n this.dragItem.appendChild(animationContainer)\n circleElement = this.dragItem.querySelector(\".error-border circle\")\n circleElement.classList.add(\"animate\")\n\n setTimeout(() => {\n animationContainer.classList.add(\"fade-out\")\n }, 1300) // Start fade-out after animation completes\n\n setTimeout(() => {\n if (animationContainer && animationContainer.parentNode) {\n animationContainer.remove()\n }\n }, 1800) // Remove after fade-out completes\n }, 100)\n\n onClick(callback) {\n this.clickCallback = callback\n }\n\n dragStart(event) {\n if (!event.target.closest(\"#floating-bubble\")) return\n this.currentlyDragging = true\n\n this.initialX = event.touches[0].clientX - this.xOffset\n this.initialY = event.touches[0].clientY - this.yOffset\n }\n\n dragEnd() {\n this.initialX = this.currentX\n this.initialY = this.currentY\n this.currentlyDragging = false\n\n saveSettings(this.settingKey, { x: this.currentX, y: this.currentY })\n }\n\n drag(event) {\n if (!this.currentlyDragging) return\n\n const touch = event.touches[0]\n const deltaX = touch.clientX - this.initialX\n const deltaY = touch.clientY - this.initialY\n\n // Constrain movement within screen bounds\n this.currentX = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaX, window.innerWidth - this.minVisible))\n this.currentY = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaY, window.innerHeight - this.minVisible))\n\n this.xOffset = this.currentX\n this.yOffset = this.currentY\n\n if (!this.animationFrame) {\n this.animationFrame = requestAnimationFrame(() => {\n this.setTranslate(this.currentX, this.currentY, this.dragItem)\n this.animationFrame = null\n })\n }\n }\n\n setTranslate(xPos, yPos, element) {\n element.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`\n }\n}\n","import * as Icons from \"../assets/icons\"\nimport { platform, formattedPlatform } from \"../utils/utils\"\nimport { saveSettings, getSettings, getConsoleFilterLevels, saveConsoleFilterLevels } from \"../utils/settings\"\n\n// WARNING: Be careful when console logging in this file, as it can cause an infinite loop\n// When you need to debug, use the `log` helper function like this:\n// this.log(\"message\")\n// or turn off the console proxy in DevTools.js\n\nexport default class BottomSheet {\n constructor(devTools) {\n this.devTools = devTools\n this.state = devTools.state.state\n this.sheetHeight = parseInt(getSettings(\"bottomSheetHeight\")) || 50\n }\n\n render() {\n this.createBottomSheet()\n this.sheetContent = this.bottomSheet.querySelector(\".content\")\n this.sheetOverlay = this.bottomSheet.querySelector(\".sheet-overlay\")\n this.addEventListeners()\n }\n\n update(newState) {\n this.state = newState\n this.checkNativeFeatures()\n this.renderConsoleLogs()\n this.renderBridgeComponents()\n this.renderBridgeLogs()\n this.renderEvents()\n this.renderNativeStack()\n }\n\n createBottomSheet() {\n const existingBottomSheet = this.devTools.shadowRoot?.querySelector(\".bottom-sheet\")\n if (existingBottomSheet) {\n this.bottomSheet = existingBottomSheet\n return\n }\n\n const activeTab = this.state.activeTab\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n this.bottomSheet = document.createElement(\"div\")\n this.bottomSheet.classList.add(\"bottom-sheet\")\n this.bottomSheet.innerHTML = `\n <div class=\"sheet-overlay ${getSettings(\"bottomSheetPinned\") === true ? \"\" : \"active\"}\"></div>\n <div class=\"content\">\n <div class=\"top-part\">\n <div class=\"tablist\">\n <button class=\"tablink ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\" data-tab-id=\"tab-bridge-components\">Bridge</button>\n <button class=\"tablink ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-console-logs\">Console</button>\n <button class=\"tablink ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-event-logs\">Events</button>\n <button class=\"tablink ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"} d-none\" data-tab-id=\"tab-native-stack\">Stack</button>\n <div class=\"dropdown d-flex\">\n <button class=\"dropdown-trigger tablink-dropdown\">${Icons.threeDotsVertical}</button>\n <div class=\"dropdown-content settings-dropdown\">\n <button class=\"btn-switch-to-single-tab-sheet\" data-tab-id=\"single-tab-settings\">Settings</button>\n <button class=\"pin-bottom-sheet\">Pin Bottom Sheet</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-action-bars\">\n <div class=\"tab-action-bar tab-bridge-components ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-bridge-logs\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar d-flex flex-column tab-console-logs ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"d-flex\">\n <button class=\"btn-icon btn-search-console\">${Icons.search}</button>\n <div class=\"dropdown\">\n <button class=\"dropdown-trigger btn-icon\">${Icons.filter}</button>\n <div class=\"dropdown-content console-filter-levels\">\n <label><input type=\"checkbox\" ${consoleFilterLevels.warn ? \"checked\" : \"\"} data-console-filter=\"warn\" /> Warnings</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.error ? \"checked\" : \"\"} data-console-filter=\"error\" /> Errors</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.debug ? \"checked\" : \"\"} data-console-filter=\"debug\" /> Debug</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.info ? \"checked\" : \"\"} data-console-filter=\"info\" /> Info</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.log ? \"checked\" : \"\"} data-console-filter=\"log\" /> Logs</label>\n </div>\n </div>\n <button class=\"btn-icon btn-clear-tab btn-clear-console-logs\">${Icons.trash}</button>\n </div>\n\n <div class=\"console-search mt-2 ${consoleSearch ? \"\" : \"d-none\"}\">\n <input type=\"search\" class=\"console-search-input\" value=\"${consoleSearch}\" placeholder=\"Search console logs\" />\n </div>\n </div>\n <div class=\"tab-action-bar tab-event-logs ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-events\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar tab-native-stack ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-reload-tab btn-reload-stack\">${Icons.rotate}</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-contents\">\n <div id=\"tab-bridge-components\" class=\"outer-tab-content ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content\">\n <button class=\"collapse bridge-components-collapse-btn\" type=\"button\" data-collapse-target=\"bridge-components-collapse\">\n Registered Bridge Components: <span class=\"bridge-components-amount\">${this.state.supportedBridgeComponents.length}</span>\n </button>\n <div id=\"bridge-components-collapse\" class=\"collapse-target\">\n <div class=\"d-flex justify-content-between border-bottom\">\n <div class=\"tab-content-bridge-components flex-grow-1\"></div>\n <button class=\"btn-icon btn-help btn-switch-to-single-tab-sheet mt-1\" data-tab-id=\"single-tab-bridge-component-help\">${Icons.questionMark}</button>\n </div>\n </div>\n\n <div class=\"tab-content-bridge-logs\">\n </div>\n </div>\n </div>\n\n <div id=\"tab-console-logs\" class=\"outer-tab-content ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-console-logs\">\n </div>\n </div>\n\n <div id=\"tab-event-logs\" class=\"outer-tab-content ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-event-logs\">\n </div>\n </div>\n\n <div id=\"tab-native-stack\" class=\"outer-tab-content ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-native-stack\">\n </div>\n </div>\n\n <div id=\"single-tab-bridge-component-help\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Bridge Components</h3>\n </div>\n <p>This list shows all the bridge components that the ${formattedPlatform()} app supports. Components that are active on this page are marked with a green dot.</p>\n <h3 class=\"mt-4\">Why is my bridge component not on the list?</h3>\n <p class=\"mt-2\">Bridge components are automatically detected when they are registered in the native code. If your component is not on the list, make sure it is registered correctly.</p>\n ${this.registerBridgeComponentExample()}\n <p class\"mt-1\">For more information, check out the documentation:</p>\n <a href=\"${this.registerBridgeComponentHelpURL()}\">${this.registerBridgeComponentHelpURL()}</a>\n </div>\n </div>\n\n <div id=\"single-tab-settings\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Settings</h3>\n </div>\n <div class=\"mb-3\">\n <label for=\"bottom-sheet-height\"> Bottom Sheet Height</label>\n <input type=\"range\" id=\"bottom-sheet-height\" class=\"w-100\" min=\"10\" max=\"100\" value=\"${this.sheetHeight}\" step=\"1\" />\n </div>\n <div class=\"mb-4\">\n <label for=\"font-size-input\"> Font Size</label>\n <input id=\"font-size-input\" type=\"number\" inputmode=\"numeric\" class=\"w-100\" value=\"${getSettings(\"fontSize\") || 16}\" />\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"console-error-animation-setting\" ${getSettings(\"errorAnimationEnabled\") !== false ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Console Error Animation</span>\n </label>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"auto-open-setting\" ${getSettings(\"autoOpen\") === true ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Auto Open</span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n this.devTools.shadowRoot.appendChild(this.bottomSheet)\n }\n\n renderConsoleLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-console-logs\")\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n container.innerHTML = this.state.consoleLogs.length\n ? this.state.consoleLogs\n .filter((log) => consoleFilterLevels[log.type])\n .filter((log) => {\n if (!consoleSearch) return true\n return log.message.toLowerCase().includes(consoleSearch.toLowerCase())\n })\n .map((log) => this.consoleLogHTML(log.type, log.message, log.time))\n .join(\"\")\n : `<div class=\"tab-empty-content\"><span>No console logs yet</span></div>`\n }\n\n renderBridgeComponents() {\n const bridgeComponentsAmount = this.state.supportedBridgeComponents.length\n this.bottomSheet.querySelector(\".bridge-components-amount\").textContent = bridgeComponentsAmount\n\n const bridgeComponentIdentifiers = this.bridgeComponentIdentifiers\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-components\")\n container.innerHTML = bridgeComponentsAmount\n ? this.state.supportedBridgeComponents.map((component) => `<div class=\"bridge-component ${bridgeComponentIdentifiers.includes(component) ? \"connected\" : \"\"}\">${component}</div>`).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\"No bridge components found\"}</span></div>`\n }\n\n renderBridgeLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-logs\")\n container.innerHTML = this.state.bridgeLogs.length\n ? this.state.bridgeLogs.map((log) => this.bridgeLogHTML(log.direction, log.componentName, log.eventName, log.eventArgs, log.time)).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\n this.state.bridgeIsConnected ? \"No bridge communication yet\" : \"Bridge is not connected <br><small>(Neither window.HotwireNative nor window.Strada is defined)</small>\"\n }</span></div>`\n }\n\n renderEvents() {\n const container = this.bottomSheet.querySelector(\".tab-content-event-logs\")\n container.innerHTML = this.state.eventLogs.length\n ? this.state.eventLogs.map((event) => this.eventMessageHTML(event.eventName, event.time)).join(\"\")\n : `<div class=\"tab-empty-content\"><span>No events captured yet</span></div>`\n }\n\n renderNativeStack() {\n const container = this.bottomSheet.querySelector(\".tab-content-native-stack\")\n container.innerHTML =\n `<div class=\"native-stack-wrapper\">` +\n (this.state.nativeStack.length ? this.state.nativeStack.map((view) => this.nativeViewStackHTML(view)).join(\"\") : `<div class=\"tab-empty-content\"><span>No native stack captured yet</span></div>`) +\n `</div>`\n }\n\n bridgeLogHTML(direction, componentName, eventName, eventArgs, time) {\n return `\n <div class=\"log-entry d-flex gap-3 pt-2 pb-2\">\n <div class=\"log-entry-icon d-flex justify-content-center align-items-center\">\n ${direction === \"send\" ? Icons.arrowDown : Icons.arrowUp}\n </div>\n <div class=\"w-100 overflow-auto\">\n <div class=\"d-flex justify-content-between\">\n <strong class=\"w-80 break-word\">${componentName}#${eventName}</strong>\n <small>${time}</small>\n </div>\n <div class=\"overflow-auto\">\n ${Object.entries(eventArgs)\n .map(([key, value]) => {\n const formattedValue = typeof value === \"object\" && value !== null ? JSON.stringify(value) : value\n return `<div class=\"white-space-collapse\">${key}: ${formattedValue}</div>`\n })\n .join(\"\")}\n </div>\n </div>\n </div>\n `\n }\n\n consoleLogHTML(type, message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message ${type}\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n eventMessageHTML(message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n nativeViewStackHTML(view) {\n const isMainView = [\"UINavigationController\", \"NavigatorHost\"].includes(view.type)\n const isTabBar = view.type === \"UITabBarController\"\n const isHotwireView = [\"VisitableViewController\", \"HotwireWebFragment\", \"BackStackEntry\"].includes(view.type)\n const activeClass = view.url === this.currentUrl ? \"current-view\" : \"\"\n const wrapperClass = `viewstack-card ${activeClass} ${isMainView ? \"main-view\" : isHotwireView ? \"hotwire-view\" : isTabBar ? \"tab-container\" : \"non-identified-view\"}`\n const uniqueViewId = \"viewstack-\" + Math.random().toString(16).slice(2)\n\n const urlPath = view.url\n ? `<div class=\"view-url\">\n ${(() => {\n try {\n return new URL(view.url).pathname\n } catch (error) {\n return view.url\n }\n })()}\n </div>`\n : \"\"\n\n const pathConfigurationPropertiesJson = (() => {\n try {\n const props = view.pathConfigurationProperties\n return JSON.stringify(typeof props === \"string\" ? JSON.parse(props) : props, null, 2)\n } catch {\n return view.pathConfigurationProperties\n }\n })()\n const pathConfigurationProperties = pathConfigurationPropertiesJson ? `<pre class=\"view-path-configuration\">${pathConfigurationPropertiesJson}</pre>` : \"\"\n\n const childrenHTML = view.children?.length\n ? `<div class=\"child-container\">\n ${view.children.map((child) => this.nativeViewStackHTML(child)).join(\"\")}\n </div>`\n : \"\"\n\n return `\n <div>\n <div class=\"${wrapperClass} collapse no-chevron\" data-collapse-target=\"path-configuration-properties-${uniqueViewId}\">\n <div>\n <div class=\"view-title\">\n ${view.title == \"null\" ? \"\" : view.title}\n <div class=\"view-title-details\">${view.type}</div>\n </div>\n ${urlPath}\n </div>\n <div id=\"path-configuration-properties-${uniqueViewId}\" class=\"collapse-target\">\n ${pathConfigurationProperties}\n </div>\n </div>\n ${childrenHTML}\n </div>\n `\n }\n\n switchToSingleTabSheet(singleTabId) {\n // Hide the top part and all tabs\n this.sheetContent.querySelector(\".top-part\").classList.add(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the single mode content\n this.devTools.shadowRoot.getElementById(singleTabId).classList.add(\"active\")\n }\n\n switchToMultiTabSheet() {\n this.sheetContent.querySelector(\".top-part\").classList.remove(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the previous active tab\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => {\n if (tab.id == this.state.activeTab) {\n tab.classList.add(\"active\")\n }\n })\n }\n\n registerBridgeComponentExample() {\n switch (platform()) {\n case \"android\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents(\n BridgeComponentFactory(\"my-component\", ::MyComponent)\n )\n</pre>\n`\n case \"ios\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents([\n MyComponent.self\n ])\n</pre>`\n default:\n return \"\"\n }\n }\n\n registerBridgeComponentHelpURL() {\n switch (platform()) {\n case \"android\":\n return \"https://native.hotwired.dev/android/bridge-components\"\n case \"ios\":\n return \"https://native.hotwired.dev/ios/bridge-components\"\n default:\n return \"https://native.hotwired.dev\"\n }\n }\n\n checkNativeFeatures() {\n if (this.state.supportsNativeStackView) {\n this.bottomSheet.querySelector(\".tablink[data-tab-id='tab-native-stack']\").classList.remove(\"d-none\")\n }\n }\n\n addEventListeners() {\n if (this.bottomSheet.hasEventListeners) return\n\n // Click outside to close\n this.sheetOverlay.addEventListener(\"click\", () => {\n this.hideBottomSheet()\n this.switchToMultiTabSheet()\n })\n\n // Tab Click\n this.bottomSheet.querySelector(\".tablist\").addEventListener(\"click\", (event) => this.handleTabClick(event))\n\n // Action Buttons\n this.bottomSheet.querySelector(\".btn-clear-console-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearConsoleLogs()\n this.renderConsoleLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-bridge-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearBridgeLogs()\n this.renderBridgeLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-events\").addEventListener(\"click\", () => {\n this.devTools.state.clearEventLogs()\n this.renderEvents()\n })\n this.bottomSheet.querySelector(\".btn-reload-stack\").addEventListener(\"click\", () => {\n this.bottomSheet.querySelector(\".native-stack-wrapper\").style.opacity = 0.5\n this.devTools.refetchNativeStack()\n })\n\n // Switch to Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-switch-to-single-tab-sheet\").forEach((button) => {\n button.addEventListener(\"click\", (event) => {\n const singleTabId = event.target.closest(\"[data-tab-id]\").dataset.tabId\n if (!singleTabId) return\n this.switchToSingleTabSheet(singleTabId)\n })\n })\n\n // Close Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-close-single-mode\").forEach((button) => {\n button.addEventListener(\"click\", () => {\n this.switchToMultiTabSheet()\n })\n })\n\n // Dragging\n this.bottomSheet.querySelector(\".top-part\").addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchmove\", this.dragging.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchend\", this.dragStop.bind(this), { passive: true })\n\n // Filters\n this.bottomSheet.querySelector(\".console-filter-levels\").addEventListener(\"click\", ({ target }) => {\n const checkbox = target.closest(\"input[type='checkbox']\")\n if (!checkbox) return\n\n const filterType = checkbox.dataset.consoleFilter\n const isActive = checkbox.checked\n\n saveConsoleFilterLevels(filterType, isActive)\n this.renderConsoleLogs()\n })\n\n this.bottomSheet.querySelector(\".btn-search-console\").addEventListener(\"click\", () => {\n const searchInput = this.bottomSheet.querySelector(\".console-search\")\n searchInput.classList.toggle(\"d-none\")\n searchInput.querySelector(\"input\").focus()\n })\n\n this.bottomSheet.querySelector(\".console-search-input\").addEventListener(\"input\", (event) => {\n this.devTools.state.setConsoleSearchValue(event.target.value.toLowerCase())\n this.renderConsoleLogs()\n })\n\n // Settings\n this.bottomSheet.querySelector(\"#bottom-sheet-height\").addEventListener(\"change\", (event) => {\n const value = event.target.value\n this.sheetHeight = parseInt(value)\n saveSettings(\"bottomSheetHeight\", value)\n this.updateSheetHeight(value)\n })\n\n this.bottomSheet.querySelector(\"#console-error-animation-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"errorAnimationEnabled\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\"#font-size-input\").addEventListener(\"change\", (event) => {\n const value = event.target.value\n saveSettings(\"fontSize\", value)\n this.devTools.setCSSProperty(\"--font-size\", `${value}px`)\n })\n\n this.bottomSheet.querySelector(\"#auto-open-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"autoOpen\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\".pin-bottom-sheet\").addEventListener(\"click\", () => {\n const isPinned = getSettings(\"bottomSheetPinned\") === true\n saveSettings(\"bottomSheetPinned\", !isPinned)\n this.sheetOverlay.classList.toggle(\"active\")\n this.bottomSheet.querySelector(\".settings-dropdown\").classList.remove(\"dropdown-open\")\n })\n\n this.bottomSheet.addEventListener(\"click\", (event) => {\n // Handle collapsible elements\n const collapsible = event.target.closest(\".collapse\")\n if (collapsible && this.bottomSheet.contains(collapsible)) {\n const targetId = collapsible.getAttribute(\"data-collapse-target\")\n const targetElement = this.bottomSheet.querySelector(`#${targetId}`)\n if (targetElement) {\n const isActive = collapsible.classList.toggle(\"active\")\n targetElement.classList.toggle(\"active\", isActive)\n }\n return\n }\n\n // Handle dropdown triggers\n const trigger = event.target.closest(\".dropdown-trigger\")\n if (trigger) {\n event.preventDefault()\n this.toggleDropdown(trigger)\n return\n }\n\n // Close dropdowns when clicking outside\n const openDropdowns = this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\")\n openDropdowns.forEach((dropdown) => {\n const dropdownContainer = dropdown.closest(\".dropdown\")\n if (!dropdownContainer.contains(event.target)) {\n dropdown.classList.remove(\"dropdown-open\")\n }\n })\n })\n\n this.bottomSheet.hasEventListeners = true\n }\n\n toggleDropdown(triggerElement) {\n const dropdownContent = triggerElement.nextElementSibling || triggerElement.closest(\".dropdown\").querySelector(\".dropdown-content\")\n // Close other dropdowns first\n this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\").forEach((el) => {\n if (el !== dropdownContent) {\n el.classList.remove(\"dropdown-open\")\n }\n })\n dropdownContent.classList.toggle(\"dropdown-open\")\n }\n\n handleTabClick = (event) => {\n const clickedTab = event.target.closest(\".tablink\")\n if (!clickedTab) return\n\n const tabId = clickedTab.dataset.tabId\n this.devTools.state.setActiveTab(tabId)\n this.updateTabView(tabId)\n }\n\n updateTabView(tabId) {\n // Hide all Tabs\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Hide all Action Bars\n this.devTools.shadowRoot.querySelectorAll(\".tab-action-bar\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the clicked tab\n this.devTools.shadowRoot.querySelector(`[data-tab-id=\"${tabId}\"]`).classList.add(\"active\")\n this.devTools.shadowRoot.getElementById(tabId).classList.add(\"active\")\n\n // Show the action bar for the clicked tab\n this.devTools.shadowRoot.querySelector(`.tab-action-bar.${tabId}`).classList.add(\"active\")\n }\n\n showBottomSheet() {\n if (this.bottomSheet.classList.contains(\"show\")) return\n this.bottomSheet.classList.add(\"show\")\n this.originalOverflow = document.body.style.overflow\n document.body.style.overflow = \"hidden\"\n this.updateSheetHeight(this.sheetHeight)\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n }\n\n hideBottomSheet() {\n this.bottomSheet.classList.remove(\"show\")\n document.body.style.overflow = this.originalOverflow\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n this.bottomSheet.classList.toggle(\"fullscreen\", height === 100)\n }\n\n dragStart(event) {\n this.isDragging = true\n this.startY = event.pageY || event.touches?.[0].pageY\n this.startHeight = parseInt(this.sheetContent.style.height)\n this.bottomSheet.classList.add(\"dragging\")\n }\n\n dragging(event) {\n if (!this.isDragging) return\n const delta = this.startY - (event.pageY || event.touches?.[0].pageY)\n const newHeight = this.startHeight + (delta / window.innerHeight) * 100\n this.updateSheetHeight(newHeight)\n }\n\n dragStop() {\n this.isDragging = false\n this.bottomSheet.classList.remove(\"dragging\")\n const draggingThreshold = 10 // Defines how much the user needs to drag to trigger the hide/show\n const currentHeight = parseInt(this.sheetContent.style.height)\n\n const minThreshold = Math.max(0, this.sheetHeight - draggingThreshold)\n const maxThreshold = Math.min(100, this.sheetHeight + draggingThreshold)\n\n if (currentHeight < minThreshold) {\n this.hideBottomSheet()\n } else if (currentHeight > maxThreshold) {\n this.updateSheetHeight(100)\n } else {\n this.updateSheetHeight(this.sheetHeight)\n }\n }\n\n // Helper function to log messages, without causing a rerender of the bottom sheet\n // (Messages with a `HotwireDevTools` prefix will not be logged in the bottom sheet)\n log(message) {\n console.log(`HotwireDevTools: ${message}`)\n }\n\n // Get all the `static component = \"...\"` from the bridge components\n get bridgeComponentIdentifiers() {\n return window.Stimulus?.controllers.map((controller) => controller.component).filter((component) => component !== undefined) || []\n }\n\n get currentUrl() {\n return window.location.href\n }\n}\n","import { getSettings, saveSettings } from \"../utils/settings\"\n\nexport default class DevToolsState {\n constructor() {\n this.state = {\n consoleLogs: [],\n bridgeLogs: [],\n eventLogs: [],\n nativeStack: [],\n supportedBridgeComponents: [],\n bridgeIsConnected: false,\n supportsNativeStackView: false,\n consoleSearch: \"\",\n activeTab: getSettings(\"activeTab\") || \"tab-bridge-components\",\n }\n this.listeners = []\n }\n\n subscribe(listener) {\n this.listeners.push(listener)\n }\n\n notify() {\n this.listeners.forEach((listener) => listener(this.state))\n }\n\n addConsoleLog(type, message) {\n const log = { type, message, time: this.currentTime }\n this.state.consoleLogs.push(log)\n this.notify()\n }\n\n addBridgeLog(direction, componentName, eventName, eventArgs) {\n const log = { direction, componentName, eventName, eventArgs, time: this.currentTime }\n this.state.bridgeLogs.push(log)\n this.notify()\n }\n\n addEventLog(eventName) {\n const event = { eventName, time: this.currentTime }\n this.state.eventLogs.push(event)\n this.notify()\n }\n\n setNativeStack(stack) {\n this.state.nativeStack = stack\n this.notify()\n }\n\n setSupportsNativeStack(supports) {\n this.state.supportsNativeStackView = supports\n this.notify()\n }\n\n setBridgeIsConnected(isConnected) {\n this.state.bridgeIsConnected = isConnected\n this.notify()\n }\n\n setSupportedBridgeComponents(components) {\n this.state.supportedBridgeComponents = components\n this.notify()\n }\n\n clearConsoleLogs() {\n this.state.consoleLogs = []\n this.notify()\n }\n\n clearBridgeLogs() {\n this.state.bridgeLogs = []\n this.notify()\n }\n\n clearEventLogs() {\n this.state.eventLogs = []\n this.notify()\n }\n\n setActiveTab(tab) {\n this.state.activeTab = tab\n saveSettings(\"activeTab\", tab)\n }\n\n setConsoleSearchValue(value) {\n this.state.consoleSearch = value\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","/*\nSimilar to the `BridgeComponent` class from the Hotwire Native Bridge,\nbut without requiring a bridge component HTML element or Stimulus controller.\n\nOriginally from: 37signals LLC\nhttps://github.com/hotwired/hotwire-native-bridge\n*/\nexport default class NativeBridge {\n bridgeIsConnected() {\n return !!(window.HotwireNative?.web || window.Strada?.web)\n }\n\n // Send a message to the native side\n send(event, data = {}, callback = null) {\n if (!this.bridgeIsConnected()) {\n return Promise.reject(\"Bridge is not connected\")\n }\n\n const messageData = {\n ...data,\n metadata: {\n url: window.location.href,\n },\n }\n\n return this.bridge.send({\n component: \"dev-tools\",\n event,\n data: messageData,\n callback,\n })\n }\n\n isComponentSupported(component) {\n if (!this.bridgeIsConnected()) {\n return false\n }\n return this.bridge.supportsComponent(component)\n }\n\n getSupportedComponents() {\n return document.documentElement.dataset.bridgeComponents?.split(\" \") || []\n }\n\n get bridge() {\n return window.HotwireNative?.web || window.Strada?.web\n }\n}\n","import { cssContent } from \"./assets/DevToolsStyling.css\"\nimport DiagnosticsChecker from \"./lib/DiagnosticsChecker\"\nimport FloatingBubble from \"./components/FloatingBubble\"\nimport BottomSheet from \"./components/BottomSheet\"\nimport DevToolsState from \"./lib/DevToolsState\"\nimport NativeBridge from \"./lib/NativeBridge\"\nimport { resetSettings } from \"./utils/settings\"\nimport { debounce } from \"./utils/utils\"\nimport { getSettings } from \"./utils/settings\"\n\nexport default class DevTools {\n constructor(options = {}) {\n this.options = {\n enabled: true,\n reset: false,\n ...options,\n }\n if (!this.options.enabled) return\n if (this.options.reset) resetSettings()\n\n this.state = new DevToolsState()\n this.bubble = new FloatingBubble(this)\n this.bottomSheet = new BottomSheet(this)\n this.nativeBridge = new NativeBridge(this)\n this.diagnosticsChecker = new DiagnosticsChecker()\n this.state.subscribe(this.update.bind(this))\n this.listenForTurboEvents()\n }\n\n // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page\n setup() {\n if (!this.options.enabled) return\n this.setupShadowRoot()\n this.bubble.render()\n this.bottomSheet.render()\n\n // Add Console Proxy\n if (!this.originalConsole) {\n this.originalConsole = window.console\n this.addConsoleProxy()\n }\n\n // Add Bridge Proxy and call the native DevTools bridge component\n if (this.originalBridge) {\n // Bridge Proxy is already added\n this.callNativeBridgeComponent()\n } else if (window.HotwireNative || window.Strada) {\n // Bridge exists -> Add Bridge Proxy\n this.nativeBridgeGotConnected()\n } else {\n // Bridge does not exist yet -> Listen for the event\n document.addEventListener(\"web-bridge:ready\", () => {\n this.nativeBridgeGotConnected()\n })\n }\n\n // Add event listeners to the window\n this.addEventListeners()\n\n // Check for warnings\n this.diagnosticsChecker.checkForWarnings()\n\n this.bubble.onClick(() => {\n this.bottomSheet.showBottomSheet()\n this.nativeBridge.send(\"vibrate\")\n })\n\n if (getSettings(\"autoOpen\") === true) {\n this.bottomSheet.showBottomSheet()\n }\n }\n\n nativeBridgeGotConnected() {\n if (this.originalBridge) return\n\n this.originalBridge = window.HotwireNative?.web || window.Strada?.web\n this.addBridgeProxy()\n this.state.setBridgeIsConnected(true)\n this.callNativeBridgeComponent()\n this.updateSupportedBridgeComponents()\n this.startBridgeComponentObserver()\n }\n\n callNativeBridgeComponent() {\n if (this.nativeBridge.bridgeIsConnected()) {\n this.nativeBridge.send(\"connect\", {}, (message) => {\n // If this callback gets executed, it means the native counterpart\n // of the dev tools are installed and running.\n this.fetchNativeStack()\n })\n }\n }\n\n update = debounce((newState) => {\n this.bottomSheet.update(newState)\n }, 200)\n\n setupShadowRoot() {\n if (this.shadowContainer.shadowRoot) {\n this.shadowRoot = this.shadowContainer.shadowRoot\n this.injectCSSToShadowRoot()\n return\n }\n this.shadowRoot = this.shadowContainer.attachShadow({ mode: \"open\" })\n this.setCSSProperty(\"--font-size\", `${getSettings(\"fontSize\") || 16}px`)\n this.injectCSSToShadowRoot()\n }\n\n addBridgeProxy() {\n const createProxyHandler = () => ({\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n\n // We are only interested in the send and receive methods\n if (typeof originalValue === \"function\" && (prop === \"send\" || prop === \"receive\")) {\n return (...args) => {\n this.interceptedBridgeMessage(prop, args)\n return originalValue.apply(target, args)\n }\n }\n\n // Forward all the other calls to the original bridge\n return typeof originalValue === \"function\" ? (...args) => originalValue.apply(target, args) : originalValue\n },\n })\n\n if (window.Strada) {\n window.Strada.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n if (window.HotwireNative) {\n window.HotwireNative.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n }\n\n addConsoleProxy() {\n window.console = new Proxy(this.originalConsole, {\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n return (...args) => {\n this.interceptedConsoleMessage(prop, args)\n return originalValue?.apply(target, args)\n }\n },\n })\n }\n\n interceptedBridgeMessage(direction, args) {\n args.forEach((arg) => {\n const componentName = arg.component\n const eventName = arg.event\n const { metadata, ...eventArgs } = arg.data // Remove metadata from the args\n\n if (componentName !== \"dev-tools\") {\n // We don't want to log our own messages\n this.state.addBridgeLog(direction, componentName, eventName, eventArgs)\n }\n })\n }\n\n interceptedConsoleMessage(type, args) {\n const message = args\n .map((arg) => {\n if (arg instanceof Element) {\n const attrs = Array.from(arg.attributes)\n .map((attr) => `${attr.name}=\"${attr.value}\"`)\n .join(\" \")\n\n return `&lt;${arg.tagName.toLowerCase()}${attrs ? \" \" + attrs : \"\"}&gt;&lt;/${arg.tagName.toLowerCase()}&gt;`\n }\n if (typeof arg === \"object\") {\n try {\n return `<pre>${JSON.stringify(arg, null, 2)}</pre>`\n } catch {\n return `<pre>${arg}</pre>`\n }\n }\n // Escape HTML in string values\n const stringValue = arg.toString()\n return stringValue.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\")\n })\n .join(\" \")\n\n // Ignore messages from the dev tools itself\n // Otherwise we could end up in an infinite loop\n if (message.includes(\"hotwire-native-dev-tools\") || message.includes(\"HotwireDevTools\")) return\n\n this.state.addConsoleLog(type, message)\n if (type === \"error\") {\n this.bubble.animateErrorBorder()\n }\n }\n\n // Fetch the current stack from the native side\n // The debounce on this function is intentionally high,\n // to ensure the native side has enough time to set the ViewController / Fragment titles.\n // With a lower debounce, the view controller / fragment title would often be empty.\n fetchNativeStack = debounce(() => {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setSupportsNativeStack(true)\n this.state.setNativeStack(message.data.stack)\n })\n }, 1000)\n\n refetchNativeStack() {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setNativeStack(message.data.stack)\n })\n }\n\n injectCSSToShadowRoot = async () => {\n if (this.shadowRoot.querySelector(\"style\")) return\n\n const style = document.createElement(\"style\")\n style.textContent = cssContent()\n this.shadowRoot.appendChild(style)\n }\n\n addEventListeners() {\n if (this.hasEventListeners) return\n\n // Capture uncaught errors and unhandled promise rejections\n window.addEventListener(\"error\", (event) => {\n const { message, filename, lineno, colno } = event\n const formattedMessage = `${message} at ${filename}:${lineno}:${colno}`\n this.interceptedConsoleMessage(\"error\", [formattedMessage])\n })\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.interceptedConsoleMessage(\"error\", [event.reason?.message])\n })\n\n // Observe screen size or orientation changes to reposition the bubble\n window.addEventListener(\n \"resize\",\n () => {\n this.bubble.render()\n },\n { passive: true }\n )\n\n this.hasEventListeners = true\n }\n\n listenForTurboEvents() {\n if (this.eventsRegistered) return\n\n const turboEvents = [\n \"turbo:click\",\n \"turbo:before-visit\",\n \"turbo:visit\",\n \"turbo:before-cache\",\n \"turbo:before-render\",\n \"turbo:render\",\n \"turbo:load\",\n \"turbo:morph\",\n \"turbo:before-morph-element\",\n \"turbo:before-morph-attribute\",\n \"turbo:morph-element\",\n \"turbo:submit-start\",\n \"turbo:submit-end\",\n \"turbo:before-frame-render\",\n \"turbo:frame-render\",\n \"turbo:frame-load\",\n \"turbo:frame-missing\",\n \"turbo:before-stream-render\",\n \"turbo:before-fetch-request\",\n \"turbo:before-fetch-response\",\n \"turbo:before-prefetch\",\n \"turbo:fetch-request-error\",\n ]\n\n turboEvents.forEach((eventName) => {\n window.addEventListener(\n eventName,\n (event) => {\n this.state.addEventLog(eventName)\n },\n { passive: true }\n )\n })\n\n this.eventsRegistered = true\n }\n\n startBridgeComponentObserver() {\n if (this.bridgeComponentObserver) return\n\n this.bridgeComponentObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\" && mutation.attributeName === \"data-bridge-components\") {\n this.updateSupportedBridgeComponents()\n }\n }\n })\n\n this.bridgeComponentObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-bridge-components\"],\n })\n }\n\n updateSupportedBridgeComponents() {\n this.state.setSupportedBridgeComponents(this.nativeBridge.getSupportedComponents().sort())\n }\n\n getCSSProperty(propertyName) {\n const rootStyles = getComputedStyle(this.shadowContainer)\n return rootStyles.getPropertyValue(propertyName).trim()\n }\n\n setCSSProperty(propertyName, value) {\n this.shadowContainer.style.setProperty(propertyName, value)\n }\n\n get shadowContainer() {\n const existingShadowContainer = document.getElementById(\"hotwire-native-dev-tools-shadow-container\")\n if (existingShadowContainer) {\n return existingShadowContainer\n }\n const shadowContainer = document.createElement(\"div\")\n shadowContainer.id = \"hotwire-native-dev-tools-shadow-container\"\n shadowContainer.setAttribute(\"data-native-prevent-pull-to-refresh\", \"\")\n document.body.appendChild(shadowContainer)\n return shadowContainer\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","import DevTools from \"./DevTools\"\n\nconst setupDevTools = (options = {}) => {\n const devTools = new DevTools(options)\n if (!devTools.options.enabled) return\n\n devTools.setup()\n\n document.addEventListener(\n \"turbo:load\",\n () => {\n devTools.setup()\n },\n { passive: true }\n )\n}\n\nexport { setupDevTools }\n"],"names":["cssContent","_checkForTurboDrive","_checkForDuplicatedTurboFrames","_checkTurboPermanentElements","DiagnosticsChecker","__publicField","message","once","extraArgs","__privateGet","__privateAdd","_a","turboFramesIds","id","index","turboPermanentElements","element","turboFrame","getSettings","key","saveSettings","value","settings","resetSettings","getConsoleFilterLevels","saveConsoleFilterLevels","consoleFilterLevels","debounce","fn","delay","timeoutId","args","callback","this","userAgent","isIosApp","isAndroidApp","platform","formattedPlatform","hotwireIcon","arrowUp","arrowDown","arrowLeft","trash","rotate","questionMark","search","filter","threeDotsVertical","FloatingBubble","devTools","errorBorder","circleElement","animationContainer","defaultPos","startX","startY","existingBubble","event","touch","deltaX","deltaY","xPos","yPos","BottomSheet","clickedTab","tabId","newState","existingBottomSheet","activeTab","consoleSearch","Icons.threeDotsVertical","Icons.trash","Icons.search","Icons.filter","Icons.rotate","Icons.questionMark","Icons.arrowLeft","container","log","bridgeComponentsAmount","bridgeComponentIdentifiers","component","view","direction","componentName","eventName","eventArgs","time","Icons.arrowDown","Icons.arrowUp","formattedValue","type","isMainView","isTabBar","isHotwireView","wrapperClass","uniqueViewId","urlPath","pathConfigurationPropertiesJson","props","pathConfigurationProperties","childrenHTML","child","singleTabId","tab","button","target","checkbox","filterType","isActive","searchInput","isPinned","collapsible","targetId","targetElement","trigger","dropdown","triggerElement","dropdownContent","el","height","delta","newHeight","draggingThreshold","currentHeight","minThreshold","maxThreshold","controller","DevToolsState","listener","stack","supports","isConnected","components","NativeBridge","_b","data","messageData","DevTools","options","style","createProxyHandler","prop","receiver","originalValue","arg","metadata","attrs","attr","filename","lineno","colno","formattedMessage","mutationsList","mutation","propertyName","existingShadowContainer","shadowContainer","setupDevTools"],"mappings":";;;;;;;AAGO,MAAMA,IAAa,MACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
1
+ {"version":3,"file":"hotwire-native-dev-tools.es.js","sources":["../src/assets/DevToolsStyling.css.js","../src/lib/DiagnosticsChecker.js","../src/utils/settings.js","../src/utils/utils.js","../src/assets/icons.js","../src/components/FloatingBubble.js","../src/components/BottomSheet.js","../src/lib/DevToolsState.js","../src/lib/NativeBridge.js","../src/DevTools.js","../src/index.js"],"sourcesContent":["// Ideally, we would use a dedicated CSS file, but I dind't find a good way to load the styles from a dedicated CSS file.\n// So we just use a function that returns the CSS content as a string.\n// For better syntax highlighting, you can set the language to CSS in the editor for this file.\nexport const cssContent = () => {\n return `\n :host {\n all: initial;\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\" !important;\n --font-size: 16px;\n font-size: var(--font-size) !important;\n }\n\n * {\n box-sizing: border-box;\n }\n\n p, span, h1, h2, h3, h4, h5, h6, div, a, button, input, label {\n font-size: inherit;\n }\n\n\n a {\n color: white;\n }\n\n h1, h2, h3, h4, h5, h6 {\n margin: 0;\n }\n\n button, label, .toggle-label {\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n input {\n display: block;\n padding: 3px;\n box-sizing: border-box;\n border: 1px solid #ccc;\n border-radius: 4px;\n }\n\n input:focus {\n outline: none;\n }\n\n .btn-icon {\n background-color: transparent;\n border: none;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n height: 100%;\n }\n\n .btn-icon svg {\n width: 1rem;\n height: 1rem;\n fill: white;\n }\n\n /* Dropdown */\n .dropdown-content {\n display: none;\n position: absolute;\n z-index: 1000;\n background: white;\n border: 1px solid #ddd;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n min-width: 200px;\n max-width: 300px;\n opacity: 0;\n transform: scale(0.9);\n transition: opacity 0.2s, transform 0.2s;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .dropdown-content.dropdown-open {\n display: block;\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .dropdown-content > * {\n padding: 12px;\n }\n\n .dropdown-content button,\n .dropdown-content label {\n color: black;\n width: 100%;\n margin: 0;\n border: none;\n display: flex;\n align-items: center;\n }\n\n .dropdown-content button:not(:first-child) {\n border-top: 1px solid #cecdcd;\n }\n\n .settings-dropdown {\n right: 0;\n top: 2rem;\n }\n\n /* Floating bubble */\n #floating-bubble {\n display: flex;\n background-color: hsl(0deg 0% 0% / 60%);\n border-radius: 50%;\n touch-action: none;\n user-select: none;\n z-index: 10000000;\n position: fixed;\n top: 10px;\n left: 10px;\n\n /* Remove tap highlight on iOS */\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n\n /* Keep width, height, and border in sync with bubbleSize in FloatingBubble.js */\n width: 4.75rem;\n height: 4.75rem;\n border: 0.3rem solid rgba(136, 136, 136, 0.5);\n }\n\n #floating-bubble svg {\n transform: scale(0.6);\n fill: #b1b1b1;\n }\n\n #floating-bubble .animation-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 1;\n }\n\n #floating-bubble .error-border {\n position: absolute;\n top: -30px;\n left: -30px;\n width: calc(100% + 60px);\n height: calc(100% + 60px);\n border-radius: 50%;\n }\n\n #floating-bubble .error-border circle {\n transform-origin: center;\n transform: rotate(-90deg);\n }\n\n #floating-bubble .error-border circle.animate {\n animation: error-border-progress 0.8s ease-out forwards;\n }\n\n #floating-bubble .animation-container.fade-out {\n animation: fade-out 0.4s ease-out forwards;\n }\n\n /*\n The \"stroke-dasharray\" defines the start of the animation\n The value is calculated by the formula: 2 * Math.PI * radius\n In this case: 2 * Math.PI * 90 = 565\n */\n @keyframes error-border-progress {\n from {\n stroke-dashoffset: 565;\n }\n to {\n stroke-dashoffset: 0;\n }\n }\n\n @keyframes fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n\n /* Bottom Sheet */\n .bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n max-height: 100%;\n display: flex;\n opacity: 0;\n pointer-events: none;\n align-items: center;\n flex-direction: column;\n justify-content: flex-end;\n transition: 0.1s linear;\n z-index: 10000001;\n }\n\n .bottom-sheet .sheet-overlay.active {\n position: fixed;\n top: 0;\n left: 0;\n z-index: -1;\n width: 100%;\n height: 100%;\n opacity: 0.2;\n background: #000;\n }\n\n .bottom-sheet .content {\n width: 100%;\n height: 40vh;\n position: relative;\n color: white;\n transform: translateY(100%);\n border-radius: 12px 12px 0 0;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.03);\n transition: 0.3s ease;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry {\n border-bottom: 1px solid #6c6c6c;\n white-space: collapse;\n }\n\n .bottom-sheet .log-entry-icon svg {\n width: 1rem;\n fill: white;\n }\n\n .bottom-sheet.show {\n opacity: 1;\n pointer-events: auto;\n }\n\n .bottom-sheet.show .content {\n transform: translateY(0%);\n }\n\n .bottom-sheet.dragging .content {\n transition: none;\n }\n .bottom-sheet.fullscreen .content {\n border-radius: 0;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry-message.warn {\n color: #f39c12;\n }\n\n .bottom-sheet .log-entry-message.error {\n color: #ED4E4C;\n }\n\n .bottom-sheet .tab-action-bars {\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tablist on Android devices */\n margin-top: -1px;\n }\n\n .bottom-sheet .tab-action-bar {\n display: none;\n justify-content: space-between;\n background-color: rgb(49, 54, 63);\n padding: 0.5rem;\n padding-right: 1rem;\n padding-left: 1rem;\n }\n\n .bottom-sheet .tab-action-bar.active {\n display: flex;\n }\n\n .bottom-sheet .tab-action-bar button:active svg {\n fill: #6c6c6c;\n }\n\n .bottom-sheet .btn-clear-tab,\n .bottom-sheet .btn-reload-tab {\n margin-left: auto;\n }\n\n /* Bottom Sheet Tabs */\n .tablist {\n display: flex;\n overflow: hidden;\n background-color: #EEEEEE;\n }\n\n .tablist .tablink {\n color: black;\n background-color: inherit;\n width: 100%;\n border: none;\n outline: none;\n padding: 14px 16px;\n margin: 0;\n font-size: 0.8em;\n }\n\n .tablist .tablink.active {\n background-color: #31363f;\n color: white;\n }\n\n .tablist .tablink-settings {\n background-color: inherit;\n }\n\n .tab-contents {\n height: 100%;\n overflow: scroll;\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tab-contents on Android devices */\n margin-top: -1px;\n }\n\n .outer-tab-content {\n display: none;\n border-top: none;\n height: 100%;\n overflow: scroll;\n background-color: hsl(0deg 0% 0% / 80%);\n backdrop-filter: blur(3px) saturate(100%);\n -webkit-backdrop-filter: blur(3px) saturate(100%);\n padding-bottom: 7em;\n }\n .outer-tab-content.active {\n display: block;\n }\n .inner-tab-content {\n padding: 1rem;\n overflow-x: auto;\n white-space: nowrap;\n }\n .single-tab-content .inner-tab-content {\n white-space: normal;\n }\n\n .tab-empty-content {\n display: flex;\n justify-content: center;\n flex-direction: column;\n align-items: center;\n padding: 1em;\n }\n\n .bottom-sheet .tablink-dropdown {\n background: inherit;\n border: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n width: 2rem;\n }\n\n .bottom-sheet .tablink-dropdown svg {\n width: 1rem;\n height: 1rem;\n fill: #121212;\n }\n\n .bottom-sheet .tablink-dropdown:active {\n background-color: #31363f;\n }\n .bottom-sheet .tablink-dropdown:active svg {\n fill: white;\n }\n\n /* Bottom Sheet Stack Visualization */\n .bottom-sheet .viewstack-card {\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 10px;\n margin: 10px 0;\n background: white;\n color: black;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: auto;\n }\n\n .bottom-sheet .viewstack-card.current-view {\n border: 2px solid #f1f208;\n }\n\n .bottom-sheet .tab-container {\n background: #EEEEEE;\n }\n\n .bottom-sheet .main-view {\n border-color: #4e6080;\n background: #31363F;\n }\n\n .bottom-sheet .hotwire-view {\n border-color: #6db1b5;\n background: #76ABAE;\n }\n\n .bottom-sheet .child-container {\n margin-left: 30px;\n position: relative;\n }\n\n .bottom-sheet .child-container::before {\n content: \"\";\n position: absolute;\n left: -15px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #ddd;\n }\n\n .bottom-sheet .view-title {\n display: flex;\n align-items: center;\n gap: 0.5em;\n\n font-weight: bold;\n color: white;\n margin-bottom: 5px;\n }\n\n .bottom-sheet .view-title-details {\n color: #efefef;\n font-size: 0.6em;\n }\n\n .bottom-sheet .tab-container .view-title-details {\n color: #6c6c6c;\n }\n\n .bottom-sheet .view-url {\n color: #000000;\n font-size: 0.9em;\n margin-top: 5px;\n word-break: break-all;\n }\n\n .bottom-sheet .non-identified-view {\n background: #EEEEEE;\n }\n .bottom-sheet .non-identified-view .view-title-details,\n .bottom-sheet .non-identified-view .view-title {\n color: #6c6c6c;\n }\n\n .bottom-sheet .viewstack-card pre {\n font-size: 0.8em;\n }\n\n /* Bottom Sheet Bridge Components */\n .bottom-sheet .bridge-components-collapse-btn {\n background: none;\n border: none;\n color: white;\n width: 100%;\n text-align: left;\n border-bottom: 1px solid #eee;\n padding: 0.5em 0em;\n font-size: 0.9em;\n }\n\n .tab-content-bridge-components {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 0.5em 0em;\n }\n\n .tab-content-bridge-components .bridge-component {\n position: relative;\n padding-left: 15px;\n }\n\n .tab-content-bridge-components .bridge-component::before {\n content: \"•\";\n color: #eee;\n font-size: 1.5em;\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n }\n .tab-content-bridge-components .bridge-component.connected::before {\n color: #5cff00\n }\n\n /* Collapsibles */\n .collapse-target {\n display: none;\n }\n\n .collapse-target.active {\n display: block;\n }\n\n .collapse:not(.no-chevron):after {\n content: '\\\\25BC';\n font-size: 13px;\n color: #777;\n float: right;\n margin-left: 5px;\n }\n\n .collapse:not(.no-chevron).active:after {\n content: \"\\\\25B2\";\n }\n\n /* Custom checkbox toggles */\n .toggle {\n display: inline-block;\n user-select: none;\n }\n\n .toggle-switch {\n display: inline-block;\n background: #ccc;\n border-radius: 16px;\n width: 29px;\n height: 16px;\n position: relative;\n vertical-align: middle;\n transition: background 0.15s;\n }\n .toggle-switch:before,\n .toggle-switch:after {\n content: \"\";\n }\n .toggle-switch:before {\n display: block;\n background: linear-gradient(to bottom, #fff 0%, #eee 100%);\n border-radius: 50%;\n width: 12px;\n height: 12px;\n position: absolute;\n top: 2px;\n left: 2px;\n transition: left 0.15s;\n }\n .toggle-checkbox:checked + .toggle-switch {\n background: #56c080;\n }\n .toggle-checkbox:checked + .toggle-switch:before {\n left: 15px;\n }\n\n .toggle-checkbox {\n position: absolute;\n visibility: hidden;\n }\n\n .toggle-label {\n position: relative;\n margin-left: 3px;\n top: 2px;\n }\n\n /* Utility classes */\n .d-none {\n display: none;\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-ellipsis {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .break-word {\n word-break: break-word;\n }\n\n .d-flex {\n display: flex;\n }\n\n .flex-column {\n flex-direction: column;\n }\n\n .justify-content-between {\n justify-content: space-between;\n }\n\n .justify-content-end {\n justify-content: flex-end;\n }\n\n .align-items-center {\n align-items: center;\n }\n\n .flex-grow-1 {\n flex-grow: 1;\n }\n\n .border-bottom {\n border-bottom: 1px solid #c5c1c1;\n }\n\n .no-wrap {\n overflow: hidden;\n white-space: nowrap;\n }\n\n .white-space-collapse {\n white-space: collapse;\n }\n\n .overflow-auto {\n overflow: auto;\n }\n\n .mt-1 {\n margin-top: 0.25rem;\n }\n\n .mt-2 {\n margin-top: 0.5rem;\n }\n\n .mt-4 {\n margin-top: 1.5rem;\n }\n\n .ms-1 {\n margin-left: 0.25rem;\n }\n\n .mb-2 {\n margin-bottom: 0.5rem;\n }\n\n .mb-3 {\n margin-bottom: 1rem;\n }\n\n .mb-4 {\n margin-bottom: 1.5rem;\n }\n\n .gap-1 {\n gap: 0.25rem;\n }\n\n .gap-3 {\n gap: 1rem;\n }\n\n .pb-2 {\n padding-bottom: 0.5rem;\n }\n\n .pt-2 {\n padding-top: 0.5rem;\n }\n\n .w-100 {\n width: 100%;\n }\n\n .w-80 {\n width: 80%;\n }\n `\n}\n","export default class DiagnosticsChecker {\n constructor() {\n this.printedWarnings = []\n }\n\n printWarning = (message, once = true, ...extraArgs) => {\n if (once && this.printedWarnings.includes(message)) return\n\n console.warn(`DevTools: ${message}`, ...extraArgs)\n this.printedWarnings.push(message)\n }\n\n checkForWarnings = () => {\n this.#checkForTurboDrive()\n this.#checkForDuplicatedTurboFrames()\n this.#checkTurboPermanentElements()\n }\n\n #checkForTurboDrive = () => {\n if (!window.Turbo) {\n // Since it's possible that the DevTools are loaded before Turbo, we need to wait a bit to check if Turbo is loaded\n setTimeout(() => {\n if (!window.Turbo) {\n this.printWarning(\"Turbo is not detected. Hotwire Native will not work correctly without Turbo\")\n }\n }, 1000)\n } else if (window.Turbo?.session.drive === false) {\n setTimeout(() => {\n if (window.Turbo?.session.drive === false) {\n this.printWarning(\"Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive\")\n }\n }, 1000)\n }\n }\n\n #checkForDuplicatedTurboFrames = () => {\n const turboFramesIds = this.turboFrameIds\n const duplicatedIds = turboFramesIds.filter((id, index) => turboFramesIds.indexOf(id) !== index)\n\n duplicatedIds.forEach((id) => {\n this.printWarning(`Multiple Turbo Frames with the same ID '${id}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`)\n })\n }\n\n #checkTurboPermanentElements = () => {\n const turboPermanentElements = document.querySelectorAll(\"[data-turbo-permanent]\")\n if (turboPermanentElements.length === 0) return\n\n turboPermanentElements.forEach((element) => {\n const id = element.id\n if (id === \"\") {\n const message = `Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n\n const idIsDuplicated = id && document.querySelectorAll(`#${id}`).length > 1\n if (idIsDuplicated) {\n const message = `Turbo Permanent Element with ID '${id}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n })\n }\n\n get turboFrameIds() {\n return Array.from(document.querySelectorAll(\"turbo-frame\")).map((turboFrame) => turboFrame.id)\n }\n}\n","export const getSettings = (key) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n return settings[key]\n}\n\nexport const saveSettings = (key, value) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n settings[key] = value\n\n localStorage.setItem(\"hotwire-native-dev-tools\", JSON.stringify(settings))\n}\n\nexport const resetSettings = () => {\n localStorage.removeItem(\"hotwire-native-dev-tools\")\n}\n\nexport const getConsoleFilterLevels = () => {\n const consoleFilterLevels = getSettings(\"consoleFilterLevels\") || {\n warn: true,\n error: true,\n debug: true,\n info: true,\n log: true,\n }\n\n return consoleFilterLevels\n}\n\nexport const saveConsoleFilterLevels = (key, value) => {\n const consoleFilterLevels = getConsoleFilterLevels()\n consoleFilterLevels[key] = value\n saveSettings(\"consoleFilterLevels\", consoleFilterLevels)\n return consoleFilterLevels\n}\n","export const debounce = (fn, delay) => {\n let timeoutId = null\n\n return (...args) => {\n const callback = () => fn.apply(this, args)\n clearTimeout(timeoutId)\n timeoutId = setTimeout(callback, delay)\n }\n}\n\nconst { userAgent } = window.navigator\nexport const isIosApp = /iOS/.test(userAgent)\nexport const isAndroidApp = /Android/.test(userAgent)\n\nexport const platform = () => {\n if (isIosApp) {\n return \"ios\"\n } else if (isAndroidApp) {\n return \"android\"\n }\n return \"unknown\"\n}\n\nexport const formattedPlatform = () => {\n switch (platform()) {\n case \"android\":\n return \"Android\"\n case \"ios\":\n return \"iOS\"\n default:\n return \"<unknown>\"\n }\n}\n","export const hotwireIcon = `\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 294 320\">\n <g transform=\"matrix(1,0,0,1,-28.38,-15.268)\">\n <g transform=\"matrix(1,0,0,1,-462.157,-144.417)\">\n <path d=\"M783.777,159.685L683.006,262.542L765.948,268.939L622.459,394.208L690.389,396.4L490.537,479.149L569.424,402.053L511.312,400.203L639.22,296.093L533.548,287.812L783.777,159.685Z\"/>\n </g>\n </g>\n </svg>\n`\n\nexport const arrowUp = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71L280 392c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-214.1-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z\"/>\n </svg>\n`\n\nexport const arrowDown = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 297c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 120c0-13.3 10.7-24 24-24s24 10.7 24 24l0 214.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 409c-9.4 9.4-24.6 9.4-33.9 0L127 297z\"/>\n </svg>\n`\n\nexport const arrowLeft = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\"/>\n </svg>\n`\n\nexport const trash = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z\"/>\n </svg>\n`\n\nexport const rotate = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z\"/>\n </svg>\n`\n\nexport const questionMark = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n`\n\nexport const search = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z\"/>\n </svg>\n`\n\nexport const filter = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M3.9 54.9C10.5 40.9 24.5 32 40 32l432 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9 320 448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z\"/>\n </svg>\n`\n\nexport const threeDotsVertical = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\"/>\n </svg>\n`\n","import { getSettings, saveSettings } from \"../utils/settings\"\nimport { debounce } from \"../utils/utils\"\nimport { hotwireIcon } from \"../assets/icons\"\n\nexport default class FloatingBubble {\n constructor(devTools) {\n this.devTools = devTools\n this.bubbleSize = 4.75 * 16 + 0.3 * 16 // 4.75rem + 0.3rem border\n this.minVisible = this.bubbleSize * 0.5 // Keep 50% of the bubble visible at all times\n this.currentlyDragging = false\n }\n\n render = debounce(() => {\n this.setPosition()\n this.createDragItem()\n this.setTranslate(this.initialX, this.initialY, this.dragItem)\n this.addEventListeners()\n }, 50)\n\n setPosition() {\n this.settingKey = window.innerWidth < window.innerHeight ? \"bubblePosPortrait\" : \"bubblePosLandscape\"\n\n // Get stored position or use default (bottom right corner)\n const defaultPos = { x: window.innerWidth - 100, y: window.innerHeight - 100 }\n const { x: startX, y: startY } = getSettings(this.settingKey) || defaultPos\n\n this.currentX = this.initialX = this.xOffset = startX\n this.currentY = this.initialY = this.yOffset = startY\n }\n\n createDragItem() {\n const existingBubble = this.devTools.shadowRoot?.getElementById(\"floating-bubble\")\n if (existingBubble) {\n this.dragItem = existingBubble\n return\n }\n\n this.dragItem = document.createElement(\"div\")\n this.dragItem.id = \"floating-bubble\"\n this.dragItem.innerHTML = hotwireIcon\n this.devTools.shadowRoot.appendChild(this.dragItem)\n }\n\n addEventListeners() {\n if (this.dragItem.hasEventListeners) return\n this.dragItem.addEventListener(\"click\", this.click.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchend\", this.dragEnd.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchmove\", this.drag.bind(this), { passive: true })\n this.dragItem.hasEventListeners = true\n }\n\n click(event) {\n if (this.clickCallback) {\n this.clickCallback(event)\n }\n }\n\n animateErrorBorder = debounce(() => {\n if (!this.dragItem) return\n if (getSettings(\"errorAnimationEnabled\") === false) return\n\n let errorBorder = this.dragItem.querySelector(\".error-border\")\n let circleElement = this.dragItem.querySelector(\".error-border circle\")\n\n if (errorBorder) {\n errorBorder.remove()\n }\n\n const animationContainer = document.createElement(\"div\")\n animationContainer.className = \"animation-container\"\n animationContainer.innerHTML = `\n <svg viewBox=\"0 0 180 180\" xmlns=\"http://www.w3.org/2000/svg\" class=\"error-border\">\n <defs>\n <linearGradient id=\"errorGradient\" gradientTransform=\"rotate(45)\">\n <stop offset=\"0%\" stop-color=\"#e4241a\" />\n <stop offset=\"50%\" stop-color=\"#dd1f15\" />\n <stop offset=\"100%\" stop-color=\"#f6160a\" />\n </linearGradient>\n </defs>\n <circle cx=\"90\" cy=\"90\" r=\"90\" fill=\"none\" stroke=\"url(#errorGradient)\" stroke-width=\"21\"\n stroke-dasharray=\"565\" stroke-dashoffset=\"565\" stroke-linecap=\"round\" />\n </svg>\n `\n\n this.dragItem.appendChild(animationContainer)\n circleElement = this.dragItem.querySelector(\".error-border circle\")\n circleElement.classList.add(\"animate\")\n\n setTimeout(() => {\n animationContainer.classList.add(\"fade-out\")\n }, 1300) // Start fade-out after animation completes\n\n setTimeout(() => {\n if (animationContainer && animationContainer.parentNode) {\n animationContainer.remove()\n }\n }, 1800) // Remove after fade-out completes\n }, 100)\n\n onClick(callback) {\n this.clickCallback = callback\n }\n\n dragStart(event) {\n if (!event.target.closest(\"#floating-bubble\")) return\n this.currentlyDragging = true\n\n this.initialX = event.touches[0].clientX - this.xOffset\n this.initialY = event.touches[0].clientY - this.yOffset\n }\n\n dragEnd() {\n this.initialX = this.currentX\n this.initialY = this.currentY\n this.currentlyDragging = false\n\n saveSettings(this.settingKey, { x: this.currentX, y: this.currentY })\n }\n\n drag(event) {\n if (!this.currentlyDragging) return\n\n const touch = event.touches[0]\n const deltaX = touch.clientX - this.initialX\n const deltaY = touch.clientY - this.initialY\n\n // Constrain movement within screen bounds\n this.currentX = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaX, window.innerWidth - this.minVisible))\n this.currentY = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaY, window.innerHeight - this.minVisible))\n\n this.xOffset = this.currentX\n this.yOffset = this.currentY\n\n if (!this.animationFrame) {\n this.animationFrame = requestAnimationFrame(() => {\n this.setTranslate(this.currentX, this.currentY, this.dragItem)\n this.animationFrame = null\n })\n }\n }\n\n setTranslate(xPos, yPos, element) {\n element.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`\n }\n}\n","import * as Icons from \"../assets/icons\"\nimport { platform, formattedPlatform } from \"../utils/utils\"\nimport { saveSettings, getSettings, getConsoleFilterLevels, saveConsoleFilterLevels } from \"../utils/settings\"\n\n// WARNING: Be careful when console logging in this file, as it can cause an infinite loop\n// When you need to debug, use the `log` helper function like this:\n// this.log(\"message\")\n// or turn off the console proxy in DevTools.js\n\nexport default class BottomSheet {\n constructor(devTools) {\n this.devTools = devTools\n this.state = devTools.state.state\n this.sheetHeight = parseInt(getSettings(\"bottomSheetHeight\")) || 55\n }\n\n render() {\n this.createBottomSheet()\n this.sheetContent = this.bottomSheet.querySelector(\".content\")\n this.sheetOverlay = this.bottomSheet.querySelector(\".sheet-overlay\")\n this.addEventListeners()\n }\n\n update(newState) {\n this.state = newState\n this.checkNativeFeatures()\n this.renderConsoleLogs()\n this.renderBridgeComponents()\n this.renderBridgeLogs()\n this.renderEvents()\n this.renderNativeStack()\n }\n\n createBottomSheet() {\n const existingBottomSheet = this.devTools.shadowRoot?.querySelector(\".bottom-sheet\")\n if (existingBottomSheet) {\n this.bottomSheet = existingBottomSheet\n return\n }\n\n const activeTab = this.state.activeTab\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n this.bottomSheet = document.createElement(\"div\")\n this.bottomSheet.classList.add(\"bottom-sheet\")\n this.bottomSheet.innerHTML = `\n <div class=\"sheet-overlay ${getSettings(\"bottomSheetPinned\") === true ? \"\" : \"active\"}\"></div>\n <div class=\"content\">\n <div class=\"top-part\">\n <div class=\"tablist\">\n <button class=\"tablink ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\" data-tab-id=\"tab-bridge-components\">Bridge</button>\n <button class=\"tablink ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-console-logs\">Console</button>\n <button class=\"tablink ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-event-logs\">Events</button>\n <button class=\"tablink ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"} d-none\" data-tab-id=\"tab-native-stack\">Stack</button>\n <div class=\"tablink-settings dropdown d-flex\">\n <button class=\"dropdown-trigger tablink-dropdown\">${Icons.threeDotsVertical}</button>\n <div class=\"dropdown-content settings-dropdown\">\n <button class=\"btn-switch-to-single-tab-sheet\" data-tab-id=\"single-tab-settings\">Settings</button>\n <button class=\"pin-bottom-sheet\">Pin Bottom Sheet</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-action-bars\">\n <div class=\"tab-action-bar tab-bridge-components ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-bridge-logs\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar d-flex flex-column tab-console-logs ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"d-flex\">\n <button class=\"btn-icon btn-search-console\">${Icons.search}</button>\n <div class=\"dropdown\">\n <button class=\"dropdown-trigger btn-icon\">${Icons.filter}</button>\n <div class=\"dropdown-content console-filter-levels\">\n <label><input type=\"checkbox\" ${consoleFilterLevels.warn ? \"checked\" : \"\"} data-console-filter=\"warn\" /> Warnings</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.error ? \"checked\" : \"\"} data-console-filter=\"error\" /> Errors</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.debug ? \"checked\" : \"\"} data-console-filter=\"debug\" /> Debug</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.info ? \"checked\" : \"\"} data-console-filter=\"info\" /> Info</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.log ? \"checked\" : \"\"} data-console-filter=\"log\" /> Logs</label>\n </div>\n </div>\n <button class=\"btn-icon btn-clear-tab btn-clear-console-logs\">${Icons.trash}</button>\n </div>\n\n <div class=\"console-search mt-2 ${consoleSearch ? \"\" : \"d-none\"}\">\n <input type=\"search\" class=\"console-search-input\" value=\"${consoleSearch}\" placeholder=\"Search console logs\" />\n </div>\n </div>\n <div class=\"tab-action-bar tab-event-logs ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-events\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar tab-native-stack ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-reload-tab btn-reload-stack\">${Icons.rotate}</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-contents\">\n <div id=\"tab-bridge-components\" class=\"outer-tab-content ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content\">\n <button class=\"collapse bridge-components-collapse-btn\" type=\"button\" data-collapse-target=\"bridge-components-collapse\">\n Registered Bridge Components: <span class=\"bridge-components-amount\">${this.state.supportedBridgeComponents.length}</span>\n </button>\n <div id=\"bridge-components-collapse\" class=\"collapse-target\">\n <div class=\"d-flex justify-content-between border-bottom\">\n <div class=\"tab-content-bridge-components flex-grow-1\"></div>\n <button class=\"btn-icon btn-help btn-switch-to-single-tab-sheet mt-1\" data-tab-id=\"single-tab-bridge-component-help\">${Icons.questionMark}</button>\n </div>\n </div>\n\n <div class=\"tab-content-bridge-logs\">\n </div>\n </div>\n </div>\n\n <div id=\"tab-console-logs\" class=\"outer-tab-content ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-console-logs\">\n </div>\n </div>\n\n <div id=\"tab-event-logs\" class=\"outer-tab-content ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-event-logs\">\n </div>\n </div>\n\n <div id=\"tab-native-stack\" class=\"outer-tab-content ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-native-stack\">\n </div>\n </div>\n\n <div id=\"single-tab-bridge-component-help\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Bridge Components</h3>\n </div>\n <p>This list shows all the bridge components that the ${formattedPlatform()} app supports. Components that are active on this page are marked with a green dot.</p>\n <h3 class=\"mt-4\">Why is my bridge component not on the list?</h3>\n <p class=\"mt-2\">Bridge components are automatically detected when they are registered in the native code. If your component is not on the list, make sure it is registered correctly.</p>\n ${this.registerBridgeComponentExample()}\n <p class\"mt-1\">For more information, check out the documentation:</p>\n <a href=\"${this.registerBridgeComponentHelpURL()}\">${this.registerBridgeComponentHelpURL()}</a>\n </div>\n </div>\n\n <div id=\"single-tab-settings\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Settings</h3>\n </div>\n <div class=\"mb-3\">\n <label for=\"bottom-sheet-height-setting\"> Bottom Sheet Height</label>\n <input type=\"range\" id=\"bottom-sheet-height-setting\" class=\"w-100\" min=\"10\" max=\"100\" value=\"${this.sheetHeight}\" step=\"1\" list=\"bottom-sheet-height-setting-markers\" />\n <datalist id=\"bottom-sheet-height-setting-markers\">\n <option value=\"55\"></option>\n </datalist>\n </div>\n <div class=\"mb-4\">\n <label for=\"font-size-setting\"> Font Size</label>\n <input type=\"range\" id=\"font-size-setting\" class=\"w-100\" min=\"8\" max=\"24\" value=\"${getSettings(\"fontSize\") || 16}\" step=\"1\" list=\"font-size-setting-markers\" />\n <datalist id=\"font-size-setting-markers\">\n <option value=\"16\"></option>\n </datalist>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"console-error-animation-setting\" ${getSettings(\"errorAnimationEnabled\") !== false ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Console Error Animation</span>\n </label>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"auto-open-setting\" ${getSettings(\"autoOpen\") === true ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Auto Open</span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n this.devTools.shadowRoot.appendChild(this.bottomSheet)\n }\n\n renderConsoleLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-console-logs\")\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n container.innerHTML = this.state.consoleLogs.length\n ? this.state.consoleLogs\n .filter((log) => consoleFilterLevels[log.type])\n .filter((log) => {\n if (!consoleSearch) return true\n return log.message.toLowerCase().includes(consoleSearch.toLowerCase())\n })\n .map((log) => this.consoleLogHTML(log.type, log.message, log.time))\n .join(\"\")\n : `<div class=\"tab-empty-content\"><span>No console logs yet</span></div>`\n }\n\n renderBridgeComponents() {\n const bridgeComponentsAmount = this.state.supportedBridgeComponents.length\n this.bottomSheet.querySelector(\".bridge-components-amount\").textContent = bridgeComponentsAmount\n\n const bridgeComponentIdentifiers = this.bridgeComponentIdentifiers\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-components\")\n container.innerHTML = bridgeComponentsAmount\n ? this.state.supportedBridgeComponents.map((component) => `<div class=\"bridge-component ${bridgeComponentIdentifiers.includes(component) ? \"connected\" : \"\"}\">${component}</div>`).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\"No bridge components found\"}</span></div>`\n }\n\n renderBridgeLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-logs\")\n container.innerHTML = this.state.bridgeLogs.length\n ? this.state.bridgeLogs.map((log) => this.bridgeLogHTML(log.direction, log.componentName, log.eventName, log.eventArgs, log.time)).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\n this.state.bridgeIsConnected ? \"No bridge communication yet\" : \"Bridge is not connected <br><small>(Neither window.HotwireNative nor window.Strada is defined)</small>\"\n }</span></div>`\n }\n\n renderEvents() {\n const container = this.bottomSheet.querySelector(\".tab-content-event-logs\")\n container.innerHTML = this.state.eventLogs.length\n ? this.state.eventLogs.map((event) => this.eventMessageHTML(event.eventName, event.time)).join(\"\")\n : `<div class=\"tab-empty-content\"><span>No events captured yet</span></div>`\n }\n\n renderNativeStack() {\n const container = this.bottomSheet.querySelector(\".tab-content-native-stack\")\n container.innerHTML =\n `<div class=\"native-stack-wrapper\">` +\n (this.state.nativeStack.length ? this.state.nativeStack.map((view) => this.nativeViewStackHTML(view)).join(\"\") : `<div class=\"tab-empty-content\"><span>No native stack captured yet</span></div>`) +\n `</div>`\n }\n\n bridgeLogHTML(direction, componentName, eventName, eventArgs, time) {\n return `\n <div class=\"log-entry d-flex gap-3 pt-2 pb-2\">\n <div class=\"log-entry-icon d-flex justify-content-center align-items-center\">\n ${direction === \"send\" ? Icons.arrowDown : Icons.arrowUp}\n </div>\n <div class=\"w-100 overflow-auto\">\n <div class=\"d-flex justify-content-between\">\n <strong class=\"w-80 break-word\">${componentName}#${eventName}</strong>\n <small>${time}</small>\n </div>\n <div class=\"overflow-auto\">\n ${Object.entries(eventArgs)\n .map(([key, value]) => {\n const formattedValue = typeof value === \"object\" && value !== null ? JSON.stringify(value) : value\n return `<div class=\"white-space-collapse\">${key}: ${formattedValue}</div>`\n })\n .join(\"\")}\n </div>\n </div>\n </div>\n `\n }\n\n consoleLogHTML(type, message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message ${type}\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n eventMessageHTML(message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n nativeViewStackHTML(view) {\n const isMainView = [\"UINavigationController\", \"NavigatorHost\"].includes(view.type)\n const isTabBar = view.type === \"UITabBarController\"\n const isHotwireView = [\"VisitableViewController\", \"HotwireWebFragment\", \"BackStackEntry\"].includes(view.type)\n const activeClass = view.url === this.currentUrl ? \"current-view\" : \"\"\n const wrapperClass = `viewstack-card ${activeClass} ${isMainView ? \"main-view\" : isHotwireView ? \"hotwire-view\" : isTabBar ? \"tab-container\" : \"non-identified-view\"}`\n const uniqueViewId = \"viewstack-\" + Math.random().toString(16).slice(2)\n\n const urlPath = view.url\n ? `<div class=\"view-url\">\n ${(() => {\n try {\n return new URL(view.url).pathname\n } catch (error) {\n return view.url\n }\n })()}\n </div>`\n : \"\"\n\n const pathConfigurationPropertiesJson = (() => {\n try {\n const props = view.pathConfigurationProperties\n return JSON.stringify(typeof props === \"string\" ? JSON.parse(props) : props, null, 2)\n } catch {\n return view.pathConfigurationProperties\n }\n })()\n const pathConfigurationProperties = pathConfigurationPropertiesJson ? `<pre class=\"view-path-configuration\">${pathConfigurationPropertiesJson}</pre>` : \"\"\n\n const childrenHTML = view.children?.length\n ? `<div class=\"child-container\">\n ${view.children.map((child) => this.nativeViewStackHTML(child)).join(\"\")}\n </div>`\n : \"\"\n\n return `\n <div>\n <div class=\"${wrapperClass} collapse no-chevron\" data-collapse-target=\"path-configuration-properties-${uniqueViewId}\">\n <div>\n <div class=\"view-title\">\n ${view.title == \"null\" ? \"\" : view.title}\n <div class=\"view-title-details\">${view.type}</div>\n </div>\n ${urlPath}\n </div>\n <div id=\"path-configuration-properties-${uniqueViewId}\" class=\"collapse-target\">\n ${pathConfigurationProperties}\n </div>\n </div>\n ${childrenHTML}\n </div>\n `\n }\n\n switchToSingleTabSheet(singleTabId) {\n // Hide the top part and all tabs\n this.sheetContent.querySelector(\".top-part\").classList.add(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the single mode content\n this.devTools.shadowRoot.getElementById(singleTabId).classList.add(\"active\")\n }\n\n switchToMultiTabSheet() {\n this.sheetContent.querySelector(\".top-part\").classList.remove(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the previous active tab\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => {\n if (tab.id == this.state.activeTab) {\n tab.classList.add(\"active\")\n }\n })\n }\n\n registerBridgeComponentExample() {\n switch (platform()) {\n case \"android\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents(\n BridgeComponentFactory(\"my-component\", ::MyComponent)\n )\n</pre>\n`\n case \"ios\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents([\n MyComponent.self\n ])\n</pre>`\n default:\n return \"\"\n }\n }\n\n registerBridgeComponentHelpURL() {\n switch (platform()) {\n case \"android\":\n return \"https://native.hotwired.dev/android/bridge-components\"\n case \"ios\":\n return \"https://native.hotwired.dev/ios/bridge-components\"\n default:\n return \"https://native.hotwired.dev\"\n }\n }\n\n checkNativeFeatures() {\n if (this.state.supportsNativeStackView) {\n this.bottomSheet.querySelector(\".tablink[data-tab-id='tab-native-stack']\").classList.remove(\"d-none\")\n }\n }\n\n addEventListeners() {\n if (this.bottomSheet.hasEventListeners) return\n\n // Click outside to close\n this.sheetOverlay.addEventListener(\"click\", () => {\n this.hideBottomSheet()\n this.switchToMultiTabSheet()\n })\n\n // Tab Click\n this.bottomSheet.querySelector(\".tablist\").addEventListener(\"click\", (event) => this.handleTabClick(event))\n\n // Action Buttons\n this.bottomSheet.querySelector(\".btn-clear-console-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearConsoleLogs()\n this.renderConsoleLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-bridge-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearBridgeLogs()\n this.renderBridgeLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-events\").addEventListener(\"click\", () => {\n this.devTools.state.clearEventLogs()\n this.renderEvents()\n })\n this.bottomSheet.querySelector(\".btn-reload-stack\").addEventListener(\"click\", () => {\n this.bottomSheet.querySelector(\".native-stack-wrapper\").style.opacity = 0.5\n this.devTools.refetchNativeStack()\n })\n\n // Switch to Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-switch-to-single-tab-sheet\").forEach((button) => {\n button.addEventListener(\"click\", (event) => {\n const singleTabId = event.target.closest(\"[data-tab-id]\").dataset.tabId\n if (!singleTabId) return\n this.switchToSingleTabSheet(singleTabId)\n })\n })\n\n // Close Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-close-single-mode\").forEach((button) => {\n button.addEventListener(\"click\", () => {\n this.switchToMultiTabSheet()\n })\n })\n\n // Dragging\n this.bottomSheet.querySelector(\".top-part\").addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchmove\", this.dragging.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchend\", this.dragStop.bind(this), { passive: true })\n\n // Filters\n this.bottomSheet.querySelector(\".console-filter-levels\").addEventListener(\"click\", ({ target }) => {\n const checkbox = target.closest(\"input[type='checkbox']\")\n if (!checkbox) return\n\n const filterType = checkbox.dataset.consoleFilter\n const isActive = checkbox.checked\n\n saveConsoleFilterLevels(filterType, isActive)\n this.renderConsoleLogs()\n })\n\n this.bottomSheet.querySelector(\".btn-search-console\").addEventListener(\"click\", () => {\n const searchInput = this.bottomSheet.querySelector(\".console-search\")\n searchInput.classList.toggle(\"d-none\")\n searchInput.querySelector(\"input\").focus()\n })\n\n this.bottomSheet.querySelector(\".console-search-input\").addEventListener(\"input\", (event) => {\n this.devTools.state.setConsoleSearchValue(event.target.value.toLowerCase())\n this.renderConsoleLogs()\n })\n\n // Settings\n this.bottomSheet.querySelector(\"#bottom-sheet-height-setting\").addEventListener(\"change\", (event) => {\n const value = event.target.value\n this.sheetHeight = parseInt(value)\n saveSettings(\"bottomSheetHeight\", value)\n this.updateSheetHeight(value)\n })\n\n this.bottomSheet.querySelector(\"#console-error-animation-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"errorAnimationEnabled\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\"#font-size-setting\").addEventListener(\"change\", (event) => {\n let value = event.target.value\n value = Math.max(8, Math.min(24, value))\n saveSettings(\"fontSize\", value)\n this.devTools.setCSSProperty(\"--font-size\", `${value}px`)\n })\n\n this.bottomSheet.querySelector(\"#auto-open-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"autoOpen\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\".pin-bottom-sheet\").addEventListener(\"click\", () => {\n const isPinned = getSettings(\"bottomSheetPinned\") === true\n saveSettings(\"bottomSheetPinned\", !isPinned)\n this.sheetOverlay.classList.toggle(\"active\")\n this.bottomSheet.querySelector(\".settings-dropdown\").classList.remove(\"dropdown-open\")\n })\n\n this.bottomSheet.addEventListener(\"click\", (event) => {\n // Handle collapsible elements\n const collapsible = event.target.closest(\".collapse\")\n if (collapsible && this.bottomSheet.contains(collapsible)) {\n const targetId = collapsible.getAttribute(\"data-collapse-target\")\n const targetElement = this.bottomSheet.querySelector(`#${targetId}`)\n if (targetElement) {\n const isActive = collapsible.classList.toggle(\"active\")\n targetElement.classList.toggle(\"active\", isActive)\n }\n return\n }\n\n // Handle dropdown triggers\n const trigger = event.target.closest(\".dropdown-trigger\")\n if (trigger) {\n event.preventDefault()\n this.toggleDropdown(trigger)\n return\n }\n\n // Close dropdowns when clicking outside\n const openDropdowns = this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\")\n openDropdowns.forEach((dropdown) => {\n const dropdownContainer = dropdown.closest(\".dropdown\")\n if (!dropdownContainer.contains(event.target)) {\n dropdown.classList.remove(\"dropdown-open\")\n }\n })\n })\n\n this.bottomSheet.hasEventListeners = true\n }\n\n toggleDropdown(triggerElement) {\n const dropdownContent = triggerElement.nextElementSibling || triggerElement.closest(\".dropdown\").querySelector(\".dropdown-content\")\n // Close other dropdowns first\n this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\").forEach((el) => {\n if (el !== dropdownContent) {\n el.classList.remove(\"dropdown-open\")\n }\n })\n dropdownContent.classList.toggle(\"dropdown-open\")\n }\n\n handleTabClick = (event) => {\n const clickedTab = event.target.closest(\".tablink\")\n if (!clickedTab) return\n\n const tabId = clickedTab.dataset.tabId\n this.devTools.state.setActiveTab(tabId)\n this.updateTabView(tabId)\n }\n\n updateTabView(tabId) {\n // Hide all Tabs\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Hide all Action Bars\n this.devTools.shadowRoot.querySelectorAll(\".tab-action-bar\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the clicked tab\n this.devTools.shadowRoot.querySelector(`[data-tab-id=\"${tabId}\"]`).classList.add(\"active\")\n this.devTools.shadowRoot.getElementById(tabId).classList.add(\"active\")\n\n // Show the action bar for the clicked tab\n this.devTools.shadowRoot.querySelector(`.tab-action-bar.${tabId}`).classList.add(\"active\")\n }\n\n showBottomSheet() {\n if (this.bottomSheet.classList.contains(\"show\")) return\n this.bottomSheet.classList.add(\"show\")\n this.originalOverflow = document.body.style.overflow\n document.body.style.overflow = \"hidden\"\n this.updateSheetHeight(this.sheetHeight)\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n }\n\n hideBottomSheet() {\n this.bottomSheet.classList.remove(\"show\")\n document.body.style.overflow = this.originalOverflow\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n this.bottomSheet.classList.toggle(\"fullscreen\", height === 100)\n }\n\n dragStart(event) {\n this.isDragging = true\n this.startY = event.pageY || event.touches?.[0].pageY\n this.startHeight = parseInt(this.sheetContent.style.height)\n this.bottomSheet.classList.add(\"dragging\")\n }\n\n dragging(event) {\n if (!this.isDragging) return\n const delta = this.startY - (event.pageY || event.touches?.[0].pageY)\n const newHeight = this.startHeight + (delta / window.innerHeight) * 100\n this.updateSheetHeight(newHeight)\n }\n\n dragStop() {\n this.isDragging = false\n this.bottomSheet.classList.remove(\"dragging\")\n const draggingThreshold = 10 // Defines how much the user needs to drag to trigger the hide/show\n const currentHeight = parseInt(this.sheetContent.style.height)\n\n const minThreshold = Math.max(0, this.sheetHeight - draggingThreshold)\n const maxThreshold = Math.min(100, this.sheetHeight + draggingThreshold)\n\n if (currentHeight < minThreshold) {\n this.hideBottomSheet()\n } else if (currentHeight > maxThreshold) {\n this.updateSheetHeight(100)\n } else {\n this.updateSheetHeight(this.sheetHeight)\n }\n }\n\n // Helper function to log messages, without causing a rerender of the bottom sheet\n // (Messages with a `HotwireDevTools` prefix will not be logged in the bottom sheet)\n log(message) {\n console.log(`HotwireDevTools: ${message}`)\n }\n\n // Get all the `static component = \"...\"` from the bridge components\n get bridgeComponentIdentifiers() {\n return window.Stimulus?.controllers.map((controller) => controller.component).filter((component) => component !== undefined) || []\n }\n\n get currentUrl() {\n return window.location.href\n }\n}\n","import { getSettings, saveSettings } from \"../utils/settings\"\n\nexport default class DevToolsState {\n constructor() {\n this.state = {\n consoleLogs: [],\n bridgeLogs: [],\n eventLogs: [],\n nativeStack: [],\n supportedBridgeComponents: [],\n bridgeIsConnected: false,\n supportsNativeStackView: false,\n consoleSearch: \"\",\n activeTab: getSettings(\"activeTab\") || \"tab-bridge-components\",\n }\n this.listeners = []\n }\n\n subscribe(listener) {\n this.listeners.push(listener)\n }\n\n notify() {\n this.listeners.forEach((listener) => listener(this.state))\n }\n\n addConsoleLog(type, message) {\n const log = { type, message, time: this.currentTime }\n this.state.consoleLogs.push(log)\n this.notify()\n }\n\n addBridgeLog(direction, componentName, eventName, eventArgs) {\n const log = { direction, componentName, eventName, eventArgs, time: this.currentTime }\n this.state.bridgeLogs.push(log)\n this.notify()\n }\n\n addEventLog(eventName) {\n const event = { eventName, time: this.currentTime }\n this.state.eventLogs.push(event)\n this.notify()\n }\n\n setNativeStack(stack) {\n this.state.nativeStack = stack\n this.notify()\n }\n\n setSupportsNativeStack(supports) {\n this.state.supportsNativeStackView = supports\n this.notify()\n }\n\n setBridgeIsConnected(isConnected) {\n this.state.bridgeIsConnected = isConnected\n this.notify()\n }\n\n setSupportedBridgeComponents(components) {\n this.state.supportedBridgeComponents = components\n this.notify()\n }\n\n clearConsoleLogs() {\n this.state.consoleLogs = []\n this.notify()\n }\n\n clearBridgeLogs() {\n this.state.bridgeLogs = []\n this.notify()\n }\n\n clearEventLogs() {\n this.state.eventLogs = []\n this.notify()\n }\n\n setActiveTab(tab) {\n this.state.activeTab = tab\n saveSettings(\"activeTab\", tab)\n }\n\n setConsoleSearchValue(value) {\n this.state.consoleSearch = value\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","/*\nSimilar to the `BridgeComponent` class from the Hotwire Native Bridge,\nbut without requiring a bridge component HTML element or Stimulus controller.\n\nOriginally from: 37signals LLC\nhttps://github.com/hotwired/hotwire-native-bridge\n*/\nexport default class NativeBridge {\n bridgeIsConnected() {\n return !!(window.HotwireNative?.web || window.Strada?.web)\n }\n\n // Send a message to the native side\n send(event, data = {}, callback = null) {\n if (!this.bridgeIsConnected()) {\n return Promise.reject(\"Bridge is not connected\")\n }\n\n const messageData = {\n ...data,\n metadata: {\n url: window.location.href,\n },\n }\n\n return this.bridge.send({\n component: \"dev-tools\",\n event,\n data: messageData,\n callback,\n })\n }\n\n isComponentSupported(component) {\n if (!this.bridgeIsConnected()) {\n return false\n }\n return this.bridge.supportsComponent(component)\n }\n\n getSupportedComponents() {\n return document.documentElement.dataset.bridgeComponents?.split(\" \") || []\n }\n\n get bridge() {\n return window.HotwireNative?.web || window.Strada?.web\n }\n}\n","import { cssContent } from \"./assets/DevToolsStyling.css\"\nimport DiagnosticsChecker from \"./lib/DiagnosticsChecker\"\nimport FloatingBubble from \"./components/FloatingBubble\"\nimport BottomSheet from \"./components/BottomSheet\"\nimport DevToolsState from \"./lib/DevToolsState\"\nimport NativeBridge from \"./lib/NativeBridge\"\nimport { resetSettings } from \"./utils/settings\"\nimport { debounce } from \"./utils/utils\"\nimport { getSettings } from \"./utils/settings\"\n\nexport default class DevTools {\n constructor(options = {}) {\n this.options = {\n enabled: true,\n reset: false,\n ...options,\n }\n if (!this.options.enabled) return\n if (this.options.reset) resetSettings()\n\n this.state = new DevToolsState()\n this.bubble = new FloatingBubble(this)\n this.bottomSheet = new BottomSheet(this)\n this.nativeBridge = new NativeBridge(this)\n this.diagnosticsChecker = new DiagnosticsChecker()\n this.state.subscribe(this.update.bind(this))\n this.listenForTurboEvents()\n }\n\n // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page\n setup() {\n if (!this.options.enabled) return\n this.setupShadowRoot()\n this.bubble.render()\n this.bottomSheet.render()\n\n // Add Console Proxy\n if (!this.originalConsole) {\n this.originalConsole = window.console\n this.addConsoleProxy()\n }\n\n // Add Bridge Proxy and call the native DevTools bridge component\n if (this.originalBridge) {\n // Bridge Proxy is already added\n this.callNativeBridgeComponent()\n } else if (window.HotwireNative || window.Strada) {\n // Bridge exists -> Add Bridge Proxy\n this.nativeBridgeGotConnected()\n } else {\n // Bridge does not exist yet -> Listen for the event\n document.addEventListener(\"web-bridge:ready\", () => {\n this.nativeBridgeGotConnected()\n })\n }\n\n // Add event listeners to the window\n this.addEventListeners()\n\n // Check for warnings\n this.diagnosticsChecker.checkForWarnings()\n\n this.bubble.onClick(() => {\n this.bottomSheet.showBottomSheet()\n this.nativeBridge.send(\"vibrate\")\n })\n\n if (getSettings(\"autoOpen\") === true) {\n this.bottomSheet.showBottomSheet()\n }\n }\n\n nativeBridgeGotConnected() {\n if (this.originalBridge) return\n\n this.originalBridge = window.HotwireNative?.web || window.Strada?.web\n this.addBridgeProxy()\n this.state.setBridgeIsConnected(true)\n this.callNativeBridgeComponent()\n this.updateSupportedBridgeComponents()\n this.startBridgeComponentObserver()\n }\n\n callNativeBridgeComponent() {\n if (this.nativeBridge.bridgeIsConnected()) {\n this.nativeBridge.send(\"connect\", {}, (message) => {\n // If this callback gets executed, it means the native counterpart\n // of the dev tools are installed and running.\n this.fetchNativeStack()\n })\n }\n }\n\n update = debounce((newState) => {\n this.bottomSheet.update(newState)\n }, 200)\n\n setupShadowRoot() {\n if (this.shadowContainer.shadowRoot) {\n this.shadowRoot = this.shadowContainer.shadowRoot\n this.injectCSSToShadowRoot()\n return\n }\n this.shadowRoot = this.shadowContainer.attachShadow({ mode: \"open\" })\n this.setCSSProperty(\"--font-size\", `${getSettings(\"fontSize\") || 16}px`)\n this.injectCSSToShadowRoot()\n }\n\n addBridgeProxy() {\n const createProxyHandler = () => ({\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n\n // We are only interested in the send and receive methods\n if (typeof originalValue === \"function\" && (prop === \"send\" || prop === \"receive\")) {\n return (...args) => {\n this.interceptedBridgeMessage(prop, args)\n return originalValue.apply(target, args)\n }\n }\n\n // Forward all the other calls to the original bridge\n return typeof originalValue === \"function\" ? (...args) => originalValue.apply(target, args) : originalValue\n },\n })\n\n if (window.Strada) {\n window.Strada.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n if (window.HotwireNative) {\n window.HotwireNative.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n }\n\n addConsoleProxy() {\n window.console = new Proxy(this.originalConsole, {\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n return (...args) => {\n this.interceptedConsoleMessage(prop, args)\n return originalValue?.apply(target, args)\n }\n },\n })\n }\n\n interceptedBridgeMessage(direction, args) {\n args.forEach((arg) => {\n const componentName = arg.component\n const eventName = arg.event\n const { metadata, ...eventArgs } = arg.data // Remove metadata from the args\n\n if (componentName !== \"dev-tools\") {\n // We don't want to log our own messages\n this.state.addBridgeLog(direction, componentName, eventName, eventArgs)\n }\n })\n }\n\n interceptedConsoleMessage(type, args) {\n const message = args\n .map((arg) => {\n if (arg instanceof Element) {\n const attrs = Array.from(arg.attributes)\n .map((attr) => `${attr.name}=\"${attr.value}\"`)\n .join(\" \")\n\n return `&lt;${arg.tagName.toLowerCase()}${attrs ? \" \" + attrs : \"\"}&gt;&lt;/${arg.tagName.toLowerCase()}&gt;`\n }\n if (typeof arg === \"object\") {\n try {\n return `<pre>${JSON.stringify(arg, null, 2)}</pre>`\n } catch {\n return `<pre>${arg}</pre>`\n }\n }\n // Escape HTML in string values\n const stringValue = arg.toString()\n return stringValue.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\")\n })\n .join(\" \")\n\n // Ignore messages from the dev tools itself\n // Otherwise we could end up in an infinite loop\n if (message.includes(\"hotwire-native-dev-tools\") || message.includes(\"HotwireDevTools\")) return\n\n this.state.addConsoleLog(type, message)\n if (type === \"error\") {\n this.bubble.animateErrorBorder()\n }\n }\n\n // Fetch the current stack from the native side\n // The debounce on this function is intentionally high,\n // to ensure the native side has enough time to set the ViewController / Fragment titles.\n // With a lower debounce, the view controller / fragment title would often be empty.\n fetchNativeStack = debounce(() => {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setSupportsNativeStack(true)\n this.state.setNativeStack(message.data.stack)\n })\n }, 1000)\n\n refetchNativeStack() {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setNativeStack(message.data.stack)\n })\n }\n\n injectCSSToShadowRoot = async () => {\n if (this.shadowRoot.querySelector(\"style\")) return\n\n const style = document.createElement(\"style\")\n style.textContent = cssContent()\n this.shadowRoot.appendChild(style)\n }\n\n addEventListeners() {\n if (this.hasEventListeners) return\n\n // Capture uncaught errors and unhandled promise rejections\n window.addEventListener(\"error\", (event) => {\n const { message, filename, lineno, colno } = event\n const formattedMessage = `${message} at ${filename}:${lineno}:${colno}`\n this.interceptedConsoleMessage(\"error\", [formattedMessage])\n })\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.interceptedConsoleMessage(\"error\", [event.reason?.message])\n })\n\n // Observe screen size or orientation changes to reposition the bubble\n window.addEventListener(\n \"resize\",\n () => {\n this.bubble.render()\n },\n { passive: true }\n )\n\n this.hasEventListeners = true\n }\n\n listenForTurboEvents() {\n if (this.eventsRegistered) return\n\n const turboEvents = [\n \"turbo:click\",\n \"turbo:before-visit\",\n \"turbo:visit\",\n \"turbo:before-cache\",\n \"turbo:before-render\",\n \"turbo:render\",\n \"turbo:load\",\n \"turbo:morph\",\n \"turbo:before-morph-element\",\n \"turbo:before-morph-attribute\",\n \"turbo:morph-element\",\n \"turbo:submit-start\",\n \"turbo:submit-end\",\n \"turbo:before-frame-render\",\n \"turbo:frame-render\",\n \"turbo:frame-load\",\n \"turbo:frame-missing\",\n \"turbo:before-stream-render\",\n \"turbo:before-fetch-request\",\n \"turbo:before-fetch-response\",\n \"turbo:before-prefetch\",\n \"turbo:fetch-request-error\",\n ]\n\n turboEvents.forEach((eventName) => {\n window.addEventListener(\n eventName,\n (event) => {\n this.state.addEventLog(eventName)\n },\n { passive: true }\n )\n })\n\n this.eventsRegistered = true\n }\n\n startBridgeComponentObserver() {\n if (this.bridgeComponentObserver) return\n\n this.bridgeComponentObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\" && mutation.attributeName === \"data-bridge-components\") {\n this.updateSupportedBridgeComponents()\n }\n }\n })\n\n this.bridgeComponentObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-bridge-components\"],\n })\n }\n\n updateSupportedBridgeComponents() {\n this.state.setSupportedBridgeComponents(this.nativeBridge.getSupportedComponents().sort())\n }\n\n getCSSProperty(propertyName) {\n const rootStyles = getComputedStyle(this.shadowContainer)\n return rootStyles.getPropertyValue(propertyName).trim()\n }\n\n setCSSProperty(propertyName, value) {\n this.shadowContainer.style.setProperty(propertyName, value)\n }\n\n get shadowContainer() {\n const existingShadowContainer = document.getElementById(\"hotwire-native-dev-tools-shadow-container\")\n if (existingShadowContainer) {\n return existingShadowContainer\n }\n const shadowContainer = document.createElement(\"div\")\n shadowContainer.id = \"hotwire-native-dev-tools-shadow-container\"\n shadowContainer.setAttribute(\"data-native-prevent-pull-to-refresh\", \"\")\n document.body.appendChild(shadowContainer)\n return shadowContainer\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","import DevTools from \"./DevTools\"\n\nconst setupDevTools = (options = {}) => {\n const devTools = new DevTools(options)\n if (!devTools.options.enabled) return\n\n devTools.setup()\n\n document.addEventListener(\n \"turbo:load\",\n () => {\n devTools.setup()\n },\n { passive: true }\n )\n}\n\nexport { setupDevTools }\n"],"names":["cssContent","_checkForTurboDrive","_checkForDuplicatedTurboFrames","_checkTurboPermanentElements","DiagnosticsChecker","__publicField","message","once","extraArgs","__privateGet","__privateAdd","_a","turboFramesIds","id","index","turboPermanentElements","element","turboFrame","getSettings","key","saveSettings","value","settings","resetSettings","getConsoleFilterLevels","saveConsoleFilterLevels","consoleFilterLevels","debounce","fn","delay","timeoutId","args","callback","this","userAgent","isIosApp","isAndroidApp","platform","formattedPlatform","hotwireIcon","arrowUp","arrowDown","arrowLeft","trash","rotate","questionMark","search","filter","threeDotsVertical","FloatingBubble","devTools","errorBorder","circleElement","animationContainer","defaultPos","startX","startY","existingBubble","event","touch","deltaX","deltaY","xPos","yPos","BottomSheet","clickedTab","tabId","newState","existingBottomSheet","activeTab","consoleSearch","Icons.threeDotsVertical","Icons.trash","Icons.search","Icons.filter","Icons.rotate","Icons.questionMark","Icons.arrowLeft","container","log","bridgeComponentsAmount","bridgeComponentIdentifiers","component","view","direction","componentName","eventName","eventArgs","time","Icons.arrowDown","Icons.arrowUp","formattedValue","type","isMainView","isTabBar","isHotwireView","wrapperClass","uniqueViewId","urlPath","pathConfigurationPropertiesJson","props","pathConfigurationProperties","childrenHTML","child","singleTabId","tab","button","target","checkbox","filterType","isActive","searchInput","isPinned","collapsible","targetId","targetElement","trigger","dropdown","triggerElement","dropdownContent","el","height","delta","newHeight","draggingThreshold","currentHeight","minThreshold","maxThreshold","controller","DevToolsState","listener","stack","supports","isConnected","components","NativeBridge","_b","data","messageData","DevTools","options","style","createProxyHandler","prop","receiver","originalValue","arg","metadata","attrs","attr","filename","lineno","colno","formattedMessage","mutationsList","mutation","propertyName","existingShadowContainer","shadowContainer","setupDevTools"],"mappings":";;;;;;;AAGO,MAAMA,IAAa,MACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hotwire-native-dev-tools",
3
- "version": "0.1.0-rc.5",
3
+ "version": "0.1.0",
4
4
  "description": "Dev Tools for Hotwire Native",
5
5
  "main": "./dist/hotwire-native-dev-tools.es.js",
6
6
  "module": "./dist/hotwire-native-dev-tools.es.js",