aitu-app 0.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/.DS_Store +0 -0
  2. package/README.md +47 -0
  3. package/_headers +84 -0
  4. package/_redirects +2 -0
  5. package/assets/ChatMessagesArea-CkUX81uB.js +251 -0
  6. package/assets/ChatMessagesArea-Di0Z80Zh.css +1 -0
  7. package/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  8. package/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  9. package/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  10. package/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  11. package/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  12. package/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  13. package/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  14. package/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  15. package/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  16. package/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  17. package/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  18. package/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  19. package/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  20. package/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  21. package/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  22. package/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  23. package/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  24. package/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  25. package/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  26. package/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  27. package/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  28. package/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  29. package/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  30. package/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  31. package/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  32. package/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  33. package/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  34. package/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  35. package/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  36. package/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  37. package/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  38. package/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  39. package/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  40. package/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  41. package/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  42. package/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  43. package/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  44. package/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  45. package/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  46. package/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  47. package/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  48. package/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  49. package/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  50. package/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  51. package/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  52. package/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  53. package/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  54. package/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  55. package/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  56. package/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  57. package/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  58. package/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  59. package/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  60. package/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  61. package/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  62. package/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  63. package/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  64. package/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  65. package/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  66. package/assets/Tableau10-B-NsZVaP.js +1 -0
  67. package/assets/Tableau10-Dnlau_Wv.js +1 -0
  68. package/assets/ToolboxDrawer-By1XMh8B.js +87 -0
  69. package/assets/ToolboxDrawer-fPqvDLQE.css +1 -0
  70. package/assets/__vite-browser-external-BIHI7g3E.js +1 -0
  71. package/assets/ai-analyze-Db-iXol6.js +1 -0
  72. package/assets/arc-BZXVqUcI.js +1 -0
  73. package/assets/arc-ajYHRRnk.js +1 -0
  74. package/assets/array-B5oSNiGi.js +1 -0
  75. package/assets/array-BKyUJesY.js +1 -0
  76. package/assets/batch-image-generation-Baqb01Lm.js +6 -0
  77. package/assets/batch-image-generation-CbLMWmjk.css +1 -0
  78. package/assets/blockDiagram-38ab4fdb-BT3H_WVv.js +118 -0
  79. package/assets/blockDiagram-38ab4fdb-u0xYP3Lt.js +118 -0
  80. package/assets/c4Diagram-3d4e48cf-CBvM6zjM.js +10 -0
  81. package/assets/c4Diagram-3d4e48cf-WOIEVidH.js +10 -0
  82. package/assets/channel-BP25wTsw.js +1 -0
  83. package/assets/channel-HzrLNFUg.js +1 -0
  84. package/assets/classDiagram-70f12bd4-BMutcvFi.js +2 -0
  85. package/assets/classDiagram-70f12bd4-Cl9U1r5F.js +2 -0
  86. package/assets/classDiagram-v2-f2320105-C0agtbR4.js +2 -0
  87. package/assets/classDiagram-v2-f2320105-tCBzATK6.js +2 -0
  88. package/assets/clone-B69pF7Y_.js +1 -0
  89. package/assets/clone-oX7o-l4R.js +1 -0
  90. package/assets/createText-2e5e7dd3-CZ9_fscE.js +5 -0
  91. package/assets/createText-2e5e7dd3-idrqgJjU.js +7 -0
  92. package/assets/edges-e0da2a9e-C-RyePMV.js +4 -0
  93. package/assets/edges-e0da2a9e-DJXAjJSL.js +4 -0
  94. package/assets/erDiagram-9861fffd-DWJR_3zL.js +51 -0
  95. package/assets/erDiagram-9861fffd-x2Kcy95-.js +51 -0
  96. package/assets/flowDb-956e92f1-BgKjOIdz.js +10 -0
  97. package/assets/flowDb-956e92f1-CF6y18Tn.js +10 -0
  98. package/assets/flowDiagram-66a62f08-BPPw0wPU.js +4 -0
  99. package/assets/flowDiagram-66a62f08-CSAllSFf.js +4 -0
  100. package/assets/flowDiagram-v2-96b9c2cf-B-UGyXRi.js +1 -0
  101. package/assets/flowDiagram-v2-96b9c2cf-Cm596kxZ.js +1 -0
  102. package/assets/flowchart-elk-definition-4a651766-9XSRJbsr.js +139 -0
  103. package/assets/flowchart-elk-definition-4a651766-DWFN9DN3.js +139 -0
  104. package/assets/ganttDiagram-c361ad54-D9tbz9tQ.js +257 -0
  105. package/assets/ganttDiagram-c361ad54-ot5pUYpT.js +257 -0
  106. package/assets/gitGraphDiagram-72cf32ee-BFV3Mt8C.js +70 -0
  107. package/assets/gitGraphDiagram-72cf32ee-C6qFzgGh.js +70 -0
  108. package/assets/graph-BxwlF7JS.js +1 -0
  109. package/assets/graph-D-2Ldvxg.js +1 -0
  110. package/assets/grid-image-cM9AmYC8.js +1 -0
  111. package/assets/has-CgdIPiQG.js +1 -0
  112. package/assets/hasIn-4iY02rGN.js +1 -0
  113. package/assets/index-3862675e-CVZnpwDN.js +1 -0
  114. package/assets/index-3862675e-DqdI9cab.js +1 -0
  115. package/assets/index-B2dvADz8.css +1 -0
  116. package/assets/index-BicRPzXC.js +1 -0
  117. package/assets/index-Bs7-jmv6.css +1 -0
  118. package/assets/index-BwSGXyRr.js +99 -0
  119. package/assets/index-C1XdOOAn.css +1 -0
  120. package/assets/index-C4AKKbpQ.css +1 -0
  121. package/assets/index-CkpXFt8n.js +1 -0
  122. package/assets/index-CrxF9gFe.js +42 -0
  123. package/assets/index-DBWqXBIQ.js +93 -0
  124. package/assets/index-DI_5V2-m.js +3 -0
  125. package/assets/index-DWUAFoZG.js +2064 -0
  126. package/assets/index-Dn0YtZ2R.js +3 -0
  127. package/assets/index-e05Rs4M6.js +12 -0
  128. package/assets/index.dom-C3-224fz.js +1 -0
  129. package/assets/infoDiagram-f8f76790-CnrpwoOt.js +7 -0
  130. package/assets/infoDiagram-f8f76790-FKC1Sy9Y.js +7 -0
  131. package/assets/init-A0kIFD9x.js +1 -0
  132. package/assets/init-Gi6I4Gst.js +1 -0
  133. package/assets/inspiration-board-B_-BBBHt.js +1 -0
  134. package/assets/isEmpty-Dj2GV0v-.js +1 -0
  135. package/assets/journeyDiagram-49397b02-B7fP21sU.js +139 -0
  136. package/assets/journeyDiagram-49397b02-Dp3X9XWq.js +139 -0
  137. package/assets/katex-BbEIqZs1.js +261 -0
  138. package/assets/katex-Cu_Erd72.js +261 -0
  139. package/assets/layout-BD3yCK_X.js +1 -0
  140. package/assets/layout-DHHYqX7p.js +1 -0
  141. package/assets/line-B3bNrkzn.js +1 -0
  142. package/assets/line-B86HLuqu.js +1 -0
  143. package/assets/linear-DU2Ciymb.js +1 -0
  144. package/assets/linear-wCAlMhOS.js +1 -0
  145. package/assets/mermaid.core-DfVvnpgz.js +91 -0
  146. package/assets/mindmap-definition-fc14e90a-D1sxE3xG.js +425 -0
  147. package/assets/mindmap-definition-fc14e90a-YuSOJC7P.js +425 -0
  148. package/assets/ordinal-BRr1uYdk.js +1 -0
  149. package/assets/ordinal-Cboi1Yqb.js +1 -0
  150. package/assets/path-CY0bYimO.js +1 -0
  151. package/assets/path-CbwjOpE9.js +1 -0
  152. package/assets/photo-wall-splitter-BVU2e0aS.js +1 -0
  153. package/assets/pick-Cvlwra4g.js +1 -0
  154. package/assets/pieDiagram-8a3498a8-B6mJUqro.js +35 -0
  155. package/assets/pieDiagram-8a3498a8-B91bWgo_.js +35 -0
  156. package/assets/quadrantDiagram-120e2f19-BxS8fQEz.js +7 -0
  157. package/assets/quadrantDiagram-120e2f19-DwudONqx.js +7 -0
  158. package/assets/requirementDiagram-deff3bca-DygaMIoy.js +52 -0
  159. package/assets/requirementDiagram-deff3bca-v9xlgfS8.js +52 -0
  160. package/assets/sankeyDiagram-04a897e0-BV23dp4l.js +8 -0
  161. package/assets/sankeyDiagram-04a897e0-BXCiXiyw.js +8 -0
  162. package/assets/sequenceDiagram-704730f1-CObRpNi4.js +122 -0
  163. package/assets/sequenceDiagram-704730f1-Ck69A6wI.js +122 -0
  164. package/assets/settings-dialog-BlCO49C4.js +1 -0
  165. package/assets/settings-dialog-QUxXj54T.css +1 -0
  166. package/assets/stateDiagram-587899a1-J_G6I0oo.js +1 -0
  167. package/assets/stateDiagram-587899a1-z-tKclr3.js +1 -0
  168. package/assets/stateDiagram-v2-d93cdb3a-DsThtOzP.js +1 -0
  169. package/assets/stateDiagram-v2-d93cdb3a-XIvq5t8a.js +1 -0
  170. package/assets/styles-6aaf32cf-1fjuNMUk.js +207 -0
  171. package/assets/styles-6aaf32cf-DT2rVNfQ.js +207 -0
  172. package/assets/styles-9a916d00-fLeUSina.js +160 -0
  173. package/assets/styles-9a916d00-q64Umkis.js +160 -0
  174. package/assets/styles-c10674c1-BWlxVc3Q.js +116 -0
  175. package/assets/styles-c10674c1-CtYpjMYU.js +116 -0
  176. package/assets/svgDrawCommon-08f97a94-C_DhKfny.js +1 -0
  177. package/assets/svgDrawCommon-08f97a94-DSBqmUv2.js +1 -0
  178. package/assets/timeline-definition-85554ec2-AKpzwLPN.js +61 -0
  179. package/assets/timeline-definition-85554ec2-dTkYwoLF.js +61 -0
  180. package/assets/ttd-dialog-CxiaIUuJ.js +47 -0
  181. package/assets/ttd-dialog-DCapefb6.css +1 -0
  182. package/assets/upload-4sxUU7q_.js +1 -0
  183. package/assets/video-recovery-service-BckHbSyK.js +1 -0
  184. package/assets/web-vitals-DcvjKPr-.js +1 -0
  185. package/assets/winbox.bundle.min-CoRPjCs5.js +1 -0
  186. package/assets/xlsx-CkFp8p6R.js +105 -0
  187. package/assets/xychartDiagram-e933f94c-DCmvL0ag.js +7 -0
  188. package/assets/xychartDiagram-e933f94c-aqOiXp_u.js +7 -0
  189. package/batch-image.html +1616 -0
  190. package/favicon.ico +0 -0
  191. package/icons/README.md +55 -0
  192. package/icons/aitu10.png +0 -0
  193. package/icons/android-chrome-192x192.png +0 -0
  194. package/icons/android-chrome-512x512.png +0 -0
  195. package/icons/apple-touch-icon.png +0 -0
  196. package/icons/favicon-16x16.png +0 -0
  197. package/icons/favicon-16x16.svg +539 -0
  198. package/icons/favicon-32x32.png +0 -0
  199. package/icons/favicon-32x32.svg +539 -0
  200. package/icons/favicon-new.svg +539 -0
  201. package/icons/favicon-new.svg.png +0 -0
  202. package/icons/icon-192x192.svg +539 -0
  203. package/icons/icon-512x512.svg +539 -0
  204. package/icons/icon-96x96.png +0 -0
  205. package/icons/icon-96x96.svg +539 -0
  206. package/iframe-test.html +340 -0
  207. package/index.html +105 -0
  208. package/init.json +6 -0
  209. package/logo/cardid.jpg +0 -0
  210. package/logo/group-qr.png +0 -0
  211. package/logo/logo_drawnix_h.svg +539 -0
  212. package/logo/logo_drawnix_h_dark.svg +539 -0
  213. package/logo/logo_drawnix_new.svg +539 -0
  214. package/manifest.json +52 -0
  215. package/package.json +31 -0
  216. package/product_showcase/aitu-01.png +0 -0
  217. package/product_showcase/aitu-02.png +0 -0
  218. package/product_showcase/aitu-03.png +0 -0
  219. package/product_showcase/aitu-04.png +0 -0
  220. package/product_showcase/aitu-05.png +0 -0
  221. package/product_showcase/aitu-06.png +0 -0
  222. package/product_showcase/case-1.png +0 -0
  223. package/product_showcase/case-2.png +0 -0
  224. package/robots.txt +13 -0
  225. package/sitemap.xml +29 -0
  226. package/sw-debug/app.js +3069 -0
  227. package/sw-debug/console-entry.js +80 -0
  228. package/sw-debug/log-entry.js +452 -0
  229. package/sw-debug/log-panel.js +309 -0
  230. package/sw-debug/postmessage-entry.js +117 -0
  231. package/sw-debug/status-panel.js +125 -0
  232. package/sw-debug/styles.css +2103 -0
  233. package/sw-debug/sw-communication.js +208 -0
  234. package/sw-debug/utils.js +112 -0
  235. package/sw-debug.html +685 -0
  236. package/sw.js +58 -0
  237. package/version.json +10 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * SW Debug Panel - Service Worker Communication Module
3
+ */
4
+
5
+ /** @type {Function|null} PostMessage log callback */
6
+ let postMessageLogCallback = null;
7
+
8
+ /** @type {number} Counter for generating unique log IDs */
9
+ let logIdCounter = 0;
10
+
11
+ /**
12
+ * Set the callback for PostMessage logging
13
+ * @param {Function} callback - Called with (logEntry) when a message is sent/received
14
+ */
15
+ export function setPostMessageLogCallback(callback) {
16
+ postMessageLogCallback = callback;
17
+ }
18
+
19
+ /**
20
+ * Message types from the debug panel itself (should be filtered out)
21
+ * We only want to show main application's communications
22
+ */
23
+ const DEBUG_PANEL_MESSAGE_PREFIXES = [
24
+ 'SW_DEBUG_',
25
+ 'SW_POSTMESSAGE_',
26
+ ];
27
+
28
+ /**
29
+ * Check if a message type is from the debug panel
30
+ * @param {string} messageType
31
+ * @returns {boolean}
32
+ */
33
+ function isDebugPanelMessage(messageType) {
34
+ return DEBUG_PANEL_MESSAGE_PREFIXES.some(prefix => messageType.startsWith(prefix));
35
+ }
36
+
37
+ /**
38
+ * Log a PostMessage event
39
+ * @param {'send'|'receive'} direction
40
+ * @param {string} messageType
41
+ * @param {object} data
42
+ * @param {object} [response]
43
+ * @param {string} [error]
44
+ */
45
+ function logPostMessage(direction, messageType, data, response, error) {
46
+ // Filter out debug panel's own messages - only log main application communications
47
+ if (isDebugPanelMessage(messageType)) {
48
+ return;
49
+ }
50
+
51
+ if (postMessageLogCallback) {
52
+ const entry = {
53
+ id: `pm-${Date.now()}-${++logIdCounter}`,
54
+ timestamp: Date.now(),
55
+ direction,
56
+ messageType,
57
+ data,
58
+ response,
59
+ error,
60
+ };
61
+ postMessageLogCallback(entry);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Send message to Service Worker
67
+ * Uses controller if available, otherwise uses registration.active
68
+ * @param {string} type
69
+ * @param {object} data
70
+ */
71
+ export function sendToSW(type, data = {}) {
72
+ const sw = getActiveSW();
73
+ if (sw) {
74
+ const message = { type, ...data };
75
+ sw.postMessage(message);
76
+ logPostMessage('send', type, data);
77
+ } else {
78
+ console.warn('[SW Debug] No active SW to send message to');
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Enable debug mode
84
+ */
85
+ export function enableDebug() {
86
+ sendToSW('SW_DEBUG_ENABLE');
87
+ }
88
+
89
+ /**
90
+ * Disable debug mode
91
+ */
92
+ export function disableDebug() {
93
+ sendToSW('SW_DEBUG_DISABLE');
94
+ }
95
+
96
+ /**
97
+ * Request status update
98
+ */
99
+ export function refreshStatus() {
100
+ sendToSW('SW_DEBUG_GET_STATUS');
101
+ }
102
+
103
+ /**
104
+ * Clear fetch logs
105
+ */
106
+ export function clearFetchLogs() {
107
+ sendToSW('SW_DEBUG_CLEAR_LOGS');
108
+ }
109
+
110
+ /**
111
+ * Clear console logs
112
+ */
113
+ export function clearConsoleLogs() {
114
+ sendToSW('SW_DEBUG_CLEAR_CONSOLE_LOGS');
115
+ }
116
+
117
+ /**
118
+ * Request all console logs from IndexedDB
119
+ */
120
+ export function loadConsoleLogs() {
121
+ sendToSW('SW_DEBUG_GET_CONSOLE_LOGS', { limit: 1000 });
122
+ }
123
+
124
+ /**
125
+ * Request logs export
126
+ */
127
+ export function requestExport() {
128
+ sendToSW('SW_DEBUG_EXPORT_LOGS');
129
+ }
130
+
131
+ /**
132
+ * Load PostMessage logs from SW
133
+ */
134
+ export function loadPostMessageLogs() {
135
+ sendToSW('SW_DEBUG_GET_POSTMESSAGE_LOGS', { limit: 500 });
136
+ }
137
+
138
+ /**
139
+ * Clear PostMessage logs in SW
140
+ */
141
+ export function clearPostMessageLogs() {
142
+ sendToSW('SW_DEBUG_CLEAR_POSTMESSAGE_LOGS');
143
+ }
144
+
145
+ /** @type {ServiceWorkerRegistration|null} */
146
+ let cachedRegistration = null;
147
+
148
+ /**
149
+ * Check if SW is available and ready
150
+ * Returns true if SW is active (even without controller - we can use registration.active)
151
+ * @returns {Promise<boolean>}
152
+ */
153
+ export async function checkSwReady() {
154
+ if (!('serviceWorker' in navigator)) {
155
+ return false;
156
+ }
157
+
158
+ const registration = await navigator.serviceWorker.ready;
159
+ cachedRegistration = registration;
160
+
161
+ // If SW is active, we can communicate with it
162
+ // (controller might be null on hard refresh, but registration.active works)
163
+ return !!registration.active;
164
+ }
165
+
166
+ /**
167
+ * Get the active SW to send messages to
168
+ * Prefers controller, falls back to registration.active
169
+ * @returns {ServiceWorker|null}
170
+ */
171
+ export function getActiveSW() {
172
+ if (navigator.serviceWorker.controller) {
173
+ return navigator.serviceWorker.controller;
174
+ }
175
+ if (cachedRegistration?.active) {
176
+ return cachedRegistration.active;
177
+ }
178
+ return null;
179
+ }
180
+
181
+ /**
182
+ * Register message handler for SW messages
183
+ * @param {object} handlers - Message type to handler function map
184
+ */
185
+ export function registerMessageHandlers(handlers) {
186
+ navigator.serviceWorker.addEventListener('message', (event) => {
187
+ const { type, ...data } = event.data;
188
+
189
+ // Log the incoming message (filtering handled inside logPostMessage)
190
+ logPostMessage('receive', type, data);
191
+
192
+ if (handlers[type]) {
193
+ handlers[type](data);
194
+ }
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Register controller change handler
200
+ * @param {Function} callback
201
+ */
202
+ export function onControllerChange(callback) {
203
+ navigator.serviceWorker.addEventListener('controllerchange', () => {
204
+ if (navigator.serviceWorker.controller) {
205
+ callback();
206
+ }
207
+ });
208
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * SW Debug Panel - Utility Functions
3
+ */
4
+
5
+ /**
6
+ * Format file size to human readable string
7
+ * @param {number} bytes
8
+ * @returns {string}
9
+ */
10
+ export function formatSize(bytes) {
11
+ if (!bytes || bytes === 0) return '0 B';
12
+ const k = 1024;
13
+ const sizes = ['B', 'KB', 'MB', 'GB'];
14
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
15
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
16
+ }
17
+
18
+ /**
19
+ * Format timestamp to time string
20
+ * @param {number} timestamp
21
+ * @returns {string}
22
+ */
23
+ export function formatTime(timestamp) {
24
+ const date = new Date(timestamp);
25
+ return date.toLocaleTimeString('zh-CN', { hour12: false });
26
+ }
27
+
28
+ /**
29
+ * Format duration in milliseconds
30
+ * @param {number} ms
31
+ * @returns {string}
32
+ */
33
+ export function formatDuration(ms) {
34
+ if (!ms) return '-';
35
+ if (ms < 1000) return ms + 'ms';
36
+ return (ms / 1000).toFixed(2) + 's';
37
+ }
38
+
39
+ /**
40
+ * Get CSS class for HTTP status code
41
+ * @param {number} status
42
+ * @returns {string}
43
+ */
44
+ export function getStatusClass(status) {
45
+ if (!status) return '';
46
+ if (status >= 200 && status < 300) return 'success';
47
+ if (status >= 300 && status < 400) return 'redirect';
48
+ return 'error';
49
+ }
50
+
51
+ /**
52
+ * Escape HTML special characters
53
+ * @param {string} text
54
+ * @returns {string}
55
+ */
56
+ export function escapeHtml(text) {
57
+ const div = document.createElement('div');
58
+ div.textContent = text;
59
+ return div.innerHTML;
60
+ }
61
+
62
+ /**
63
+ * Format JSON or return text as-is
64
+ * @param {string} text
65
+ * @returns {string}
66
+ */
67
+ export function formatJsonOrText(text) {
68
+ if (!text) return '';
69
+ try {
70
+ const json = JSON.parse(text);
71
+ return JSON.stringify(json, null, 2);
72
+ } catch {
73
+ return text;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Extract display URL from full URL
79
+ * @param {string} url
80
+ * @param {number} maxLength
81
+ * @returns {string}
82
+ */
83
+ export function extractDisplayUrl(url, maxLength = 80) {
84
+ if (!url) return '-';
85
+ try {
86
+ const urlObj = new URL(url);
87
+ let displayUrl = urlObj.pathname + urlObj.search;
88
+ if (displayUrl.length > maxLength) {
89
+ displayUrl = displayUrl.substring(0, maxLength) + '...';
90
+ }
91
+ return displayUrl;
92
+ } catch {
93
+ return url;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Export data as JSON file download
99
+ * @param {object} data
100
+ * @param {string} filename
101
+ */
102
+ export function downloadJson(data, filename) {
103
+ const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
104
+ const url = URL.createObjectURL(blob);
105
+ const a = document.createElement('a');
106
+ a.href = url;
107
+ a.download = filename;
108
+ document.body.appendChild(a);
109
+ a.click();
110
+ document.body.removeChild(a);
111
+ URL.revokeObjectURL(url);
112
+ }