@aippy/runtime 0.2.0 → 0.2.1

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.
@@ -0,0 +1,26 @@
1
+ var e = Object.defineProperty;
2
+ var o = (E, R, N) => R in E ? e(E, R, { enumerable: !0, configurable: !0, writable: !0, value: N }) : E[R] = N;
3
+ var O = (E, R, N) => o(E, typeof R != "symbol" ? R + "" : R, N);
4
+ class I extends Error {
5
+ constructor(N, r = "AIPPY_ERROR", t) {
6
+ super(N);
7
+ O(this, "code");
8
+ O(this, "context");
9
+ this.name = "AippyRuntimeError", this.code = r, this.context = t;
10
+ }
11
+ }
12
+ const _ = {
13
+ NOT_SUPPORTED: "NOT_SUPPORTED",
14
+ PERMISSION_DENIED: "PERMISSION_DENIED",
15
+ INVALID_CONFIG: "INVALID_CONFIG",
16
+ NETWORK_ERROR: "NETWORK_ERROR",
17
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
18
+ };
19
+ function s(E, R = "UNKNOWN_ERROR", N) {
20
+ return new I(E, _[R], N);
21
+ }
22
+ export {
23
+ I as A,
24
+ _ as E,
25
+ s as c
26
+ };
@@ -1,40 +1,40 @@
1
- import { DEFAULT_CONFIG, SDK_NAME, VERSION, getConfigFromEnv, getVersionInfo, mergeConfig } from "../core/index.js";
2
- import { A, E, c } from "../errors-DAz5_jDJ.js";
3
- import { CameraAPI, FileSystemAPI, GeolocationAPI, SensorsAPI, camera, fileSystem, geolocation, sensors, vibrate } from "../device/index.js";
4
- import { c as c2, a, P, b, p, d } from "../pwa-BkviTQoN.js";
5
- import { a as a2, b as b2 } from "../useTweaks-mK5PAWOs.js";
6
- import { c as c3, a as a3, i, b as b3, p as p2, u } from "../useAudioContext-D9Y4gIw9.js";
1
+ import { DEFAULT_CONFIG as o, SDK_NAME as r, VERSION as t, getConfigFromEnv as s, getVersionInfo as i, mergeConfig as m } from "../core/index.js";
2
+ import { A as p, E as c, c as f } from "../errors-CDEBaBxB.js";
3
+ import { CameraAPI as A, FileSystemAPI as E, GeolocationAPI as l, SensorsAPI as S, camera as u, fileSystem as x, geolocation as I, sensors as P, vibrate as C } from "../device/index.js";
4
+ import { c as R, a as y, P as D, b as M, p as O, d as b } from "../pwa-DPd78fwK.js";
5
+ import { a as v, b as w } from "../useTweaks-Bc26i-fJ.js";
6
+ import { c as T, a as V, i as _, b as k, p as G, u as H } from "../useAudioContext-DaLkaQ8P.js";
7
7
  export {
8
- A as AippyRuntimeError,
9
- CameraAPI,
10
- DEFAULT_CONFIG,
11
- E as ERROR_CODES,
12
- FileSystemAPI,
13
- GeolocationAPI,
14
- c2 as PWAUtils,
15
- a as PerformanceMonitor,
16
- P as PlatformDetector,
17
- SDK_NAME,
18
- SensorsAPI,
19
- VERSION,
20
- a2 as aippyTweaks,
21
- b2 as aippyTweaksRuntime,
22
- camera,
23
- c as createError,
24
- c3 as createHiddenMediaElement,
25
- a3 as createHiddenVideoElement,
26
- fileSystem,
27
- geolocation,
28
- getConfigFromEnv,
29
- getVersionInfo,
30
- i as isIOSDevice,
31
- b3 as isMediaStreamAudioSupported,
32
- mergeConfig,
33
- p2 as patchAudioContext,
34
- b as performanceMonitor,
35
- p as platform,
36
- d as pwa,
37
- sensors,
38
- u as useAudioContext,
39
- vibrate
8
+ p as AippyRuntimeError,
9
+ A as CameraAPI,
10
+ o as DEFAULT_CONFIG,
11
+ c as ERROR_CODES,
12
+ E as FileSystemAPI,
13
+ l as GeolocationAPI,
14
+ R as PWAUtils,
15
+ y as PerformanceMonitor,
16
+ D as PlatformDetector,
17
+ r as SDK_NAME,
18
+ S as SensorsAPI,
19
+ t as VERSION,
20
+ v as aippyTweaks,
21
+ w as aippyTweaksRuntime,
22
+ u as camera,
23
+ f as createError,
24
+ T as createHiddenMediaElement,
25
+ V as createHiddenVideoElement,
26
+ x as fileSystem,
27
+ I as geolocation,
28
+ s as getConfigFromEnv,
29
+ i as getVersionInfo,
30
+ _ as isIOSDevice,
31
+ k as isMediaStreamAudioSupported,
32
+ m as mergeConfig,
33
+ G as patchAudioContext,
34
+ M as performanceMonitor,
35
+ O as platform,
36
+ b as pwa,
37
+ P as sensors,
38
+ H as useAudioContext,
39
+ C as vibrate
40
40
  };
@@ -0,0 +1,342 @@
1
+ var u = Object.defineProperty;
2
+ var f = (o, e, r) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : o[e] = r;
3
+ var l = (o, e, r) => f(o, typeof e != "symbol" ? e + "" : e, r);
4
+ import { UAParser as m } from "ua-parser-js";
5
+ class p {
6
+ constructor() {
7
+ l(this, "parser");
8
+ this.parser = new m();
9
+ }
10
+ /**
11
+ * Get platform information
12
+ */
13
+ getPlatformInfo() {
14
+ const e = this.parser.getResult(), r = this.normalizePlatformName(e.os.name), t = this.normalizeBrowserName(e.browser.name), n = this.isMobileDevice(), i = !n;
15
+ return {
16
+ name: r,
17
+ version: e.os.version,
18
+ browser: t,
19
+ browserVersion: e.browser.version,
20
+ isMobile: n,
21
+ isDesktop: i
22
+ };
23
+ }
24
+ /**
25
+ * Get platform capabilities
26
+ */
27
+ getCapabilities() {
28
+ return {
29
+ serviceWorker: "serviceWorker" in navigator,
30
+ pushNotifications: "PushManager" in window,
31
+ webShare: "share" in navigator,
32
+ clipboard: "clipboard" in navigator,
33
+ webRTC: !!(window.RTCPeerConnection || window.webkitRTCPeerConnection),
34
+ webGL: !!this.getWebGLContext(),
35
+ webAssembly: "WebAssembly" in window
36
+ };
37
+ }
38
+ /**
39
+ * Check if device is mobile
40
+ */
41
+ isMobileDevice() {
42
+ const e = navigator.userAgent;
43
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e) || this.isTouchDevice();
44
+ }
45
+ /**
46
+ * Check if device supports touch
47
+ */
48
+ isTouchDevice() {
49
+ return "ontouchstart" in window || navigator.maxTouchPoints > 0;
50
+ }
51
+ /**
52
+ * Check if running in standalone mode (PWA)
53
+ */
54
+ isStandalone() {
55
+ return window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === !0;
56
+ }
57
+ /**
58
+ * Check if running in iOS Safari
59
+ */
60
+ isIOSSafari() {
61
+ const e = this.getPlatformInfo();
62
+ return e.name === "ios" && e.browser === "safari";
63
+ }
64
+ /**
65
+ * Check if running in Android Chrome
66
+ */
67
+ isAndroidChrome() {
68
+ const e = this.getPlatformInfo();
69
+ return e.name === "android" && e.browser === "chrome";
70
+ }
71
+ normalizePlatformName(e) {
72
+ if (!e) return "unknown";
73
+ const r = e.toLowerCase();
74
+ return r.includes("ios") ? "ios" : r.includes("android") ? "android" : r.includes("windows") ? "windows" : r.includes("mac") ? "macos" : r.includes("linux") ? "linux" : "unknown";
75
+ }
76
+ normalizeBrowserName(e) {
77
+ if (!e) return "unknown";
78
+ const r = e.toLowerCase();
79
+ return r.includes("chrome") ? "chrome" : r.includes("firefox") ? "firefox" : r.includes("safari") ? "safari" : r.includes("edge") ? "edge" : "unknown";
80
+ }
81
+ getWebGLContext() {
82
+ try {
83
+ const e = document.createElement("canvas");
84
+ return e.getContext("webgl") || e.getContext("experimental-webgl");
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+ }
90
+ const y = new p();
91
+ class w {
92
+ /**
93
+ * Get Core Web Vitals metrics
94
+ */
95
+ async getCoreWebVitals() {
96
+ const e = {};
97
+ try {
98
+ const r = performance.getEntriesByName("first-contentful-paint")[0];
99
+ r && (e.fcp = r.startTime);
100
+ const t = performance.getEntriesByType("largest-contentful-paint");
101
+ if (t.length > 0) {
102
+ const s = t[t.length - 1];
103
+ e.lcp = s.startTime;
104
+ }
105
+ const n = performance.getEntriesByType("first-input");
106
+ if (n.length > 0) {
107
+ const s = n[0];
108
+ e.fid = s.processingStart - s.startTime;
109
+ }
110
+ const i = performance.getEntriesByType("layout-shift");
111
+ if (i.length > 0) {
112
+ let s = 0;
113
+ for (const d of i) {
114
+ const c = d;
115
+ c.hadRecentInput || (s += c.value);
116
+ }
117
+ e.cls = s;
118
+ }
119
+ const a = this.calculateTTI();
120
+ a && (e.tti = a);
121
+ } catch (r) {
122
+ console.warn("Failed to get Core Web Vitals:", r);
123
+ }
124
+ return e;
125
+ }
126
+ /**
127
+ * Get navigation timing metrics
128
+ */
129
+ getNavigationTiming() {
130
+ const e = performance.getEntriesByType("navigation")[0];
131
+ return e ? {
132
+ // DNS lookup time
133
+ dns: e.domainLookupEnd - e.domainLookupStart,
134
+ // TCP connection time
135
+ tcp: e.connectEnd - e.connectStart,
136
+ // Request time
137
+ request: e.responseStart - e.requestStart,
138
+ // Response time
139
+ response: e.responseEnd - e.responseStart,
140
+ // DOM processing time
141
+ domProcessing: e.domComplete - e.domInteractive,
142
+ // Total page load time
143
+ total: e.loadEventEnd - e.fetchStart
144
+ } : null;
145
+ }
146
+ /**
147
+ * Get resource timing metrics
148
+ */
149
+ getResourceTiming() {
150
+ return performance.getEntriesByType("resource").map((r) => ({
151
+ name: r.name,
152
+ duration: r.duration,
153
+ size: r.transferSize,
154
+ type: this.getResourceType(r.name)
155
+ }));
156
+ }
157
+ /**
158
+ * Measure function execution time
159
+ */
160
+ measureFunction(e, r) {
161
+ const t = performance.now(), n = e(), i = performance.now();
162
+ return r && (performance.mark(`${r}-start`), performance.mark(`${r}-end`), performance.measure(r, `${r}-start`, `${r}-end`)), console.log(`Function ${r || "anonymous"} took ${i - t} milliseconds`), n;
163
+ }
164
+ /**
165
+ * Measure async function execution time
166
+ */
167
+ async measureAsyncFunction(e, r) {
168
+ const t = performance.now(), n = await e(), i = performance.now();
169
+ return r && (performance.mark(`${r}-start`), performance.mark(`${r}-end`), performance.measure(r, `${r}-start`, `${r}-end`)), console.log(`Async function ${r || "anonymous"} took ${i - t} milliseconds`), n;
170
+ }
171
+ /**
172
+ * Get memory usage (if available)
173
+ */
174
+ getMemoryUsage() {
175
+ if ("memory" in performance) {
176
+ const e = performance.memory;
177
+ return {
178
+ used: e.usedJSHeapSize,
179
+ total: e.totalJSHeapSize,
180
+ limit: e.jsHeapSizeLimit
181
+ };
182
+ }
183
+ return null;
184
+ }
185
+ calculateTTI() {
186
+ const e = performance.getEntriesByType("navigation")[0];
187
+ return e ? e.domContentLoadedEventEnd - e.fetchStart : null;
188
+ }
189
+ getResourceType(e) {
190
+ return e.includes(".js") ? "script" : e.includes(".css") ? "stylesheet" : e.includes(".png") || e.includes(".jpg") || e.includes(".gif") ? "image" : e.includes(".woff") || e.includes(".ttf") ? "font" : "other";
191
+ }
192
+ }
193
+ const b = new w();
194
+ class g {
195
+ /**
196
+ * Get PWA information
197
+ */
198
+ getPWAInfo() {
199
+ return {
200
+ isInstalled: this.isInstalled(),
201
+ isInstallable: this.isInstallable(),
202
+ canInstall: this.canInstall(),
203
+ isStandalone: this.isStandalone()
204
+ };
205
+ }
206
+ /**
207
+ * Check if PWA is installed
208
+ */
209
+ isInstalled() {
210
+ return this.isStandalone() || this.isInApp();
211
+ }
212
+ /**
213
+ * Check if PWA is installable
214
+ */
215
+ isInstallable() {
216
+ return "serviceWorker" in navigator && "PushManager" in window;
217
+ }
218
+ /**
219
+ * Check if install prompt is available
220
+ */
221
+ canInstall() {
222
+ return this.isInstallable() && !this.isInstalled();
223
+ }
224
+ /**
225
+ * Check if running in standalone mode
226
+ */
227
+ isStandalone() {
228
+ return window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === !0;
229
+ }
230
+ /**
231
+ * Check if running in app (iOS)
232
+ */
233
+ isInApp() {
234
+ return window.navigator.standalone === !0;
235
+ }
236
+ /**
237
+ * Register service worker
238
+ */
239
+ async registerServiceWorker(e) {
240
+ if (!("serviceWorker" in navigator))
241
+ return console.warn("Service Worker not supported"), null;
242
+ try {
243
+ const r = await navigator.serviceWorker.register(e);
244
+ return console.log("Service Worker registered:", r), r;
245
+ } catch (r) {
246
+ return console.error("Service Worker registration failed:", r), null;
247
+ }
248
+ }
249
+ /**
250
+ * Unregister service worker
251
+ */
252
+ async unregisterServiceWorker() {
253
+ if (!("serviceWorker" in navigator))
254
+ return !1;
255
+ try {
256
+ const e = await navigator.serviceWorker.getRegistrations();
257
+ for (const r of e)
258
+ await r.unregister();
259
+ return !0;
260
+ } catch (e) {
261
+ return console.error("Service Worker unregistration failed:", e), !1;
262
+ }
263
+ }
264
+ /**
265
+ * Request notification permission
266
+ */
267
+ async requestNotificationPermission() {
268
+ if (!("Notification" in window))
269
+ throw new Error("Notifications not supported");
270
+ return Notification.permission === "granted" ? "granted" : Notification.permission === "denied" ? "denied" : await Notification.requestPermission();
271
+ }
272
+ /**
273
+ * Send notification
274
+ */
275
+ async sendNotification(e, r) {
276
+ if (!("Notification" in window))
277
+ throw new Error("Notifications not supported");
278
+ if (Notification.permission !== "granted")
279
+ throw new Error("Notification permission not granted");
280
+ const t = new Notification(e, r);
281
+ setTimeout(() => {
282
+ t.close();
283
+ }, 5e3);
284
+ }
285
+ /**
286
+ * Share content using Web Share API
287
+ */
288
+ async share(e) {
289
+ if (!("share" in navigator))
290
+ throw new Error("Web Share API not supported");
291
+ try {
292
+ await navigator.share(e);
293
+ } catch (r) {
294
+ if (r instanceof Error && r.name !== "AbortError")
295
+ throw new Error(`Share failed: ${r.message}`);
296
+ }
297
+ }
298
+ /**
299
+ * Copy text to clipboard
300
+ */
301
+ async copyToClipboard(e) {
302
+ if (!("clipboard" in navigator))
303
+ throw new Error("Clipboard API not supported");
304
+ try {
305
+ await navigator.clipboard.writeText(e);
306
+ } catch (r) {
307
+ throw new Error(`Copy to clipboard failed: ${r instanceof Error ? r.message : "Unknown error"}`);
308
+ }
309
+ }
310
+ /**
311
+ * Read text from clipboard
312
+ */
313
+ async readFromClipboard() {
314
+ if (!("clipboard" in navigator))
315
+ throw new Error("Clipboard API not supported");
316
+ try {
317
+ return await navigator.clipboard.readText();
318
+ } catch (e) {
319
+ throw new Error(`Read from clipboard failed: ${e instanceof Error ? e.message : "Unknown error"}`);
320
+ }
321
+ }
322
+ /**
323
+ * Get install prompt event
324
+ */
325
+ getInstallPromptEvent() {
326
+ return new Promise((e) => {
327
+ const r = (t) => {
328
+ t.preventDefault(), e(t), window.removeEventListener("beforeinstallprompt", r);
329
+ };
330
+ window.addEventListener("beforeinstallprompt", r);
331
+ });
332
+ }
333
+ }
334
+ const E = new g();
335
+ export {
336
+ p as P,
337
+ w as a,
338
+ b,
339
+ g as c,
340
+ E as d,
341
+ y as p
342
+ };
@@ -1,5 +1,5 @@
1
- import { a, b } from "../useTweaks-mK5PAWOs.js";
1
+ import { a as e, b as s } from "../useTweaks-Bc26i-fJ.js";
2
2
  export {
3
- a as aippyTweaks,
4
- b as aippyTweaksRuntime
3
+ e as aippyTweaks,
4
+ s as aippyTweaksRuntime
5
5
  };
@@ -0,0 +1,223 @@
1
+ var v = Object.defineProperty;
2
+ var S = (e, t, n) => t in e ? v(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var s = (e, t, n) => S(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { useState as k, useRef as w, useEffect as p } from "react";
5
+ function T() {
6
+ const e = navigator.userAgent;
7
+ return !!(/iPad|iPhone|iPod/.test(e) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);
8
+ }
9
+ function P() {
10
+ try {
11
+ if (!window.AudioContext)
12
+ return !1;
13
+ const e = new AudioContext(), t = typeof e.createMediaStreamDestination == "function";
14
+ return e.close(), t;
15
+ } catch {
16
+ return !1;
17
+ }
18
+ }
19
+ function D(e = "video", t = !1) {
20
+ const n = document.createElement(e);
21
+ return n.muted = !1, n.autoplay = !0, e === "video" && (n.playsInline = !0), t ? n.style.cssText = "position:fixed;bottom:10px;right:10px;width:200px;background:#ff0000;z-index:9999;" : n.style.cssText = "position:fixed;width:1px;height:1px;opacity:0;pointer-events:none;", n;
22
+ }
23
+ function M(e = !1) {
24
+ return D("video", e);
25
+ }
26
+ class E {
27
+ constructor(t, n, i, a = !1) {
28
+ s(this, "analyser");
29
+ s(this, "dataArray");
30
+ s(this, "rafId", null);
31
+ s(this, "silenceStartTime", 0);
32
+ s(this, "isPaused", !1);
33
+ s(this, "lastCheckTime", 0);
34
+ s(this, "silenceThreshold");
35
+ s(this, "silenceDuration");
36
+ s(this, "checkInterval");
37
+ s(this, "debug");
38
+ /**
39
+ * Check audio levels and pause/resume as needed
40
+ */
41
+ s(this, "check", () => {
42
+ const t = performance.now();
43
+ t - this.lastCheckTime >= this.checkInterval && (this.lastCheckTime = t, this.getAudioLevel() < this.silenceThreshold ? this.silenceStartTime === 0 ? this.silenceStartTime = t : t - this.silenceStartTime >= this.silenceDuration && !this.isPaused && this.pauseMedia() : (this.silenceStartTime = 0, this.isPaused && this.resumeMedia())), this.rafId = requestAnimationFrame(this.check);
44
+ });
45
+ this.audioContext = t, this.mediaElement = n, this.silenceThreshold = i.silenceThreshold, this.silenceDuration = i.silenceDuration, this.checkInterval = i.checkInterval, this.debug = a, this.analyser = t.createAnalyser(), this.analyser.fftSize = 512, this.analyser.smoothingTimeConstant = 0.3, this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
46
+ }
47
+ /**
48
+ * Connect the detector to the audio stream
49
+ */
50
+ connect(t) {
51
+ t.connect(this.analyser);
52
+ }
53
+ /**
54
+ * Start monitoring audio levels
55
+ */
56
+ start() {
57
+ this.rafId === null && (this.lastCheckTime = performance.now(), this.check(), this.debug && console.log("[AudioSilenceDetector] Started monitoring"));
58
+ }
59
+ /**
60
+ * Stop monitoring
61
+ */
62
+ stop() {
63
+ this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null), this.debug && console.log("[AudioSilenceDetector] Stopped monitoring");
64
+ }
65
+ /**
66
+ * Cleanup resources
67
+ */
68
+ dispose() {
69
+ this.stop(), this.analyser.disconnect();
70
+ }
71
+ /**
72
+ * Get current audio level (0-1)
73
+ */
74
+ getAudioLevel() {
75
+ this.analyser.getByteTimeDomainData(this.dataArray);
76
+ let t = 0;
77
+ for (let n = 0; n < this.dataArray.length; n++) {
78
+ const i = (this.dataArray[n] - 128) / 128;
79
+ t += i * i;
80
+ }
81
+ return Math.sqrt(t / this.dataArray.length);
82
+ }
83
+ /**
84
+ * Pause media element to stop audio output
85
+ */
86
+ pauseMedia() {
87
+ try {
88
+ this.mediaElement.pause(), this.isPaused = !0, this.debug && console.log("[AudioSilenceDetector] Paused media element (silence detected)");
89
+ } catch (t) {
90
+ console.error("[AudioSilenceDetector] Failed to pause:", t);
91
+ }
92
+ }
93
+ /**
94
+ * Resume media element playback
95
+ */
96
+ resumeMedia() {
97
+ try {
98
+ this.audioContext.state === "running" && this.mediaElement.play().catch((t) => {
99
+ this.debug && console.warn("[AudioSilenceDetector] Failed to resume:", t);
100
+ }), this.isPaused = !1, this.debug && console.log("[AudioSilenceDetector] Resumed media element (audio detected)");
101
+ } catch (t) {
102
+ console.error("[AudioSilenceDetector] Failed to resume:", t);
103
+ }
104
+ }
105
+ }
106
+ function x(e, t = {}) {
107
+ const {
108
+ forceEnable: n = !1,
109
+ autoCleanup: i = !0,
110
+ debug: a = !1,
111
+ mediaElementType: m = "video",
112
+ autoPause: d = {}
113
+ } = t, h = {
114
+ enabled: d.enabled ?? !0,
115
+ silenceThreshold: d.silenceThreshold ?? 1e-3,
116
+ silenceDuration: d.silenceDuration ?? 50,
117
+ checkInterval: d.checkInterval ?? 16
118
+ };
119
+ if (!(n || T()))
120
+ return Object.assign(e, {
121
+ unlock: async () => {
122
+ e.state === "suspended" && await e.resume();
123
+ },
124
+ cleanup: () => {
125
+ },
126
+ isPatched: !1,
127
+ originalDestination: e.destination
128
+ });
129
+ if (!P())
130
+ return console.warn(
131
+ "[AudioContext] MediaStreamAudioDestinationNode not supported, falling back to native"
132
+ ), Object.assign(e, {
133
+ unlock: async () => e.resume(),
134
+ cleanup: () => {
135
+ },
136
+ isPatched: !1,
137
+ originalDestination: e.destination
138
+ });
139
+ const c = e.destination, g = e.createMediaStreamDestination(), f = e.createGain();
140
+ f.gain.value = 1, f.connect(g);
141
+ const l = D(m, a);
142
+ l.srcObject = g.stream, document.body.appendChild(l);
143
+ let u = null;
144
+ h.enabled && (u = new E(
145
+ e,
146
+ l,
147
+ h,
148
+ a
149
+ ), u.connect(f)), Object.defineProperty(e, "destination", {
150
+ get: () => f,
151
+ enumerable: !0,
152
+ configurable: !0
153
+ }), "maxChannelCount" in f || Object.defineProperty(f, "maxChannelCount", {
154
+ get: () => c.maxChannelCount,
155
+ enumerable: !0
156
+ });
157
+ let y = !1;
158
+ const b = async () => {
159
+ if (!y)
160
+ try {
161
+ await l.play(), e.state === "suspended" && await e.resume(), u && u.start(), y = !0, a && console.log("[AudioContext] iOS unlock successful");
162
+ } catch (o) {
163
+ throw o instanceof DOMException && o.name === "NotAllowedError" ? (a && console.log("[AudioContext] Unlock requires user interaction"), o) : (console.error("[AudioContext] Unlock failed:", o), o);
164
+ }
165
+ }, A = () => {
166
+ try {
167
+ u && (u.dispose(), u = null), l.pause(), l.srcObject = null, l.remove(), a && console.log("[AudioContext] Cleanup completed");
168
+ } catch (o) {
169
+ console.error("[AudioContext] Cleanup error:", o);
170
+ }
171
+ };
172
+ if (i) {
173
+ const o = e.close.bind(e);
174
+ e.close = async () => (A(), o());
175
+ }
176
+ return Object.assign(e, {
177
+ unlock: b,
178
+ cleanup: A,
179
+ isPatched: !0,
180
+ originalDestination: c
181
+ });
182
+ }
183
+ function O(e = {}) {
184
+ const { autoUnlock: t = !0, ...n } = e, [i, a] = k(null), [m, d] = k(!1), h = w(null);
185
+ return p(() => {
186
+ const r = new AudioContext(), c = x(r, n);
187
+ return a(c), () => {
188
+ c.cleanup(), c.close();
189
+ };
190
+ }, []), p(() => {
191
+ i && (h.current = async () => {
192
+ if (!m)
193
+ try {
194
+ await i.unlock(), d(!0);
195
+ } catch (r) {
196
+ if (r instanceof DOMException && r.name === "NotAllowedError")
197
+ return;
198
+ console.warn("Failed to unlock audio:", r);
199
+ }
200
+ });
201
+ }, [i, m]), p(() => {
202
+ if (!t || !i) return;
203
+ const r = async (c) => {
204
+ c.isTrusted && await h.current?.();
205
+ };
206
+ return document.addEventListener("click", r, { once: !0, capture: !0 }), document.addEventListener("touchstart", r, { once: !0, capture: !0 }), () => {
207
+ document.removeEventListener("click", r, { capture: !0 }), document.removeEventListener("touchstart", r, { capture: !0 });
208
+ };
209
+ }, [t, i]), {
210
+ audioContext: i,
211
+ isUnlocked: m,
212
+ unlock: h.current || (async () => {
213
+ })
214
+ };
215
+ }
216
+ export {
217
+ M as a,
218
+ P as b,
219
+ D as c,
220
+ T as i,
221
+ x as p,
222
+ O as u
223
+ };