@blotch/angular-lynx 22.2.2 → 22.2.3

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,18 +1,481 @@
1
1
  import * as i0 from "@angular/core";
2
- import { ApplicationRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, ErrorHandler, Injectable, InjectionToken, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2, TemplateRef, ViewContainerRef, ViewEncapsulation, computed, contentChild, createComponent, effect, forwardRef, inject, input, makeEnvironmentProviders, output, signal, viewChild } from "@angular/core";
2
+ import { ApplicationRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, ErrorHandler, Injectable, InjectionToken, Injector, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2, TemplateRef, ViewContainerRef, ViewEncapsulation, computed, contentChild, createComponent, effect, forwardRef, inject, input, makeEnvironmentProviders, output, provideEnvironmentInitializer, signal, viewChild, ɵɵreplaceMetadata } from "@angular/core";
3
+ import { ReplaySubject, Subject, firstValueFrom } from "rxjs";
4
+ import { APP_BASE_HREF, IMAGE_CONFIG, Location, LocationStrategy, PlatformLocation, getLocaleId } from "@angular/common";
3
5
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
4
- import { APP_BASE_HREF, IMAGE_CONFIG, LocationStrategy, PlatformLocation } from "@angular/common";
5
- import { RouteReuseStrategy, provideRouter as provideRouter$1, withRouterConfig } from "@angular/router";
6
+ import { provideRouter as provideRouter$1, withRouterConfig } from "@angular/router";
6
7
  import { bootstrapApplication as bootstrapApplication$1 } from "@angular/platform-browser";
7
- import { Subject, firstValueFrom } from "rxjs";
8
+ const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9
+ const VALUES = new Map(Array.from(ALPHABET, (char, index) => [char, index]));
10
+ const SLICE$1 = 8192;
11
+ const bytesToBase64 = (bytes) => {
12
+ const codes = [];
13
+ let output = "";
14
+ for (let index = 0; index < bytes.length; index += 3) {
15
+ const a = bytes[index];
16
+ const b = bytes[index + 1];
17
+ const c = bytes[index + 2];
18
+ codes.push(ALPHABET.charCodeAt(a >> 2), ALPHABET.charCodeAt((a & 3) << 4 | (b ?? 0) >> 4), b === void 0 ? 61 : ALPHABET.charCodeAt((b & 15) << 2 | (c ?? 0) >> 6), c === void 0 ? 61 : ALPHABET.charCodeAt(c & 63));
19
+ if (codes.length >= SLICE$1) {
20
+ output += String.fromCharCode(...codes);
21
+ codes.length = 0;
22
+ }
23
+ }
24
+ return output + String.fromCharCode(...codes);
25
+ };
26
+ const base64ToBytes = (base64) => {
27
+ const values = [];
28
+ for (const char of base64) {
29
+ const value = VALUES.get(char);
30
+ if (value !== void 0) values.push(value);
31
+ }
32
+ const bytes = new Uint8Array(Math.floor(values.length * 3 / 4));
33
+ let byteIndex = 0;
34
+ for (let index = 0; index < values.length; index += 4) {
35
+ const a = values[index];
36
+ const b = values[index + 1] ?? 0;
37
+ const c = values[index + 2];
38
+ const d = values[index + 3];
39
+ bytes[byteIndex++] = a << 2 | b >> 4;
40
+ if (c !== void 0) bytes[byteIndex++] = (b & 15) << 4 | c >> 2;
41
+ if (d !== void 0) bytes[byteIndex++] = (c & 3) << 6 | d;
42
+ }
43
+ return bytes;
44
+ };
45
+ const LYNX_FAILURE_STATUS = 499;
46
+ const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
47
+ 101,
48
+ 103,
49
+ 204,
50
+ 205,
51
+ 304
52
+ ]);
53
+ const TEXT_TYPE = /^(text\/|application\/([\w.+-]*\+)?(json|xml|javascript|ecmascript|x-www-form-urlencoded|graphql)\b)/;
54
+ const isUtf8Text = (contentType) => {
55
+ if (!contentType) return false;
56
+ const type = contentType.toLowerCase();
57
+ const charset = /;\s*charset="?([^";]+)/.exec(type)?.[1];
58
+ return TEXT_TYPE.test(type) && (charset === void 0 || /^utf-?8$/.test(charset));
59
+ };
60
+ const decodeBody = (body) => {
61
+ if (body === null) return void 0;
62
+ if ("text" in body) return body.text;
63
+ return base64ToBytes(body.base64).buffer;
64
+ };
65
+ const backgroundFetch = () => typeof fetch === "function" ? fetch : void 0;
66
+ const controllers = /* @__PURE__ */ new Map();
67
+ const fetchForMainThread = async (id, request) => {
68
+ const fetchImpl = backgroundFetch();
69
+ if (!fetchImpl) throw new TypeError("fetch isn't available on the background thread in this environment");
70
+ const controller = new AbortController();
71
+ controllers.set(id, controller);
72
+ try {
73
+ const response = await fetchImpl(request.url, {
74
+ ...request.options,
75
+ method: request.method,
76
+ headers: Object.fromEntries(request.headers),
77
+ body: decodeBody(request.body),
78
+ signal: controller.signal
79
+ });
80
+ const headers = [];
81
+ response.headers.forEach((value, name) => headers.push([name, value]));
82
+ if (response.status === LYNX_FAILURE_STATUS && headers.length === 0) throw new TypeError(response.statusText || "Network request failed");
83
+ let body = null;
84
+ if (!NULL_BODY_STATUSES.has(response.status)) body = isUtf8Text(response.headers.get("content-type")) ? { text: await response.text() } : { base64: bytesToBase64(new Uint8Array(await response.arrayBuffer())) };
85
+ return {
86
+ status: response.status,
87
+ statusText: response.statusText,
88
+ url: response.url || request.url,
89
+ redirected: response.redirected === true,
90
+ headers,
91
+ body
92
+ };
93
+ } finally {
94
+ controllers.delete(id);
95
+ }
96
+ };
97
+ const abortFetchForMainThread = (id) => {
98
+ controllers.get(id)?.abort();
99
+ };
100
+ const CALL_EVENT = "AngularLynx.BackgroundCall";
101
+ const RESULT_EVENT = "AngularLynx.BackgroundCallResult";
102
+ const SESSION_STORAGE_EVENT = "AngularLynx.SessionStorageChange";
103
+ const CALLBACK_EVENT = "AngularLynx.Callback";
104
+ const isMainThread = () => typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__;
105
+ const lynxApi = (name) => {
106
+ const fn = typeof lynx !== "undefined" ? lynx[name] : void 0;
107
+ if (typeof fn !== "function") throw new Error(`lynx.${name} is not available in this environment`);
108
+ return fn.bind(lynx);
109
+ };
110
+ const relayedSubscriptions = /* @__PURE__ */ new Map();
111
+ const relayedFunctions = /* @__PURE__ */ new Map();
112
+ const relayedFunctionIds = /* @__PURE__ */ new WeakMap();
113
+ let nextFunctionId = 0;
114
+ const standIns = /* @__PURE__ */ new Map();
115
+ const isPlainObject = (value) => {
116
+ if (typeof value !== "object" || value === null) return false;
117
+ const proto = Object.getPrototypeOf(value);
118
+ return proto === Object.prototype || proto === null;
119
+ };
120
+ const isFunctionMarker = (value) => isPlainObject(value) && typeof value["__angularLynxCallback"] === "number";
121
+ const markFunction = (fn, owner) => {
122
+ let id = relayedFunctionIds.get(fn);
123
+ if (id === void 0) {
124
+ id = nextFunctionId++;
125
+ relayedFunctionIds.set(fn, id);
126
+ relayedFunctions.set(id, (...args) => fn.apply(owner, args));
127
+ }
128
+ return { __angularLynxCallback: id };
129
+ };
130
+ const relayFunctions = (value) => {
131
+ if (!isMainThread()) return value;
132
+ const relay = (item, owner) => {
133
+ if (typeof item === "function") return markFunction(item, owner);
134
+ if (Array.isArray(item)) return item.map((entry) => relay(entry));
135
+ if (isPlainObject(item)) {
136
+ const result = {};
137
+ for (const key of Object.keys(item)) result[key] = relay(item[key], item);
138
+ return result;
139
+ }
140
+ return item;
141
+ };
142
+ return relay(value);
143
+ };
144
+ const relayModuleObject = (module) => {
145
+ if (!isMainThread()) return module;
146
+ const result = {};
147
+ for (let source = module; source !== null && source !== Object.prototype; source = Object.getPrototypeOf(source)) for (const key of Object.getOwnPropertyNames(source)) {
148
+ if (key === "constructor" || key in result) continue;
149
+ const value = module[key];
150
+ result[key] = typeof value === "function" ? markFunction(value, module) : relayFunctions(value);
151
+ }
152
+ return result;
153
+ };
154
+ const restoreFunctions = (value) => {
155
+ if (isFunctionMarker(value)) {
156
+ const id = value.__angularLynxCallback;
157
+ let standIn = standIns.get(id);
158
+ if (!standIn) {
159
+ standIn = (...args) => {
160
+ try {
161
+ lynx.getCoreContext().dispatchEvent({
162
+ type: CALLBACK_EVENT,
163
+ data: JSON.stringify({
164
+ id,
165
+ args
166
+ })
167
+ });
168
+ } catch {}
169
+ };
170
+ standIns.set(id, standIn);
171
+ }
172
+ return standIn;
173
+ }
174
+ if (Array.isArray(value)) {
175
+ const items = value.map(restoreFunctions);
176
+ return items.some((item, i) => item !== value[i]) ? items : value;
177
+ }
178
+ if (isPlainObject(value)) {
179
+ let changed = false;
180
+ const result = {};
181
+ for (const key of Object.keys(value)) {
182
+ result[key] = restoreFunctions(value[key]);
183
+ changed ||= result[key] !== value[key];
184
+ }
185
+ return changed ? result : value;
186
+ }
187
+ return value;
188
+ };
189
+ const nativeBridge = () => {
190
+ const bridge = typeof NativeModules !== "undefined" && NativeModules != null ? NativeModules.bridge : void 0;
191
+ return typeof bridge?.call === "function" ? bridge : void 0;
192
+ };
193
+ const findModule = (kind, name) => {
194
+ if (kind === "native") return typeof NativeModules !== "undefined" && NativeModules != null ? NativeModules[name] : void 0;
195
+ return typeof lynx !== "undefined" && typeof lynx.getJSModule === "function" ? lynx.getJSModule(name) : void 0;
196
+ };
197
+ const handlers = {
198
+ accessibilityAnnounce: (content) => new Promise((resolve) => lynxApi("accessibilityAnnounce")({ content }, () => resolve())),
199
+ addFont: (fontFamily, src) => new Promise((resolve, reject) => lynxApi("addFont")({
200
+ "font-family": fontFamily,
201
+ src
202
+ }, (err) => err ? reject(err) : resolve())),
203
+ setObserverFrameRate: (options) => lynxApi("setObserverFrameRate")(options),
204
+ stopExposure: (options) => lynxApi("stopExposure")(options ?? {}),
205
+ resumeExposure: () => lynxApi("resumeExposure")(),
206
+ subscribeSessionStorage: (key, relayId) => {
207
+ const listenerId = lynxApi("subscribeSessionStorage")(key, (value) => lynx.getCoreContext().dispatchEvent({
208
+ type: SESSION_STORAGE_EVENT,
209
+ data: JSON.stringify({
210
+ relayId,
211
+ value
212
+ })
213
+ }));
214
+ relayedSubscriptions.set(relayId, {
215
+ key,
216
+ listenerId
217
+ });
218
+ },
219
+ unsubscribeSessionStorage: (relayId) => {
220
+ const subscription = relayedSubscriptions.get(relayId);
221
+ if (!subscription) return;
222
+ relayedSubscriptions.delete(relayId);
223
+ lynxApi("unsubscribeSessionStorage")(subscription.key, subscription.listenerId);
224
+ },
225
+ requestResourcePrefetch: (data) => new Promise((resolve) => lynxApi("requestResourcePrefetch")(data, resolve)),
226
+ cancelResourcePrefetch: (data) => new Promise((resolve) => lynxApi("cancelResourcePrefetch")(data, resolve)),
227
+ nativeBridgeCall: (name, params) => {
228
+ const bridge = nativeBridge();
229
+ if (!bridge) return Promise.resolve(void 0);
230
+ return new Promise((resolve) => bridge.call(name, params, (...args) => resolve(args[0])));
231
+ },
232
+ nativeBridgeOn: (name, callback) => {
233
+ nativeBridge()?.on(name, restoreFunctions(callback));
234
+ },
235
+ callModule: (kind, name, method, args) => {
236
+ const module = findModule(kind, name);
237
+ const fn = module?.[method];
238
+ if (typeof fn !== "function") throw new Error(`${kind === "native" ? "NativeModules" : "lynx.getJSModule"}: ${name}.${method} is not available`);
239
+ return fn.apply(module, restoreFunctions(args));
240
+ },
241
+ registerJSModule: (name, module) => {
242
+ lynxApi("registerModule")(name, restoreFunctions(module));
243
+ },
244
+ fetch: (id, request) => fetchForMainThread(id, request),
245
+ abortFetch: (id) => abortFetchForMainThread(id)
246
+ };
247
+ const pending = /* @__PURE__ */ new Map();
248
+ let nextCallId = 0;
249
+ const callOnBackground = (name, ...args) => {
250
+ if (!isMainThread()) try {
251
+ return Promise.resolve(handlers[name](...args));
252
+ } catch (error) {
253
+ return Promise.reject(error);
254
+ }
255
+ return new Promise((resolve, reject) => {
256
+ const id = nextCallId++;
257
+ pending.set(id, {
258
+ resolve,
259
+ reject
260
+ });
261
+ try {
262
+ lynx.getJSContext().dispatchEvent({
263
+ type: CALL_EVENT,
264
+ data: JSON.stringify({
265
+ id,
266
+ name,
267
+ args
268
+ })
269
+ });
270
+ } catch {
271
+ pending.delete(id);
272
+ reject(/* @__PURE__ */ new Error(`Can't reach the background thread to call lynx.${name} in this environment`));
273
+ }
274
+ });
275
+ };
276
+ const moduleProxies = /* @__PURE__ */ new Map();
277
+ const relayedModule = (kind, name) => {
278
+ const cacheKey = `${kind}:${name}`;
279
+ let proxy = moduleProxies.get(cacheKey);
280
+ if (!proxy) {
281
+ const methods = /* @__PURE__ */ new Map();
282
+ proxy = new Proxy({}, { get: (_target, method) => {
283
+ if (typeof method !== "string" || method === "then") return;
284
+ let call = methods.get(method);
285
+ if (!call) {
286
+ call = (...args) => callOnBackground("callModule", kind, name, method, relayFunctions(args));
287
+ methods.set(method, call);
288
+ }
289
+ return call;
290
+ } });
291
+ moduleProxies.set(cacheKey, proxy);
292
+ }
293
+ return proxy;
294
+ };
295
+ const sessionStorageListeners = /* @__PURE__ */ new Map();
296
+ let nextRelayId = 0;
297
+ const subscribeSessionStorageFromMainThread = (key, listener) => {
298
+ const relayId = nextRelayId++;
299
+ sessionStorageListeners.set(relayId, listener);
300
+ callOnBackground("subscribeSessionStorage", key, relayId).catch(() => {
301
+ sessionStorageListeners.delete(relayId);
302
+ });
303
+ return relayId;
304
+ };
305
+ const unsubscribeSessionStorageFromMainThread = (relayId) => {
306
+ if (!sessionStorageListeners.delete(relayId)) return;
307
+ callOnBackground("unsubscribeSessionStorage", relayId).catch(() => {});
308
+ };
309
+ const installRelay = () => {
310
+ if (typeof lynx === "undefined") return;
311
+ try {
312
+ if (isMainThread()) {
313
+ const context = lynx.getJSContext();
314
+ context.addEventListener(RESULT_EVENT, (event) => {
315
+ const { id, value, error } = JSON.parse(event.data);
316
+ const call = pending.get(id);
317
+ if (!call) return;
318
+ pending.delete(id);
319
+ if (error !== void 0) call.reject(new Error(error));
320
+ else call.resolve(value);
321
+ });
322
+ context.addEventListener(SESSION_STORAGE_EVENT, (event) => {
323
+ const { relayId, value } = JSON.parse(event.data);
324
+ sessionStorageListeners.get(relayId)?.(value);
325
+ });
326
+ context.addEventListener(CALLBACK_EVENT, (event) => {
327
+ const { id, args } = JSON.parse(event.data);
328
+ relayedFunctions.get(id)?.(...args);
329
+ });
330
+ return;
331
+ }
332
+ const context = lynx.getCoreContext();
333
+ context.addEventListener(CALL_EVENT, async (event) => {
334
+ const { id, name, args } = JSON.parse(event.data);
335
+ let reply;
336
+ try {
337
+ const handler = handlers[name];
338
+ if (!handler) throw new Error(`Unknown background call: ${name}`);
339
+ reply = {
340
+ id,
341
+ value: await handler(...args)
342
+ };
343
+ } catch (error) {
344
+ reply = {
345
+ id,
346
+ error: error instanceof Error ? error.message : String(error)
347
+ };
348
+ }
349
+ let data;
350
+ try {
351
+ data = JSON.stringify(reply);
352
+ } catch (error) {
353
+ data = JSON.stringify({
354
+ id,
355
+ error: `The result of ${name} can't be sent to the main thread: ${error.message}`
356
+ });
357
+ }
358
+ context.dispatchEvent({
359
+ type: RESULT_EVENT,
360
+ data
361
+ });
362
+ });
363
+ } catch {}
364
+ };
365
+ installRelay();
366
+ const ANIMATION_START = 0;
367
+ const ANIMATION_PLAY = 1;
368
+ const ANIMATION_PAUSE = 2;
369
+ const ANIMATION_CANCEL = 3;
370
+ var LynxAnimation = class LynxAnimation {
371
+ static #count = 0;
372
+ id;
373
+ #element;
374
+ #key;
375
+ #webAnimation;
376
+ constructor(element, keyframes, options) {
377
+ this.#element = element;
378
+ this.id = `__lynx-angular-animation-${LynxAnimation.#count++}`;
379
+ this.#key = __WEB__ ? this.id : options.name ?? this.id;
380
+ const wireOptions = { ...options };
381
+ if (options.iterations != null && !("iterationCount" in options)) wireOptions["iterationCount"] = options.iterations === Infinity ? "infinite" : options.iterations;
382
+ if (options.easing != null && !("timingFunction" in options)) wireOptions["timingFunction"] = options.easing;
383
+ if (options.fill != null && !("fillMode" in options)) wireOptions["fillMode"] = options.fill;
384
+ __ElementAnimate(this.#element, [
385
+ ANIMATION_START,
386
+ this.#key,
387
+ keyframes,
388
+ wireOptions
389
+ ]);
390
+ if (__WEB__) this.#webAnimation = this.#element.getAnimations?.().at(-1);
391
+ }
392
+ play() {
393
+ __ElementAnimate(this.#element, [ANIMATION_PLAY, this.#key]);
394
+ }
395
+ pause() {
396
+ __ElementAnimate(this.#element, [ANIMATION_PAUSE, this.#key]);
397
+ }
398
+ cancel() {
399
+ __ElementAnimate(this.#element, [ANIMATION_CANCEL, this.#key]);
400
+ this.#webAnimation?.cancel();
401
+ }
402
+ };
403
+ let willFlush = false;
404
+ const scheduleFlush = () => {
405
+ if (willFlush) return;
406
+ willFlush = true;
407
+ Promise.resolve().then(() => {
408
+ willFlush = false;
409
+ __FlushElementTree();
410
+ });
411
+ };
412
+ var MainThreadElement = class MainThreadElement {
413
+ #element;
414
+ constructor(element) {
415
+ this.#element = element;
416
+ }
417
+ setAttribute(name, value) {
418
+ __SetAttribute(this.#element, name, value);
419
+ scheduleFlush();
420
+ }
421
+ getAttribute(name) {
422
+ return __GetAttributeByName(this.#element, name);
423
+ }
424
+ getAttributeNames() {
425
+ return __GetAttributeNames(this.#element);
426
+ }
427
+ setStyleProperty(name, value) {
428
+ __AddInlineStyle(this.#element, name, value);
429
+ scheduleFlush();
430
+ }
431
+ setStyleProperties(styles) {
432
+ for (const key in styles) __AddInlineStyle(this.#element, key, styles[key]);
433
+ scheduleFlush();
434
+ }
435
+ querySelector(selector) {
436
+ const ref = __QuerySelector(this.#element, selector, {});
437
+ return ref ? new MainThreadElement(ref) : null;
438
+ }
439
+ querySelectorAll(selector) {
440
+ return __QuerySelectorAll(this.#element, selector, {}).map((el) => new MainThreadElement(el));
441
+ }
442
+ invoke(methodName, params) {
443
+ return new Promise((resolve, reject) => {
444
+ __InvokeUIMethod(this.#element, methodName, params ?? {}, (res) => {
445
+ if (res.code === 0) resolve(res.data);
446
+ else reject(/* @__PURE__ */ new Error("UI method invoke: " + JSON.stringify(res)));
447
+ });
448
+ scheduleFlush();
449
+ });
450
+ }
451
+ animate(keyframes, options) {
452
+ const normalizedOptions = typeof options === "number" ? { duration: options } : options ?? {};
453
+ return new LynxAnimation(this.#element, keyframes, normalizedOptions);
454
+ }
455
+ getBoundingClientRect(options) {
456
+ return this.invoke("boundingClientRect", options).then((rect) => {
457
+ const { left, top, right, bottom, width, height } = rect;
458
+ return {
459
+ left,
460
+ top,
461
+ right,
462
+ bottom,
463
+ width,
464
+ height
465
+ };
466
+ });
467
+ }
468
+ };
8
469
  var LynxAccessibility = class LynxAccessibility {
9
470
  announce(content) {
10
- if (typeof lynx === "undefined" || typeof lynx.accessibilityAnnounce !== "function") return Promise.reject(/* @__PURE__ */ new Error("lynx.accessibilityAnnounce is not available in this environment"));
11
- return new Promise((resolve) => {
12
- lynx.accessibilityAnnounce({ content }, () => resolve());
13
- });
471
+ return callOnBackground("accessibilityAnnounce", content);
14
472
  }
15
473
  requestFocus(selector) {
474
+ if (typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__) {
475
+ const element = new MainThreadElement(__GetPageElement()).querySelector(selector);
476
+ if (!element) return Promise.reject(/* @__PURE__ */ new Error(`requestAccessibilityFocus: no element matches ${selector}`));
477
+ return element.invoke("requestAccessibilityFocus").then(() => void 0);
478
+ }
16
479
  if (typeof lynx === "undefined" || !lynx.createSelectorQuery) return Promise.reject(/* @__PURE__ */ new Error("lynx.createSelectorQuery is not available in this environment"));
17
480
  return new Promise((resolve, reject) => {
18
481
  lynx.createSelectorQuery().select(selector).invoke({
@@ -49,38 +512,6 @@ i0.ɵɵngDeclareClassMetadata({
49
512
  args: [{ providedIn: "root" }]
50
513
  }]
51
514
  });
52
- const ANIMATION_START = 0;
53
- const ANIMATION_PLAY = 1;
54
- const ANIMATION_PAUSE = 2;
55
- const ANIMATION_CANCEL = 3;
56
- var LynxAnimation = class LynxAnimation {
57
- static #count = 0;
58
- id;
59
- #element;
60
- constructor(element, keyframes, options) {
61
- this.#element = element;
62
- this.id = `__lynx-angular-animation-${LynxAnimation.#count++}`;
63
- const wireOptions = { ...options };
64
- if (options.iterations != null && !("iterationCount" in options)) wireOptions["iterationCount"] = options.iterations === Infinity ? "infinite" : options.iterations;
65
- if (options.easing != null && !("timingFunction" in options)) wireOptions["timingFunction"] = options.easing;
66
- if (options.fill != null && !("fillMode" in options)) wireOptions["fillMode"] = options.fill;
67
- __ElementAnimate(this.#element, [
68
- ANIMATION_START,
69
- options.name ?? this.id,
70
- keyframes,
71
- wireOptions
72
- ]);
73
- }
74
- play() {
75
- __ElementAnimate(this.#element, [ANIMATION_PLAY, this.id]);
76
- }
77
- pause() {
78
- __ElementAnimate(this.#element, [ANIMATION_PAUSE, this.id]);
79
- }
80
- cancel() {
81
- __ElementAnimate(this.#element, [ANIMATION_CANCEL, this.id]);
82
- }
83
- };
84
515
  var LynxPerformance = class LynxPerformance {
85
516
  #perf = this.#resolve();
86
517
  #resolve() {
@@ -142,6 +573,15 @@ const devStats = {
142
573
  this.lastCdDurationMs = 0;
143
574
  }
144
575
  };
576
+ const now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
577
+ const cdStartTimes = [];
578
+ const startCdTiming = () => {
579
+ cdStartTimes.push(now());
580
+ };
581
+ const endCdTiming = () => {
582
+ const start = cdStartTimes.pop();
583
+ if (start !== void 0) devStats.lastCdDurationMs = now() - start;
584
+ };
145
585
  var LynxDevTools = class LynxDevTools {
146
586
  #tick = signal(0, ...ngDevMode ? [{ debugName: "#tick" }] : /* istanbul ignore next */ []);
147
587
  stats = computed(() => {
@@ -206,13 +646,33 @@ const registerDataProcessors = (definition) => {
206
646
  }
207
647
  };
208
648
  };
649
+ const initDataUpdates = new Subject();
650
+ const globalDataUpdates = new Subject();
651
+ const asRecord = (data) => typeof data === "object" && data !== null ? data : {};
652
+ const applyInitDataUpdate = (data, reset) => {
653
+ const host = lynx;
654
+ const next = {
655
+ ...reset ? {} : host.__initData,
656
+ ...asRecord(data)
657
+ };
658
+ host.__initData = next;
659
+ initDataUpdates.next(next);
660
+ return next;
661
+ };
662
+ const applyGlobalDataUpdate = (data) => {
663
+ const next = {
664
+ ...lynx.__globalProps,
665
+ ...asRecord(data)
666
+ };
667
+ lynx.__globalProps = next;
668
+ globalDataUpdates.next(next);
669
+ return next;
670
+ };
209
671
  var LynxGlobalData = class LynxGlobalData {
210
- globalData = signal(typeof lynx !== "undefined" ? lynx.__globalProps : {}, ...ngDevMode ? [{ debugName: "globalData" }] : /* istanbul ignore next */ []);
672
+ globalData = signal(typeof lynx !== "undefined" && lynx.__globalProps || {}, ...ngDevMode ? [{ debugName: "globalData" }] : /* istanbul ignore next */ []);
211
673
  constructor() {
212
- if (typeof lynx === "undefined" || typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__ || typeof lynx.getJSModule !== "function") return;
213
- const emitter = lynx.getJSModule("GlobalEventEmitter");
214
- if (!emitter?.addListener) return;
215
- emitter.addListener("onGlobalPropsChanged", (...args) => this.globalData.set(args[0]));
674
+ const subscription = globalDataUpdates.subscribe((data) => this.globalData.set(data));
675
+ inject(DestroyRef).onDestroy(() => subscription.unsubscribe());
216
676
  }
217
677
  static ɵfac = i0.ɵɵngDeclareFactory({
218
678
  minVersion: "12.0.0",
@@ -242,12 +702,10 @@ i0.ɵɵngDeclareClassMetadata({
242
702
  ctorParameters: () => []
243
703
  });
244
704
  var LynxInitData = class LynxInitData {
245
- initData = signal(typeof lynx !== "undefined" ? lynx.__initData : {}, ...ngDevMode ? [{ debugName: "initData" }] : /* istanbul ignore next */ []);
705
+ initData = signal(typeof lynx !== "undefined" && lynx.__initData || {}, ...ngDevMode ? [{ debugName: "initData" }] : /* istanbul ignore next */ []);
246
706
  constructor() {
247
- if (typeof lynx === "undefined" || typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__ || typeof lynx.getJSModule !== "function") return;
248
- const emitter = lynx.getJSModule("GlobalEventEmitter");
249
- if (!emitter?.addListener) return;
250
- emitter.addListener("onDataChanged", (...args) => this.initData.set(args[0]));
707
+ const subscription = initDataUpdates.subscribe((data) => this.initData.set(data));
708
+ inject(DestroyRef).onDestroy(() => subscription.unsubscribe());
251
709
  }
252
710
  static ɵfac = i0.ɵɵngDeclareFactory({
253
711
  minVersion: "12.0.0",
@@ -356,30 +814,57 @@ i0.ɵɵngDeclareClassMetadata({
356
814
  }],
357
815
  ctorParameters: () => []
358
816
  });
817
+ const globalExposureBatches = new Subject();
818
+ const FORWARD_EVENT = "AngularLynx.GlobalExposure";
819
+ const installGlobalExposureBridge = () => {
820
+ if (typeof lynx === "undefined") return;
821
+ try {
822
+ if (__MAIN_THREAD__) {
823
+ lynx.getJSContext?.()?.addEventListener(FORWARD_EVENT, (event) => globalExposureBatches.next(JSON.parse(event.data)));
824
+ return;
825
+ }
826
+ const emitter = lynx.getJSModule?.("GlobalEventEmitter");
827
+ if (!emitter?.addListener) return;
828
+ for (const type of ["exposure", "disexposure"]) emitter.addListener(type, (...args) => {
829
+ const batch = {
830
+ type,
831
+ events: args[0]
832
+ };
833
+ globalExposureBatches.next(batch);
834
+ lynx.getCoreContext?.()?.dispatchEvent({
835
+ type: FORWARD_EVENT,
836
+ data: JSON.stringify(batch)
837
+ });
838
+ });
839
+ } catch {}
840
+ };
841
+ installGlobalExposureBridge();
359
842
  var LynxGlobalExposure = class LynxGlobalExposure {
360
843
  exposures = signal([], ...ngDevMode ? [{ debugName: "exposures" }] : /* istanbul ignore next */ []);
361
844
  disexposures = signal([], ...ngDevMode ? [{ debugName: "disexposures" }] : /* istanbul ignore next */ []);
362
845
  active = signal(true, ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
363
846
  constructor() {
364
- if (typeof lynx === "undefined" || typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__) return;
365
- const emitter = lynx.getJSModule("GlobalEventEmitter");
366
- if (!emitter?.addListener) return;
367
- emitter.addListener("exposure", (...args) => this.exposures.set(args[0]));
368
- emitter.addListener("disexposure", (...args) => this.disexposures.set(args[0]));
847
+ const subscription = globalExposureBatches.subscribe(({ type, events }) => (type === "exposure" ? this.exposures : this.disexposures).set(events));
848
+ inject(DestroyRef).onDestroy(() => subscription.unsubscribe());
369
849
  }
370
850
  stopExposure(options) {
371
851
  if (typeof lynx === "undefined") return;
372
- lynx.stopExposure(options);
852
+ if (typeof lynx.stopExposure === "function") lynx.stopExposure(options);
853
+ else this.#relay(callOnBackground("stopExposure", options));
373
854
  this.active.set(false);
374
855
  }
375
856
  resumeExposure() {
376
857
  if (typeof lynx === "undefined") return;
377
- lynx.resumeExposure();
858
+ if (typeof lynx.resumeExposure === "function") lynx.resumeExposure();
859
+ else this.#relay(callOnBackground("resumeExposure"));
378
860
  this.active.set(true);
379
861
  }
380
862
  setObserverFrameRate(options) {
381
- if (typeof lynx === "undefined") return;
382
- lynx.setObserverFrameRate(options);
863
+ if (typeof lynx === "undefined") return Promise.resolve();
864
+ return callOnBackground("setObserverFrameRate", options);
865
+ }
866
+ #relay(call) {
867
+ call.catch((error) => console.error(error));
383
868
  }
384
869
  static ɵfac = i0.ɵɵngDeclareFactory({
385
870
  minVersion: "12.0.0",
@@ -428,30 +913,23 @@ var LynxFont = class LynxFont {
428
913
  src,
429
914
  status: "loading"
430
915
  });
431
- const promise = new Promise((resolve, reject) => {
432
- lynx.addFont({
433
- "font-family": fontFamily,
434
- src
435
- }, (err) => {
436
- if (err) {
437
- this.#updateEntry(fontFamily, {
438
- fontFamily,
439
- src,
440
- status: "error",
441
- error: err
442
- });
443
- this.#pending.delete(fontFamily);
444
- reject(err);
445
- } else {
446
- this.#updateEntry(fontFamily, {
447
- fontFamily,
448
- src,
449
- status: "loaded"
450
- });
451
- this.#pending.delete(fontFamily);
452
- resolve();
453
- }
916
+ const promise = callOnBackground("addFont", fontFamily, src).then(() => {
917
+ this.#updateEntry(fontFamily, {
918
+ fontFamily,
919
+ src,
920
+ status: "loaded"
454
921
  });
922
+ this.#pending.delete(fontFamily);
923
+ }, (err) => {
924
+ const error = err instanceof Error ? err : new Error(String(err));
925
+ this.#updateEntry(fontFamily, {
926
+ fontFamily,
927
+ src,
928
+ status: "error",
929
+ error
930
+ });
931
+ this.#pending.delete(fontFamily);
932
+ throw error;
455
933
  });
456
934
  this.#pending.set(fontFamily, promise);
457
935
  return promise;
@@ -541,10 +1019,48 @@ const reportError = (source, cause) => {
541
1019
  _ReportError(error, { errorCode: 6 });
542
1020
  }
543
1021
  };
1022
+ const DATA_KEY = "angularLynx";
1023
+ const ɵhmrAccept = (hot, components, signature, code) => {
1024
+ hot.accept();
1025
+ if (!isMainThread()) return components;
1026
+ const previous = hot.data?.[DATA_KEY];
1027
+ let live = components;
1028
+ let invalidated = false;
1029
+ if (previous && !previous.invalidated) {
1030
+ if (previous.code !== code && previous.signature === signature && previous.components.length === components.length) try {
1031
+ previous.components.forEach((type, index) => replaceComponent(type, components[index]));
1032
+ live = previous.components;
1033
+ } catch (error) {
1034
+ console.error("[HMR] Could not update the component in place:", error);
1035
+ invalidated = true;
1036
+ }
1037
+ else invalidated = true;
1038
+ }
1039
+ hot.dispose((data) => {
1040
+ data[DATA_KEY] = {
1041
+ components: live,
1042
+ signature,
1043
+ code,
1044
+ invalidated
1045
+ };
1046
+ });
1047
+ if (invalidated) hot.invalidate();
1048
+ return live;
1049
+ };
1050
+ const replaceComponent = (current, next) => {
1051
+ const currentDef = current.ɵcmp;
1052
+ const nextDef = next.ɵcmp;
1053
+ currentDef.directiveDefs = nextDef.directiveDefs;
1054
+ currentDef.pipeDefs = nextDef.pipeDefs;
1055
+ ɵɵreplaceMetadata(current, (type) => {
1056
+ type.ɵcmp = next.ɵcmp;
1057
+ }, [], []);
1058
+ };
544
1059
  const extractAppLocale = (globalProps) => {
545
1060
  const value = globalProps?.["appLocale"];
546
1061
  return typeof value === "string" && value ? value : void 0;
547
1062
  };
1063
+ const getSourceLocale = () => typeof __LYNX_SOURCE_LOCALE__ !== "undefined" ? __LYNX_SOURCE_LOCALE__ : "en-US";
548
1064
  const getLynxAppLocale = () => {
549
1065
  if (typeof lynx === "undefined") return;
550
1066
  return extractAppLocale(lynx.__globalProps);
@@ -552,9 +1068,7 @@ const getLynxAppLocale = () => {
552
1068
  var LynxLocale = class LynxLocale {
553
1069
  #globalData = inject(LynxGlobalData);
554
1070
  locale = computed(() => {
555
- const value = extractAppLocale(this.#globalData.globalData());
556
- if (value) return value;
557
- return typeof __LYNX_SOURCE_LOCALE__ !== "undefined" ? __LYNX_SOURCE_LOCALE__ : "en-US";
1071
+ return extractAppLocale(this.#globalData.globalData()) ?? getSourceLocale();
558
1072
  }, ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
559
1073
  static ɵfac = i0.ɵɵngDeclareFactory({
560
1074
  minVersion: "12.0.0",
@@ -582,17 +1096,31 @@ i0.ɵɵngDeclareClassMetadata({
582
1096
  args: [{ providedIn: "root" }]
583
1097
  }]
584
1098
  });
1099
+ const hasLocaleData = (locale) => {
1100
+ try {
1101
+ getLocaleId(locale);
1102
+ return true;
1103
+ } catch {
1104
+ return false;
1105
+ }
1106
+ };
585
1107
  const provideLocale = () => {
586
1108
  return makeEnvironmentProviders([{
587
1109
  provide: LOCALE_ID,
588
- useFactory: () => inject(LynxLocale).locale()
1110
+ useFactory: () => {
1111
+ const locale = inject(LynxLocale).locale();
1112
+ const source = getSourceLocale();
1113
+ if (locale === source || hasLocaleData(locale)) return locale;
1114
+ console.warn(`provideLocale(): Angular has no locale data for "${locale}", so LOCALE_ID is "${source}". Register it with registerLocaleData() to format dates and numbers for it.`);
1115
+ return source;
1116
+ }
589
1117
  }]);
590
1118
  };
591
1119
  let nextGestureId = 1;
592
1120
  var BaseGesture = class {
593
1121
  id = nextGestureId++;
594
1122
  _callbacks = {};
595
- _config = {};
1123
+ _config = { enabled: true };
596
1124
  _waitFor = [];
597
1125
  _simultaneousWith = [];
598
1126
  _continueWith = [];
@@ -716,7 +1244,7 @@ const mapGestureEvent = (raw, name, origin) => {
716
1244
  absoluteY
717
1245
  };
718
1246
  if (origin) {
719
- if (name === "onBegin" || name === "onStart" || origin.x === null) {
1247
+ if (name === "onBegin" || origin.x === null) {
720
1248
  origin.x = absoluteX ?? 0;
721
1249
  origin.y = absoluteY ?? 0;
722
1250
  }
@@ -756,19 +1284,22 @@ var LynxGestureDetector = class LynxGestureDetector {
756
1284
  #el = inject(ElementRef).nativeElement;
757
1285
  #attachedIds = [];
758
1286
  lynxGesture;
1287
+ constructor() {
1288
+ const elementRef = this.#el.element;
1289
+ if (elementRef) __SetAttribute(elementRef, "flatten", false);
1290
+ }
759
1291
  ngOnChanges(_changes) {
760
1292
  this.#detachAll();
761
1293
  const gestures = this.#resolveGestures();
762
1294
  if (gestures.length === 0) return;
763
1295
  const elementRef = this.#el.element;
764
1296
  if (!elementRef) return;
765
- __SetAttribute(elementRef, "flatten", false);
766
1297
  for (const g of gestures) {
767
1298
  const stateManager = new GestureStateManager(elementRef, g.id);
768
1299
  const origin = createGestureOrigin();
769
1300
  const config = {
770
1301
  callbacks: buildGestureCallbacks(g, origin, stateManager),
771
- config: Object.keys(g._config).length > 0 ? g._config : void 0
1302
+ config: g._config
772
1303
  };
773
1304
  const relationMap = {
774
1305
  waitFor: g._waitFor.map((dep) => dep.id),
@@ -826,7 +1357,8 @@ i0.ɵɵngDeclareClassMetadata({
826
1357
  selector: "[lynxGesture]",
827
1358
  inputs: ["lynxGesture"]
828
1359
  }]
829
- }]
1360
+ }],
1361
+ ctorParameters: () => []
830
1362
  });
831
1363
  const buildGestureCallbacks = (gesture, origin, stateManager) => {
832
1364
  const wrap = (name, cb) => ({
@@ -834,7 +1366,11 @@ const buildGestureCallbacks = (gesture, origin, stateManager) => {
834
1366
  callback: { _fn: (event) => cb(mapGestureEvent(event, name, origin), stateManager) }
835
1367
  });
836
1368
  const userEnd = gesture._callbacks["onEnd"];
837
- if (!(gesture.type === GestureType.TAP || gesture.type === GestureType.LONGPRESS) || !userEnd) return Object.entries(gesture._callbacks).map(([name, cb]) => wrap(name, cb));
1369
+ if (!(gesture.type === GestureType.TAP || gesture.type === GestureType.LONGPRESS) || !userEnd) {
1370
+ const callbacks = Object.entries(gesture._callbacks).map(([name, cb]) => wrap(name, cb));
1371
+ if (gesture instanceof ContinuousGesture && !gesture._callbacks["onBegin"]) callbacks.push(wrap("onBegin", () => {}));
1372
+ return callbacks;
1373
+ }
838
1374
  const userStart = gesture._callbacks["onStart"];
839
1375
  const lifecycle = { started: false };
840
1376
  const callbacks = [{
@@ -934,6 +1470,15 @@ var TapGesture = class extends BaseGesture {
934
1470
  return this;
935
1471
  }
936
1472
  };
1473
+ function booleanInput(value) {
1474
+ return typeof value === "string" ? value !== "false" : value;
1475
+ }
1476
+ function panInterceptDirectionInput(value) {
1477
+ return typeof value === "string" ? Number(value) : value;
1478
+ }
1479
+ function panInterceptScopeInput(value) {
1480
+ return typeof value === "string" ? Number(value) : value;
1481
+ }
937
1482
  var LynxElementBase = class LynxElementBase {
938
1483
  #el = inject(ElementRef).nativeElement;
939
1484
  ngOnChanges(changes) {
@@ -947,7 +1492,7 @@ var LynxElementBase = class LynxElementBase {
947
1492
  name;
948
1493
  "accessibility-element";
949
1494
  "accessibility-label";
950
- "accessibility-trait";
1495
+ "accessibility-traits";
951
1496
  "accessibility-elements";
952
1497
  "accessibility-elements-hidden";
953
1498
  "accessibility-exclusive-focus";
@@ -959,6 +1504,11 @@ var LynxElementBase = class LynxElementBase {
959
1504
  "block-native-event";
960
1505
  "ignore-focus";
961
1506
  "ios-enable-simultaneous-touch";
1507
+ flatten;
1508
+ "pan-intercept-direction";
1509
+ "pan-intercept-scope";
1510
+ "consume-slide-event";
1511
+ "enable-touch-pseudo-propagation";
962
1512
  "exposure-id";
963
1513
  "exposure-scene";
964
1514
  "exposure-area";
@@ -970,6 +1520,7 @@ var LynxElementBase = class LynxElementBase {
970
1520
  "exposure-ui-margin-bottom";
971
1521
  "exposure-ui-margin-left";
972
1522
  "exposure-ui-margin-right";
1523
+ "enable-exposure-ui-margin";
973
1524
  static ɵfac = i0.ɵɵngDeclareFactory({
974
1525
  minVersion: "12.0.0",
975
1526
  version: "22.2.1",
@@ -979,27 +1530,86 @@ var LynxElementBase = class LynxElementBase {
979
1530
  target: i0.ɵɵFactoryTarget.Directive
980
1531
  });
981
1532
  static ɵdir = i0.ɵɵngDeclareDirective({
982
- minVersion: "14.0.0",
1533
+ minVersion: "16.1.0",
983
1534
  version: "22.2.1",
984
1535
  type: LynxElementBase,
985
1536
  isStandalone: true,
986
1537
  inputs: {
987
1538
  id: "id",
988
1539
  name: "name",
989
- "accessibility-element": "accessibility-element",
1540
+ "accessibility-element": [
1541
+ "accessibility-element",
1542
+ "accessibility-element",
1543
+ booleanInput
1544
+ ],
990
1545
  "accessibility-label": "accessibility-label",
991
- "accessibility-trait": "accessibility-trait",
1546
+ "accessibility-value": "accessibility-value",
1547
+ "accessibility-actions": "accessibility-actions",
1548
+ "accessibility-traits": "accessibility-traits",
992
1549
  "accessibility-elements": "accessibility-elements",
993
- "accessibility-elements-hidden": "accessibility-elements-hidden",
994
- "accessibility-exclusive-focus": "accessibility-exclusive-focus",
1550
+ "accessibility-elements-hidden": [
1551
+ "accessibility-elements-hidden",
1552
+ "accessibility-elements-hidden",
1553
+ booleanInput
1554
+ ],
1555
+ "accessibility-exclusive-focus": [
1556
+ "accessibility-exclusive-focus",
1557
+ "accessibility-exclusive-focus",
1558
+ booleanInput
1559
+ ],
995
1560
  "a11y-id": "a11y-id",
996
- "user-interaction-enabled": "user-interaction-enabled",
997
- "native-interaction-enabled": "native-interaction-enabled",
998
- "event-through": "event-through",
1561
+ "user-interaction-enabled": [
1562
+ "user-interaction-enabled",
1563
+ "user-interaction-enabled",
1564
+ booleanInput
1565
+ ],
1566
+ "native-interaction-enabled": [
1567
+ "native-interaction-enabled",
1568
+ "native-interaction-enabled",
1569
+ booleanInput
1570
+ ],
1571
+ "event-through": [
1572
+ "event-through",
1573
+ "event-through",
1574
+ booleanInput
1575
+ ],
999
1576
  "hit-slop": "hit-slop",
1000
- "block-native-event": "block-native-event",
1001
- "ignore-focus": "ignore-focus",
1002
- "ios-enable-simultaneous-touch": "ios-enable-simultaneous-touch",
1577
+ "block-native-event": [
1578
+ "block-native-event",
1579
+ "block-native-event",
1580
+ booleanInput
1581
+ ],
1582
+ "ignore-focus": [
1583
+ "ignore-focus",
1584
+ "ignore-focus",
1585
+ booleanInput
1586
+ ],
1587
+ "ios-enable-simultaneous-touch": [
1588
+ "ios-enable-simultaneous-touch",
1589
+ "ios-enable-simultaneous-touch",
1590
+ booleanInput
1591
+ ],
1592
+ flatten: [
1593
+ "flatten",
1594
+ "flatten",
1595
+ booleanInput
1596
+ ],
1597
+ "pan-intercept-direction": [
1598
+ "pan-intercept-direction",
1599
+ "pan-intercept-direction",
1600
+ panInterceptDirectionInput
1601
+ ],
1602
+ "pan-intercept-scope": [
1603
+ "pan-intercept-scope",
1604
+ "pan-intercept-scope",
1605
+ panInterceptScopeInput
1606
+ ],
1607
+ "consume-slide-event": "consume-slide-event",
1608
+ "enable-touch-pseudo-propagation": [
1609
+ "enable-touch-pseudo-propagation",
1610
+ "enable-touch-pseudo-propagation",
1611
+ booleanInput
1612
+ ],
1003
1613
  "exposure-id": "exposure-id",
1004
1614
  "exposure-scene": "exposure-scene",
1005
1615
  "exposure-area": "exposure-area",
@@ -1010,7 +1620,12 @@ var LynxElementBase = class LynxElementBase {
1010
1620
  "exposure-ui-margin-top": "exposure-ui-margin-top",
1011
1621
  "exposure-ui-margin-bottom": "exposure-ui-margin-bottom",
1012
1622
  "exposure-ui-margin-left": "exposure-ui-margin-left",
1013
- "exposure-ui-margin-right": "exposure-ui-margin-right"
1623
+ "exposure-ui-margin-right": "exposure-ui-margin-right",
1624
+ "enable-exposure-ui-margin": [
1625
+ "enable-exposure-ui-margin",
1626
+ "enable-exposure-ui-margin",
1627
+ booleanInput
1628
+ ]
1014
1629
  },
1015
1630
  usesOnChanges: true,
1016
1631
  ngImport: i0
@@ -1026,20 +1641,66 @@ i0.ɵɵngDeclareClassMetadata({
1026
1641
  args: [{ inputs: [
1027
1642
  "id",
1028
1643
  "name",
1029
- "accessibility-element",
1644
+ {
1645
+ name: "accessibility-element",
1646
+ transform: booleanInput
1647
+ },
1030
1648
  "accessibility-label",
1031
- "accessibility-trait",
1649
+ "accessibility-value",
1650
+ "accessibility-actions",
1651
+ "accessibility-traits",
1032
1652
  "accessibility-elements",
1033
- "accessibility-elements-hidden",
1034
- "accessibility-exclusive-focus",
1653
+ {
1654
+ name: "accessibility-elements-hidden",
1655
+ transform: booleanInput
1656
+ },
1657
+ {
1658
+ name: "accessibility-exclusive-focus",
1659
+ transform: booleanInput
1660
+ },
1035
1661
  "a11y-id",
1036
- "user-interaction-enabled",
1037
- "native-interaction-enabled",
1038
- "event-through",
1662
+ {
1663
+ name: "user-interaction-enabled",
1664
+ transform: booleanInput
1665
+ },
1666
+ {
1667
+ name: "native-interaction-enabled",
1668
+ transform: booleanInput
1669
+ },
1670
+ {
1671
+ name: "event-through",
1672
+ transform: booleanInput
1673
+ },
1039
1674
  "hit-slop",
1040
- "block-native-event",
1041
- "ignore-focus",
1042
- "ios-enable-simultaneous-touch",
1675
+ {
1676
+ name: "block-native-event",
1677
+ transform: booleanInput
1678
+ },
1679
+ {
1680
+ name: "ignore-focus",
1681
+ transform: booleanInput
1682
+ },
1683
+ {
1684
+ name: "ios-enable-simultaneous-touch",
1685
+ transform: booleanInput
1686
+ },
1687
+ {
1688
+ name: "flatten",
1689
+ transform: booleanInput
1690
+ },
1691
+ {
1692
+ name: "pan-intercept-direction",
1693
+ transform: panInterceptDirectionInput
1694
+ },
1695
+ {
1696
+ name: "pan-intercept-scope",
1697
+ transform: panInterceptScopeInput
1698
+ },
1699
+ "consume-slide-event",
1700
+ {
1701
+ name: "enable-touch-pseudo-propagation",
1702
+ transform: booleanInput
1703
+ },
1043
1704
  "exposure-id",
1044
1705
  "exposure-scene",
1045
1706
  "exposure-area",
@@ -1050,7 +1711,11 @@ i0.ɵɵngDeclareClassMetadata({
1050
1711
  "exposure-ui-margin-top",
1051
1712
  "exposure-ui-margin-bottom",
1052
1713
  "exposure-ui-margin-left",
1053
- "exposure-ui-margin-right"
1714
+ "exposure-ui-margin-right",
1715
+ {
1716
+ name: "enable-exposure-ui-margin",
1717
+ transform: booleanInput
1718
+ }
1054
1719
  ] }]
1055
1720
  }]
1056
1721
  });
@@ -1106,7 +1771,6 @@ i0.ɵɵngDeclareClassMetadata({
1106
1771
  type: Directive,
1107
1772
  args: [{
1108
1773
  selector: "blur-view",
1109
- standalone: true,
1110
1774
  inputs: [
1111
1775
  "blur-radius",
1112
1776
  "blur-sampling",
@@ -1149,10 +1813,7 @@ i0.ɵɵngDeclareClassMetadata({
1149
1813
  type: LynxCoverView,
1150
1814
  decorators: [{
1151
1815
  type: Directive,
1152
- args: [{
1153
- selector: "cover-view",
1154
- standalone: true
1155
- }]
1816
+ args: [{ selector: "cover-view" }]
1156
1817
  }]
1157
1818
  });
1158
1819
  var LynxInputValueAccessor = class LynxInputValueAccessor {
@@ -1167,7 +1828,7 @@ var LynxInputValueAccessor = class LynxInputValueAccessor {
1167
1828
  this.#onTouched();
1168
1829
  }
1169
1830
  writeValue(value) {
1170
- this.#el.nativeElement.invoke?.("setValue", { value: value ?? "" });
1831
+ this.#el.nativeElement.invoke("setValue", { value: value ?? "" });
1171
1832
  }
1172
1833
  registerOnChange(fn) {
1173
1834
  this.#onChange = fn;
@@ -1215,7 +1876,6 @@ i0.ɵɵngDeclareClassMetadata({
1215
1876
  type: Directive,
1216
1877
  args: [{
1217
1878
  selector: "input[formControlName],input[formControl],input[ngModel],input[formField]",
1218
- standalone: true,
1219
1879
  providers: [{
1220
1880
  provide: NG_VALUE_ACCESSOR,
1221
1881
  /* v8 ignore next -- Angular metadata: the forwardRef arrow is only invoked by Angular's directive DI resolution, which happens inside a full template render — the accessor's runtime behavior is covered by direct unit tests below. */
@@ -1241,7 +1901,7 @@ var LynxTextareaValueAccessor = class LynxTextareaValueAccessor {
1241
1901
  this.#onTouched();
1242
1902
  }
1243
1903
  writeValue(value) {
1244
- this.#el.nativeElement.invoke?.("setValue", { value: value ?? "" });
1904
+ this.#el.nativeElement.invoke("setValue", { value: value ?? "" });
1245
1905
  }
1246
1906
  registerOnChange(fn) {
1247
1907
  this.#onChange = fn;
@@ -1289,7 +1949,6 @@ i0.ɵɵngDeclareClassMetadata({
1289
1949
  type: Directive,
1290
1950
  args: [{
1291
1951
  selector: "textarea[formControlName],textarea[formControl],textarea[ngModel],textarea[formField]",
1292
- standalone: true,
1293
1952
  providers: [{
1294
1953
  provide: NG_VALUE_ACCESSOR,
1295
1954
  /* v8 ignore next -- Angular metadata: the forwardRef arrow is only invoked by Angular's directive DI resolution, which happens inside a full template render — the accessor's runtime behavior is covered by direct unit tests below. */
@@ -1350,7 +2009,6 @@ i0.ɵɵngDeclareClassMetadata({
1350
2009
  type: Directive,
1351
2010
  args: [{
1352
2011
  selector: "frame",
1353
- standalone: true,
1354
2012
  inputs: [
1355
2013
  "src",
1356
2014
  "data",
@@ -1422,7 +2080,6 @@ i0.ɵɵngDeclareClassMetadata({
1422
2080
  type: Directive,
1423
2081
  args: [{
1424
2082
  selector: "image",
1425
- standalone: true,
1426
2083
  inputs: [
1427
2084
  "src",
1428
2085
  "mode",
@@ -1446,7 +2103,7 @@ var LynxInput = class LynxInput extends LynxElementBase {
1446
2103
  #el = inject(ElementRef).nativeElement;
1447
2104
  ngOnChanges(changes) {
1448
2105
  if ("value" in changes) {
1449
- this.#el.invoke?.("setValue", { value: changes["value"].currentValue ?? "" });
2106
+ this.#el.invoke("setValue", { value: changes["value"].currentValue ?? "" });
1450
2107
  const { value: _ignored, ...rest } = changes;
1451
2108
  if (Object.keys(rest).length) super.ngOnChanges(rest);
1452
2109
  } else super.ngOnChanges(changes);
@@ -1507,7 +2164,6 @@ i0.ɵɵngDeclareClassMetadata({
1507
2164
  type: Directive,
1508
2165
  args: [{
1509
2166
  selector: "input",
1510
- standalone: true,
1511
2167
  inputs: [
1512
2168
  "type",
1513
2169
  "placeholder",
@@ -1530,7 +2186,7 @@ var LynxTextarea = class LynxTextarea extends LynxElementBase {
1530
2186
  #el = inject(ElementRef).nativeElement;
1531
2187
  ngOnChanges(changes) {
1532
2188
  if ("value" in changes) {
1533
- this.#el.invoke?.("setValue", { value: changes["value"].currentValue ?? "" });
2189
+ this.#el.invoke("setValue", { value: changes["value"].currentValue ?? "" });
1534
2190
  const { value: _ignored, ...rest } = changes;
1535
2191
  if (Object.keys(rest).length) super.ngOnChanges(rest);
1536
2192
  } else super.ngOnChanges(changes);
@@ -1599,7 +2255,6 @@ i0.ɵɵngDeclareClassMetadata({
1599
2255
  type: Directive,
1600
2256
  args: [{
1601
2257
  selector: "textarea",
1602
- standalone: true,
1603
2258
  inputs: [
1604
2259
  "type",
1605
2260
  "placeholder",
@@ -1641,8 +2296,6 @@ var LynxList = class LynxList extends LynxElementBase {
1641
2296
  "preload-buffer-count";
1642
2297
  "item-snap";
1643
2298
  "update-animation";
1644
- "list-main-axis-gap";
1645
- "list-cross-axis-gap";
1646
2299
  "enable-async-list";
1647
2300
  "enable-insert-platform-view-operation";
1648
2301
  "experimental-search-ref-anchor-strategy";
@@ -1680,8 +2333,6 @@ var LynxList = class LynxList extends LynxElementBase {
1680
2333
  "preload-buffer-count": "preload-buffer-count",
1681
2334
  "item-snap": "item-snap",
1682
2335
  "update-animation": "update-animation",
1683
- "list-main-axis-gap": "list-main-axis-gap",
1684
- "list-cross-axis-gap": "list-cross-axis-gap",
1685
2336
  "enable-async-list": "enable-async-list",
1686
2337
  "enable-insert-platform-view-operation": "enable-insert-platform-view-operation",
1687
2338
  "experimental-search-ref-anchor-strategy": "experimental-search-ref-anchor-strategy",
@@ -1700,7 +2351,6 @@ i0.ɵɵngDeclareClassMetadata({
1700
2351
  type: Directive,
1701
2352
  args: [{
1702
2353
  selector: "list",
1703
- standalone: true,
1704
2354
  inputs: [
1705
2355
  "list-type",
1706
2356
  "span-count",
@@ -1720,8 +2370,6 @@ i0.ɵɵngDeclareClassMetadata({
1720
2370
  "preload-buffer-count",
1721
2371
  "item-snap",
1722
2372
  "update-animation",
1723
- "list-main-axis-gap",
1724
- "list-cross-axis-gap",
1725
2373
  "enable-async-list",
1726
2374
  "enable-insert-platform-view-operation",
1727
2375
  "experimental-search-ref-anchor-strategy",
@@ -1738,7 +2386,6 @@ var LynxListItem = class LynxListItem extends LynxElementBase {
1738
2386
  recyclable;
1739
2387
  "reuse-identifier";
1740
2388
  "estimated-main-axis-size-px";
1741
- defer;
1742
2389
  static ɵfac = i0.ɵɵngDeclareFactory({
1743
2390
  minVersion: "12.0.0",
1744
2391
  version: "22.2.1",
@@ -1760,8 +2407,7 @@ var LynxListItem = class LynxListItem extends LynxElementBase {
1760
2407
  "sticky-bottom": "sticky-bottom",
1761
2408
  recyclable: "recyclable",
1762
2409
  "reuse-identifier": "reuse-identifier",
1763
- "estimated-main-axis-size-px": "estimated-main-axis-size-px",
1764
- defer: "defer"
2410
+ "estimated-main-axis-size-px": "estimated-main-axis-size-px"
1765
2411
  },
1766
2412
  usesInheritance: true,
1767
2413
  ngImport: i0
@@ -1776,7 +2422,6 @@ i0.ɵɵngDeclareClassMetadata({
1776
2422
  type: Directive,
1777
2423
  args: [{
1778
2424
  selector: "list-item",
1779
- standalone: true,
1780
2425
  inputs: [
1781
2426
  "item-key",
1782
2427
  "full-span",
@@ -1784,8 +2429,7 @@ i0.ɵɵngDeclareClassMetadata({
1784
2429
  "sticky-bottom",
1785
2430
  "recyclable",
1786
2431
  "reuse-identifier",
1787
- "estimated-main-axis-size-px",
1788
- "defer"
2432
+ "estimated-main-axis-size-px"
1789
2433
  ]
1790
2434
  }]
1791
2435
  }]
@@ -1816,10 +2460,7 @@ i0.ɵɵngDeclareClassMetadata({
1816
2460
  type: LynxBlock,
1817
2461
  decorators: [{
1818
2462
  type: Directive,
1819
- args: [{
1820
- selector: "block",
1821
- standalone: true
1822
- }]
2463
+ args: [{ selector: "block" }]
1823
2464
  }]
1824
2465
  });
1825
2466
  var LynxIf = class LynxIf extends LynxElementBase {
@@ -1848,10 +2489,7 @@ i0.ɵɵngDeclareClassMetadata({
1848
2489
  type: LynxIf,
1849
2490
  decorators: [{
1850
2491
  type: Directive,
1851
- args: [{
1852
- selector: "if",
1853
- standalone: true
1854
- }]
2492
+ args: [{ selector: "if" }]
1855
2493
  }]
1856
2494
  });
1857
2495
  var LynxFor = class LynxFor extends LynxElementBase {
@@ -1880,10 +2518,7 @@ i0.ɵɵngDeclareClassMetadata({
1880
2518
  type: LynxFor,
1881
2519
  decorators: [{
1882
2520
  type: Directive,
1883
- args: [{
1884
- selector: "for",
1885
- standalone: true
1886
- }]
2521
+ args: [{ selector: "for" }]
1887
2522
  }]
1888
2523
  });
1889
2524
  var LynxOverlay = class LynxOverlay extends LynxElementBase {
@@ -1928,7 +2563,6 @@ i0.ɵɵngDeclareClassMetadata({
1928
2563
  type: Directive,
1929
2564
  args: [{
1930
2565
  selector: "overlay",
1931
- standalone: true,
1932
2566
  inputs: [
1933
2567
  "visible",
1934
2568
  "level",
@@ -1970,7 +2604,6 @@ i0.ɵɵngDeclareClassMetadata({
1970
2604
  type: Directive,
1971
2605
  args: [{
1972
2606
  selector: "refresh",
1973
- standalone: true,
1974
2607
  inputs: ["enable-refresh"]
1975
2608
  }]
1976
2609
  }]
@@ -2001,10 +2634,7 @@ i0.ɵɵngDeclareClassMetadata({
2001
2634
  type: LynxRefreshHeader,
2002
2635
  decorators: [{
2003
2636
  type: Directive,
2004
- args: [{
2005
- selector: "refresh-header",
2006
- standalone: true
2007
- }]
2637
+ args: [{ selector: "refresh-header" }]
2008
2638
  }]
2009
2639
  });
2010
2640
  var LynxScrollCoordinator = class LynxScrollCoordinator extends LynxElementBase {
@@ -2057,7 +2687,6 @@ i0.ɵɵngDeclareClassMetadata({
2057
2687
  type: Directive,
2058
2688
  args: [{
2059
2689
  selector: "scroll-coordinator",
2060
- standalone: true,
2061
2690
  inputs: [
2062
2691
  "enable-scroll",
2063
2692
  "bounces",
@@ -2099,10 +2728,7 @@ i0.ɵɵngDeclareClassMetadata({
2099
2728
  type: LynxScrollCoordinatorHeader,
2100
2729
  decorators: [{
2101
2730
  type: Directive,
2102
- args: [{
2103
- selector: "scroll-coordinator-header",
2104
- standalone: true
2105
- }]
2731
+ args: [{ selector: "scroll-coordinator-header" }]
2106
2732
  }]
2107
2733
  });
2108
2734
  var LynxScrollCoordinatorToolbar = class LynxScrollCoordinatorToolbar extends LynxElementBase {
@@ -2131,10 +2757,7 @@ i0.ɵɵngDeclareClassMetadata({
2131
2757
  type: LynxScrollCoordinatorToolbar,
2132
2758
  decorators: [{
2133
2759
  type: Directive,
2134
- args: [{
2135
- selector: "scroll-coordinator-toolbar",
2136
- standalone: true
2137
- }]
2760
+ args: [{ selector: "scroll-coordinator-toolbar" }]
2138
2761
  }]
2139
2762
  });
2140
2763
  var LynxScrollCoordinatorSlot = class LynxScrollCoordinatorSlot extends LynxElementBase {
@@ -2163,10 +2786,7 @@ i0.ɵɵngDeclareClassMetadata({
2163
2786
  type: LynxScrollCoordinatorSlot,
2164
2787
  decorators: [{
2165
2788
  type: Directive,
2166
- args: [{
2167
- selector: "scroll-coordinator-slot",
2168
- standalone: true
2169
- }]
2789
+ args: [{ selector: "scroll-coordinator-slot" }]
2170
2790
  }]
2171
2791
  });
2172
2792
  var LynxScrollCoordinatorSlotDrag = class LynxScrollCoordinatorSlotDrag extends LynxElementBase {
@@ -2199,7 +2819,6 @@ i0.ɵɵngDeclareClassMetadata({
2199
2819
  type: Directive,
2200
2820
  args: [{
2201
2821
  selector: "scroll-coordinator-slot-drag",
2202
- standalone: true,
2203
2822
  inputs: ["enable-drag"]
2204
2823
  }]
2205
2824
  }]
@@ -2254,7 +2873,6 @@ i0.ɵɵngDeclareClassMetadata({
2254
2873
  type: Directive,
2255
2874
  args: [{
2256
2875
  selector: "scroll-view",
2257
- standalone: true,
2258
2876
  inputs: [
2259
2877
  "scroll-orientation",
2260
2878
  "enable-scroll",
@@ -2306,7 +2924,6 @@ i0.ɵɵngDeclareClassMetadata({
2306
2924
  type: Directive,
2307
2925
  args: [{
2308
2926
  selector: "svg",
2309
- standalone: true,
2310
2927
  inputs: [
2311
2928
  "src",
2312
2929
  "content",
@@ -2363,7 +2980,6 @@ i0.ɵɵngDeclareClassMetadata({
2363
2980
  type: Directive,
2364
2981
  args: [{
2365
2982
  selector: "text",
2366
- standalone: true,
2367
2983
  inputs: [
2368
2984
  "text-maxline",
2369
2985
  "text-single-line-vertical-align",
@@ -2404,10 +3020,7 @@ i0.ɵɵngDeclareClassMetadata({
2404
3020
  type: LynxInlineTruncation,
2405
3021
  decorators: [{
2406
3022
  type: Directive,
2407
- args: [{
2408
- selector: "inline-truncation",
2409
- standalone: true
2410
- }]
3023
+ args: [{ selector: "inline-truncation" }]
2411
3024
  }]
2412
3025
  });
2413
3026
  var LynxTitleBarView = class LynxTitleBarView extends LynxElementBase {
@@ -2440,7 +3053,6 @@ i0.ɵɵngDeclareClassMetadata({
2440
3053
  type: Directive,
2441
3054
  args: [{
2442
3055
  selector: "title-bar-view",
2443
- standalone: true,
2444
3056
  inputs: ["moveable"]
2445
3057
  }]
2446
3058
  }]
@@ -2491,7 +3103,6 @@ i0.ɵɵngDeclareClassMetadata({
2491
3103
  type: Directive,
2492
3104
  args: [{
2493
3105
  selector: "video",
2494
- standalone: true,
2495
3106
  inputs: [
2496
3107
  "src",
2497
3108
  "loop",
@@ -2504,13 +3115,8 @@ i0.ɵɵngDeclareClassMetadata({
2504
3115
  ]
2505
3116
  }]
2506
3117
  }]
2507
- });
2508
- var LynxView = class LynxView extends LynxElementBase {
2509
- flatten;
2510
- "pan-intercept-direction";
2511
- "pan-intercept-scope";
2512
- "consume-slide-event";
2513
- "enable-touch-pseudo-propagation";
3118
+ });
3119
+ var LynxView = class LynxView extends LynxElementBase {
2514
3120
  static ɵfac = i0.ɵɵngDeclareFactory({
2515
3121
  minVersion: "12.0.0",
2516
3122
  version: "22.2.1",
@@ -2525,13 +3131,6 @@ var LynxView = class LynxView extends LynxElementBase {
2525
3131
  type: LynxView,
2526
3132
  isStandalone: true,
2527
3133
  selector: "view",
2528
- inputs: {
2529
- flatten: "flatten",
2530
- "pan-intercept-direction": "pan-intercept-direction",
2531
- "pan-intercept-scope": "pan-intercept-scope",
2532
- "consume-slide-event": "consume-slide-event",
2533
- "enable-touch-pseudo-propagation": "enable-touch-pseudo-propagation"
2534
- },
2535
3134
  usesInheritance: true,
2536
3135
  ngImport: i0
2537
3136
  });
@@ -2543,17 +3142,7 @@ i0.ɵɵngDeclareClassMetadata({
2543
3142
  type: LynxView,
2544
3143
  decorators: [{
2545
3144
  type: Directive,
2546
- args: [{
2547
- selector: "view",
2548
- standalone: true,
2549
- inputs: [
2550
- "flatten",
2551
- "pan-intercept-direction",
2552
- "pan-intercept-scope",
2553
- "consume-slide-event",
2554
- "enable-touch-pseudo-propagation"
2555
- ]
2556
- }]
3145
+ args: [{ selector: "view" }]
2557
3146
  }]
2558
3147
  });
2559
3148
  var LynxViewPager = class LynxViewPager extends LynxElementBase {
@@ -2606,7 +3195,6 @@ i0.ɵɵngDeclareClassMetadata({
2606
3195
  type: Directive,
2607
3196
  args: [{
2608
3197
  selector: "viewpager",
2609
- standalone: true,
2610
3198
  inputs: [
2611
3199
  "initial-select-index",
2612
3200
  "enable-scroll",
@@ -2648,10 +3236,7 @@ i0.ɵɵngDeclareClassMetadata({
2648
3236
  type: LynxViewPagerItem,
2649
3237
  decorators: [{
2650
3238
  type: Directive,
2651
- args: [{
2652
- selector: "viewpager-item",
2653
- standalone: true
2654
- }]
3239
+ args: [{ selector: "viewpager-item" }]
2655
3240
  }]
2656
3241
  });
2657
3242
  var LynxWebView = class LynxWebView extends LynxElementBase {
@@ -2704,7 +3289,6 @@ i0.ɵɵngDeclareClassMetadata({
2704
3289
  type: Directive,
2705
3290
  args: [{
2706
3291
  selector: "webview",
2707
- standalone: true,
2708
3292
  inputs: [
2709
3293
  "src",
2710
3294
  "html",
@@ -2734,7 +3318,8 @@ const LYNX_ELEMENTS = [
2734
3318
  LynxFrame,
2735
3319
  LynxInput,
2736
3320
  LynxTextarea,
2737
- ...LYNX_FORM_ACCESSORS,
3321
+ LynxInputValueAccessor,
3322
+ LynxTextareaValueAccessor,
2738
3323
  LynxOverlay,
2739
3324
  LynxRefresh,
2740
3325
  LynxRefreshHeader,
@@ -2752,26 +3337,53 @@ const LYNX_ELEMENTS = [
2752
3337
  LynxCoverView,
2753
3338
  LynxTitleBarView
2754
3339
  ];
3340
+ const LOG_EVENT = "__lynx_log__";
3341
+ const logUrl = () => __DEV__ && typeof __DEV_LOG_URL__ !== "undefined" ? __DEV_LOG_URL__ : "";
3342
+ const resolveFetch = () => {
3343
+ try {
3344
+ if (typeof fetch === "function") return fetch;
3345
+ else if (typeof globalThis.fetch === "function") return globalThis.fetch;
3346
+ } catch {}
3347
+ };
3348
+ const toLogArg = (arg) => {
3349
+ if (arg instanceof Error) return {
3350
+ __type: "Error",
3351
+ name: arg.name,
3352
+ message: arg.message,
3353
+ stack: arg.stack
3354
+ };
3355
+ if (typeof arg === "object" && arg !== null) try {
3356
+ JSON.stringify(arg);
3357
+ return arg;
3358
+ } catch {}
3359
+ return String(arg);
3360
+ };
3361
+ const postToServer = (fetchFn, url, entry) => {
3362
+ try {
3363
+ fetchFn(url, {
3364
+ method: "POST",
3365
+ headers: { "Content-Type": "application/json" },
3366
+ body: JSON.stringify({ logs: [entry] })
3367
+ }).catch(() => {});
3368
+ } catch {}
3369
+ };
3370
+ const installLogRelay = () => {
3371
+ if (typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__) return;
3372
+ const url = logUrl();
3373
+ const fetchFn = resolveFetch();
3374
+ if (!url || !fetchFn) return;
3375
+ try {
3376
+ if (typeof lynx !== "undefined" && typeof lynx.getCoreContext === "function") lynx.getCoreContext().addEventListener(LOG_EVENT, (event) => {
3377
+ try {
3378
+ postToServer(fetchFn, url, JSON.parse(event.data));
3379
+ } catch {}
3380
+ });
3381
+ } catch {}
3382
+ };
3383
+ installLogRelay();
2755
3384
  var LynxLogger = class LynxLogger {
2756
- #url = "";
2757
- #fetchFn;
2758
- constructor() {
2759
- if (!__DEV__) return;
2760
- this.#url = typeof __DEV_LOG_URL__ !== "undefined" ? __DEV_LOG_URL__ : "";
2761
- if (!this.#url) return;
2762
- try {
2763
- if (typeof fetch === "function") this.#fetchFn = fetch;
2764
- else if (typeof globalThis.fetch === "function") this.#fetchFn = globalThis.fetch;
2765
- } catch {}
2766
- if (!this.#fetchFn) return;
2767
- try {
2768
- if (typeof lynx !== "undefined" && typeof lynx.getCoreContext === "function") lynx.getCoreContext().addEventListener("__lynx_log__", (event) => {
2769
- try {
2770
- this.#postToServer(JSON.parse(event.data));
2771
- } catch {}
2772
- });
2773
- } catch {}
2774
- }
3385
+ #url = logUrl();
3386
+ #fetchFn = this.#url ? resolveFetch() : void 0;
2775
3387
  log(...args) {
2776
3388
  this.#send("log", args);
2777
3389
  }
@@ -2792,25 +3404,16 @@ var LynxLogger = class LynxLogger {
2792
3404
  const entry = {
2793
3405
  level,
2794
3406
  timestamp: Date.now(),
2795
- args: args.map(String)
3407
+ args: args.map(toLogArg)
2796
3408
  };
2797
- if (this.#fetchFn) this.#postToServer(entry);
3409
+ if (this.#fetchFn) postToServer(this.#fetchFn, this.#url, entry);
2798
3410
  else try {
2799
3411
  if (typeof lynx !== "undefined" && typeof lynx.getJSContext === "function") lynx.getJSContext().dispatchEvent({
2800
- type: "__lynx_log__",
3412
+ type: LOG_EVENT,
2801
3413
  data: JSON.stringify(entry)
2802
3414
  });
2803
3415
  } catch {}
2804
3416
  }
2805
- #postToServer(entry) {
2806
- try {
2807
- this.#fetchFn(this.#url, {
2808
- method: "POST",
2809
- headers: { "Content-Type": "application/json" },
2810
- body: JSON.stringify({ logs: [entry] })
2811
- }).catch(() => {});
2812
- } catch {}
2813
- }
2814
3417
  static ɵfac = i0.ɵɵngDeclareFactory({
2815
3418
  minVersion: "12.0.0",
2816
3419
  version: "22.2.1",
@@ -2835,39 +3438,35 @@ i0.ɵɵngDeclareClassMetadata({
2835
3438
  decorators: [{
2836
3439
  type: Injectable,
2837
3440
  args: [{ providedIn: "root" }]
2838
- }],
2839
- ctorParameters: () => []
3441
+ }]
2840
3442
  });
2841
3443
  var LynxNativeModule = class LynxNativeModule {
2842
3444
  #hasNativeModules() {
2843
- return typeof NativeModules !== "undefined" && NativeModules != null && typeof NativeModules.bridge?.call === "function";
3445
+ return typeof NativeModules !== "undefined" && NativeModules != null;
2844
3446
  }
2845
3447
  #hasLynx() {
2846
3448
  return typeof lynx !== "undefined" && typeof lynx.getJSModule === "function";
2847
3449
  }
2848
3450
  call(name, params = {}) {
2849
- if (!this.#hasNativeModules()) return Promise.resolve(void 0);
2850
- return new Promise((resolve) => {
2851
- NativeModules.bridge.call(name, params, (...args) => {
2852
- resolve(args[0]);
2853
- });
2854
- });
3451
+ if (isMainThread() && typeof lynx === "undefined") return Promise.resolve(void 0);
3452
+ return callOnBackground("nativeBridgeCall", name, params);
2855
3453
  }
2856
3454
  on(name, callback) {
2857
- if (!this.#hasNativeModules()) return;
2858
- NativeModules.bridge.on(name, callback);
3455
+ callOnBackground("nativeBridgeOn", name, relayFunctions(callback)).catch(() => {});
2859
3456
  }
2860
3457
  getNativeModule(name) {
2861
- if (typeof NativeModules === "undefined" || NativeModules == null) return;
3458
+ if (isMainThread()) return typeof lynx !== "undefined" ? relayedModule("native", name) : void 0;
3459
+ if (!this.#hasNativeModules()) return;
2862
3460
  return NativeModules[name];
2863
3461
  }
2864
3462
  getJSModule(name) {
3463
+ if (isMainThread()) return typeof lynx !== "undefined" ? relayedModule("js", name) : void 0;
2865
3464
  if (!this.#hasLynx()) return;
2866
3465
  return lynx.getJSModule(name);
2867
3466
  }
2868
3467
  registerJSModule(name, module) {
2869
- if (!this.#hasLynx()) return;
2870
- lynx.registerModule(name, module);
3468
+ if (typeof lynx === "undefined") return;
3469
+ callOnBackground("registerJSModule", name, relayModuleObject(module)).catch(() => {});
2871
3470
  }
2872
3471
  static ɵfac = i0.ɵɵngDeclareFactory({
2873
3472
  minVersion: "12.0.0",
@@ -2979,10 +3578,67 @@ i0.ɵɵngDeclareClassMetadata({
2979
3578
  args: [{ providedIn: "root" }]
2980
3579
  }]
2981
3580
  });
3581
+ const __workletMap = {};
3582
+ const __mainThreadRefMap = {};
3583
+ const __pendingResolvers = {};
3584
+ let __nextResolveId = 0;
3585
+ const nextResolveId = () => __nextResolveId++;
3586
+ const transform = (value, elements) => {
3587
+ if (typeof value !== "object" || value === null) return value;
3588
+ if (Array.isArray(value)) return value.map((item) => transform(item, elements));
3589
+ const obj = value;
3590
+ if (elements && "elementRefptr" in obj) return new MainThreadElement(obj["elementRefptr"]);
3591
+ if ("_wvid" in obj) return __mainThreadRefMap[obj["_wvid"]] ?? obj;
3592
+ const result = {};
3593
+ for (const key of Object.keys(obj)) result[key] = transform(obj[key], elements);
3594
+ return result;
3595
+ };
3596
+ const transformParams = (value) => transform(value, true);
3597
+ const restoreRefs = (value) => transform(value, false);
3598
+ const isThenable = (value) => typeof value?.then === "function";
3599
+ const errorText = (e) => e instanceof Error ? e.message : String(e);
3600
+ const answerCall = (resolveId, run, send) => {
3601
+ const reply = (result) => {
3602
+ let data;
3603
+ try {
3604
+ data = JSON.stringify({
3605
+ resolveId,
3606
+ ...result
3607
+ });
3608
+ } catch (e) {
3609
+ data = JSON.stringify({
3610
+ resolveId,
3611
+ error: `[angular-lynx] The return value can't be sent to the other thread: ${errorText(e)}`
3612
+ });
3613
+ }
3614
+ send(data);
3615
+ };
3616
+ let returnValue;
3617
+ try {
3618
+ returnValue = run();
3619
+ } catch (e) {
3620
+ reply({ error: errorText(e) });
3621
+ return;
3622
+ }
3623
+ if (isThenable(returnValue)) returnValue.then((value) => reply({ returnValue: value }), (e) => reply({ error: errorText(e) }));
3624
+ else reply({ returnValue });
3625
+ };
2982
3626
  let nextWorkletId = 0;
3627
+ const constructorDestroyRef = () => {
3628
+ try {
3629
+ return inject(DestroyRef);
3630
+ } catch {
3631
+ return null;
3632
+ }
3633
+ };
2983
3634
  const mainThreadFn = (fn) => {
2984
3635
  const id = "__angular_mts_" + nextWorkletId++;
2985
- if (__MAIN_THREAD__) globalThis.registerWorklet("main-thread", id, fn);
3636
+ if (__MAIN_THREAD__) {
3637
+ globalThis.registerWorklet("main-thread", id, fn);
3638
+ constructorDestroyRef()?.onDestroy(() => {
3639
+ delete __workletMap[id];
3640
+ });
3641
+ }
2986
3642
  return {
2987
3643
  _wkltId: id,
2988
3644
  _workletType: "main-thread",
@@ -2990,11 +3646,11 @@ const mainThreadFn = (fn) => {
2990
3646
  };
2991
3647
  };
2992
3648
  let nextBgWorkletId = 0;
2993
- const backgroundFn = (fn) => {
2994
- const id = "__angular_bg_" + nextBgWorkletId++;
2995
- if (!__MAIN_THREAD__) globalThis.registerWorklet("background", id, fn);
3649
+ const backgroundFn = (fn, id) => {
3650
+ const workletId = id ?? "__angular_bg_" + nextBgWorkletId++;
3651
+ if (!__MAIN_THREAD__) globalThis.registerWorklet("background", workletId, fn);
2996
3652
  return {
2997
- _wkltId: id,
3653
+ _wkltId: workletId,
2998
3654
  _workletType: "background",
2999
3655
  __isBackgroundFn: true
3000
3656
  };
@@ -3003,10 +3659,10 @@ let nextRefId = 0;
3003
3659
  var MainThreadRef = class {
3004
3660
  _wvid;
3005
3661
  #_value;
3006
- constructor(initValue) {
3007
- this._wvid = nextRefId++;
3662
+ constructor(initValue, id) {
3663
+ this._wvid = id ?? nextRefId++;
3008
3664
  this.#_value = initValue;
3009
- if (__MAIN_THREAD__) globalThis.__workletRefMap[this._wvid] = this;
3665
+ __mainThreadRefMap[this._wvid] = this;
3010
3666
  }
3011
3667
  get current() {
3012
3668
  return this.#_value;
@@ -3018,82 +3674,7 @@ var MainThreadRef = class {
3018
3674
  return { _wvid: this._wvid };
3019
3675
  }
3020
3676
  };
3021
- const createMainThreadRef = (initValue) => new MainThreadRef(initValue);
3022
- let willFlush = false;
3023
- const scheduleFlush = () => {
3024
- if (willFlush) return;
3025
- willFlush = true;
3026
- Promise.resolve().then(() => {
3027
- willFlush = false;
3028
- __FlushElementTree();
3029
- });
3030
- };
3031
- var MainThreadElement = class MainThreadElement {
3032
- #element;
3033
- constructor(element) {
3034
- this.#element = element;
3035
- }
3036
- setAttribute(name, value) {
3037
- __SetAttribute(this.#element, name, value);
3038
- scheduleFlush();
3039
- }
3040
- getAttribute(name) {
3041
- return __GetAttributeByName(this.#element, name);
3042
- }
3043
- getAttributeNames() {
3044
- return __GetAttributeNames(this.#element);
3045
- }
3046
- setStyleProperty(name, value) {
3047
- __AddInlineStyle(this.#element, name, value);
3048
- scheduleFlush();
3049
- }
3050
- setStyleProperties(styles) {
3051
- for (const key in styles) __AddInlineStyle(this.#element, key, styles[key]);
3052
- scheduleFlush();
3053
- }
3054
- querySelector(selector) {
3055
- const ref = __QuerySelector(this.#element, selector, {});
3056
- return ref ? new MainThreadElement(ref) : null;
3057
- }
3058
- querySelectorAll(selector) {
3059
- return __QuerySelectorAll(this.#element, selector, {}).map((el) => new MainThreadElement(el));
3060
- }
3061
- invoke(methodName, params) {
3062
- return new Promise((resolve, reject) => {
3063
- __InvokeUIMethod(this.#element, methodName, params ?? {}, (res) => {
3064
- if (res.code === 0) resolve(res.data);
3065
- else reject(/* @__PURE__ */ new Error("UI method invoke: " + JSON.stringify(res)));
3066
- });
3067
- scheduleFlush();
3068
- });
3069
- }
3070
- animate(keyframes, options) {
3071
- const normalizedOptions = typeof options === "number" ? { duration: options } : options ?? {};
3072
- return new LynxAnimation(this.#element, keyframes, normalizedOptions);
3073
- }
3074
- getBoundingClientRect() {
3075
- if (typeof __GetComputedStyleByKey !== "function") return {
3076
- left: 0,
3077
- top: 0,
3078
- right: 0,
3079
- bottom: 0,
3080
- width: 0,
3081
- height: 0
3082
- };
3083
- const width = parseFloat(__GetComputedStyleByKey(this.#element, "width")) || 0;
3084
- const height = parseFloat(__GetComputedStyleByKey(this.#element, "height")) || 0;
3085
- const left = parseFloat(__GetComputedStyleByKey(this.#element, "left")) || 0;
3086
- const top = parseFloat(__GetComputedStyleByKey(this.#element, "top")) || 0;
3087
- return {
3088
- left,
3089
- top,
3090
- right: left + width,
3091
- bottom: top + height,
3092
- width,
3093
- height
3094
- };
3095
- }
3096
- };
3677
+ const createMainThreadRef = (initValue, id) => new MainThreadRef(initValue, id);
3097
3678
  const INPUT_TO_EVENT = {
3098
3679
  mainThreadBindtap: ["bindEvent", "tap"],
3099
3680
  mainThreadCatchtap: ["catchEvent", "tap"],
@@ -3103,6 +3684,12 @@ const INPUT_TO_EVENT = {
3103
3684
  mainThreadCatchtouchmove: ["catchEvent", "touchmove"],
3104
3685
  mainThreadBindtouchend: ["bindEvent", "touchend"],
3105
3686
  mainThreadCatchtouchend: ["catchEvent", "touchend"],
3687
+ mainThreadBindmousedown: ["bindEvent", "mousedown"],
3688
+ mainThreadCatchmousedown: ["catchEvent", "mousedown"],
3689
+ mainThreadBindmousemove: ["bindEvent", "mousemove"],
3690
+ mainThreadCatchmousemove: ["catchEvent", "mousemove"],
3691
+ mainThreadBindmouseup: ["bindEvent", "mouseup"],
3692
+ mainThreadCatchmouseup: ["catchEvent", "mouseup"],
3106
3693
  mainThreadBindlongpress: ["bindEvent", "longpress"],
3107
3694
  mainThreadCatchlongpress: ["catchEvent", "longpress"],
3108
3695
  mainThreadBindscroll: ["bindEvent", "scroll"],
@@ -3113,9 +3700,14 @@ const INPUT_TO_EVENT = {
3113
3700
  mainThreadBindlayoutchange: ["bindEvent", "layoutchange"]
3114
3701
  };
3115
3702
  const isMainThreadHandle = (h) => !!h && "__isMainThreadFn" in h && !!h.__isMainThreadFn;
3703
+ let nextHandlerId = 0;
3704
+ const noHandler = () => ({
3705
+ type: "worklet",
3706
+ value: { _workletType: "main-thread" }
3707
+ });
3116
3708
  var LynxMainThreadEvent = class LynxMainThreadEvent {
3117
3709
  #el = inject(ElementRef).nativeElement;
3118
- #registeredEvents = [];
3710
+ #registrations = /* @__PURE__ */ new Map();
3119
3711
  mainThreadBindtap;
3120
3712
  mainThreadCatchtap;
3121
3713
  mainThreadBindtouchstart;
@@ -3124,6 +3716,12 @@ var LynxMainThreadEvent = class LynxMainThreadEvent {
3124
3716
  mainThreadCatchtouchmove;
3125
3717
  mainThreadBindtouchend;
3126
3718
  mainThreadCatchtouchend;
3719
+ mainThreadBindmousedown;
3720
+ mainThreadCatchmousedown;
3721
+ mainThreadBindmousemove;
3722
+ mainThreadCatchmousemove;
3723
+ mainThreadBindmouseup;
3724
+ mainThreadCatchmouseup;
3127
3725
  mainThreadBindlongpress;
3128
3726
  mainThreadCatchlongpress;
3129
3727
  mainThreadBindscroll;
@@ -3140,23 +3738,44 @@ var LynxMainThreadEvent = class LynxMainThreadEvent {
3140
3738
  if (!mapping) continue;
3141
3739
  const [eventType, eventName] = mapping;
3142
3740
  const handle = this[inputName];
3143
- if (isMainThreadHandle(handle)) {
3144
- __AddEvent(elementRef, eventType, eventName, {
3145
- type: "worklet",
3146
- value: {
3147
- _wkltId: handle._wkltId,
3148
- _workletType: "main-thread"
3149
- }
3150
- });
3151
- this.#registeredEvents.push([eventType, eventName]);
3741
+ this.#release(inputName);
3742
+ const registration = {
3743
+ eventType,
3744
+ eventName
3745
+ };
3746
+ let workletId;
3747
+ if (isMainThreadHandle(handle)) workletId = handle._wkltId;
3748
+ else if (typeof handle === "function") {
3749
+ workletId = "__angular_mts_handler_" + nextHandlerId++;
3750
+ registration.ownId = workletId;
3751
+ __workletMap[workletId] = handle;
3752
+ }
3753
+ if (workletId === void 0) {
3754
+ if (this.#registrations.delete(inputName)) __AddEvent(elementRef, eventType, eventName, noHandler());
3755
+ continue;
3152
3756
  }
3757
+ __AddEvent(elementRef, eventType, eventName, {
3758
+ type: "worklet",
3759
+ value: {
3760
+ _wkltId: workletId,
3761
+ _workletType: "main-thread"
3762
+ }
3763
+ });
3764
+ this.#registrations.set(inputName, registration);
3153
3765
  }
3154
3766
  }
3155
3767
  ngOnDestroy() {
3156
3768
  const elementRef = this.#el.element;
3157
3769
  if (!elementRef) return;
3158
- for (const [eventType, eventName] of this.#registeredEvents) __AddEvent(elementRef, eventType, eventName, void 0);
3159
- this.#registeredEvents = [];
3770
+ for (const [inputName, { eventType, eventName }] of this.#registrations) {
3771
+ __AddEvent(elementRef, eventType, eventName, noHandler());
3772
+ this.#release(inputName);
3773
+ }
3774
+ this.#registrations.clear();
3775
+ }
3776
+ #release(inputName) {
3777
+ const ownId = this.#registrations.get(inputName)?.ownId;
3778
+ if (ownId !== void 0) delete __workletMap[ownId];
3160
3779
  }
3161
3780
  static ɵfac = i0.ɵɵngDeclareFactory({
3162
3781
  minVersion: "12.0.0",
@@ -3171,7 +3790,7 @@ var LynxMainThreadEvent = class LynxMainThreadEvent {
3171
3790
  version: "22.2.1",
3172
3791
  type: LynxMainThreadEvent,
3173
3792
  isStandalone: true,
3174
- selector: "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]",
3793
+ selector: "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindmousedown],[mainThreadCatchmousedown],[mainThreadBindmousemove],[mainThreadCatchmousemove],[mainThreadBindmouseup],[mainThreadCatchmouseup],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]",
3175
3794
  inputs: {
3176
3795
  mainThreadBindtap: "mainThreadBindtap",
3177
3796
  mainThreadCatchtap: "mainThreadCatchtap",
@@ -3181,6 +3800,12 @@ var LynxMainThreadEvent = class LynxMainThreadEvent {
3181
3800
  mainThreadCatchtouchmove: "mainThreadCatchtouchmove",
3182
3801
  mainThreadBindtouchend: "mainThreadBindtouchend",
3183
3802
  mainThreadCatchtouchend: "mainThreadCatchtouchend",
3803
+ mainThreadBindmousedown: "mainThreadBindmousedown",
3804
+ mainThreadCatchmousedown: "mainThreadCatchmousedown",
3805
+ mainThreadBindmousemove: "mainThreadBindmousemove",
3806
+ mainThreadCatchmousemove: "mainThreadCatchmousemove",
3807
+ mainThreadBindmouseup: "mainThreadBindmouseup",
3808
+ mainThreadCatchmouseup: "mainThreadCatchmouseup",
3184
3809
  mainThreadBindlongpress: "mainThreadBindlongpress",
3185
3810
  mainThreadCatchlongpress: "mainThreadCatchlongpress",
3186
3811
  mainThreadBindscroll: "mainThreadBindscroll",
@@ -3202,8 +3827,7 @@ i0.ɵɵngDeclareClassMetadata({
3202
3827
  decorators: [{
3203
3828
  type: Directive,
3204
3829
  args: [{
3205
- selector: "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]",
3206
- standalone: true,
3830
+ selector: "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindmousedown],[mainThreadCatchmousedown],[mainThreadBindmousemove],[mainThreadCatchmousemove],[mainThreadBindmouseup],[mainThreadCatchmouseup],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]",
3207
3831
  inputs: [
3208
3832
  "mainThreadBindtap",
3209
3833
  "mainThreadCatchtap",
@@ -3213,6 +3837,12 @@ i0.ɵɵngDeclareClassMetadata({
3213
3837
  "mainThreadCatchtouchmove",
3214
3838
  "mainThreadBindtouchend",
3215
3839
  "mainThreadCatchtouchend",
3840
+ "mainThreadBindmousedown",
3841
+ "mainThreadCatchmousedown",
3842
+ "mainThreadBindmousemove",
3843
+ "mainThreadCatchmousemove",
3844
+ "mainThreadBindmouseup",
3845
+ "mainThreadCatchmouseup",
3216
3846
  "mainThreadBindlongpress",
3217
3847
  "mainThreadCatchlongpress",
3218
3848
  "mainThreadBindscroll",
@@ -3227,42 +3857,13 @@ i0.ɵɵngDeclareClassMetadata({
3227
3857
  });
3228
3858
  var LynxMainThread = class LynxMainThread {
3229
3859
  runOnMainThread(handle, ...args) {
3230
- if (__MAIN_THREAD__) {
3231
- const invokeDirect = globalThis.__lynxRunMainThreadWorklet;
3232
- if (!invokeDirect) return Promise.reject(/* @__PURE__ */ new Error("[angular-lynx] runOnMainThread() called on the main thread before the runtime worklet registry was initialized"));
3233
- try {
3234
- return Promise.resolve(invokeDirect(handle._wkltId, args));
3235
- } catch (e) {
3236
- return Promise.reject(e);
3237
- }
3238
- }
3239
- /* v8 ignore next 9 */
3240
- if (__DEV__) try {
3241
- JSON.stringify(args);
3242
- } catch {
3243
- throw new Error("[angular-lynx] MTS arguments must be JSON-serializable");
3860
+ const invokeDirect = globalThis.__lynxRunMainThreadWorklet;
3861
+ if (!invokeDirect) return Promise.reject(/* @__PURE__ */ new Error("[angular-lynx] runOnMainThread() called before the runtime worklet registry was initialized"));
3862
+ try {
3863
+ return Promise.resolve(invokeDirect(handle._wkltId, args));
3864
+ } catch (e) {
3865
+ return Promise.reject(e);
3244
3866
  }
3245
- const resolveId = globalThis.__lynxMtsNextResolveId();
3246
- const pendingResolvers = globalThis.__lynxMtsPendingResolvers;
3247
- return new Promise((resolve, reject) => {
3248
- pendingResolvers[resolveId] = {
3249
- resolve,
3250
- reject
3251
- };
3252
- try {
3253
- lynx.getCoreContext().dispatchEvent({
3254
- type: "Lynx.Worklet.runWorkletCtx",
3255
- data: JSON.stringify({
3256
- worklet: { _wkltId: handle._wkltId },
3257
- params: args,
3258
- resolveId
3259
- })
3260
- });
3261
- } catch (e) {
3262
- delete pendingResolvers[resolveId];
3263
- reject(e);
3264
- }
3265
- });
3266
3867
  }
3267
3868
  static ɵfac = i0.ɵɵngDeclareFactory({
3268
3869
  minVersion: "12.0.0",
@@ -3292,18 +3893,10 @@ i0.ɵɵngDeclareClassMetadata({
3292
3893
  });
3293
3894
  var LynxResourcePrefetch = class LynxResourcePrefetch {
3294
3895
  request(resources) {
3295
- if (typeof lynx === "undefined" || !lynx.requestResourcePrefetch) return Promise.reject(/* @__PURE__ */ new Error("lynx.requestResourcePrefetch is not available in this environment"));
3296
- const data = this.#toNativeData(resources);
3297
- return new Promise((resolve) => {
3298
- lynx.requestResourcePrefetch(data, resolve);
3299
- });
3896
+ return callOnBackground("requestResourcePrefetch", this.#toNativeData(resources));
3300
3897
  }
3301
3898
  cancel(resources) {
3302
- if (typeof lynx === "undefined" || !lynx.cancelResourcePrefetch) return Promise.reject(/* @__PURE__ */ new Error("lynx.cancelResourcePrefetch is not available in this environment"));
3303
- const data = this.#toNativeData(resources);
3304
- return new Promise((resolve) => {
3305
- lynx.cancelResourcePrefetch(data, resolve);
3306
- });
3899
+ return callOnBackground("cancelResourcePrefetch", this.#toNativeData(resources));
3307
3900
  }
3308
3901
  #toNativeData(resources) {
3309
3902
  return { data: resources.map((r) => {
@@ -3352,8 +3945,9 @@ i0.ɵɵngDeclareClassMetadata({
3352
3945
  var LynxSystemInfo = class LynxSystemInfo {
3353
3946
  #info;
3354
3947
  constructor() {
3355
- if (typeof SystemInfo === "undefined") throw new Error("SystemInfo is not available in this environment");
3356
- this.#info = SystemInfo;
3948
+ const info = (typeof lynx !== "undefined" ? lynx.SystemInfo : void 0) ?? (typeof SystemInfo !== "undefined" ? SystemInfo : void 0);
3949
+ if (!info) throw new Error("SystemInfo is not available in this environment");
3950
+ this.#info = info;
3357
3951
  }
3358
3952
  get platform() {
3359
3953
  return this.#info.platform;
@@ -3418,10 +4012,10 @@ const SAFE_AREA_INSET_LEFT = "env(safe-area-inset-left)";
3418
4012
  const SAFE_AREA_INSET_RIGHT = "env(safe-area-inset-right)";
3419
4013
  var LynxSafeArea = class LynxSafeArea {
3420
4014
  #globalData = inject(LynxGlobalData);
3421
- #systemInfo = inject(LynxSystemInfo);
4015
+ #injector = inject(Injector);
3422
4016
  isNotchScreen = computed(() => !!this.#globalData.globalData()["isNotchScreen"], ...ngDevMode ? [{ debugName: "isNotchScreen" }] : /* istanbul ignore next */ []);
3423
4017
  get platform() {
3424
- return this.#systemInfo.platform;
4018
+ return this.#injector.get(LynxSystemInfo).platform;
3425
4019
  }
3426
4020
  static ɵfac = i0.ɵɵngDeclareFactory({
3427
4021
  minVersion: "12.0.0",
@@ -3453,11 +4047,18 @@ var LynxSessionStorage = class LynxSessionStorage {
3453
4047
  #store = /* @__PURE__ */ new Map();
3454
4048
  #listeners = /* @__PURE__ */ new Map();
3455
4049
  #nextId = 0;
4050
+ #relayIds = /* @__PURE__ */ new Map();
3456
4051
  #hasNativeSessionStorage() {
3457
- return typeof lynx !== "undefined" && typeof lynx.setSessionStorageItem === "function";
4052
+ return typeof lynx !== "undefined" && typeof lynx.setSessionStorageItem === "function" && !(typeof SystemInfo !== "undefined" && SystemInfo.platform === "web");
3458
4053
  }
3459
4054
  #hasNativeSubscription() {
3460
- return this.#hasNativeSessionStorage() && !(typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__);
4055
+ return this.#hasNativeSessionStorage() && !this.#isMainThread();
4056
+ }
4057
+ #isMainThread() {
4058
+ return typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__;
4059
+ }
4060
+ #unwrap(raw) {
4061
+ return raw != null && typeof raw === "object" && "__data" in raw && Object.keys(raw).length === 1 ? raw.__data : raw;
3461
4062
  }
3462
4063
  #notifyLocalListeners(key, value) {
3463
4064
  const keyListeners = this.#listeners.get(key);
@@ -3465,7 +4066,7 @@ var LynxSessionStorage = class LynxSessionStorage {
3465
4066
  }
3466
4067
  setItem(key, value) {
3467
4068
  if (this.#hasNativeSessionStorage()) {
3468
- if (typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__) {
4069
+ if (this.#isMainThread()) {
3469
4070
  const wrapped = typeof value === "object" && value !== null ? value : { __data: value };
3470
4071
  lynx.setSessionStorageItem(key, wrapped);
3471
4072
  this.#notifyLocalListeners(key, value);
@@ -3479,13 +4080,9 @@ var LynxSessionStorage = class LynxSessionStorage {
3479
4080
  }
3480
4081
  getItem(key) {
3481
4082
  if (this.#hasNativeSessionStorage()) {
3482
- if (typeof __MAIN_THREAD__ !== "undefined" && __MAIN_THREAD__) {
3483
- const raw = lynx.getSessionStorageItem(key);
3484
- const unwrapped = raw != null && typeof raw === "object" && "__data" in raw && Object.keys(raw).length === 1 ? raw.__data : raw;
3485
- return Promise.resolve(unwrapped);
3486
- }
4083
+ if (this.#isMainThread()) return Promise.resolve(this.#unwrap(lynx.getSessionStorageItem(key)));
3487
4084
  return new Promise((resolve) => {
3488
- lynx.getSessionStorageItem(key, (value) => resolve(value));
4085
+ lynx.getSessionStorageItem(key, (value) => resolve(this.#unwrap(value)));
3489
4086
  });
3490
4087
  }
3491
4088
  return Promise.resolve(this.#store.get(key));
@@ -3493,7 +4090,7 @@ var LynxSessionStorage = class LynxSessionStorage {
3493
4090
  subscribe(key, callback) {
3494
4091
  if (this.#hasNativeSubscription()) return {
3495
4092
  key,
3496
- listenerId: lynx.subscribeSessionStorage(key, callback)
4093
+ listenerId: lynx.subscribeSessionStorage(key, (value) => callback(this.#unwrap(value)))
3497
4094
  };
3498
4095
  const id = this.#nextId++;
3499
4096
  let keyListeners = this.#listeners.get(key);
@@ -3502,6 +4099,7 @@ var LynxSessionStorage = class LynxSessionStorage {
3502
4099
  this.#listeners.set(key, keyListeners);
3503
4100
  }
3504
4101
  keyListeners.set(id, callback);
4102
+ if (this.#isMainThread() && this.#hasNativeSessionStorage()) this.#relayIds.set(id, subscribeSessionStorageFromMainThread(key, (value) => callback(this.#unwrap(value))));
3505
4103
  return {
3506
4104
  key,
3507
4105
  listenerId: id
@@ -3513,6 +4111,11 @@ var LynxSessionStorage = class LynxSessionStorage {
3513
4111
  return;
3514
4112
  }
3515
4113
  this.#listeners.get(subscription.key)?.delete(subscription.listenerId);
4114
+ const relayId = this.#relayIds.get(subscription.listenerId);
4115
+ if (relayId !== void 0) {
4116
+ this.#relayIds.delete(subscription.listenerId);
4117
+ unsubscribeSessionStorageFromMainThread(relayId);
4118
+ }
3516
4119
  }
3517
4120
  watch(key, options) {
3518
4121
  const value = signal(void 0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
@@ -3549,7 +4152,7 @@ i0.ɵɵngDeclareClassMetadata({
3549
4152
  });
3550
4153
  var LynxTextMeasure = class LynxTextMeasure {
3551
4154
  measure(text, options) {
3552
- if (typeof lynx === "undefined") throw new Error("lynx.getTextInfo is not available in this environment");
4155
+ if (typeof lynx === "undefined" || typeof lynx.getTextInfo !== "function") throw new Error("lynx.getTextInfo is not available in this environment");
3553
4156
  if (!text) return { width: 0 };
3554
4157
  return lynx.getTextInfo(text, options);
3555
4158
  }
@@ -3726,7 +4329,6 @@ i0.ɵɵngDeclareClassMetadata({
3726
4329
  type: Component,
3727
4330
  args: [{
3728
4331
  selector: "lynx-transition",
3729
- standalone: true,
3730
4332
  template: `@if (shouldRender()) {
3731
4333
  <ng-content />
3732
4334
  }`
@@ -4003,7 +4605,6 @@ i0.ɵɵngDeclareClassMetadata({
4003
4605
  type: Component,
4004
4606
  args: [{
4005
4607
  selector: "lynx-transition-group",
4006
- standalone: true,
4007
4608
  template: `<ng-template #anchor />`
4008
4609
  }]
4009
4610
  }],
@@ -4062,186 +4663,18 @@ i0.ɵɵngDeclareClassMetadata({
4062
4663
  }]
4063
4664
  }
4064
4665
  });
4065
- var NoopLynxAnimation = class NoopLynxAnimation {
4066
- static #count = 0;
4067
- id;
4068
- constructor() {
4069
- this.id = `__lynx-angular-noop-animation-${NoopLynxAnimation.#count++}`;
4070
- }
4071
- play() {}
4072
- pause() {}
4073
- cancel() {}
4074
- };
4075
- var LynxBackgroundElement = class {
4076
- isRootPageElement = false;
4077
- tagName = "";
4078
- #props = /* @__PURE__ */ new Map();
4079
- #styles = /* @__PURE__ */ new Map();
4080
- #classes = /* @__PURE__ */ new Set();
4081
- #events = /* @__PURE__ */ new Map();
4082
- #parent = null;
4083
- #firstChild = null;
4084
- #lastChild = null;
4085
- #previousSibling = null;
4086
- #nextSibling = null;
4087
- setProperty(name, value) {
4088
- this.#props.set(name, value);
4089
- }
4090
- setAttribute(name, value) {
4091
- this.#props.set(name, value);
4092
- }
4093
- getAttribute(name) {
4094
- return this.#props.get(name) ?? null;
4095
- }
4096
- removeAttribute(name) {
4097
- this.#props.delete(name);
4098
- }
4099
- setStyle(key, value) {
4100
- this.#styles.set(key, value);
4101
- }
4102
- removeStyle(key) {
4103
- this.#styles.delete(key);
4104
- }
4105
- setInlineStyles(inlineStyle) {
4106
- const styles = inlineStyle.split(";").map((s) => s.trim()).filter((s) => s.length > 0);
4107
- for (const s of styles) {
4108
- const [key, value] = s.split(":").map((s) => s.trim());
4109
- this.setStyle(key, value);
4110
- }
4111
- }
4112
- insertBefore(newChild, refChild) {
4113
- if (newChild.isRootPageElement) return;
4114
- if (refChild == null) {
4115
- this.appendChild(newChild);
4116
- return;
4117
- }
4118
- if (!refChild.#previousSibling) this.#firstChild = newChild;
4119
- else refChild.#previousSibling.#nextSibling = newChild;
4120
- newChild.#previousSibling = refChild.#previousSibling;
4121
- refChild.#previousSibling = newChild;
4122
- newChild.#nextSibling = refChild;
4123
- newChild.#parent = this;
4124
- }
4125
- appendChild(newChild) {
4126
- if (newChild.isRootPageElement) return;
4127
- if (!this.#firstChild) {
4128
- this.#firstChild = newChild;
4129
- this.#lastChild = newChild;
4130
- } else {
4131
- /* v8 ignore next 5 */
4132
- if (!this.#lastChild) throw new Error("Invariant violation: lastChild is null while firstChild is not null.");
4133
- this.#lastChild.#nextSibling = newChild;
4134
- newChild.#previousSibling = this.#lastChild;
4135
- this.#lastChild = newChild;
4136
- }
4137
- newChild.#parent = this;
4138
- }
4139
- addClass(name) {
4140
- this.#classes.add(name);
4141
- }
4142
- removeClass(name) {
4143
- this.#classes.delete(name);
4144
- }
4145
- remove() {
4146
- if (this.isRootPageElement) return;
4147
- if (!this.#parent) return;
4148
- if (this.#previousSibling) this.#previousSibling.#nextSibling = this.#nextSibling;
4149
- else this.#parent.#firstChild = this.#nextSibling;
4150
- if (this.#nextSibling) this.#nextSibling.#previousSibling = this.#previousSibling;
4151
- else this.#parent.#lastChild = this.#previousSibling;
4152
- this.#nextSibling = null;
4153
- this.#previousSibling = null;
4154
- this.#parent = null;
4155
- }
4156
- parentNode() {
4157
- return this.#parent;
4158
- }
4159
- nextSibling() {
4160
- return this.#nextSibling;
4161
- }
4162
- querySelector(selector) {
4163
- let child = this.#firstChild;
4164
- while (child) {
4165
- if (child.#matchesSelector(selector)) return child;
4166
- const found = child.querySelector(selector);
4167
- if (found) return found;
4168
- child = child.#nextSibling;
4169
- }
4170
- return null;
4171
- }
4172
- querySelectorAll(selector) {
4173
- const results = [];
4174
- this.#collectMatches(selector, results);
4175
- return results;
4176
- }
4177
- #collectMatches(selector, results) {
4178
- let child = this.#firstChild;
4179
- while (child) {
4180
- if (child.#matchesSelector(selector)) results.push(child);
4181
- child.#collectMatches(selector, results);
4182
- child = child.#nextSibling;
4183
- }
4184
- }
4185
- #matchesSelector(selector) {
4186
- let remaining = selector.trim();
4187
- if (/[\s>~+]/.test(remaining)) return false;
4188
- let tagName = null;
4189
- const classes = [];
4190
- const attrs = [];
4191
- const tagMatch = remaining.match(/^([a-zA-Z][a-zA-Z0-9_-]*)/);
4192
- if (tagMatch) {
4193
- tagName = tagMatch[1];
4194
- remaining = remaining.slice(tagMatch[0].length);
4195
- }
4196
- while (remaining.length > 0) {
4197
- const classMatch = remaining.match(/^\.([a-zA-Z0-9_-]+)/);
4198
- if (classMatch) {
4199
- classes.push(classMatch[1]);
4200
- remaining = remaining.slice(classMatch[0].length);
4201
- continue;
4202
- }
4203
- const idMatch = remaining.match(/^#([a-zA-Z0-9_-]+)/);
4204
- if (idMatch) {
4205
- attrs.push(["id", idMatch[1]]);
4206
- remaining = remaining.slice(idMatch[0].length);
4207
- continue;
4208
- }
4209
- const attrMatch = remaining.match(/^\[([a-zA-Z0-9_-]+)(?:=["']?([^"'\]]*)["']?)?\]/);
4210
- if (attrMatch) {
4211
- attrs.push([attrMatch[1], attrMatch[2] ?? null]);
4212
- remaining = remaining.slice(attrMatch[0].length);
4213
- continue;
4214
- }
4215
- return false;
4216
- }
4217
- if (!tagName && classes.length === 0 && attrs.length === 0) return false;
4218
- if (tagName && this.#props.get("tagName") !== tagName) return false;
4219
- for (const cls of classes) if (!this.#classes.has(cls)) return false;
4220
- for (const [attr, value] of attrs) {
4221
- const stored = this.#props.get(attr);
4222
- if (value === null) {
4223
- if (stored === void 0 || stored === null) return false;
4224
- } else if (String(stored) !== value) return false;
4225
- }
4226
- return true;
4227
- }
4228
- animate(_keyframes, _options) {
4229
- /* v8 ignore next 6 -- build-time __DEV__ define is false in vitest, so the guarded warn is dead code from the test bundle's point of view. */
4230
- if (__DEV__) console.warn("[angular-lynx] animate() called on background thread — animation will not play. Use a main-thread script for imperative animations.");
4231
- return new NoopLynxAnimation();
4232
- }
4233
- addEventListener(name, cb) {
4234
- this.#events.set(name, cb);
4235
- return () => {
4236
- this.#events.delete(name);
4237
- };
4238
- }
4239
- };
4240
4666
  const createBlockElement = (pageId) => {
4241
4667
  return __CreateWrapperElement(pageId);
4242
4668
  };
4669
+ const ANDROID_BLUR_CAPTURE_TARGET = "angular-lynx-page";
4670
+ const isAndroid = () => {
4671
+ return ((typeof lynx !== "undefined" ? lynx.SystemInfo : void 0) ?? (typeof SystemInfo !== "undefined" ? SystemInfo : void 0))?.platform === "Android";
4672
+ };
4243
4673
  const createBlurViewElement = (pageId) => {
4244
- return __CreateElement("blur-view", pageId);
4674
+ const element = __CreateElement("blur-view", pageId);
4675
+ if (!__WEB__ && isAndroid()) __SetAttribute(element, "android-capture-target", ANDROID_BLUR_CAPTURE_TARGET);
4676
+ if (__WEB__ && __MAIN_THREAD__) import("./blotch-angular-lynx-web-glass-8MFrhPz0.mjs").then(({ attachWebGlass }) => attachWebGlass(element)).catch(() => {});
4677
+ return element;
4245
4678
  };
4246
4679
  const createCommentElement = (pageId) => {
4247
4680
  const element = __CreateView(pageId);
@@ -4265,22 +4698,13 @@ const createIfElement = (pageId) => {
4265
4698
  return __CreateElement("if", pageId);
4266
4699
  };
4267
4700
  const createImageElement = (pageId) => {
4268
- const element = __CreateImage(pageId);
4269
- __SetConfig(element, {
4270
- mode: "aspectFit",
4271
- fadeIn: true,
4272
- loadingPlaceholder: ""
4273
- });
4274
- return element;
4701
+ return __CreateImage(pageId);
4275
4702
  };
4276
4703
  const createInlineTruncationElement = (pageId) => {
4277
4704
  return __CreateElement("inline-truncation", pageId);
4278
4705
  };
4279
4706
  const createInputElement = (tag, pageId) => {
4280
- const element = __CreateElement(tag, pageId);
4281
- __AddInlineStyle(element, "height", tag === "textarea" ? "80px" : "40px");
4282
- __AddInlineStyle(element, "border", "1px solid");
4283
- return element;
4707
+ return __CreateElement(tag, pageId);
4284
4708
  };
4285
4709
  const createListItemElement = (pageId) => {
4286
4710
  return __CreateElement("list-item", pageId);
@@ -4374,11 +4798,51 @@ const createNativeRefByTag = (tag, pageId, text) => {
4374
4798
  default: return createDefaultElement(tag, pageId);
4375
4799
  }
4376
4800
  };
4801
+ const BLUR_BACKGROUND_VARIABLE = "--angular-lynx-blur-background";
4802
+ const BLUR_BACKGROUND_IMAGE_VARIABLE = "--angular-lynx-blur-background-image";
4803
+ const BLUR_BOX_SHADOW_VARIABLE = "--angular-lynx-blur-box-shadow";
4804
+ const BLUR_MATERIAL_ATTRIBUTES = /* @__PURE__ */ new Set([
4805
+ "blur-effect",
4806
+ "blur-radius",
4807
+ "glass-style",
4808
+ "glass-tint-color"
4809
+ ]);
4810
+ const MATERIAL_BACKGROUNDS = {
4811
+ light: "rgba(255, 255, 255, 0.3)",
4812
+ "extra-light": "rgba(255, 255, 255, 0.75)",
4813
+ dark: "rgba(0, 0, 0, 0.6)"
4814
+ };
4815
+ const GLASS_SHEEN = "rgba(255, 255, 255, 0.3)";
4816
+ const CLEAR_GLASS_SHEEN = "rgba(255, 255, 255, 0.1)";
4817
+ const GLASS_RIM = "inset 0 1px 0 rgba(255, 255, 255, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.12)";
4818
+ const usesAndroidBlurMaterials = () => !__WEB__ && isAndroid();
4819
+ const declarations = (background, { image = "none", boxShadow = "none" } = {}) => `${BLUR_BACKGROUND_VARIABLE}: ${background}; ${BLUR_BACKGROUND_IMAGE_VARIABLE}: ${image}; ${BLUR_BOX_SHADOW_VARIABLE}: ${boxShadow}`;
4820
+ const androidBlurMaterialStyle = (attrs) => {
4821
+ const effect = attrs.get("blur-effect") ?? "light";
4822
+ if (effect === "glass") {
4823
+ const tint = attrs.get("glass-tint-color");
4824
+ return declarations(attrs.get("glass-style") === "clear" ? CLEAR_GLASS_SHEEN : GLASS_SHEEN, {
4825
+ image: typeof tint === "string" && tint !== "" && tint !== "transparent" ? `linear-gradient(${tint}, ${tint})` : "none",
4826
+ boxShadow: GLASS_RIM
4827
+ });
4828
+ }
4829
+ if (effect === "glass-container" || !parseFloat(String(attrs.get("blur-radius") ?? ""))) return declarations("transparent");
4830
+ return declarations(MATERIAL_BACKGROUNDS[String(effect)] ?? MATERIAL_BACKGROUNDS["light"]);
4831
+ };
4377
4832
  let __pageElementRef = null;
4378
4833
  const setPageElementRef = (ref) => {
4379
4834
  __pageElementRef = ref;
4380
4835
  };
4381
4836
  const getPageId = () => __pageElementRef ? __GetElementUniqueID(__pageElementRef) : 0;
4837
+ let handingOverPage = false;
4838
+ const handOverPageToNextApp = () => {
4839
+ handingOverPage = true;
4840
+ };
4841
+ const takePageHandOver = () => {
4842
+ const handing = handingOverPage;
4843
+ handingOverPage = false;
4844
+ return handing;
4845
+ };
4382
4846
  let firstRenderPending = true;
4383
4847
  const deferredCallbacks = [];
4384
4848
  const isFirstRenderPending = () => firstRenderPending;
@@ -4402,6 +4866,24 @@ const setInsideChangeDetection = (value) => {
4402
4866
  insideChangeDetection = value;
4403
4867
  };
4404
4868
  const isInsideChangeDetection = () => insideChangeDetection;
4869
+ const DASHARRAY_ATTRIBUTE = /(\s)stroke-dasharray\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
4870
+ const DASHARRAY_DECLARATION = /(^|[;"'\s])stroke-dasharray\s*:\s*([^;"']*);?/g;
4871
+ const DASH_LENGTH = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(?:px)?$/i;
4872
+ const normalizeDashArray = (value) => {
4873
+ const tokens = value.trim().split(/[\s,]+/).filter((token) => token.length > 0);
4874
+ if (tokens.length === 0 || !tokens.every((t) => DASH_LENGTH.test(t))) return null;
4875
+ return tokens.map((token) => token.replace(/px$/i, "")).join(" ");
4876
+ };
4877
+ const sanitizeSvgContent = (content) => {
4878
+ if (!content.includes("stroke-dasharray")) return content;
4879
+ return content.replace(DASHARRAY_ATTRIBUTE, (_match, space, double, single) => {
4880
+ const normalized = normalizeDashArray(double ?? single);
4881
+ return normalized === null ? "" : `${space}stroke-dasharray="${normalized}"`;
4882
+ }).replace(DASHARRAY_DECLARATION, (_match, before, value) => {
4883
+ const normalized = normalizeDashArray(value);
4884
+ return normalized === null ? before : `${before}stroke-dasharray:${normalized};`;
4885
+ });
4886
+ };
4405
4887
  const EVENT_PREFIXES = [
4406
4888
  ["capture-bind", "capture-bindEvent"],
4407
4889
  ["capture-catch", "capture-catchEvent"],
@@ -4426,13 +4908,15 @@ var LynxElement = class {
4426
4908
  _virtualParent = null;
4427
4909
  _virtualPrev = null;
4428
4910
  _virtualNext = null;
4429
- #activeAnimationIds = [];
4911
+ #activeAnimations = [];
4430
4912
  #attrs = /* @__PURE__ */ new Map();
4431
4913
  #id = null;
4432
4914
  #dataset = {};
4433
4915
  #classes = "";
4916
+ #scopeClasses = [];
4434
4917
  #inlineStyleWhole = null;
4435
4918
  #inlineStyleKeys = /* @__PURE__ */ new Map();
4919
+ #runtimeStyle = "";
4436
4920
  #listeners = [];
4437
4921
  #text;
4438
4922
  #rawText;
@@ -4468,8 +4952,9 @@ var LynxElement = class {
4468
4952
  }
4469
4953
  setAttribute(name, value) {
4470
4954
  if (name === "class") {
4471
- __SetClasses(this.element, value ?? "");
4472
- this.#classes = value ?? "";
4955
+ const classes = [.../* @__PURE__ */ new Set([...String(value ?? "").split(/\s+/).filter(Boolean), ...this.#scopeClasses])].join(" ");
4956
+ __SetClasses(this.element, classes);
4957
+ this.#classes = classes;
4473
4958
  } else if (name === "style") this.setInlineStyles(value);
4474
4959
  else if (name === "id") {
4475
4960
  __SetID(this.element, value);
@@ -4481,6 +4966,7 @@ var LynxElement = class {
4481
4966
  __SetDataset(this.element, data);
4482
4967
  this.#dataset[key] = value;
4483
4968
  } else {
4969
+ if (this.tagName === "svg" && name === "content" && typeof value === "string") value = sanitizeSvgContent(value);
4484
4970
  __SetAttribute(this.element, name, value);
4485
4971
  if (value == null) this.#attrs.delete(name);
4486
4972
  else this.#attrs.set(name, value);
@@ -4490,8 +4976,12 @@ var LynxElement = class {
4490
4976
  this.#rawText = text;
4491
4977
  _a.#enqueueTextNormalization(this);
4492
4978
  }
4979
+ if (this.tagName === "blur-view" && BLUR_MATERIAL_ATTRIBUTES.has(name)) this.updateBlurMaterial();
4493
4980
  }
4494
4981
  }
4982
+ updateBlurMaterial() {
4983
+ if (usesAndroidBlurMaterials()) this.#setRuntimeStyle(androidBlurMaterialStyle(this.#attrs));
4984
+ }
4495
4985
  getAttribute(name) {
4496
4986
  return __GetAttributeByName(this.element, name);
4497
4987
  }
@@ -4507,9 +4997,19 @@ var LynxElement = class {
4507
4997
  this.#inlineStyleKeys.delete(key);
4508
4998
  }
4509
4999
  setInlineStyles(inlineStyle) {
4510
- __SetInlineStyles(this.element, inlineStyle);
5000
+ __SetInlineStyles(this.element, this.#withRuntimeStyle(inlineStyle));
4511
5001
  this.#inlineStyleWhole = inlineStyle;
4512
5002
  }
5003
+ #withRuntimeStyle(inlineStyle) {
5004
+ if (!this.#runtimeStyle) return inlineStyle;
5005
+ return inlineStyle ? `${this.#runtimeStyle}; ${inlineStyle}` : this.#runtimeStyle;
5006
+ }
5007
+ #setRuntimeStyle(style) {
5008
+ if (style === this.#runtimeStyle) return;
5009
+ this.#runtimeStyle = style;
5010
+ __SetInlineStyles(this.element, this.#withRuntimeStyle(this.#inlineStyleWhole));
5011
+ for (const [key, value] of this.#inlineStyleKeys) __AddInlineStyle(this.element, key, value);
5012
+ }
4513
5013
  insertBefore(newChild, refChild) {
4514
5014
  if (newChild.isRootPageElement) return;
4515
5015
  newChild.#cancelPendingRemoval();
@@ -4551,6 +5051,11 @@ var LynxElement = class {
4551
5051
  set.add(name);
4552
5052
  this.#classes = [...set].join(" ");
4553
5053
  }
5054
+ addScopeClass(name) {
5055
+ if (this.#scopeClasses.includes(name)) return;
5056
+ this.#scopeClasses.push(name);
5057
+ this.addClass(name);
5058
+ }
4554
5059
  removeClass(name) {
4555
5060
  const joined = __GetClasses(this.element).filter((c) => c !== name).join(" ");
4556
5061
  __SetClasses(this.element, joined);
@@ -4626,11 +5131,11 @@ var LynxElement = class {
4626
5131
  #doRemove() {
4627
5132
  const parent = this.parentNode();
4628
5133
  if (!parent) return;
4629
- for (const id of this.#activeAnimationIds) __ElementAnimate(this.element, [3, id]);
4630
- if (this.#activeAnimationIds.length > 0) {
5134
+ for (const anim of this.#activeAnimations) anim.cancel();
5135
+ if (this.#activeAnimations.length > 0) {
4631
5136
  __AddInlineStyle(this.element, "opacity", null);
4632
5137
  __AddInlineStyle(this.element, "transform", null);
4633
- this.#activeAnimationIds.length = 0;
5138
+ this.#activeAnimations.length = 0;
4634
5139
  }
4635
5140
  __RemoveElement(parent.element, this.element);
4636
5141
  const jsParent = this.#jsParent;
@@ -4665,7 +5170,8 @@ var LynxElement = class {
4665
5170
  if (Object.keys(this.#dataset).length > 0) __SetDataset(fresh, this.#dataset);
4666
5171
  for (const [name, value] of this.#attrs) __SetAttribute(fresh, name, value);
4667
5172
  if (this.#classes) __SetClasses(fresh, this.#classes);
4668
- if (this.#inlineStyleWhole != null) __SetInlineStyles(fresh, this.#inlineStyleWhole);
5173
+ const inlineStyle = this.#withRuntimeStyle(this.#inlineStyleWhole);
5174
+ if (inlineStyle != null) __SetInlineStyles(fresh, inlineStyle);
4669
5175
  for (const [key, value] of this.#inlineStyleKeys) __AddInlineStyle(fresh, key, value);
4670
5176
  for (const { eventType, eventName, listener } of this.#listeners) __AddEvent(fresh, eventType, eventName, {
4671
5177
  type: "worklet",
@@ -4703,7 +5209,7 @@ var LynxElement = class {
4703
5209
  animate(keyframes, options) {
4704
5210
  const normalizedOptions = typeof options === "number" ? { duration: options } : options ?? {};
4705
5211
  const anim = new LynxAnimation(this.element, keyframes, normalizedOptions);
4706
- this.#activeAnimationIds.push(anim.id);
5212
+ this.#activeAnimations.push(anim);
4707
5213
  return anim;
4708
5214
  }
4709
5215
  addEventListener(name, cb) {
@@ -4893,42 +5399,6 @@ var LynxListElement = class extends LynxElement {
4893
5399
  __FlushElementTree(void 0, { triggerLayout: true });
4894
5400
  }
4895
5401
  };
4896
- var LynxBackgroundDocument = class {
4897
- #page = null;
4898
- constructor() {}
4899
- createRootElement() {
4900
- const page = new LynxBackgroundElement();
4901
- page.tagName = "page";
4902
- page.setAttribute("tagName", "page");
4903
- page.isRootPageElement = true;
4904
- this.#page = page;
4905
- return this.#page;
4906
- }
4907
- createElement(tag, value) {
4908
- if (tag === "page") return this.#page;
4909
- const element = new LynxBackgroundElement();
4910
- element.tagName = tag;
4911
- element.setAttribute("tagName", tag);
4912
- if (value) element.setAttribute("textContent", value);
4913
- return element;
4914
- }
4915
- createText(value) {
4916
- const element = new LynxBackgroundElement();
4917
- element.tagName = "text";
4918
- element.setAttribute("tagName", "text");
4919
- element.setAttribute("textContent", value);
4920
- return element;
4921
- }
4922
- createComment() {
4923
- const element = new LynxBackgroundElement();
4924
- element.tagName = "comment";
4925
- element.setAttribute("tagName", "comment");
4926
- return element;
4927
- }
4928
- appendChild(newChild) {
4929
- this.#page?.appendChild(newChild);
4930
- }
4931
- };
4932
5402
  const createListElement = (pageId) => {
4933
5403
  let listEl;
4934
5404
  const componentAtIndex = (listRef, listId, cellIndex, opId) => {
@@ -4985,16 +5455,23 @@ const createPageElement = (page, pageElementRequested) => {
4985
5455
  pageElementRequested: true
4986
5456
  };
4987
5457
  };
5458
+ const takeOverPage = () => {
5459
+ const page = __pageElementRef;
5460
+ if (!takePageHandOver() || !page) return null;
5461
+ for (const child of __GetChildren(page) ?? []) __RemoveElement(page, child);
5462
+ return page;
5463
+ };
4988
5464
  var LynxDocument = class {
4989
5465
  page;
4990
5466
  #pageId = 0;
4991
5467
  #pageElementRequested = false;
4992
5468
  constructor() {}
4993
5469
  createRootElement() {
4994
- const pageElement = __CreatePage("0", 0);
5470
+ const pageElement = takeOverPage() ?? __CreatePage("0", 0);
4995
5471
  this.page = new LynxElement(pageElement);
4996
5472
  this.page.tagName = "page";
4997
5473
  this.page.isRootPageElement = true;
5474
+ if (isAndroid()) __SetID(pageElement, ANDROID_BLUR_CAPTURE_TARGET);
4998
5475
  this.#pageId = __GetElementUniqueID(pageElement);
4999
5476
  setPageElementRef(pageElement);
5000
5477
  return this.page;
@@ -5012,6 +5489,7 @@ var LynxDocument = class {
5012
5489
  const el = new LynxElement(createNativeRefByTag(tag, this.#pageId, value));
5013
5490
  el.tagName = tag;
5014
5491
  if (tag === "raw-text") el.setInitialText(value ?? "");
5492
+ if (tag === "blur-view") el.updateBlurMaterial();
5015
5493
  return el;
5016
5494
  }
5017
5495
  createText(value) {
@@ -5164,14 +5642,24 @@ var LynxRenderer = class {
5164
5642
  }
5165
5643
  };
5166
5644
  var EmulatedLynxRenderer = class extends LynxRenderer {
5167
- #componentScopeId;
5645
+ #contentClass;
5646
+ #hostClass;
5168
5647
  constructor(document, componentId) {
5169
5648
  super(document);
5170
- this.#componentScopeId = componentId;
5649
+ this.#contentClass = `_ngcontent-${componentId}`;
5650
+ this.#hostClass = `_nghost-${componentId}`;
5651
+ }
5652
+ applyToHost(element) {
5653
+ element.addScopeClass(this.#hostClass);
5654
+ }
5655
+ createElement(name, namespace) {
5656
+ const element = super.createElement(name, namespace);
5657
+ element.addScopeClass(this.#contentClass);
5658
+ return element;
5171
5659
  }
5172
5660
  selectRootElement() {
5173
5661
  const el = super.selectRootElement();
5174
- el.addClass(`_nghost-${this.#componentScopeId}`);
5662
+ this.applyToHost(el);
5175
5663
  return el;
5176
5664
  }
5177
5665
  };
@@ -5179,13 +5667,9 @@ var LynxRendererFactory2 = class LynxRendererFactory2 {
5179
5667
  lynxDocument = inject(LYNX_DOCUMENT);
5180
5668
  #defaultRenderer = null;
5181
5669
  #emulatedRenderers = /* @__PURE__ */ new Map();
5182
- createRenderer(_hostElement, type) {
5183
- if (!type || type.encapsulation === ViewEncapsulation.None) {
5184
- if (!this.#defaultRenderer) this.#defaultRenderer = new LynxRenderer(this.lynxDocument);
5185
- return this.#defaultRenderer;
5186
- }
5187
- if (type.encapsulation === ViewEncapsulation.ShadowDom) {
5188
- console.warn("ViewEncapsulation.ShadowDom is not supported in Lynx. Falling back to no encapsulation.");
5670
+ createRenderer(hostElement, type) {
5671
+ if (!type || type.encapsulation !== ViewEncapsulation.Emulated) {
5672
+ if (type && type.encapsulation !== ViewEncapsulation.None) console.warn("ViewEncapsulation.ShadowDom is not supported in Lynx. Falling back to no encapsulation.");
5189
5673
  if (!this.#defaultRenderer) this.#defaultRenderer = new LynxRenderer(this.lynxDocument);
5190
5674
  return this.#defaultRenderer;
5191
5675
  }
@@ -5194,14 +5678,18 @@ var LynxRendererFactory2 = class LynxRendererFactory2 {
5194
5678
  renderer = new EmulatedLynxRenderer(this.lynxDocument, type.id);
5195
5679
  this.#emulatedRenderers.set(type.id, renderer);
5196
5680
  }
5681
+ if (hostElement) renderer.applyToHost(hostElement);
5197
5682
  return renderer;
5198
5683
  }
5199
5684
  begin() {
5200
5685
  setInsideChangeDetection(true);
5686
+ /* v8 ignore start */
5687
+ if (__PROFILE__) startCdTiming();
5688
+ /* v8 ignore stop */
5201
5689
  }
5202
5690
  end() {
5203
- setInsideChangeDetection(false);
5204
- if (__MAIN_THREAD__) {
5691
+ try {
5692
+ setInsideChangeDetection(false);
5205
5693
  /* v8 ignore start */
5206
5694
  if (__ENABLE_SSR__ && globalThis.__LYNX_IS_HYDRATING__) return;
5207
5695
  /* v8 ignore stop */
@@ -5215,6 +5703,9 @@ var LynxRendererFactory2 = class LynxRendererFactory2 {
5215
5703
  processPendingTextNormalization();
5216
5704
  if (!isFirstRenderPending()) __FlushElementTree();
5217
5705
  processPendingListUpdates();
5706
+ } finally {
5707
+ /* v8 ignore start */
5708
+ if (__PROFILE__) endCdTiming();
5218
5709
  }
5219
5710
  }
5220
5711
  static ɵfac = i0.ɵɵngDeclareFactory({
@@ -5244,12 +5735,9 @@ const provideRenderer = () => {
5244
5735
  {
5245
5736
  provide: LYNX_DOCUMENT,
5246
5737
  useFactory: () => {
5247
- if (__MAIN_THREAD__) {
5248
- /* v8 ignore next 6 */
5249
- if (__ENABLE_SSR__ && globalThis.__LYNX_IS_HYDRATING__) return new LynxHydrateDocument(globalThis.__LYNX_HYDRATE_PAGE__, globalThis.__LYNX_HYDRATE_QUEUE__);
5250
- return new LynxDocument();
5251
- }
5252
- return new LynxBackgroundDocument();
5738
+ /* v8 ignore next 6 */
5739
+ if (__ENABLE_SSR__ && globalThis.__LYNX_IS_HYDRATING__) return new LynxHydrateDocument(globalThis.__LYNX_HYDRATE_PAGE__, globalThis.__LYNX_HYDRATE_QUEUE__);
5740
+ return new LynxDocument();
5253
5741
  }
5254
5742
  },
5255
5743
  {
@@ -5278,6 +5766,12 @@ const provideRenderer = () => {
5278
5766
  }
5279
5767
  ]);
5280
5768
  };
5769
+ let carriedOver;
5770
+ let snapshotOf;
5771
+ const carryOverLocation = (injector) => {
5772
+ const strategy = injector?.get(LocationStrategy, null);
5773
+ if (strategy instanceof LynxLocationStrategy) carriedOver = snapshotOf(strategy);
5774
+ };
5281
5775
  var LynxLocationStrategy = class LynxLocationStrategy extends LocationStrategy {
5282
5776
  #path = "/";
5283
5777
  #baseHref = "/";
@@ -5287,6 +5781,24 @@ var LynxLocationStrategy = class LynxLocationStrategy extends LocationStrategy {
5287
5781
  }];
5288
5782
  #historyIndex = 0;
5289
5783
  #listeners = [];
5784
+ #canGoBack = signal(false, ...ngDevMode ? [{ debugName: "#canGoBack" }] : /* istanbul ignore next */ []);
5785
+ constructor() {
5786
+ super();
5787
+ if (carriedOver) {
5788
+ this.#history = carriedOver.history;
5789
+ this.#historyIndex = carriedOver.index;
5790
+ this.#path = this.#history[this.#historyIndex].url;
5791
+ this.#canGoBack.set(this.#historyIndex > 0);
5792
+ carriedOver = void 0;
5793
+ }
5794
+ }
5795
+ static {
5796
+ snapshotOf = (strategy) => ({
5797
+ history: strategy.#history.map((entry) => ({ ...entry })),
5798
+ index: strategy.#historyIndex
5799
+ });
5800
+ }
5801
+ canGoBack = this.#canGoBack.asReadonly();
5290
5802
  path() {
5291
5803
  return this.#path;
5292
5804
  }
@@ -5307,6 +5819,7 @@ var LynxLocationStrategy = class LynxLocationStrategy extends LocationStrategy {
5307
5819
  url: fullUrl
5308
5820
  });
5309
5821
  this.#historyIndex++;
5822
+ this.#canGoBack.set(true);
5310
5823
  this.#path = fullUrl;
5311
5824
  }
5312
5825
  replaceState(state, _title, url, queryParams) {
@@ -5327,6 +5840,7 @@ var LynxLocationStrategy = class LynxLocationStrategy extends LocationStrategy {
5327
5840
  const target = this.#historyIndex + relativePosition;
5328
5841
  if (target < 0 || target >= this.#history.length) return;
5329
5842
  this.#historyIndex = target;
5843
+ this.#canGoBack.set(target > 0);
5330
5844
  this.#path = this.#history[target].url;
5331
5845
  for (const fn of this.#listeners) fn({
5332
5846
  type: "popstate",
@@ -5344,7 +5858,7 @@ var LynxLocationStrategy = class LynxLocationStrategy extends LocationStrategy {
5344
5858
  version: "22.2.1",
5345
5859
  ngImport: i0,
5346
5860
  type: LynxLocationStrategy,
5347
- deps: null,
5861
+ deps: [],
5348
5862
  target: i0.ɵɵFactoryTarget.Injectable
5349
5863
  });
5350
5864
  static ɵprov = i0.ɵɵngDeclareInjectable({
@@ -5359,7 +5873,8 @@ i0.ɵɵngDeclareClassMetadata({
5359
5873
  version: "22.2.1",
5360
5874
  ngImport: i0,
5361
5875
  type: LynxLocationStrategy,
5362
- decorators: [{ type: Injectable }]
5876
+ decorators: [{ type: Injectable }],
5877
+ ctorParameters: () => []
5363
5878
  });
5364
5879
  var LynxPlatformLocation = class LynxPlatformLocation extends PlatformLocation {
5365
5880
  #history = [{
@@ -5520,6 +6035,51 @@ i0.ɵɵngDeclareClassMetadata({
5520
6035
  type: LynxRouteReuseStrategy,
5521
6036
  decorators: [{ type: Injectable }]
5522
6037
  });
6038
+ const SHELL_MODULE = "AngularLynxShell";
6039
+ const BACK_EVENT = "angularLynxBack";
6040
+ var LynxBackButton = class LynxBackButton {
6041
+ constructor() {
6042
+ const strategy = inject(LocationStrategy);
6043
+ if (!(strategy instanceof LynxLocationStrategy)) return;
6044
+ const location = inject(Location);
6045
+ const modules = inject(LynxNativeModule);
6046
+ const shell = modules.getNativeModule(SHELL_MODULE);
6047
+ let hasShell = true;
6048
+ effect(() => {
6049
+ const enabled = strategy.canGoBack();
6050
+ if (!hasShell) return;
6051
+ Promise.resolve().then(() => shell?.setBackHandlerEnabled(enabled)).catch(() => hasShell = false);
6052
+ });
6053
+ const emitter = modules.getJSModule("GlobalEventEmitter");
6054
+ Promise.resolve().then(() => emitter?.addListener(BACK_EVENT, () => setTimeout(() => location.back()))).catch(() => {});
6055
+ }
6056
+ static ɵfac = i0.ɵɵngDeclareFactory({
6057
+ minVersion: "12.0.0",
6058
+ version: "22.2.1",
6059
+ ngImport: i0,
6060
+ type: LynxBackButton,
6061
+ deps: [],
6062
+ target: i0.ɵɵFactoryTarget.Injectable
6063
+ });
6064
+ static ɵprov = i0.ɵɵngDeclareInjectable({
6065
+ minVersion: "12.0.0",
6066
+ version: "22.2.1",
6067
+ ngImport: i0,
6068
+ type: LynxBackButton,
6069
+ providedIn: "root"
6070
+ });
6071
+ };
6072
+ i0.ɵɵngDeclareClassMetadata({
6073
+ minVersion: "12.0.0",
6074
+ version: "22.2.1",
6075
+ ngImport: i0,
6076
+ type: LynxBackButton,
6077
+ decorators: [{
6078
+ type: Injectable,
6079
+ args: [{ providedIn: "root" }]
6080
+ }],
6081
+ ctorParameters: () => []
6082
+ });
5523
6083
  const provideRouter = (routes, ...features) => {
5524
6084
  return makeEnvironmentProviders([
5525
6085
  {
@@ -5530,11 +6090,8 @@ const provideRouter = (routes, ...features) => {
5530
6090
  provide: LocationStrategy,
5531
6091
  useClass: LynxLocationStrategy
5532
6092
  },
5533
- {
5534
- provide: RouteReuseStrategy,
5535
- useClass: LynxRouteReuseStrategy
5536
- },
5537
- provideRouter$1(routes, withRouterConfig({ resolveNavigationPromiseOnError: true }), ...features)
6093
+ provideRouter$1(routes, withRouterConfig({ resolveNavigationPromiseOnError: true }), ...features),
6094
+ provideEnvironmentInitializer(() => inject(LynxBackButton))
5538
6095
  ]);
5539
6096
  };
5540
6097
  globalThis.__lynxLastError = "";
@@ -5552,12 +6109,98 @@ if (typeof globalThis.onunhandledrejection !== "function") globalThis.onunhandle
5552
6109
  globalThis.__lynxLastError = `${e.name}: ${e.message}\n${e.stack ?? ""}`;
5553
6110
  reportToNative(e);
5554
6111
  };
5555
- const REPLACEMENT_CHARACTER = 65533;
6112
+ const CODES = {
6113
+ NotSupportedError: 9,
6114
+ InvalidStateError: 11,
6115
+ SyntaxError: 12,
6116
+ InvalidAccessError: 15,
6117
+ NetworkError: 19,
6118
+ AbortError: 20,
6119
+ TimeoutError: 23
6120
+ };
6121
+ var LynxDOMException = class extends Error {
6122
+ code;
6123
+ constructor(message = "", name = "Error") {
6124
+ super(message);
6125
+ this.name = name;
6126
+ this.code = CODES[name] ?? 0;
6127
+ }
6128
+ };
6129
+ const NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
6130
+ const normalizeValue = (value) => {
6131
+ const normalized = String(value).replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
6132
+ if (/[\r\n]/.test(normalized) || normalized.includes("\0")) throw new TypeError(`Invalid header value: ${JSON.stringify(value)}`);
6133
+ return normalized;
6134
+ };
6135
+ const normalizeName = (name) => {
6136
+ const normalized = String(name);
6137
+ if (!NAME.test(normalized)) throw new TypeError(`Invalid header name: ${JSON.stringify(name)}`);
6138
+ return normalized.toLowerCase();
6139
+ };
6140
+ var LynxHeaders = class LynxHeaders {
6141
+ #list = [];
6142
+ constructor(init) {
6143
+ if (init == null) return;
6144
+ if (init instanceof LynxHeaders) this.#list = init.#list.map(([name, value]) => [name, value]);
6145
+ else if (typeof init[Symbol.iterator] === "function") for (const pair of init) {
6146
+ if (pair.length !== 2) throw new TypeError("Failed to construct 'Headers': Invalid value: each header must be a [name, value] pair");
6147
+ this.append(pair[0], pair[1]);
6148
+ }
6149
+ else for (const name of Object.keys(init)) this.append(name, init[name]);
6150
+ }
6151
+ append(name, value) {
6152
+ this.#list.push([normalizeName(name), normalizeValue(value)]);
6153
+ }
6154
+ delete(name) {
6155
+ const key = normalizeName(name);
6156
+ this.#list = this.#list.filter(([listed]) => listed !== key);
6157
+ }
6158
+ get(name) {
6159
+ const key = normalizeName(name);
6160
+ const values = this.#list.filter(([listed]) => listed === key).map(([, value]) => value);
6161
+ return values.length > 0 ? values.join(", ") : null;
6162
+ }
6163
+ getSetCookie() {
6164
+ return this.#list.filter(([name]) => name === "set-cookie").map(([, value]) => value);
6165
+ }
6166
+ has(name) {
6167
+ const key = normalizeName(name);
6168
+ return this.#list.some(([listed]) => listed === key);
6169
+ }
6170
+ set(name, value) {
6171
+ const key = normalizeName(name);
6172
+ const index = this.#list.findIndex(([listed]) => listed === key);
6173
+ if (index === -1) {
6174
+ this.append(key, value);
6175
+ return;
6176
+ }
6177
+ this.#list[index] = [key, normalizeValue(value)];
6178
+ this.#list = this.#list.filter(([listed], i) => listed !== key || i === index);
6179
+ }
6180
+ forEach(callback, thisArg) {
6181
+ for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this);
6182
+ }
6183
+ *entries() {
6184
+ const names = [...new Set(this.#list.map(([name]) => name))].sort();
6185
+ for (const name of names) if (name === "set-cookie") for (const value of this.getSetCookie()) yield [name, value];
6186
+ else yield [name, this.get(name)];
6187
+ }
6188
+ *keys() {
6189
+ for (const [name] of this.entries()) yield name;
6190
+ }
6191
+ *values() {
6192
+ for (const [, value] of this.entries()) yield value;
6193
+ }
6194
+ [Symbol.iterator]() {
6195
+ return this.entries();
6196
+ }
6197
+ };
6198
+ const REPLACEMENT_CHARACTER$1 = 65533;
5556
6199
  const utf8Encode = (input) => {
5557
6200
  const bytes = [];
5558
6201
  for (const char of input) {
5559
6202
  let codePoint = char.codePointAt(0);
5560
- if (codePoint >= 55296 && codePoint <= 57343) codePoint = REPLACEMENT_CHARACTER;
6203
+ if (codePoint >= 55296 && codePoint <= 57343) codePoint = REPLACEMENT_CHARACTER$1;
5561
6204
  if (codePoint < 128) bytes.push(codePoint);
5562
6205
  else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
5563
6206
  else if (codePoint < 65536) bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
@@ -5593,7 +6236,7 @@ const utf8Decode = (bytes) => {
5593
6236
  needed = 3;
5594
6237
  codePoint = lead & 7;
5595
6238
  } else {
5596
- output += String.fromCharCode(REPLACEMENT_CHARACTER);
6239
+ output += String.fromCharCode(REPLACEMENT_CHARACTER$1);
5597
6240
  index++;
5598
6241
  continue;
5599
6242
  }
@@ -5607,7 +6250,7 @@ const utf8Decode = (bytes) => {
5607
6250
  seen++;
5608
6251
  }
5609
6252
  if (seen < needed) {
5610
- output += String.fromCharCode(REPLACEMENT_CHARACTER);
6253
+ output += String.fromCharCode(REPLACEMENT_CHARACTER$1);
5611
6254
  index += 1 + seen;
5612
6255
  continue;
5613
6256
  }
@@ -5654,6 +6297,700 @@ const formUrlEncode = (input) => {
5654
6297
  else output += percentEncodeByte(byte);
5655
6298
  return output;
5656
6299
  };
6300
+ const UTF8_LABELS = /* @__PURE__ */ new Set([
6301
+ "unicode-1-1-utf-8",
6302
+ "unicode11utf8",
6303
+ "unicode20utf8",
6304
+ "utf-8",
6305
+ "utf8",
6306
+ "x-unicode20utf8"
6307
+ ]);
6308
+ const REPLACEMENT_CHARACTER = 65533;
6309
+ const BYTE_ORDER_MARK = 65279;
6310
+ const SLICE = 8192;
6311
+ const toBytes$1 = (input) => {
6312
+ if (input === void 0) return /* @__PURE__ */ new Uint8Array(0);
6313
+ if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
6314
+ if (input instanceof ArrayBuffer) return new Uint8Array(input);
6315
+ throw new TypeError("Failed to execute 'decode' on 'TextDecoder': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'.");
6316
+ };
6317
+ const sequenceLength = (lead) => {
6318
+ if (lead >= 194 && lead <= 223) return 2;
6319
+ if (lead >= 224 && lead <= 239) return 3;
6320
+ if (lead >= 240 && lead <= 244) return 4;
6321
+ return 1;
6322
+ };
6323
+ const completeLength = (bytes) => {
6324
+ for (let back = 1; back <= 3 && back <= bytes.length; back++) {
6325
+ const byte = bytes[bytes.length - back];
6326
+ if ((byte & 192) !== 128) return sequenceLength(byte) > back ? bytes.length - back : bytes.length;
6327
+ }
6328
+ return bytes.length;
6329
+ };
6330
+ var LynxTextEncoder = class {
6331
+ encoding = "utf-8";
6332
+ encode(input = "") {
6333
+ return new Uint8Array(utf8Encode(String(input)));
6334
+ }
6335
+ encodeInto(source, destination) {
6336
+ let read = 0;
6337
+ let written = 0;
6338
+ for (const char of String(source)) {
6339
+ const bytes = utf8Encode(char);
6340
+ if (written + bytes.length > destination.length) break;
6341
+ destination.set(bytes, written);
6342
+ written += bytes.length;
6343
+ read += char.length;
6344
+ }
6345
+ return {
6346
+ read,
6347
+ written
6348
+ };
6349
+ }
6350
+ };
6351
+ var LynxTextDecoder = class {
6352
+ encoding = "utf-8";
6353
+ fatal;
6354
+ ignoreBOM;
6355
+ #pending = [];
6356
+ #started = false;
6357
+ constructor(label = "utf-8", options = {}) {
6358
+ if (!UTF8_LABELS.has(String(label).trim().toLowerCase())) throw new RangeError(`The encoding label provided ('${label}') is invalid or isn't supported on Lynx, which only decodes UTF-8.`);
6359
+ this.fatal = !!options.fatal;
6360
+ this.ignoreBOM = !!options.ignoreBOM;
6361
+ }
6362
+ decode(input, options = {}) {
6363
+ let bytes = toBytes$1(input);
6364
+ if (this.#pending.length > 0) bytes = [...this.#pending, ...Array.from(bytes)];
6365
+ const end = options.stream ? completeLength(bytes) : bytes.length;
6366
+ this.#pending = Array.from({ length: bytes.length - end }, (_, i) => Number(bytes[end + i]));
6367
+ let output = this.#decode(bytes, end);
6368
+ if (!this.ignoreBOM && !this.#started && output.charCodeAt(0) === BYTE_ORDER_MARK) output = output.slice(1);
6369
+ this.#started = options.stream ? this.#started || output !== "" : false;
6370
+ return output;
6371
+ }
6372
+ #decode(bytes, end) {
6373
+ let output = "";
6374
+ const codes = [];
6375
+ const invalid = () => {
6376
+ if (this.fatal) throw new TypeError("Failed to execute 'decode' on 'TextDecoder': The encoded data was not valid.");
6377
+ codes.push(REPLACEMENT_CHARACTER);
6378
+ };
6379
+ let index = 0;
6380
+ while (index < end) {
6381
+ const lead = bytes[index];
6382
+ if (lead < 128) {
6383
+ codes.push(lead);
6384
+ index++;
6385
+ } else {
6386
+ const needed = sequenceLength(lead) - 1;
6387
+ let lower = lead === 224 ? 160 : lead === 240 ? 144 : 128;
6388
+ let upper = lead === 237 ? 159 : lead === 244 ? 143 : 191;
6389
+ let codePoint = lead & 255 >> needed + 2;
6390
+ let seen = 0;
6391
+ while (seen < needed && index + 1 + seen < end) {
6392
+ const next = bytes[index + 1 + seen];
6393
+ if (next < lower || next > upper) break;
6394
+ lower = 128;
6395
+ upper = 191;
6396
+ codePoint = codePoint << 6 | next & 63;
6397
+ seen++;
6398
+ }
6399
+ if (needed === 0 || seen < needed) {
6400
+ invalid();
6401
+ index += 1 + seen;
6402
+ } else {
6403
+ if (codePoint > 65535) {
6404
+ codePoint -= 65536;
6405
+ codes.push(55296 | codePoint >> 10, 56320 | codePoint & 1023);
6406
+ } else codes.push(codePoint);
6407
+ index += 1 + needed;
6408
+ }
6409
+ }
6410
+ if (codes.length >= SLICE) {
6411
+ output += String.fromCharCode(...codes);
6412
+ codes.length = 0;
6413
+ }
6414
+ }
6415
+ return output + String.fromCharCode(...codes);
6416
+ }
6417
+ };
6418
+ const toBytes = (source) => typeof source === "string" ? new LynxTextEncoder().encode(source) : source ?? /* @__PURE__ */ new Uint8Array(0);
6419
+ const unsupportedBody = (kind) => /* @__PURE__ */ new TypeError(`${kind} request bodies aren't supported on Lynx. Send a string, URLSearchParams, an ArrayBuffer or a typed array.`);
6420
+ const extractBody = (body) => {
6421
+ if (body == null) return {
6422
+ source: null,
6423
+ type: null
6424
+ };
6425
+ if (typeof body === "string") return {
6426
+ source: body,
6427
+ type: "text/plain;charset=UTF-8"
6428
+ };
6429
+ if (body instanceof ArrayBuffer) return {
6430
+ source: new Uint8Array(body.slice(0)),
6431
+ type: null
6432
+ };
6433
+ if (ArrayBuffer.isView(body)) return {
6434
+ source: new Uint8Array(body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength)),
6435
+ type: null
6436
+ };
6437
+ if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) return {
6438
+ source: body.toString(),
6439
+ type: "application/x-www-form-urlencoded;charset=UTF-8"
6440
+ };
6441
+ for (const kind of [
6442
+ "Blob",
6443
+ "FormData",
6444
+ "ReadableStream"
6445
+ ]) {
6446
+ const type = globalThis[kind];
6447
+ if (typeof type === "function" && body instanceof type) throw unsupportedBody(kind);
6448
+ }
6449
+ if (typeof body.getReader === "function") throw unsupportedBody("ReadableStream");
6450
+ return {
6451
+ source: String(body),
6452
+ type: "text/plain;charset=UTF-8"
6453
+ };
6454
+ };
6455
+ var LynxBodyStream = class {
6456
+ #chunk;
6457
+ #onRead;
6458
+ locked = false;
6459
+ constructor(chunk, onRead) {
6460
+ this.#chunk = chunk.length > 0 ? chunk : null;
6461
+ this.#onRead = onRead;
6462
+ }
6463
+ getReader() {
6464
+ if (this.locked) throw new TypeError("Failed to execute 'getReader' on 'ReadableStream': ReadableStreamDefaultReader constructor can only accept readable streams that are not yet locked to a reader");
6465
+ this.locked = true;
6466
+ this.#onRead();
6467
+ let released = false;
6468
+ return {
6469
+ read: async () => {
6470
+ if (released) throw new TypeError("This reader has been released");
6471
+ const chunk = this.#chunk;
6472
+ this.#chunk = null;
6473
+ return chunk ? {
6474
+ done: false,
6475
+ value: chunk
6476
+ } : {
6477
+ done: true,
6478
+ value: void 0
6479
+ };
6480
+ },
6481
+ cancel: async () => {
6482
+ this.#chunk = null;
6483
+ },
6484
+ releaseLock: () => {
6485
+ released = true;
6486
+ this.locked = false;
6487
+ },
6488
+ closed: Promise.resolve(void 0)
6489
+ };
6490
+ }
6491
+ async cancel() {
6492
+ this.#onRead();
6493
+ this.#chunk = null;
6494
+ }
6495
+ async *[Symbol.asyncIterator]() {
6496
+ const reader = this.getReader();
6497
+ for (;;) {
6498
+ const { done, value } = await reader.read();
6499
+ if (done) return;
6500
+ yield value;
6501
+ }
6502
+ }
6503
+ };
6504
+ var LynxBody = class {
6505
+ #source;
6506
+ #used = false;
6507
+ #stream;
6508
+ constructor(source) {
6509
+ this.#source = source;
6510
+ }
6511
+ get body() {
6512
+ if (this.#source === null) return null;
6513
+ this.#stream ??= new LynxBodyStream(toBytes(this.#source), () => {
6514
+ this.#used = true;
6515
+ });
6516
+ return this.#stream;
6517
+ }
6518
+ get bodyUsed() {
6519
+ return this.#used;
6520
+ }
6521
+ relayedBody() {
6522
+ const source = this.#source;
6523
+ if (source === null) return null;
6524
+ return typeof source === "string" ? { text: source } : { base64: bytesToBase64(source) };
6525
+ }
6526
+ cloneSource() {
6527
+ if (this.#used) throw new TypeError("Failed to execute 'clone': the body is already used");
6528
+ return this.#source;
6529
+ }
6530
+ async #consume() {
6531
+ if (this.#used) throw new TypeError("Failed to execute 'text' on 'Body': body stream already read");
6532
+ this.#used = true;
6533
+ return this.#source;
6534
+ }
6535
+ async text() {
6536
+ const source = await this.#consume();
6537
+ return typeof source === "string" ? source : new LynxTextDecoder().decode(toBytes(source));
6538
+ }
6539
+ async json() {
6540
+ return JSON.parse(await this.text());
6541
+ }
6542
+ async bytes() {
6543
+ return toBytes(await this.#consume());
6544
+ }
6545
+ async arrayBuffer() {
6546
+ const bytes = await this.bytes();
6547
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
6548
+ }
6549
+ async blob() {
6550
+ const BlobType = globalThis.Blob;
6551
+ if (typeof BlobType !== "function") throw new TypeError("Lynx has no Blob. Use arrayBuffer() instead.");
6552
+ return new BlobType([await this.arrayBuffer()], { type: this.headers.get("content-type") ?? "" });
6553
+ }
6554
+ async formData() {
6555
+ throw new TypeError("Lynx has no FormData. Use text() or json() instead.");
6556
+ }
6557
+ };
6558
+ const NORMALIZED_METHODS = /* @__PURE__ */ new Set([
6559
+ "DELETE",
6560
+ "GET",
6561
+ "HEAD",
6562
+ "OPTIONS",
6563
+ "POST",
6564
+ "PUT"
6565
+ ]);
6566
+ const parseUrl$1 = (input) => {
6567
+ try {
6568
+ return new URL(input).href;
6569
+ } catch {
6570
+ throw new TypeError(`Failed to parse URL from ${input}. Lynx has no page URL to resolve a relative URL against, so requests need an absolute URL.`);
6571
+ }
6572
+ };
6573
+ const DEFAULT_OPTIONS = {
6574
+ cache: "default",
6575
+ credentials: "same-origin",
6576
+ integrity: "",
6577
+ keepalive: false,
6578
+ mode: "cors",
6579
+ priority: "auto",
6580
+ redirect: "follow",
6581
+ referrer: "about:client",
6582
+ referrerPolicy: ""
6583
+ };
6584
+ const neverAborts = () => new AbortController().signal;
6585
+ var LynxRequest = class LynxRequest extends LynxBody {
6586
+ url;
6587
+ method;
6588
+ headers;
6589
+ signal;
6590
+ cache;
6591
+ credentials;
6592
+ integrity;
6593
+ keepalive;
6594
+ mode;
6595
+ priority;
6596
+ redirect;
6597
+ referrer;
6598
+ referrerPolicy;
6599
+ destination = "";
6600
+ constructor(input, init = {}) {
6601
+ const base = input instanceof LynxRequest ? input : void 0;
6602
+ const method = init.method ?? base?.method ?? "GET";
6603
+ const upper = method.toUpperCase();
6604
+ const normalizedMethod = NORMALIZED_METHODS.has(upper) ? upper : method;
6605
+ const { source, type } = init.body !== void 0 ? extractBody(init.body) : {
6606
+ source: base ? base.cloneSource() : null,
6607
+ type: null
6608
+ };
6609
+ if (source !== null && (upper === "GET" || upper === "HEAD")) throw new TypeError("Failed to construct 'Request': Request with GET/HEAD method cannot have body.");
6610
+ super(source);
6611
+ this.url = base ? base.url : parseUrl$1(String(input));
6612
+ this.method = normalizedMethod;
6613
+ this.headers = new LynxHeaders(init.headers ?? base?.headers);
6614
+ if (type !== null && !this.headers.has("content-type")) this.headers.set("content-type", type);
6615
+ this.signal = init.signal ?? base?.signal ?? neverAborts();
6616
+ const options = base ?? DEFAULT_OPTIONS;
6617
+ this.cache = init.cache ?? options.cache;
6618
+ this.credentials = init.credentials ?? options.credentials;
6619
+ this.integrity = init.integrity ?? options.integrity;
6620
+ this.keepalive = init.keepalive ?? options.keepalive;
6621
+ this.mode = init.mode ?? options.mode;
6622
+ this.priority = init.priority ?? options.priority;
6623
+ this.redirect = init.redirect ?? options.redirect;
6624
+ this.referrer = init.referrer ?? options.referrer;
6625
+ this.referrerPolicy = init.referrerPolicy ?? options.referrerPolicy;
6626
+ }
6627
+ clone() {
6628
+ return new LynxRequest(this);
6629
+ }
6630
+ toRelayed() {
6631
+ return {
6632
+ url: this.url,
6633
+ method: this.method,
6634
+ headers: [...this.headers.entries()],
6635
+ body: this.relayedBody(),
6636
+ options: Object.fromEntries(Object.entries(DEFAULT_OPTIONS).filter(([name, value]) => this[name] !== value).map(([name]) => [name, this[name]]))
6637
+ };
6638
+ }
6639
+ };
6640
+ var ExtractedBody = class {
6641
+ source;
6642
+ constructor(source) {
6643
+ this.source = source;
6644
+ }
6645
+ };
6646
+ var LynxResponse = class LynxResponse extends LynxBody {
6647
+ status;
6648
+ statusText;
6649
+ headers;
6650
+ url;
6651
+ redirected;
6652
+ type;
6653
+ constructor(body, init = {}, details = {
6654
+ url: "",
6655
+ redirected: false,
6656
+ type: "default"
6657
+ }) {
6658
+ const status = init.status ?? 200;
6659
+ if (details.type === "default" && (!Number.isInteger(status) || status < 200 || status > 599)) throw new RangeError(`Failed to construct 'Response': The status provided (${status}) is outside the range [200, 599].`);
6660
+ const { source, type } = body instanceof ExtractedBody ? {
6661
+ source: body.source,
6662
+ type: null
6663
+ } : extractBody(body);
6664
+ super(source);
6665
+ this.status = status;
6666
+ this.statusText = init.statusText ?? "";
6667
+ this.headers = new LynxHeaders(init.headers);
6668
+ if (type !== null && !this.headers.has("content-type")) this.headers.set("content-type", type);
6669
+ this.url = details.url;
6670
+ this.redirected = details.redirected;
6671
+ this.type = details.type;
6672
+ }
6673
+ get ok() {
6674
+ return this.status >= 200 && this.status < 300;
6675
+ }
6676
+ clone() {
6677
+ return new LynxResponse(new ExtractedBody(this.cloneSource()), {
6678
+ status: this.status,
6679
+ statusText: this.statusText,
6680
+ headers: this.headers
6681
+ }, {
6682
+ url: this.url,
6683
+ redirected: this.redirected,
6684
+ type: this.type
6685
+ });
6686
+ }
6687
+ static error() {
6688
+ return new LynxResponse(null, { status: 0 }, {
6689
+ url: "",
6690
+ redirected: false,
6691
+ type: "error"
6692
+ });
6693
+ }
6694
+ static json(data, init = {}) {
6695
+ const response = new LynxResponse(new ExtractedBody(JSON.stringify(data)), init);
6696
+ if (!response.headers.has("content-type")) response.headers.set("content-type", "application/json");
6697
+ return response;
6698
+ }
6699
+ static redirect(url, status = 302) {
6700
+ if (![
6701
+ 301,
6702
+ 302,
6703
+ 303,
6704
+ 307,
6705
+ 308
6706
+ ].includes(status)) throw new RangeError(`Failed to execute 'redirect' on 'Response': Invalid status code ${status}`);
6707
+ return new LynxResponse(null, {
6708
+ status,
6709
+ headers: { location: parseUrl$1(url) }
6710
+ });
6711
+ }
6712
+ static fromRelayed(relayed) {
6713
+ const body = relayed.body;
6714
+ const source = body === null ? null : "text" in body ? body.text : base64ToBytes(body.base64);
6715
+ return new LynxResponse(new ExtractedBody(source), {
6716
+ status: relayed.status,
6717
+ statusText: relayed.statusText,
6718
+ headers: relayed.headers
6719
+ }, {
6720
+ url: relayed.url,
6721
+ redirected: relayed.redirected,
6722
+ type: "basic"
6723
+ });
6724
+ }
6725
+ };
6726
+ let nextFetchId = 0;
6727
+ const relayFetch = (input, init) => new Promise((resolve, reject) => {
6728
+ const request = new LynxRequest(input, init);
6729
+ const { signal } = request;
6730
+ if (signal.aborted) {
6731
+ reject(signal.reason);
6732
+ return;
6733
+ }
6734
+ const id = nextFetchId++;
6735
+ let settled = false;
6736
+ const onAbort = () => {
6737
+ settled = true;
6738
+ reject(signal.reason);
6739
+ callOnBackground("abortFetch", id).catch(() => {});
6740
+ };
6741
+ signal.addEventListener("abort", onAbort);
6742
+ const settle = (fn) => {
6743
+ signal.removeEventListener("abort", onAbort);
6744
+ if (settled) return;
6745
+ settled = true;
6746
+ fn();
6747
+ };
6748
+ callOnBackground("fetch", id, request.toRelayed()).then((relayed) => settle(() => resolve(LynxResponse.fromRelayed(relayed))), (error) => settle(() => reject(new TypeError(error.message))));
6749
+ });
6750
+ var XhrEventTarget = class {
6751
+ #listeners = /* @__PURE__ */ new Map();
6752
+ onloadstart = null;
6753
+ onprogress = null;
6754
+ onabort = null;
6755
+ onerror = null;
6756
+ onload = null;
6757
+ ontimeout = null;
6758
+ onloadend = null;
6759
+ addEventListener(type, listener) {
6760
+ if (!listener) return;
6761
+ let listeners = this.#listeners.get(type);
6762
+ if (!listeners) {
6763
+ listeners = /* @__PURE__ */ new Set();
6764
+ this.#listeners.set(type, listeners);
6765
+ }
6766
+ listeners.add(listener);
6767
+ }
6768
+ removeEventListener(type, listener) {
6769
+ if (listener) this.#listeners.get(type)?.delete(listener);
6770
+ }
6771
+ dispatchEvent(event) {
6772
+ const full = {
6773
+ lengthComputable: false,
6774
+ loaded: 0,
6775
+ total: 0,
6776
+ ...event,
6777
+ target: this,
6778
+ currentTarget: this
6779
+ };
6780
+ const handler = this[`on${event.type}`];
6781
+ if (typeof handler === "function") handler.call(this, full);
6782
+ for (const listener of Array.from(this.#listeners.get(event.type) ?? [])) listener.call(this, full);
6783
+ return true;
6784
+ }
6785
+ fire(type, loaded = 0, total = 0) {
6786
+ this.dispatchEvent({
6787
+ type,
6788
+ lengthComputable: total > 0,
6789
+ loaded,
6790
+ total
6791
+ });
6792
+ }
6793
+ };
6794
+ var XhrUpload = class extends XhrEventTarget {
6795
+ emit(type, loaded, total) {
6796
+ this.fire(type, loaded, total);
6797
+ }
6798
+ };
6799
+ const UNSENT = 0;
6800
+ const OPENED = 1;
6801
+ const HEADERS_RECEIVED = 2;
6802
+ const LOADING = 3;
6803
+ const DONE = 4;
6804
+ const bodySize = (body) => {
6805
+ if (typeof body === "string") return body.length;
6806
+ if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) return body.byteLength;
6807
+ return 0;
6808
+ };
6809
+ var LynxXMLHttpRequest = class extends XhrEventTarget {
6810
+ static UNSENT = UNSENT;
6811
+ static OPENED = OPENED;
6812
+ static HEADERS_RECEIVED = HEADERS_RECEIVED;
6813
+ static LOADING = LOADING;
6814
+ static DONE = DONE;
6815
+ UNSENT = UNSENT;
6816
+ OPENED = OPENED;
6817
+ HEADERS_RECEIVED = HEADERS_RECEIVED;
6818
+ LOADING = LOADING;
6819
+ DONE = DONE;
6820
+ upload = new XhrUpload();
6821
+ onreadystatechange = null;
6822
+ readyState = UNSENT;
6823
+ status = 0;
6824
+ statusText = "";
6825
+ responseURL = "";
6826
+ responseType = "";
6827
+ response = "";
6828
+ timeout = 0;
6829
+ withCredentials = false;
6830
+ #method = "GET";
6831
+ #url = "";
6832
+ #requestHeaders = new LynxHeaders();
6833
+ #responseHeaders = new LynxHeaders();
6834
+ #responseText = "";
6835
+ #controller;
6836
+ #generation = 0;
6837
+ #timer;
6838
+ #uploading = false;
6839
+ get responseText() {
6840
+ if (this.responseType !== "" && this.responseType !== "text") throw new LynxDOMException(`Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was '${this.responseType}').`, "InvalidStateError");
6841
+ return this.#responseText;
6842
+ }
6843
+ open(method, url, async = true) {
6844
+ if (!async) throw new LynxDOMException("Failed to execute 'open' on 'XMLHttpRequest': Synchronous requests aren't supported on Lynx, where the request runs on another thread.", "InvalidAccessError");
6845
+ this.#cancel();
6846
+ this.#method = method;
6847
+ this.#url = String(url);
6848
+ this.#requestHeaders = new LynxHeaders();
6849
+ this.#reset();
6850
+ this.#setReadyState(OPENED);
6851
+ }
6852
+ setRequestHeader(name, value) {
6853
+ this.#assertOpened("setRequestHeader");
6854
+ this.#requestHeaders.append(name, value);
6855
+ }
6856
+ send(body = null) {
6857
+ this.#assertOpened("send");
6858
+ const generation = ++this.#generation;
6859
+ const controller = new AbortController();
6860
+ this.#controller = controller;
6861
+ const method = this.#method.toUpperCase();
6862
+ const sendsBody = method !== "GET" && method !== "HEAD" && body != null;
6863
+ const uploadSize = sendsBody ? bodySize(body) : 0;
6864
+ this.#uploading = sendsBody;
6865
+ this.fire("loadstart");
6866
+ if (sendsBody) this.upload.emit("loadstart", 0, uploadSize);
6867
+ if (this.timeout > 0) this.#timer = setTimeout(() => {
6868
+ if (generation !== this.#generation) return;
6869
+ this.#fail("timeout");
6870
+ }, this.timeout);
6871
+ const current = () => generation === this.#generation;
6872
+ Promise.resolve().then(() => globalThis.fetch(this.#url, {
6873
+ method: this.#method,
6874
+ headers: this.#requestHeaders,
6875
+ body: sendsBody ? body : void 0,
6876
+ credentials: this.withCredentials ? "include" : "same-origin",
6877
+ signal: controller.signal
6878
+ })).then(async (response) => {
6879
+ if (!current()) return;
6880
+ this.#uploadDone(uploadSize);
6881
+ this.status = response.status;
6882
+ this.statusText = response.statusText;
6883
+ this.responseURL = response.url;
6884
+ this.#responseHeaders = new LynxHeaders(response.headers);
6885
+ this.#setReadyState(HEADERS_RECEIVED);
6886
+ this.#setReadyState(LOADING);
6887
+ const size = await this.#readResponse(response);
6888
+ if (!current()) return;
6889
+ this.#finish();
6890
+ this.fire("progress", size, size);
6891
+ this.#setReadyState(DONE);
6892
+ this.fire("load", size, size);
6893
+ this.fire("loadend", size, size);
6894
+ }).catch(() => {
6895
+ if (current()) this.#fail("error");
6896
+ });
6897
+ }
6898
+ abort() {
6899
+ if (this.#controller && this.readyState !== DONE) this.#fail("abort");
6900
+ if (this.readyState === DONE) this.readyState = UNSENT;
6901
+ }
6902
+ getResponseHeader(name) {
6903
+ return this.readyState >= HEADERS_RECEIVED ? this.#responseHeaders.get(name) : null;
6904
+ }
6905
+ getAllResponseHeaders() {
6906
+ if (this.readyState < HEADERS_RECEIVED) return "";
6907
+ let headers = "";
6908
+ for (const [name, value] of this.#responseHeaders) headers += `${name}: ${value}\r\n`;
6909
+ return headers;
6910
+ }
6911
+ overrideMimeType(_mime) {}
6912
+ async #readResponse(response) {
6913
+ const type = this.responseType;
6914
+ if (type === "arraybuffer" || type === "blob") {
6915
+ const buffer = await response.arrayBuffer();
6916
+ const BlobType = globalThis.Blob;
6917
+ this.response = type === "arraybuffer" ? buffer : typeof BlobType === "function" ? new BlobType([buffer], { type: this.#responseHeaders.get("content-type") ?? "" }) : null;
6918
+ return buffer.byteLength;
6919
+ }
6920
+ const text = await response.text();
6921
+ if (type === "json") try {
6922
+ this.response = text === "" ? null : JSON.parse(text);
6923
+ } catch {
6924
+ this.response = null;
6925
+ }
6926
+ else if (type === "document") this.response = null;
6927
+ else {
6928
+ this.#responseText = text;
6929
+ this.response = text;
6930
+ }
6931
+ const length = Number(this.#responseHeaders.get("content-length"));
6932
+ return Number.isFinite(length) && length > 0 ? length : text.length;
6933
+ }
6934
+ #uploadDone(size) {
6935
+ if (!this.#uploading) return;
6936
+ this.#uploading = false;
6937
+ this.upload.emit("progress", size, size);
6938
+ this.upload.emit("load", size, size);
6939
+ this.upload.emit("loadend", size, size);
6940
+ }
6941
+ #fail(type) {
6942
+ this.#cancel();
6943
+ this.#reset();
6944
+ this.#setReadyState(DONE);
6945
+ if (this.#uploading) {
6946
+ this.#uploading = false;
6947
+ this.upload.emit(type);
6948
+ this.upload.emit("loadend");
6949
+ }
6950
+ this.fire(type);
6951
+ this.fire("loadend");
6952
+ }
6953
+ #cancel() {
6954
+ this.#generation++;
6955
+ this.#finish();
6956
+ this.#controller?.abort();
6957
+ this.#controller = void 0;
6958
+ }
6959
+ #finish() {
6960
+ if (this.#timer !== void 0) clearTimeout(this.#timer);
6961
+ this.#timer = void 0;
6962
+ }
6963
+ #reset() {
6964
+ this.status = 0;
6965
+ this.statusText = "";
6966
+ this.responseURL = "";
6967
+ this.response = this.responseType === "" || this.responseType === "text" ? "" : null;
6968
+ this.#responseText = "";
6969
+ this.#responseHeaders = new LynxHeaders();
6970
+ }
6971
+ #assertOpened(method) {
6972
+ if (this.readyState !== OPENED || this.#controller) throw new LynxDOMException(`Failed to execute '${method}' on 'XMLHttpRequest': The object's state must be OPENED.`, "InvalidStateError");
6973
+ }
6974
+ #setReadyState(state) {
6975
+ this.readyState = state;
6976
+ this.dispatchEvent({ type: "readystatechange" });
6977
+ }
6978
+ };
6979
+ const installNetworkGlobals = (target) => {
6980
+ const install = (name, value) => {
6981
+ if (typeof target[name] === "undefined") target[name] = value;
6982
+ };
6983
+ install("TextEncoder", LynxTextEncoder);
6984
+ install("TextDecoder", LynxTextDecoder);
6985
+ install("DOMException", LynxDOMException);
6986
+ if (typeof target["fetch"] === "undefined") {
6987
+ install("fetch", relayFetch);
6988
+ install("Headers", LynxHeaders);
6989
+ install("Request", LynxRequest);
6990
+ install("Response", LynxResponse);
6991
+ }
6992
+ install("XMLHttpRequest", LynxXMLHttpRequest);
6993
+ };
5657
6994
  const invalidUrl = () => /* @__PURE__ */ new TypeError("Invalid URL");
5658
6995
  const FORBIDDEN_HOST = /[\u0000\t\n\r #/:<>?@[\\\]^|]/;
5659
6996
  const FORBIDDEN_DOMAIN = /[\u0000-\u001f #%/:<>?@[\\\]^|\u007f]/;
@@ -6388,6 +7725,7 @@ if (typeof AbortController === "undefined") {
6388
7725
  };
6389
7726
  }
6390
7727
  installUrl(globalThis);
7728
+ if (isMainThread()) installNetworkGlobals(globalThis);
6391
7729
  if (typeof globalThis.queueMicrotask !== "function") {
6392
7730
  if (typeof lynx !== "undefined" && lynx.queueMicrotask) globalThis.queueMicrotask = lynx.queueMicrotask;
6393
7731
  else {
@@ -6548,27 +7886,41 @@ const ssrHydrate = (info) => {
6548
7886
  globalThis.__LYNX_HYDRATE_PAGE__ = nativePage;
6549
7887
  globalThis.__LYNX_HYDRATE_QUEUE__ = elementQueue;
6550
7888
  };
6551
- const __workletMap = {};
6552
- const __mainThreadRefMap = {};
6553
- const __pendingResolvers = {};
6554
- let __nextResolveId = 0;
6555
- const nextResolveId = () => __nextResolveId++;
6556
- const transformParams = (value) => {
6557
- if (typeof value !== "object" || value === null) return value;
6558
- if (Array.isArray(value)) return value.map(transformParams);
6559
- const obj = value;
6560
- if ("elementRefptr" in obj) return new MainThreadElement(obj["elementRefptr"]);
6561
- if ("_wvid" in obj) return __mainThreadRefMap[obj["_wvid"]] ?? obj;
6562
- const result = {};
6563
- for (const key of Object.keys(obj)) result[key] = transformParams(obj[key]);
6564
- return result;
7889
+ const callWorklet = (id, args, kind) => {
7890
+ const fn = __workletMap[id];
7891
+ if (!fn) throw new Error(`[angular-lynx] ${kind} not found: ${id}`);
7892
+ return fn(...args);
6565
7893
  };
6566
- const pageReady = new Subject();
6567
- globalThis.renderPage = () => {
7894
+ const pageReady = new ReplaySubject(1);
7895
+ globalThis.renderPage = (data) => {
7896
+ if (typeof lynx !== "undefined") lynx.__initData = data ?? {};
6568
7897
  pageReady.next();
6569
7898
  };
6570
- globalThis.updatePage = () => {};
6571
- globalThis.processData = () => {};
7899
+ globalThis.updatePage = (data, options) => {
7900
+ if (typeof lynx !== "undefined") applyInitDataUpdate(data, !!options?.resetPageData);
7901
+ };
7902
+ globalThis.updateGlobalProps = (data) => {
7903
+ if (typeof lynx !== "undefined") applyGlobalDataUpdate(data);
7904
+ };
7905
+ if (__MAIN_THREAD__ && typeof lynx !== "undefined" && typeof lynx.getEngine === "function") lynx.getEngine().addEventListener("__UpdateGlobalProps", (event) => applyGlobalDataUpdate(event.data?.[0]));
7906
+ globalThis.processData = (data) => data;
7907
+ if (!__MAIN_THREAD__ && typeof lynx !== "undefined" && typeof lynx.getApp === "function") {
7908
+ const app = lynx.getApp();
7909
+ const params = app._params;
7910
+ lynx.__initData = {
7911
+ ...params?.initData,
7912
+ ...params?.updateData
7913
+ };
7914
+ const emit = (eventName, args) => lynx.getJSModule?.("GlobalEventEmitter")?.emit?.(eventName, args);
7915
+ app.updateCardData = (data, options) => {
7916
+ const { __lynx_timing_flag: _timingFlag, ...patch } = data ?? {};
7917
+ applyInitDataUpdate(patch, options?.type === 1);
7918
+ emit("onDataChanged", [patch]);
7919
+ };
7920
+ app.updateGlobalProps = (data) => {
7921
+ emit("onGlobalPropsChanged", [applyGlobalDataUpdate(data)]);
7922
+ };
7923
+ }
6572
7924
  if (__ENABLE_SSR__) {
6573
7925
  globalThis.ssrEncode = ssrEncode;
6574
7926
  globalThis.ssrHydrate = ssrHydrate;
@@ -6588,36 +7940,15 @@ globalThis.runWorklet = (ctx, params) => {
6588
7940
  };
6589
7941
  if (__MAIN_THREAD__) {
6590
7942
  try {
6591
- if (typeof lynx !== "undefined" && lynx.getJSContext) {
6592
- lynx.getJSContext().addEventListener("Lynx.Worklet.runWorkletCtx", (event) => {
6593
- const { worklet, params, resolveId } = JSON.parse(event.data);
6594
- const fn = __workletMap[worklet._wkltId];
6595
- let returnValue;
6596
- let error;
6597
- try {
6598
- returnValue = fn?.(...params);
6599
- } catch (e) {
6600
- error = String(e);
6601
- }
6602
- lynx.getJSContext().dispatchEvent({
6603
- type: "Lynx.Worklet.FunctionCallRet",
6604
- data: JSON.stringify({
6605
- resolveId,
6606
- returnValue,
6607
- error
6608
- })
6609
- });
6610
- });
6611
- lynx.getJSContext().addEventListener("Lynx.Worklet.BgFunctionCallRet", (event) => {
6612
- const { resolveId, returnValue, error } = JSON.parse(event.data);
6613
- const resolver = __pendingResolvers[resolveId];
6614
- if (resolver) {
6615
- delete __pendingResolvers[resolveId];
6616
- if (error) resolver.reject(new Error(error));
6617
- else resolver.resolve(returnValue);
6618
- }
6619
- });
6620
- }
7943
+ if (typeof lynx !== "undefined" && lynx.getJSContext) lynx.getJSContext().addEventListener("Lynx.Worklet.BgFunctionCallRet", (event) => {
7944
+ const { resolveId, returnValue, error } = JSON.parse(event.data);
7945
+ const resolver = __pendingResolvers[resolveId];
7946
+ if (resolver) {
7947
+ delete __pendingResolvers[resolveId];
7948
+ if (error) resolver.reject(new Error(error));
7949
+ else resolver.resolve(returnValue);
7950
+ }
7951
+ });
6621
7952
  } catch {}
6622
7953
  globalThis.runOnBackground = (handle, ...args) => {
6623
7954
  const resolveId = nextResolveId();
@@ -6643,44 +7974,15 @@ if (__MAIN_THREAD__) {
6643
7974
  };
6644
7975
  }
6645
7976
  if (!__MAIN_THREAD__) try {
6646
- if (typeof lynx !== "undefined" && lynx.getCoreContext) {
6647
- lynx.getCoreContext().addEventListener("Lynx.Worklet.FunctionCallRet", (event) => {
6648
- const { resolveId, returnValue, error } = JSON.parse(event.data);
6649
- const resolver = __pendingResolvers[resolveId];
6650
- if (resolver) {
6651
- delete __pendingResolvers[resolveId];
6652
- if (error) resolver.reject(new Error(error));
6653
- else resolver.resolve(returnValue);
6654
- }
6655
- });
6656
- lynx.getCoreContext().addEventListener("Lynx.Worklet.runOnBackground", (event) => {
6657
- const { worklet, params, resolveId } = JSON.parse(event.data);
6658
- const fn = __workletMap[worklet._wkltId];
6659
- let returnValue;
6660
- let error;
6661
- try {
6662
- returnValue = fn?.(...params);
6663
- } catch (e) {
6664
- error = String(e);
6665
- }
6666
- lynx.getCoreContext().dispatchEvent({
6667
- type: "Lynx.Worklet.BgFunctionCallRet",
6668
- data: JSON.stringify({
6669
- resolveId,
6670
- returnValue,
6671
- error
6672
- })
6673
- });
6674
- });
6675
- }
7977
+ if (typeof lynx !== "undefined" && lynx.getCoreContext) lynx.getCoreContext().addEventListener("Lynx.Worklet.runOnBackground", (event) => {
7978
+ const { worklet, params, resolveId } = JSON.parse(event.data);
7979
+ answerCall(resolveId, () => callWorklet(worklet._wkltId, params.map(restoreRefs), "Background function"), (data) => lynx.getCoreContext().dispatchEvent({
7980
+ type: "Lynx.Worklet.BgFunctionCallRet",
7981
+ data
7982
+ }));
7983
+ });
6676
7984
  } catch {}
6677
- globalThis.__lynxMtsPendingResolvers = __pendingResolvers;
6678
- globalThis.__lynxMtsNextResolveId = nextResolveId;
6679
- globalThis.__lynxRunMainThreadWorklet = (wkltId, args) => {
6680
- const fn = __workletMap[wkltId];
6681
- if (!fn) throw new Error(`[angular-lynx] Main-thread worklet not found: ${wkltId}`);
6682
- return fn(...args);
6683
- };
7985
+ globalThis.__lynxRunMainThreadWorklet = (wkltId, args) => callWorklet(wkltId, args, "Main-thread worklet");
6684
7986
  const installLazyBundleLoader = () => {
6685
7987
  const host = lynx;
6686
7988
  host.loadLazyBundle = loadLazyBundleWithQueryComponent;
@@ -6746,15 +8048,25 @@ const makeSyncThen = (value) => (onFulfilled) => {
6746
8048
  if (next && typeof next.then === "function") return next;
6747
8049
  return syncResolved(next);
6748
8050
  };
8051
+ const ɵstartBackgroundThread = () => {
8052
+ installLazyBundleLoader();
8053
+ };
6749
8054
  const bootstrapApplication = async (rootComponent, options) => {
8055
+ if (!__MAIN_THREAD__) return new Promise(() => {});
6750
8056
  installLazyBundleLoader();
8057
+ const bootstrap = bootstrapOnMainThread(rootComponent, options);
8058
+ globalThis.__LYNX_ANGULAR_BOOTSTRAP__ = bootstrap;
8059
+ return bootstrap;
8060
+ };
8061
+ const bootstrapOnMainThread = async (rootComponent, options) => {
6751
8062
  const prev = globalThis.__LYNX_ANGULAR_APP_REF__;
6752
8063
  if (prev) {
8064
+ carryOverLocation(prev.injector);
8065
+ handOverPageToNextApp();
6753
8066
  prev.destroy();
6754
8067
  globalThis.__LYNX_ANGULAR_APP_REF__ = void 0;
6755
- for (const key of Object.keys(__workletMap)) delete __workletMap[key];
6756
8068
  }
6757
- if (__MAIN_THREAD__ && !prev) await firstValueFrom(pageReady);
8069
+ await firstValueFrom(pageReady);
6758
8070
  const appRef = await bootstrapApplication$1(rootComponent, options);
6759
8071
  markFirstRenderComplete();
6760
8072
  globalThis.__LYNX_ANGULAR_APP_REF__ = appRef;
@@ -6764,9 +8076,9 @@ const bootstrapApplication = async (rootComponent, options) => {
6764
8076
  globalThis.__LYNX_HYDRATE_PAGE__ = void 0;
6765
8077
  globalThis.__LYNX_HYDRATE_QUEUE__ = void 0;
6766
8078
  }
6767
- if (__WEB__ && __MAIN_THREAD__ && !wasHydrating) setTimeout(() => __FlushElementTree(), 0);
8079
+ if (__WEB__ && !wasHydrating) setTimeout(() => __FlushElementTree(), 0);
6768
8080
  return appRef;
6769
8081
  };
6770
- export { BaseGesture, ComposedGesture, ContinuousGesture, FlingDirection, FlingGesture, Gesture, GestureState, GestureStateManager, GestureType, LYNX_ELEMENTS, LYNX_FORM_ACCESSORS, LongPressGesture, LynxAccessibility, LynxAnimation, LynxBlock, LynxBlurView, LynxCoverView, LynxDevTools, LynxErrorHandler, LynxExposure, LynxFont, LynxFor, LynxFrame, LynxGestureDetector, LynxGlobalData, LynxGlobalExposure, LynxIf, LynxImage, LynxInitData, LynxInlineTruncation, LynxInput, LynxInputValueAccessor, LynxList, LynxListItem, LynxLocale, LynxLocationStrategy, LynxLogger, LynxMainThread, LynxMainThreadEvent, LynxNativeModule, LynxOverlay, LynxPerformance, LynxPlatformLocation, LynxPortal, LynxRefresh, LynxRefreshHeader, LynxResourcePrefetch, LynxRouteReuseStrategy, LynxSafeArea, LynxScrollCoordinator, LynxScrollCoordinatorHeader, LynxScrollCoordinatorSlot, LynxScrollCoordinatorSlotDrag, LynxScrollCoordinatorToolbar, LynxScrollView, LynxSessionStorage, LynxSvg, LynxSystemInfo, LynxText, LynxTextMeasure, LynxTextarea, LynxTextareaValueAccessor, LynxTheme, LynxTitleBarView, LynxTransition, LynxTransitionGroup, LynxVideo, LynxView, LynxViewPager, LynxViewPagerItem, LynxWebView, MainThreadElement, MainThreadRef, PanGesture, PinchGesture, PortalRef, RotationGesture, SAFE_AREA_INSET_BOTTOM, SAFE_AREA_INSET_LEFT, SAFE_AREA_INSET_RIGHT, SAFE_AREA_INSET_TOP, TapGesture, backgroundFn, bootstrapApplication, createMainThreadRef, getLynxAppLocale, loadLazyBundle, mainThreadFn, provideLocale, provideRenderer, provideRouter, registerDataProcessors };
8082
+ export { BaseGesture, ComposedGesture, ContinuousGesture, FlingDirection, FlingGesture, Gesture, GestureState, GestureStateManager, GestureType, LYNX_ELEMENTS, LYNX_FORM_ACCESSORS, LongPressGesture, LynxAccessibility, LynxAnimation, LynxBlock, LynxBlurView, LynxCoverView, LynxDevTools, LynxErrorHandler, LynxExposure, LynxFont, LynxFor, LynxFrame, LynxGestureDetector, LynxGlobalData, LynxGlobalExposure, LynxIf, LynxImage, LynxInitData, LynxInlineTruncation, LynxInput, LynxInputValueAccessor, LynxList, LynxListItem, LynxLocale, LynxLocationStrategy, LynxLogger, LynxMainThread, LynxMainThreadEvent, LynxNativeModule, LynxOverlay, LynxPerformance, LynxPlatformLocation, LynxPortal, LynxRefresh, LynxRefreshHeader, LynxResourcePrefetch, LynxRouteReuseStrategy, LynxSafeArea, LynxScrollCoordinator, LynxScrollCoordinatorHeader, LynxScrollCoordinatorSlot, LynxScrollCoordinatorSlotDrag, LynxScrollCoordinatorToolbar, LynxScrollView, LynxSessionStorage, LynxSvg, LynxSystemInfo, LynxText, LynxTextMeasure, LynxTextarea, LynxTextareaValueAccessor, LynxTheme, LynxTitleBarView, LynxTransition, LynxTransitionGroup, LynxVideo, LynxView, LynxViewPager, LynxViewPagerItem, LynxWebView, MainThreadElement, MainThreadRef, PanGesture, PinchGesture, PortalRef, RotationGesture, SAFE_AREA_INSET_BOTTOM, SAFE_AREA_INSET_LEFT, SAFE_AREA_INSET_RIGHT, SAFE_AREA_INSET_TOP, TapGesture, backgroundFn, bootstrapApplication, createMainThreadRef, getLynxAppLocale, loadLazyBundle, mainThreadFn, provideLocale, provideRenderer, provideRouter, registerDataProcessors, ɵhmrAccept, ɵstartBackgroundThread };
6771
8083
 
6772
8084
  //# sourceMappingURL=blotch-angular-lynx.mjs.map