@webview-native-ui/engine 0.0.5 → 0.0.6

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.
@@ -44,7 +44,11 @@ const createProjectionEngine = async (scope, transport, callbacks) => {
44
44
  const signature = (candidates) => JSON.stringify(candidates.map((candidate) => {
45
45
  if (!scopeIDs.has(candidate.scope))
46
46
  scopeIDs.set(candidate.scope, ++scopeSerial);
47
- return [scopeIDs.get(candidate.scope), layout([candidate], !!callbacks.opaqueUnderlay)];
47
+ const origin = callbacks.transient && !callbacks.opaqueUnderlay ? candidate.scope.element.getBoundingClientRect() : undefined;
48
+ const relative = origin
49
+ ? { ...candidate, control: { ...candidate.control, x: candidate.control.x - origin.x, y: candidate.control.y - origin.y } }
50
+ : candidate;
51
+ return [scopeIDs.get(candidate.scope), layout([relative], !!callbacks.opaqueUnderlay)];
48
52
  }));
49
53
  const sheets = new Map();
50
54
  const rootFor = (element) => {
@@ -609,6 +613,10 @@ const createProjectionEngine = async (scope, transport, callbacks) => {
609
613
  updateOffsets();
610
614
  return true;
611
615
  };
616
+ const currentParts = (image) => image.images.map((element, index) => {
617
+ const rect = element.getBoundingClientRect();
618
+ return { ...image.data.parts[index], x: rect.x, y: rect.y, width: rect.width, height: rect.height };
619
+ });
612
620
  const begin = () => {
613
621
  retireRestoration();
614
622
  if (stopped || destination === 'none' || active)
@@ -650,7 +658,11 @@ const createProjectionEngine = async (scope, transport, callbacks) => {
650
658
  handoffPending = false;
651
659
  callbacks.wake();
652
660
  });
653
- void bounded(call({ action: 'cover', token: image.data.token, ...(callbacks.transient ? { transient: true } : {}) }))
661
+ void bounded(call({
662
+ action: 'cover',
663
+ token: image.data.token,
664
+ ...(callbacks.transient ? { transient: true, viewportWidth: win.innerWidth, parts: currentParts(image) } : {}),
665
+ }))
654
666
  .then((result) => {
655
667
  if (!isCurrent())
656
668
  return;
@@ -704,16 +716,14 @@ const createProjectionEngine = async (scope, transport, callbacks) => {
704
716
  abandon(image, false);
705
717
  return;
706
718
  }
707
- const parts = targets.map((target, index) => {
708
- const rect = image.images[index].getBoundingClientRect();
709
- return { ...image.data.parts[index], x: rect.x, y: rect.y, width: rect.width, height: rect.height };
710
- });
711
- if (parts.some((part, index) => ['x', 'y', 'width', 'height'].some((key) => part[key] !== image.data.parts[index][key]))) {
712
- if (callbacks.opaqueUnderlay)
713
- image.data = { ...image.data, parts };
714
- else
715
- cached = undefined;
716
- }
719
+ const parts = currentParts(image);
720
+ // Translation changes placement, not pixels. Keep the pre-interaction
721
+ // image until its replacement is ready; resizing still invalidates it.
722
+ if (callbacks.opaqueUnderlay ||
723
+ parts.every((part, index) => part.width === image.data.parts[index].width && part.height === image.data.parts[index].height))
724
+ image.data = { ...image.data, parts };
725
+ else
726
+ cached = undefined;
717
727
  // Both requests use the same ordered bridge. Reprojection need not await this optional copy.
718
728
  void call({ action: 'restore', token: image.data.token, viewportWidth: win.innerWidth, parts }).catch(() => { });
719
729
  }
package/dist/types.d.ts CHANGED
@@ -52,6 +52,10 @@ export type WebProjectionRequest = {
52
52
  action: 'cover';
53
53
  token: string;
54
54
  transient?: boolean;
55
+ viewportWidth?: number;
56
+ parts?: (Frame & {
57
+ ids: string[];
58
+ })[];
55
59
  } | {
56
60
  action: 'restore';
57
61
  token: string;
@@ -220,7 +220,7 @@ Use `createWebProjectionBatch(transport, options)` when several fallback element
220
220
 
221
221
  The batch derives its Document from the first nonempty `consider`; all subsequent scopes and sources must belong to that Document. Before this first update, `begin()` does nothing and `destroy()` is safe. A changed fallback requires a new scope. Scope identity participates in cache invalidation; an active presentation retains its captured scopes until restoration finishes.
222
222
 
223
- `WebProjectionRequest` is an action-discriminated union. `prepare` requires `revision`, `viewportWidth` and `ids`; `cover` requires `token`; `restore` requires `token`, `viewportWidth` and destination `parts`; `painted`, `restored` and `release` require `token`; `reset` takes no payload. Empty preparation results and `{ shown: false }` mean the plugin should use its normal Web fallback. Use the plugin's existing ordered bridge; the engine does not retry user actions.
223
+ `WebProjectionRequest` is an action-discriminated union. `prepare` requires `revision`, `viewportWidth` and `ids`; `cover` requires `token` and includes `viewportWidth` and destination `parts` for transient movement; `restore` requires `token`, `viewportWidth` and destination `parts`; `painted`, `restored` and `release` require `token`; `reset` takes no payload. Empty preparation results and `{ shown: false }` mean the plugin should use its normal Web fallback. Use the plugin's existing ordered bridge; the engine does not retry user actions.
224
224
 
225
225
  ### Native handoff on both platforms
226
226
 
@@ -229,13 +229,17 @@ Call all view and snapshot lifecycle APIs on the main/UI thread. Native input fr
229
229
  On both platforms, `cover` installs the prepared entry image **before hiding the supplied live views**, within the same UI turn. Its boolean result reports whether this was possible; failure leaves visibility unchanged. Supply the actual views for every captured component. Do not separately hide views or create another entry copy.
230
230
 
231
231
  ```swift
232
- let shown = snapshots.cover(token, in: webView, views: renderedViews, transient: movingSurface)
232
+ let shown = snapshots.cover(token, in: webView, views: renderedViews, transient: movingSurface, frames: destinationFrames)
233
233
  ```
234
234
 
235
235
  ```kotlin
236
- val shown = snapshots.cover(token, activity.window, webView, renderedViews, transient = movingSurface)
236
+ val shown = snapshots.cover(token, activity.window, webView, renderedViews, transient = movingSurface, frames = destinationFrames)
237
237
  ```
238
238
 
239
+ For a custom transport, convert request `parts` from CSS pixels to native frames using `webView.bounds.width / viewportWidth` on iOS or `webView.width / viewportWidth` on Android, mapping each part's IDs to its rectangle. Pass these as `destinationFrames` for both `cover` and `restore`. A retained image can move before its first cover or after a failed return copy; always use the supplied coordinates. When `parts` is absent, pass `nil` / `null` to retain the captured placement. The high-level `NativeUIProjection` registration handles this conversion automatically.
240
+
241
+ A transient surface keeps its image while its sources retain the same sizes and positions relative to their projection scopes. Moving the whole scope can reuse pixels; moving a source inside a fixed scope invalidates the cached layout.
242
+
239
243
  `transient: true` is for a moving foreground surface: it does not replace the background's `coveringToken`. Retire the entry copy with `retireCopy(token)` after Web image readiness. Before applying a normal native update, undo the engine's visibility changes with iOS `restoreControls()` / Android `restoreViews()`. For return, `restore` installs the cached return image, the plugin renders underneath it, and `retireCopy(token, entry: false)` retires it after the corresponding acknowledgement/readiness. These platform-native names remain idiomatic; the lifecycle is the same. `cover` is an entry operation, not a method to repeat on each normal update.
240
244
 
241
245
  Token cleanup uses `release(token)`; owner teardown uses `reset()` (and Android `close()` when disposing its encoder). A surface manager must not reset another surface's captures. Web fallback remains the renderer's responsibility when a capture or native placement is unavailable.
@@ -244,15 +248,15 @@ The optional `eligible(source)` and `current(sources)` callbacks keep framework-
244
248
 
245
249
  The image transport accepts `WebProjectionRequest` and returns prepared token/parts or `{ shown: false }`. Parts use local `file:` URLs and CSS-pixel viewport coordinates. Requests use the plugin's existing ordered bridge:
246
250
 
247
- | Action | Native responsibility |
248
- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
249
- | `prepare` | Validate the current revision and IDs, then `NativeUICoveredSnapshots.prepare` using actual rendered frames. |
250
- | `cover` | Validate the token and complete native surface ownership; create the entry copy and hide the associated native views. Return `shown: false` on failure. |
251
- | `painted` | Retire only that token's entry copy. |
252
- | `restore` | Rebase the prepared return copy to supplied frames. Never capture here. |
253
- | `restored` | Retire only that token's return copy after the native update ACK and Web paint boundary. |
254
- | `release` | Release the named token, files and associated temporary views. |
255
- | `reset` | Owner teardown only; release all native capture resources. |
251
+ | Action | Native responsibility |
252
+ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
253
+ | `prepare` | Validate the current revision and IDs, then `NativeUICoveredSnapshots.prepare` using actual rendered frames. |
254
+ | `cover` | Validate the token and complete native surface ownership; create the entry copy at supplied frames (or captured frames when absent) and hide the associated native views. Return `shown: false` on failure. |
255
+ | `painted` | Retire only that token's entry copy. |
256
+ | `restore` | Rebase the prepared return copy to supplied frames. Never capture here. |
257
+ | `restored` | Retire only that token's return copy after the native update ACK and Web paint boundary. |
258
+ | `release` | Release the named token, files and associated temporary views. |
259
+ | `reset` | Owner teardown only; release all native capture resources. |
256
260
 
257
261
  Use `NativeUICoveredSnapshots.observe` to notify the JS listener when interaction starts/ends. On iOS, captures rasterize the visible window with `drawHierarchy(in:afterScreenUpdates:)`, including the background under the clipped native component. Screen snapshot views are display replicas and are not used as bitmap sources. UIKit rasterization can differ from the live compositor for materials such as Liquid Glass; validate the appearance on physical devices with the backgrounds your plugin supports. Cache validity therefore includes layout and the plugin's visual-change notifications. The engine does not capture continuously or guarantee every possible renderer can be captured.
258
262
 
@@ -150,8 +150,8 @@ public final class NativeUICoveredSnapshots {
150
150
 
151
151
  /// Install prepared pixels before hiding live views, within the same main-thread turn.
152
152
  /// A transient (moving) surface does not replace background covering ownership.
153
- @discardableResult public func cover(_ token: String, in webView: UIView, views: [UIView], transient: Bool = false) -> Bool {
154
- guard restore(in: webView, token: token, entry: true) else { return false }
153
+ @discardableResult public func cover(_ token: String, in webView: UIView, views: [UIView], transient: Bool = false, frames: [String: CGRect]? = nil) -> Bool {
154
+ guard restore(in: webView, token: token, frames: frames, entry: true) else { return false }
155
155
  if !transient { coveringToken = token }
156
156
  hide(views, for: token)
157
157
  return true
@@ -30,7 +30,18 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
30
30
  private let views: () -> [String: UIView]
31
31
  private let snapshots: NativeUICoveredSnapshots
32
32
  private let scrolling = NativeUIScrollBindings()
33
- private var masks: [String: CAShapeLayer] = [:]
33
+ private struct ScrollMask {
34
+ weak var view: UIView?
35
+ let layer: CAShapeLayer
36
+ }
37
+ private var masks: [String: ScrollMask] = [:]
38
+ private func resetScrolling() {
39
+ scrolling.reset()
40
+ for mask in masks.values where mask.view?.layer.mask === mask.layer {
41
+ mask.view?.layer.mask = nil
42
+ }
43
+ masks.removeAll()
44
+ }
34
45
  private let id = "nativeUI" + UUID().uuidString.replacingOccurrences(of: "-", with: "")
35
46
  private let origins: Set<String>
36
47
  private let allowedOriginsJSON: String
@@ -145,12 +156,26 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
145
156
  let key = message["key"] as? String, key.hasPrefix(id + ":"),
146
157
  let request = message["request"] as? [String: Any] else { return }
147
158
  let page = key.split(separator: ":").dropFirst().first.map(String.init)
148
- if documentID != page { snapshots.reset(); scrolling.reset(); captured.removeAll(); anchors.removeAll(); documentID = page }
159
+ if documentID != page { snapshots.reset(); resetScrolling(); captured.removeAll(); anchors.removeAll(); documentID = page }
149
160
  let complete: ([String: Any]) -> Void = { [weak self] value in
150
161
  guard let self, !self.closed, self.documentID == page else { return }
151
162
  self.reply(key, value)
152
163
  }
153
164
  let token = request["token"] as? String ?? ""
165
+ func projectionFrames() -> [String: CGRect]? {
166
+ guard let width = request["viewportWidth"] as? Double, width.isFinite, width > 0,
167
+ let parts = request["parts"] as? [[String: Any]] else { return nil }
168
+ var frames: [String: CGRect] = [:]
169
+ let scale = webView.bounds.width / width
170
+ for part in parts {
171
+ guard let ids = part["ids"] as? [String], let x = part["x"] as? Double, let y = part["y"] as? Double,
172
+ let w = part["width"] as? Double, let h = part["height"] as? Double,
173
+ [x,y,w,h].allSatisfy({ $0.isFinite }), w > 0, h > 0 else { return nil }
174
+ for id in ids { frames[id] = CGRect(x: x*scale, y: y*scale, width: w*scale, height: h*scale) }
175
+ }
176
+ guard Set(frames.keys) == snapshots.identifiers(for: token), !frames.isEmpty else { return nil }
177
+ return frames
178
+ }
154
179
  switch request["action"] as? String {
155
180
  case "connect":
156
181
  if !connected { destination = (views().values.contains(where: { !$0.isHidden }) ? "native" : "none"); connected = true }
@@ -159,9 +184,7 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
159
184
  if let next = request["destination"] as? String, ["native", "web", "none"].contains(next) { destination = next; connected = true }
160
185
  complete([:])
161
186
  case "track":
162
- scrolling.reset()
163
- for (id, mask) in masks { if views()[id]?.layer.mask === mask { views()[id]?.layer.mask = nil } }
164
- masks.removeAll()
187
+ resetScrolling()
165
188
  guard let raw = request["scroll"] as? [String: Any], let width = request["viewportWidth"] as? Double, width.isFinite, width > 0,
166
189
  let data = try? JSONSerialization.data(withJSONObject: raw),
167
190
  let placement = try? JSONDecoder().decode(NativeUIScrollPlacement.self, from: data), placement.isValid else {
@@ -185,8 +208,8 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
185
208
  let from = parent.convert(CGPoint(x: old.midX, y: old.midY), from: webView)
186
209
  let to = parent.convert(CGPoint(x: frame.midX, y: frame.midY), from: webView)
187
210
  view.transform.tx += to.x-from.x; view.transform.ty += to.y-from.y
188
- let mask = self.masks[id] ?? CAShapeLayer()
189
- self.masks[id] = mask
211
+ let mask = self.masks[id]?.layer ?? CAShapeLayer()
212
+ self.masks[id] = ScrollMask(view: view, layer: mask)
190
213
  mask.frame = view.bounds
191
214
  mask.path = UIBezierPath(rect: clip.isNull ? .zero : view.convert(clip, from: webView).intersection(view.bounds)).cgPath
192
215
  view.layer.mask = mask
@@ -221,21 +244,13 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
221
244
  case "cover":
222
245
  let selected = captured[token] ?? [:], current = views()
223
246
  let valid = visible && canCapture() && !selected.isEmpty && selected.allSatisfy { current[$0.key] === $0.value }
247
+ let frames = request["parts"] == nil ? nil : projectionFrames()
248
+ guard request["parts"] == nil || frames != nil else { complete(["shown": false]); return }
224
249
  restoreAccepted = true
225
- complete(["shown": valid && snapshots.cover(token, in: webView, views: Array(Dictionary(grouping: selected.values, by: { ObjectIdentifier($0) }).values.compactMap { $0.first }), transient: true)])
250
+ complete(["shown": valid && snapshots.cover(token, in: webView, views: Array(Dictionary(grouping: selected.values, by: { ObjectIdentifier($0) }).values.compactMap { $0.first }), transient: true, frames: frames)])
226
251
  case "restore":
227
252
  restoreAccepted = false
228
- guard let width = request["viewportWidth"] as? Double, width.isFinite, width > 0,
229
- let parts = request["parts"] as? [[String: Any]] else { complete(["shown": false]); return }
230
- var frames: [String: CGRect] = [:]
231
- let scale = webView.bounds.width / width
232
- for part in parts {
233
- guard let ids = part["ids"] as? [String], let x = part["x"] as? Double, let y = part["y"] as? Double,
234
- let w = part["width"] as? Double, let h = part["height"] as? Double,
235
- [x,y,w,h].allSatisfy({ $0.isFinite }), w > 0, h > 0 else { complete(["shown": false]); return }
236
- for id in ids { frames[id] = CGRect(x: x*scale, y: y*scale, width: w*scale, height: h*scale) }
237
- }
238
- guard Set(frames.keys) == snapshots.identifiers(for: token), !frames.isEmpty else { complete(["shown": false]); return }
253
+ guard let frames = projectionFrames() else { complete(["shown": false]); return }
239
254
  let current = views()
240
255
  // Preserve renderer-owned constraints. Translation follows the corresponding DOM's movement.
241
256
  for (id, frame) in frames {
@@ -298,11 +313,9 @@ public final class NativeUIProjection: NSObject, WKScriptMessageHandler {
298
313
  controller.removeAllUserScripts()
299
314
  remaining.forEach { controller.addUserScript($0) }
300
315
  }
301
- snapshots.reset(); scrolling.reset(); captured.removeAll(); anchors.removeAll()
316
+ snapshots.reset(); resetScrolling(); captured.removeAll(); anchors.removeAll()
302
317
  if destination != "none" { hiddenByProjection.forEach { $0.isHidden = false } }
303
318
  hiddenByProjection.removeAll()
304
- for (id, mask) in masks { if views()[id]?.layer.mask === mask { views()[id]?.layer.mask = nil } }
305
- masks.removeAll()
306
319
  }
307
320
  }
308
321
  private final class WeakProjectionHandler: NSObject, WKScriptMessageHandler {
@@ -1,4 +1,4 @@
1
- "use strict";var WebViewNativeUIEngineRuntime=(()=>{var _e=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var dt=Object.getOwnPropertyNames;var ut=Object.prototype.hasOwnProperty;var ft=(t,r)=>{for(var o in r)_e(t,o,{get:r[o],enumerable:!0})},pt=(t,r,o,v)=>{if(r&&typeof r=="object"||typeof r=="function")for(let h of dt(r))!ut.call(t,h)&&h!==o&&_e(t,h,{get:()=>r[h],enumerable:!(v=lt(r,h))||v.enumerable});return t};var mt=t=>pt(_e({},"__esModule",{value:!0}),t);var Ct={};ft(Ct,{hide:()=>Ht,notify:()=>Tt,receive:()=>jt,show:()=>St,start:()=>kt,stop:()=>xt});var vt=Symbol.for("webview-native-ui-engine.projection-placement");var Ne=t=>t?.[vt];var ht=(t,r)=>{if(t.matches("ion-toast, ion-menu"))return!1;let o=t;if(o.showBackdrop===!1)return!1;if(!t.matches("ion-modal"))return!0;let v=r??o.initialBreakpoint;return v===void 0||v>(o.backdropBreakpoint??0)},yt=Symbol.for("@webview-native-ui/engine/overlays/v1"),gt=t=>{let r=new Set,o=new Set,v=new Set,h=new WeakMap,d=new WeakSet,p=new Map,T=[],f={},M=new Map,C,j=y=>{for(let l of[...v])try{l(y)}catch(g){console.error("Native UI overlay listener failed",g)}},B=(y,l,g)=>{l==="willPresent"||l==="didPresent"?(d.delete(y),r.add(y)):l==="didDismiss"&&(d.add(y),r.delete(y),o.delete(y),h.delete(y));let c=g?.detail?.breakpoint;typeof c=="number"&&c>0&&h.set(y,c),j({element:y,phase:l,event:g})},S=(y=!1)=>{let l=!1;for(let g of r)(!g.isConnected||g.ownerDocument!==t||!T.some(({selector:c})=>g.matches(c)))&&(r.delete(g),o.delete(g),l=!0);for(let g of t.querySelectorAll(T.map(({selector:c})=>c).join(",")))!r.has(g)&&!d.has(g)&&(y||!g.matches("ion-popover"))&&(g.presented||g.classList.contains("show-menu"))&&(r.add(g),l=!0);l&&j({phase:"change"})};return{get active(){return r},subscribe(y){return v.add(y),()=>{v.delete(y)}},setNative(y,l){o.has(y)!==l&&(l?o.add(y):o.delete(y),j({element:y,phase:"change"}))},isExcluded(y){return!!f.exclude&&y.matches(f.exclude)},isNative(y){return o.has(y)},get stack(){let y=[...r].filter(g=>g.isConnected&&g.ownerDocument===t),l=g=>{let c=Number.parseFloat(t.defaultView.getComputedStyle(g).zIndex);return Number.isFinite(c)?c:g.overlayIndex??0};return y.sort((g,c)=>l(g)-l(c)),y},isCovered(y){let l=this.stack,g=l.reduce((c,D,H)=>D.contains(y)?H:c,-1);return l.some((c,D)=>{if(o.has(c)||f.exclude&&c.matches(f.exclude))return!1;let H=f.covers?.(c,y);return H!==void 0?H:D>g&&!c.contains(y)&&(c.matches("ion-menu")||ht(c,h.get(c)))})},enable(y,l){let g={...f,...l},c=[...y,...g.additional??[]];g.exclude&&t.querySelector(g.exclude);let D=new Map;for(let m of c){t.querySelector(m.selector);for(let[W,A]of Object.entries(m.events)){let N=D.get(A);if(N&&N.phase!==W)throw new TypeError(`Overlay event "${A}" has conflicting phases`);D.set(A,{phase:W,selector:N?`${N.selector}, ${m.selector}`:m.selector})}}f=g,T=c,M=D;for(let m of M.keys()){if(p.has(m))continue;let W=A=>{let N=M.get(m),oe=A.composedPath().find(F=>F instanceof t.defaultView.HTMLElement&&F.matches(N.selector));oe&&B(oe,N.phase,A)};t.addEventListener(m,W,!0),p.set(m,()=>t.removeEventListener(m,W,!0))}for(let[m,W]of p)M.has(m)||(W(),p.delete(m));let H=!C;C||(C=new MutationObserver(()=>S()),C.observe(t.documentElement,{childList:!0,subtree:!0}),t.addEventListener("nativeUIOverlayAdopted",m=>{let W=m.detail;W?.ownerDocument===t&&B(W,"willPresent",m)})),S(H),(H||l)&&j({phase:"change"})}}},et=t=>{let r=t;return r[yt]??=gt(t)};function*Oe(t){let r=t;for(;r;){let o=r.getRootNode();r=r.assignedSlot??r.parentElement??(o instanceof ShadowRoot?o.host:null),r&&(yield r)}}var wt=({x:t,y:r,width:o,height:v})=>({x:t,y:r,width:o,height:v}),tt=t=>{let r=t.getBoundingClientRect(),o=getComputedStyle(t),v=parseFloat(o.borderLeftWidth)||0,h=parseFloat(o.borderTopWidth)||0;return{x:r.left+v,y:r.top+h,width:r.width-v-(parseFloat(o.borderRightWidth)||0),height:r.height-h-(parseFloat(o.borderBottomWidth)||0)}},Ge=(t,r,o)=>{let v=[t,...Oe(t)],h=v.indexOf(r);if(h<=0||r===t.ownerDocument.scrollingElement)return;let d=t.ownerDocument.defaultView;if(d.visualViewport&&(d.visualViewport.scale!==1||d.visualViewport.offsetLeft||d.visualViewport.offsetTop))return;let p=0,T=0,f=d.innerWidth,M=d.innerHeight;for(let[S,y]of v.entries()){let l=getComputedStyle(y);if(l.transform!=="none"&&!new DOMMatrixReadOnly(l.transform).isIdentity||l.zoom&&l.zoom!=="normal"&&Number(l.zoom)!==1||[l.translate,l.rotate,l.scale,l.perspective].some(H=>H&&H!=="none")||l.writingMode&&l.writingMode!=="horizontal-tb"||S<h&&/^(fixed|sticky)$/.test(l.position))return;if(S===0)continue;if(l.scrollbarGutter&&l.scrollbarGutter!=="auto")return;let g=/^(auto|scroll|hidden|clip)$/.test(l.overflowX),c=/^(auto|scroll|hidden|clip)$/.test(l.overflowY);if(S<h&&(g||c))return;let D=y===t.ownerDocument.scrollingElement;if(S>h&&((g||D)&&y.scrollWidth>y.clientWidth||(c||D)&&y.scrollHeight>y.clientHeight)||(g||c)&&[l.borderTopLeftRadius,l.borderTopRightRadius,l.borderBottomLeftRadius,l.borderBottomRightRadius].some(H=>parseFloat(H)>0)||l.clipPath&&l.clipPath!=="none"||l.maskImage&&l.maskImage!=="none")return;if(S>=h){let H=tt(y);g&&(p=Math.max(p,H.x),f=Math.min(f,H.x+H.width)),c&&(T=Math.max(T,H.y),M=Math.min(M,H.y+H.height))}}let C=getComputedStyle(r);if(!/^(auto|scroll)$/.test(C.overflowX)&&!/^(auto|scroll)$/.test(C.overflowY))return;let j=tt(r);if(f<=p||M<=T||!j.width||!j.height)return;let B=wt(t.getBoundingClientRect());return{id:o(r),offsetX:r.scrollLeft,offsetY:r.scrollTop,viewport:j,clip:{x:p,y:T,width:f-p,height:M-T},contentWidth:r.scrollWidth,contentHeight:r.scrollHeight,frame:{...B,x:B.x-j.x+r.scrollLeft,y:B.y-j.y+r.scrollTop}}};var nt=t=>{let r=globalThis;if(r.Capacitor?.convertFileSrc)return r.Capacitor.convertFileSrc(t);if(!t.startsWith("file:"))return t;if(r.WkWebView?.convertFilePath)return r.WkWebView.convertFilePath(t);throw new Error("Native UI file URL requires a host resource handler")};var pe=t=>new Promise((r,o)=>{let v=setTimeout(()=>o(new Error("Native UI bridge timed out")),5e3);t.then(r,o).finally(()=>clearTimeout(v))}),Be=async t=>{try{return await pe(t)}catch(r){throw t.then(o=>o.remove()).catch(()=>{}),r}};var ze=async(t,r)=>{let o=new Map;for(let T of t.update??[])o.set(T,{updated:!0});for(let T of["native","web","none"])for(let f of t.projection?.[T]??[]){let M=o.get(f)??{updated:!1};if(M.destination&&M.destination!==T)throw new TypeError(`Projection event "${f}" has conflicting destinations`);o.set(f,{...M,destination:T})}let v=!1,h=[],d=async()=>{v=!0;let f=(await Promise.allSettled(h.splice(0).map(M=>Promise.resolve().then(()=>M.remove())))).find(M=>M.status==="rejected");if(f?.status==="rejected")throw f.reason},p=[...o].map(async([T,f])=>{let M=await Be(Promise.resolve().then(()=>t.addListener(T,C=>{!v&&(!t.accepts||t.accepts(C))&&r(f.destination,f.updated)})));v?await M.remove():h.push(M)});try{return await Promise.all(p),{remove:d}}catch(T){throw await d().catch(()=>{}),T}};var je=":is([data-native-ui-snapshot-source], [data-native-ui-snapshot-prepared], [data-native-ui-snapshot-content])",ot=`
1
+ "use strict";var WebViewNativeUIEngineRuntime=(()=>{var _e=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var ft=Object.prototype.hasOwnProperty;var pt=(t,i)=>{for(var r in i)_e(t,r,{get:i[r],enumerable:!0})},mt=(t,i,r,v)=>{if(i&&typeof i=="object"||typeof i=="function")for(let h of ut(i))!ft.call(t,h)&&h!==r&&_e(t,h,{get:()=>i[h],enumerable:!(v=dt(i,h))||v.enumerable});return t};var vt=t=>mt(_e({},"__esModule",{value:!0}),t);var Rt={};pt(Rt,{hide:()=>Ht,notify:()=>Lt,receive:()=>St,show:()=>xt,start:()=>Ct,stop:()=>kt});var ht=Symbol.for("webview-native-ui-engine.projection-placement");var Ne=t=>t?.[ht];var yt=(t,i)=>{if(t.matches("ion-toast, ion-menu"))return!1;let r=t;if(r.showBackdrop===!1)return!1;if(!t.matches("ion-modal"))return!0;let v=i??r.initialBreakpoint;return v===void 0||v>(r.backdropBreakpoint??0)},gt=Symbol.for("@webview-native-ui/engine/overlays/v1"),wt=t=>{let i=new Set,r=new Set,v=new Set,h=new WeakMap,d=new WeakSet,p=new Map,T=[],f={},L=new Map,C,j=y=>{for(let l of[...v])try{l(y)}catch(g){console.error("Native UI overlay listener failed",g)}},B=(y,l,g)=>{l==="willPresent"||l==="didPresent"?(d.delete(y),i.add(y)):l==="didDismiss"&&(d.add(y),i.delete(y),r.delete(y),h.delete(y));let c=g?.detail?.breakpoint;typeof c=="number"&&c>0&&h.set(y,c),j({element:y,phase:l,event:g})},S=(y=!1)=>{let l=!1;for(let g of i)(!g.isConnected||g.ownerDocument!==t||!T.some(({selector:c})=>g.matches(c)))&&(i.delete(g),r.delete(g),l=!0);for(let g of t.querySelectorAll(T.map(({selector:c})=>c).join(",")))!i.has(g)&&!d.has(g)&&(y||!g.matches("ion-popover"))&&(g.presented||g.classList.contains("show-menu"))&&(i.add(g),l=!0);l&&j({phase:"change"})};return{get active(){return i},subscribe(y){return v.add(y),()=>{v.delete(y)}},setNative(y,l){r.has(y)!==l&&(l?r.add(y):r.delete(y),j({element:y,phase:"change"}))},isExcluded(y){return!!f.exclude&&y.matches(f.exclude)},isNative(y){return r.has(y)},get stack(){let y=[...i].filter(g=>g.isConnected&&g.ownerDocument===t),l=g=>{let c=Number.parseFloat(t.defaultView.getComputedStyle(g).zIndex);return Number.isFinite(c)?c:g.overlayIndex??0};return y.sort((g,c)=>l(g)-l(c)),y},isCovered(y){let l=this.stack,g=l.reduce((c,D,x)=>D.contains(y)?x:c,-1);return l.some((c,D)=>{if(r.has(c)||f.exclude&&c.matches(f.exclude))return!1;let x=f.covers?.(c,y);return x!==void 0?x:D>g&&!c.contains(y)&&(c.matches("ion-menu")||yt(c,h.get(c)))})},enable(y,l){let g={...f,...l},c=[...y,...g.additional??[]];g.exclude&&t.querySelector(g.exclude);let D=new Map;for(let m of c){t.querySelector(m.selector);for(let[O,A]of Object.entries(m.events)){let N=D.get(A);if(N&&N.phase!==O)throw new TypeError(`Overlay event "${A}" has conflicting phases`);D.set(A,{phase:O,selector:N?`${N.selector}, ${m.selector}`:m.selector})}}f=g,T=c,L=D;for(let m of L.keys()){if(p.has(m))continue;let O=A=>{let N=L.get(m),oe=A.composedPath().find(F=>F instanceof t.defaultView.HTMLElement&&F.matches(N.selector));oe&&B(oe,N.phase,A)};t.addEventListener(m,O,!0),p.set(m,()=>t.removeEventListener(m,O,!0))}for(let[m,O]of p)L.has(m)||(O(),p.delete(m));let x=!C;C||(C=new MutationObserver(()=>S()),C.observe(t.documentElement,{childList:!0,subtree:!0}),t.addEventListener("nativeUIOverlayAdopted",m=>{let O=m.detail;O?.ownerDocument===t&&B(O,"willPresent",m)})),S(x),(x||l)&&j({phase:"change"})}}},tt=t=>{let i=t;return i[gt]??=wt(t)};function*We(t){let i=t;for(;i;){let r=i.getRootNode();i=i.assignedSlot??i.parentElement??(r instanceof ShadowRoot?r.host:null),i&&(yield i)}}var bt=({x:t,y:i,width:r,height:v})=>({x:t,y:i,width:r,height:v}),nt=t=>{let i=t.getBoundingClientRect(),r=getComputedStyle(t),v=parseFloat(r.borderLeftWidth)||0,h=parseFloat(r.borderTopWidth)||0;return{x:i.left+v,y:i.top+h,width:i.width-v-(parseFloat(r.borderRightWidth)||0),height:i.height-h-(parseFloat(r.borderBottomWidth)||0)}},Ge=(t,i,r)=>{let v=[t,...We(t)],h=v.indexOf(i);if(h<=0||i===t.ownerDocument.scrollingElement)return;let d=t.ownerDocument.defaultView;if(d.visualViewport&&(d.visualViewport.scale!==1||d.visualViewport.offsetLeft||d.visualViewport.offsetTop))return;let p=0,T=0,f=d.innerWidth,L=d.innerHeight;for(let[S,y]of v.entries()){let l=getComputedStyle(y);if(l.transform!=="none"&&!new DOMMatrixReadOnly(l.transform).isIdentity||l.zoom&&l.zoom!=="normal"&&Number(l.zoom)!==1||[l.translate,l.rotate,l.scale,l.perspective].some(x=>x&&x!=="none")||l.writingMode&&l.writingMode!=="horizontal-tb"||S<h&&/^(fixed|sticky)$/.test(l.position))return;if(S===0)continue;if(l.scrollbarGutter&&l.scrollbarGutter!=="auto")return;let g=/^(auto|scroll|hidden|clip)$/.test(l.overflowX),c=/^(auto|scroll|hidden|clip)$/.test(l.overflowY);if(S<h&&(g||c))return;let D=y===t.ownerDocument.scrollingElement;if(S>h&&((g||D)&&y.scrollWidth>y.clientWidth||(c||D)&&y.scrollHeight>y.clientHeight)||(g||c)&&[l.borderTopLeftRadius,l.borderTopRightRadius,l.borderBottomLeftRadius,l.borderBottomRightRadius].some(x=>parseFloat(x)>0)||l.clipPath&&l.clipPath!=="none"||l.maskImage&&l.maskImage!=="none")return;if(S>=h){let x=nt(y);g&&(p=Math.max(p,x.x),f=Math.min(f,x.x+x.width)),c&&(T=Math.max(T,x.y),L=Math.min(L,x.y+x.height))}}let C=getComputedStyle(i);if(!/^(auto|scroll)$/.test(C.overflowX)&&!/^(auto|scroll)$/.test(C.overflowY))return;let j=nt(i);if(f<=p||L<=T||!j.width||!j.height)return;let B=bt(t.getBoundingClientRect());return{id:r(i),offsetX:i.scrollLeft,offsetY:i.scrollTop,viewport:j,clip:{x:p,y:T,width:f-p,height:L-T},contentWidth:i.scrollWidth,contentHeight:i.scrollHeight,frame:{...B,x:B.x-j.x+i.scrollLeft,y:B.y-j.y+i.scrollTop}}};var ot=t=>{let i=globalThis;if(i.Capacitor?.convertFileSrc)return i.Capacitor.convertFileSrc(t);if(!t.startsWith("file:"))return t;if(i.WkWebView?.convertFilePath)return i.WkWebView.convertFilePath(t);throw new Error("Native UI file URL requires a host resource handler")};var pe=t=>new Promise((i,r)=>{let v=setTimeout(()=>r(new Error("Native UI bridge timed out")),5e3);t.then(i,r).finally(()=>clearTimeout(v))}),Be=async t=>{try{return await pe(t)}catch(i){throw t.then(r=>r.remove()).catch(()=>{}),i}};var ze=async(t,i)=>{let r=new Map;for(let T of t.update??[])r.set(T,{updated:!0});for(let T of["native","web","none"])for(let f of t.projection?.[T]??[]){let L=r.get(f)??{updated:!1};if(L.destination&&L.destination!==T)throw new TypeError(`Projection event "${f}" has conflicting destinations`);r.set(f,{...L,destination:T})}let v=!1,h=[],d=async()=>{v=!0;let f=(await Promise.allSettled(h.splice(0).map(L=>Promise.resolve().then(()=>L.remove())))).find(L=>L.status==="rejected");if(f?.status==="rejected")throw f.reason},p=[...r].map(async([T,f])=>{let L=await Be(Promise.resolve().then(()=>t.addListener(T,C=>{!v&&(!t.accepts||t.accepts(C))&&i(f.destination,f.updated)})));v?await L.remove():h.push(L)});try{return await Promise.all(p),{remove:d}}catch(T){throw await d().catch(()=>{}),T}};var je=":is([data-native-ui-snapshot-source], [data-native-ui-snapshot-prepared], [data-native-ui-snapshot-content])",rt=`
2
2
  @layer native-ui-projection {
3
3
  ${je}, ${je} *, ${je}::part(native) { visibility: hidden !important; }
4
4
  ${je}::before, ${je}::after,
@@ -19,4 +19,4 @@ ${je} *::before, ${je} *::after {
19
19
  visibility: hidden !important;
20
20
  }
21
21
  }
22
- `;var bt=(t,r=!1)=>JSON.stringify(t.map(({control:o})=>[o.id,o.kind,o.placement,r?0:o.x,r?0:o.y,o.width,o.height,o.dark,o.rtl])),Et=async(t,r,o)=>{let v=o.captureDelayMs??50;if(!Number.isFinite(v)||v<0||v>2147483647)throw new RangeError("captureDelayMs must be a finite, nonnegative timer interval");let h="native",d=t.element.ownerDocument,p=d.defaultView,T=Array.from(p.crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),f=e=>e.isConnected&&e.ownerDocument===d,M=e=>!!e?.isConnected&&e.ownerDocument===d,C=new Map,j=new Set,B=e=>{j.delete(e),e.style.setProperty("display","none","important"),e.removeAttribute("data-native-ui-projection-image"),e.removeAttribute("src"),le()},S=r.send.bind(r),y="data-native-ui-snapshot",l=`${t.namespace}:sources-change`,g=new Set,c=new Set,D=new Set,H=new WeakMap,m=0,W=e=>JSON.stringify(e.map(i=>(H.has(i.scope)||H.set(i.scope,++m),[H.get(i.scope),bt([i],!!o.opaqueUnderlay)]))),A=new Map,N=e=>{let i=e.getRootNode();return i.nodeType===11&&"host"in i?i:d},oe=e=>{if(A.has(e))return;let i=d.createElement("style");i.setAttribute("data-native-ui-snapshot-base",""),i.textContent=ot+(e.nodeType===11?it:""),(e.nodeType===11?e:e.head).append(i),A.set(e,i)},F=e=>{let i=[...e.getAnimations({subtree:!0}),...[...se.get(e)??[]].flatMap(n=>n.shadowRoot?.getAnimations()??[])];for(let n of i)"transitionProperty"in n&&n.transitionProperty==="visibility"&&n.cancel()},se=new Map,Se=e=>{let i=se.get(e)??new Set;se.set(e,i);let n=e.hasAttribute("data-native-ui-snapshot-source")||e.hasAttribute("data-native-ui-snapshot-prepared"),s=w=>{if(!w.hasAttribute("data-native-ui-projection-node")){if(w.shadowRoot){i.add(w),oe(w.shadowRoot);for(let L of w.shadowRoot.children)s(L)}for(let L of w.children)s(L)}};s(e);for(let w of i)w.toggleAttribute("data-native-ui-snapshot-content",n);F(e)},O=()=>`${p.innerWidth}:${p.innerHeight}:${p.devicePixelRatio}`,Z=!1,ae=!1,J=0,me=0,R,U,E,X=!1,Y=!1,we=0,We=0,ee=0,ve=0,z=0,be=-1,V=!1,te=!1,q,le=()=>{let e=new Set(q?.candidates.map(n=>n.scope.element));for(let[n,s]of C){let w=!V&&n.isConnected&&e.has(n);if(w&&(E||Y||Z))continue;let L=w?2*Math.max(1,R?.scopes.filter(k=>k.element===n).length??0):0,x=Math.max(0,L-s.filter(k=>j.has(k)).length),I=s.filter(k=>j.has(k)||x-- >0?!0:(k.remove(),!1));I.length?C.set(n,I):C.delete(n)}let i=new Set([...q?.candidates.map(n=>n.scope.element.getRootNode())??[],...E?.scopes.map(n=>n.element.getRootNode())??[],...R?.scopes.map(n=>n.element.getRootNode())??[],...[...j].map(n=>n.getRootNode()),...[...se.values()].flatMap(n=>[...n].map(s=>s.shadowRoot))]);for(let[n,s]of A)n.nodeType===11&&!i.has(n)&&(s.remove(),A.delete(n))},he=new Set,Ie=(e,i,n)=>{let s=()=>{he.delete(s)&&(S({action:e,token:i}).catch(()=>{}),e==="restored"&&le())};he.add(s),n&&!V?p.requestAnimationFrame(()=>p.requestAnimationFrame(s)):s()},de=new Set,He=()=>{de.forEach(e=>D.delete(e)),de.clear()},xe=(e,i=!1)=>{!e||e===R||e===E||(e.images.forEach(n=>{B(n)}),Ie("release",e.data.token,i))},Ee=e=>e.filter(i=>{if(!M(i.scope.element)||![i.element,...i.sources??[]].every(f))return!1;if(i.control.scroll){let n=i.element.getBoundingClientRect(),s=i.control.scroll.clip;if(n.right<=s.x||n.bottom<=s.y||n.left>=s.x+s.width||n.top>=s.y+s.height)return!1}return o.eligible?.(i)??!0}),Xe=async()=>{if(ve=0,V||h!=="native"||te||X||E||o.blocked()||!q||R?.revision===q.revision&&be===z)return;let{revision:e,candidates:i}=q,n=ee,s=z,w=O(),L=Ee(i);if(!L.length)return;te=!0;let x,I=!1,k=[];try{let ie=!1,re=S({action:"prepare",revision:o.captureRevision?.()??e,viewportWidth:p.innerWidth,ids:L.map(b=>b.control.id)});re.then(b=>{ie&&b.token&&S({action:"release",token:b.token}).catch(()=>{})}).catch(()=>{});try{x=await pe(re)}finally{ie=!0}if(!x.token||!x.parts?.length)return;let Ce=new Set(L.map(b=>b.control.id));if(x.parts.some(b=>!b.url.startsWith("file:")&&!/^\/__native_ui_engine__\/nativeUI[a-fA-F0-9]+\/[a-fA-F0-9-]+-[0-9]+\.png$/.test(b.url)||!b.ids.length||b.ids.some(G=>!Ce.has(G))||![b.x,b.y,b.width,b.height].every(Number.isFinite)||b.width<=0||b.height<=0)||new Set(x.parts.flatMap(b=>b.ids)).size!==Ce.size||x.parts.some(b=>new Set(b.ids.map(G=>L.find(Me=>Me.control.id===G).scope)).size!==1)||(await pe(Promise.all(x.parts.map(async b=>{let G=L.find(qe=>b.ids.includes(qe.control.id)).scope.element,Me=C.get(G);Me||(Me=[],C.set(G,Me));let fe=Me.find(qe=>!j.has(qe));return fe||(fe=d.createElement("img"),fe.setAttribute("data-native-ui-projection-node",""),Me.push(fe)),j.add(fe),k.push(fe),fe.src=nt(b.url),await fe.decode(),fe}))),V||h!=="native"||X||E||o.blocked()||ee!==n||O()!==w||q?.revision!==e||L.some(b=>!M(b.scope.element)||![b.element,...b.sources??[]].every(f))))return;let Re=R,Qe={data:x,images:k,sources:Array.from(new Set(L.flatMap(b=>[b.element,...b.sources??[]]))),targets:x.parts.map(b=>L.find(G=>b.ids.includes(G.control.id)).element),scopes:x.parts.map(b=>L.find(G=>b.ids.includes(G.control.id)).scope),parents:x.parts.map(b=>L.find(G=>b.ids.includes(G.control.id)).scope.element.parentNode),frames:[],viewport:w,revision:e,layout:W(L)};try{if(!Ue(Qe))throw new Error("Projection destination is unavailable")}catch(b){Q();try{Ue(),R?.sources.forEach(G=>{D.add(G),de.add(G)})}catch{$()}throw b}R=Qe,He(),R.sources.forEach(b=>{D.add(b),de.add(b)}),o.opaqueUnderlay&&S({action:"prepared",token:x.token}).catch(()=>{}),p.dispatchEvent(new Event(l)),be=s,I=!0,xe(Re)}catch{}finally{I||k.forEach(ie=>{B(ie)}),x?.token&&!I&&S({action:"release",token:x.token}).catch(()=>{}),te=!1,q&&(q.revision!==e||z!==s)&&ue()}},ue=()=>{p.clearTimeout(ve),!V&&h==="native"&&!E&&!X&&!o.blocked()&&(ve=p.setTimeout(()=>{Xe()},v))},Ae,a=(e,i)=>{if(i.some(s=>s.scope.element.ownerDocument!==d||[s.element,...s.sources??[]].some(w=>w.ownerDocument!==d)))throw new TypeError("All projection sources and fallback scopes must share one Document");if(o.blocked())return;!E&&R&&R.layout!==W(Ee(i))&&Le();let n=W(i);Ae!==n&&(Ae=n,z++,ee++),q?.revision!==e&&ee++,q={revision:e,candidates:i},le(),(R?.revision!==e||be!==z)&&ue()},u=e=>{!E&&R&&e&&q?.candidates.some(i=>i.scrollElement===e&&R.sources.includes(i.element))&&Le(),E&&ke(),z++,ee++,ue()},P=await Be(r.listen(({active:e})=>{X=e,ee++,p.clearTimeout(ve),e||ue()})),_=new Set,ce=e=>{se.get(e)?.forEach(i=>i.removeAttribute("data-native-ui-snapshot-content")),_.delete(e)&&e.removeAttribute("data-native-ui-snapshot-prepared"),e.removeAttribute("data-native-ui-snapshot-visible"),e.removeAttribute(y),e.removeAttribute("data-native-ui-snapshot-positioned"),e.removeAttribute("data-native-ui-snapshot-source"),F(e),se.delete(e)},Q=()=>{me++,p.cancelAnimationFrame(J);for(let e of Fe.keys())e.style.setProperty("opacity","0","important");Fe.clear(),J=0,Z=!1,ae=!1,He(),E?.sources.forEach(e=>{g.delete(e),c.delete(e)}),K.forEach(ce),K.clear(),A.forEach((e,i)=>{(V||i.nodeType===11&&!i.host.isConnected)&&(e.remove(),A.delete(i))})},$=(e=E,i=Y)=>{if(E!==e)return;let n=new Set([E,R]);Q(),E=void 0,R=void 0,Y=!1,p.clearTimeout(we),n.forEach(s=>xe(s,i)),o.wake()},ne=()=>{if(!E)return;if(R!==E){$();return}let e=E;me++,p.cancelAnimationFrame(J),J=0,Z=ae=!1,e.sources.forEach(i=>{g.delete(i),c.delete(i)}),K.forEach(i=>i.removeAttribute("data-native-ui-snapshot-source")),Ye(e,!!o.opaqueUnderlay),E=void 0,Y=!1,p.clearTimeout(we),Ie("restored",e.data.token,!0),e.sources.forEach(i=>{D.add(i),de.add(i)}),o.wake()},Pe=()=>{Y&&ne(),he.forEach(e=>e())},De=e=>e.scopes.map(i=>M(i.element)?i.element:void 0),K=new Set,Ye=(e,i)=>{for(let n of K)n.toggleAttribute("data-native-ui-snapshot-visible",i),Se(n);e.images.forEach(n=>n.style.setProperty("opacity",i?"1":"0","important"))},Te=new Map,Fe=new Map,ke=()=>{let e=[];for(let[i,n]of Fe){let{target:s,frame:w}=n;if(!s.isConnected){i.remove();continue}let L=s.shadowRoot??s;i.parentNode!==L&&L.insertBefore(i,null);let x=s.getBoundingClientRect(),I=i.getBoundingClientRect(),k=parseFloat(i.style.width)||w.width,ie=parseFloat(i.style.height)||w.height,re=I.width/k||1,Ce=I.height/ie||1,Re=n.scale??(n.scale={x:re,y:Ce});e.push({element:i,left:(parseFloat(i.style.left)||0)+(x.x+w.x*re/Re.x-I.x)/re,top:(parseFloat(i.style.top)||0)+(x.y+w.y*Ce/Re.y-I.y)/Ce,width:w.width/Re.x,height:w.height/Re.y})}for(let{element:i,...n}of e)for(let[s,w]of Object.entries(n)){let L=`${w}px`;i.style.getPropertyValue(s)!==L&&i.style.setProperty(s,L,"important")}},Ue=(e=E??R)=>{if(!e||Y)return!1;if(!e.sources.every(f)||De(e).some(n=>!n))return Le(),!1;let i=De(e);if(E){if(i.some(s=>!s?.isConnected||!A.has(N(s))))return $(E,!1),!1;let n=new Set;for(let[s,w]of e.targets.entries()){let L=Te.get(w),x=i[s];!L||!x?.isConnected||(x.setAttribute(y,L),x.setAttribute("data-native-ui-snapshot-source",""),n.add(x))}for(let s of K)n.has(s)||ce(s);return K.clear(),n.forEach(s=>K.add(s)),Ye(e,ae),!0}C.forEach(n=>n.forEach(s=>{e.images.includes(s)||(s.style.setProperty("display","none","important"),s.removeAttribute("data-native-ui-projection-image"))})),Te.clear(),Fe.clear(),K.forEach(ce),K.clear();for(let n of new Set(i)){if(!n)continue;K.add(n),oe(N(n));let s=i.flatMap((I,k)=>I===n?[k]:[]),w=`${T}-${s[0]}`;n.setAttribute(y,w),n!==e.targets[s[0]]&&(n.setAttribute("data-native-ui-snapshot-prepared",""),_.add(n)),n.toggleAttribute("data-native-ui-snapshot-visible",!!o.opaqueUnderlay),Se(n);let L=n.getBoundingClientRect();n.toggleAttribute("data-native-ui-snapshot-positioned",p.getComputedStyle(n).position==="static");let x=n.shadowRoot??n;for(let I of[...s].reverse()){let k=e.images[I],ie=e.data.parts[I],re=e.frames[I]??{x:o.opaqueUnderlay?0:ie.x-L.x,y:o.opaqueUnderlay?0:ie.y-L.y,width:ie.width,height:ie.height};e.frames[I]=re,Te.set(e.targets[I],w),k.inert=!0,k.setAttribute("aria-hidden","true"),k.setAttribute("data-native-ui-projection-image",w),k.style.cssText="all:initial!important;position:absolute!important;display:block!important;visibility:visible!important;pointer-events:none!important;image-rendering:pixelated!important;will-change:opacity!important;opacity:0!important;",k.style.setProperty("width",`${re.width}px`,"important"),k.style.setProperty("height",`${re.height}px`,"important"),k.style.setProperty("left","0px","important"),k.style.setProperty("top","0px","important"),k.style.setProperty("opacity",o.opaqueUnderlay?"1":"0","important"),k.parentNode!==x&&x.insertBefore(k,null),Fe.set(k,{target:n,frame:re})}}return e.parents=e.scopes.map(n=>n.element.parentNode),ke(),!0},Je=()=>{if(Pe(),V||h==="none"||E)return;let e=R;if(!e||e.viewport!==O()||!e.sources.every(f)||o.current&&!o.current(e.targets)||e.targets.some(s=>!Te.has(s))||De(e).some(s=>!s?.isConnected)||[...K].some(s=>!s.isConnected))return;e.scopes.some((s,w)=>s.element.parentNode!==e.parents[w])&&Ue(),ke();let i=++me,n=()=>me===i;Z=!0,ae=!!o.opaqueUnderlay,E=e,ee++,p.clearTimeout(ve),e.sources.forEach(s=>{g.add(s)}),K.forEach(s=>s.setAttribute("data-native-ui-snapshot-source","")),Ye(e,ae),J=p.requestAnimationFrame(()=>{J=0,n()&&(Z=!1,o.wake())}),pe(S({action:"cover",token:e.data.token,...o.transient?{transient:!0}:{}})).then(s=>{if(n()){if(Z=!1,s?.shown!==!0){$(e,!1);return}Y||(ae=!0,e.sources.forEach(w=>c.add(w)),Ue(),ke()),p.cancelAnimationFrame(J),J=p.requestAnimationFrame(()=>{J=0,n()&&S({action:"painted",token:e.data.token}).catch(()=>{n()&&$(e,!1)})}),o.wake()}}).catch(()=>{n()&&$(e,!1)})},Ke=()=>{if(!(!E||V||Y)){if(!E.sources.every(f)||De(E).some(e=>!e)||o.current&&!o.current(E.targets)){$(E,!1);return}if(!o.blocked()){if(ke(),o.transient){let e=E,i=De(e);if(i.some(s=>!s?.isConnected)){$(e,!1);return}let n=i.map((s,w)=>{let L=e.images[w].getBoundingClientRect();return{...e.data.parts[w],x:L.x,y:L.y,width:L.width,height:L.height}});n.some((s,w)=>["x","y","width","height"].some(L=>s[L]!==e.data.parts[w][L]))&&(o.opaqueUnderlay?e.data={...e.data,parts:n}:R=void 0),S({action:"restore",token:e.data.token,viewportWidth:p.innerWidth,parts:n}).catch(()=>{})}We=o.revision?.()??q?.revision??0,Y=!0,E.sources.forEach(e=>g.delete(e)),we=p.setTimeout(()=>{Y&&$(E,!1)},250),o.wake()}}},ct=(e,i,n)=>{!Y||!E||n===void 0||n<=We||!o.transient&&e||E.data.parts.every(s=>s.ids.every(w=>i?.includes(w)))&&(ne(),ue())},Le=(e=!1)=>{he.forEach(n=>n()),ee++,p.clearTimeout(ve);let i=R;if(R=void 0,(e||V)&&(U=void 0),o.retainPreparedUntilRelease&&!E&&!e&&!V){if(i){let n={};U=n,pe(S({action:"release",token:i.data.token})).catch(()=>{}).finally(()=>{if(i.images.forEach(s=>{B(s)}),U===n&&(U=void 0,!(R||E))){for(let s of K)s.getAttribute(y)!==Te.get(s)&&(K.delete(s),_.delete(s));Q(),Te.clear(),p.dispatchEvent(new Event(l))}})}if(U)return}xe(i),E?$(E,!1):(Q(),Te.clear(),p.dispatchEvent(new Event(l)))},Ze;try{o.events&&(Ze=await ze(o.events,(e,i)=>{if(!V){if(e&&(h=e),h==="none"){Le();return}e==="web"&&Je(),e==="native"&&(Ke(),ue()),i&&u()}}))}catch(e){throw V=!0,Le(),await pe(Promise.resolve(P.remove())).catch(()=>{}),e}return{get owners(){return[...g]},get visibleOwners(){return[...c]},get preparedOwners(){return[...D]},consider:a,changed:u,moved:ke,get token(){return Y?void 0:E?.data.token},begin:Je,get restoring(){return Y},get handoffPending(){return Z},retireRestoration:Pe,end:Ke,updated:ct,invalidate:Le,async destroy(){V=!0,Le(),C.forEach(e=>e.forEach(i=>i.remove())),C.clear(),await Promise.allSettled([pe(Promise.resolve().then(()=>P?.remove())),pe(Promise.resolve().then(()=>Ze?.remove()))])}}},rt=async(t,r,o)=>{let v=await Et(t,r,o),h=v.consider;return Object.assign(v,{consider:(d,p)=>h(d,p.map(T=>({...T,scope:t})))})};var st=(t,r)=>{if(t.nodeType!==1||t.namespaceURI!=="http://www.w3.org/1999/xhtml"||!t.ownerDocument||!("style"in t))throw new TypeError("A Web projection scope requires an HTMLElement fallback");if(t.matches("img, input, textarea, select, video, audio, canvas, iframe, embed, object, br, hr, area, base, link, meta, source, track, wbr"))throw new TypeError("A Web projection fallback must be a container element; use the existing fallback container");return Object.freeze({element:t,namespace:r})};var at=async(t,r,o={addListener:async(v,h)=>globalThis.Capacitor.addListener(t.plugin,v,h)})=>{let v="view",h=t.receiveListeners,d=!1,p=!1,T="native",f="native",M=et(document),C=()=>T==="native"&&m&&M.isCovered(m)?"web":T,j=!1,B=!1,S=!1,y=!1,l,g,c,D=!1,H=()=>{let a=D;D=!0;try{c?.begin()}finally{D=a}},m,W={},A,N=0,oe=()=>{N++,A=void 0;let a=Ne(m);a?.owner===W&&(a.projected=!1,a.owner=void 0)},F={listen:a=>r.listen(u=>{a(u),!u.active&&B&&(B=!1,he()),u.precovered&&Ie(u.precovered)}),send:a=>{if(!t.placementHandoff)return r.send(a);let u=Ne(m);if(a.action==="cover"){let $=A===a.token&&u?.owner===W&&u.projected,ne=++N;return A=a.token,u&&(u.owner=W,u.projected=!!$),r.send(a).then(Pe=>(ne===N&&u===Ne(m)&&u?.owner===W&&(u.projected=Pe?.shown===!0),Pe)).catch(Pe=>{throw ne===N&&u?.owner===W&&(oe(),u.invalidate()),Pe})}let P=a.action==="release"&&a.token===A,_=A&&(a.action==="restore"||P||a.action==="reset"||a.action==="visibility"&&a.visible);_&&N++;let ce=N,Q=()=>{ce!==N||u?.owner!==W||(oe(),u.invalidate())};try{let $=_&&u?.owner===W?{...a,token:"token"in a?a.token:A,placement:u.measure()}:a;return r.send($).then(async ne=>(a.action==="release"&&ne?.requiresPlacement&&(u&&(!u.owner||u.owner===W)?ne=await r.send({...a,placement:u.measure()}):(await r.send({action:"visibility",visible:!1}),ne=await r.send(a))),ce===N&&(a.action==="resume"||P||a.action==="reset"||a.action==="visibility")&&oe(),ne)).catch(ne=>{throw Q(),ne})}catch($){return Q(),Promise.reject($)}}},se=0,Se=0,O=0,Z=!1,ae=!1,J=!1,me=!1,R=document.createElement("style"),U=`data-native-ui-session-${t.id.replace(/[^a-zA-Z0-9-]/g,"")}`;R.textContent=`[${U}="native"], [${U}="native"] *, [${U}="none"], [${U}="none"] * {visibility:hidden!important}`,document.documentElement.append(R);let E=()=>{let a=document.querySelectorAll(t.projectionSelector);return a.length===1&&a[0]instanceof HTMLElement?a[0]:void 0},X=()=>{m&&(f==="web"||f==="native"&&S?m.removeAttribute(U):m.setAttribute(U,f))},Y=()=>{if(!m?.isConnected)return[];let a=m.getBoundingClientRect(),u={x:a.x,y:a.y,width:a.width,height:a.height},P=l&&Ge(m,l,()=>t.id);return[{element:m,scrollElement:l,control:{id:v,...u,...P?{scroll:P}:{}}}]},we=async()=>{if(d)return;let a=O,u=t.failedFallback==="native"&&C()==="native"&&!!m?.isConnected;await F.send({action:"visibility",visible:u}).catch(()=>{}),!(d||a!==O)&&(u||f==="none"?X():m?.removeAttribute(U))},We=()=>{if(!j||f!=="native"||!m?.isConnected||c?.token||c?.restoring)return;let a=t.failedFallback==="native";F.send({action:"visibility",visible:a}).catch(()=>{}),a?X():m.removeAttribute(U)},ee=()=>{if(d||D)return;if(We(),f==="web"&&c&&!c.token&&!c.restoring){F.send({action:"visibility",visible:!1}).catch(()=>{}),m?.removeAttribute(U);return}if(Z||!c?.restoring||f!=="native")return;Z=!0;let a=O,u=c;F.send({action:"resume"}).then(()=>{d||a!==O||u!==c||(S=!1,u.updated(void 0,[v],++se),X(),z())}).catch(()=>{a!==O||d||(u.invalidate(),we())}).finally(()=>{Z=!1,ee()})},ve=async()=>{if(d||ae||j)return;if(c?.restoring){ee();return}let a=E();if(a!==m){if(O++,oe(),m?.removeAttribute(U),await c?.destroy(),c=void 0,d)return;m=a,S=!1,V.disconnect(),m&&V.observe(m)}if(de(),f=C(),!m){await F.send({action:"visibility",visible:!1});return}if(!c){ae=!0;let u=O;try{let P=await rt(st(m,t.id),F,{wake:ee,captureDelayMs:t.captureDelayMs,retainPreparedUntilRelease:t.nativeDragHandoff,blocked:()=>f!=="native"||j||S&&!c?.token,revision:()=>se,captureRevision:t.captureMode==="view"?()=>Se:void 0,transient:!0,opaqueUnderlay:t.captureMode==="view"});if(d||u!==O){await P.destroy();return}c=P}finally{ae=!1}}if(!d){if(f==="native"&&S){await F.send({action:"visibility",visible:!1}),X();return}if(f==="native"){let u=O;if(await F.send({action:"visibility",visible:!0}),d||u!==O||f!=="native")return;X(),l=[...Oe(m)].find(Q=>{let $=getComputedStyle(Q);return/auto|scroll/.test($.overflowX+$.overflowY)&&(Q.scrollHeight>Q.clientHeight||Q.scrollWidth>Q.clientWidth)});let P=l&&Ge(m,l,()=>t.id),_=t.nativeDragHandoff&&t.captureMode==="view"&&l?{viewport:l.getBoundingClientRect(),offsetX:l.scrollLeft,offsetY:l.scrollTop,rangeX:Math.max(0,l.scrollWidth-l.clientWidth),rangeY:Math.max(0,l.scrollHeight-l.clientHeight)}:void 0,ce=await F.send({action:"track",viewportWidth:innerWidth,...P?{scroll:P}:{},..._?{gesture:_}:{}});if(d||u!==O)return;y=ce?.tracked===!0,c.consider(t.captureMode==="view"?Se:++se,Y())}else await F.send({action:"visibility",visible:!1}),X()}},z=()=>{d||(J=!0,!(!p||me)&&(me=!0,Promise.resolve().then(async()=>{try{for(;J&&!d;)J=!1,await ve()}catch{await we()}finally{me=!1,J&&z()}})))},be=()=>{c?.invalidate(),z()},V=new ResizeObserver(be);window.addEventListener("resize",be);let te=new Set,q=new WeakSet,le=a=>{let u=a.composedPath()[0]??a.target;if(!(d||f!=="native"||!m||q.has(a)||u!==document&&![...Oe(m)].includes(u))){if(q.add(a),y&&u===l){c?.changed(u);return}j?t.captureMode==="view"?c?.moved():c?.changed():((Z||c?.restoring)&&O++,j=!0,H(),S=t.failedFallback!=="native",c?.token?m.removeAttribute(U):We()),he()}};function he(){clearTimeout(g),g=setTimeout(()=>{B||(j=!1,!(d||f!=="native")&&(c?.end(),c?.restoring||z()))},100)}function Ie(a){if(d||f!=="native"||!m?.isConnected||!c||(B=!0,c.token))return;(Z||c.restoring)&&O++,A=a;let u=Ne(m);if(u&&(u.owner=W,u.projected=!0),j=!0,H(),!c.token){j=!1,we();return}he()}let de=()=>{let a=new Set(m?Oe(m):[]),u=a.size!==te.size||[...a].some(P=>!te.has(P));for(let P of te)a.has(P)||(P.removeEventListener("scroll",le),P.removeEventListener("slotchange",He),te.delete(P));for(let P of a)te.has(P)||(P.addEventListener("scroll",le,{passive:!0}),P.addEventListener("slotchange",He),te.add(P));u&&(y=!1,l=void 0,c?.invalidate(),z())},He=()=>{de(),z()};document.addEventListener("scroll",le,!0);let xe=new MutationObserver(a=>{de(),E()!==m?z():m&&a.some(u=>u.type==="childList")&&Ee(C())});xe.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let Ee=(a,u=!1)=>{if(d||!u&&a===f)return;j=!1,B=!1,clearTimeout(g),f=a,O++;let P=O;f==="none"?F.send({action:"visibility",visible:!1}).then(()=>{f!=="none"||P!==O||d||(c?.invalidate(!0),X())}).catch(()=>{f!=="none"||P!==O||d||(c?.invalidate(!0),X())}):f==="web"?(H(),c?.token||F.send({action:"visibility",visible:!1}).catch(()=>{}),X()):f==="native"&&(c?.end(),c?.restoring||z())},Xe=M.subscribe(()=>queueMicrotask(()=>Ee(C()))),ue,Ae=async()=>{if(!d){d=!0,oe(),O++,Xe(),xe.disconnect(),V.disconnect(),window.removeEventListener("resize",be),document.removeEventListener("scroll",le,!0);for(let a of te)a.removeEventListener("scroll",le),a.removeEventListener("slotchange",He);te.clear(),clearTimeout(g),m?.removeAttribute(U),R.remove(),await Promise.allSettled([Promise.resolve(ue?.remove()),c?.destroy()])}};try{let a=O;ue=await ze({addListener:(P,_)=>o.addListener(P,_),update:h?.update,projection:h?.projection,accepts:P=>!h?.match||Object.entries(h?.match).every(([_,ce])=>typeof P=="object"&&P!==null&&P[_]===ce)},(P,_)=>{d||(P&&(P==="native"&&(S=!1),T=P,F.send({action:"destination",destination:P}).catch(()=>{}),Ee(C(),!0)),_&&(Se++,c?.changed(),f==="native"&&z()))});let u=await F.send({action:"connect"});return O===a&&["native","web","none"].includes(u?.destination)&&(T=u.destination),f=C(),p=!0,z(),{destroy:Ae,show:()=>{S=!1,T="native",Ee(C(),!0)},hide:()=>{T=f="none",O++,j=!1,B=!1,clearTimeout(g),c?.invalidate(!0),X()}}}catch(a){throw await Ae(),a}};var ye=new Map,ge=new Map,$e=new Map,Pt=Array.from(crypto.getRandomValues(new Uint32Array(4)),t=>t.toString(16)).join("-"),Ve=new Map,Tt=(t,r,o)=>Ve.get(t)?.get(r)?.(o),Lt=0,Mt=(t,r)=>new Promise((o,v)=>{let h=`${t}:${Pt}:${++Lt}`,d=setTimeout(()=>{ge.delete(h),v(new Error("Native UI session timed out"))},5e3);ge.set(h,{resolve:o,reject:v,timer:d});let p=JSON.stringify({key:h,request:r}),T=globalThis,f=T.webkit?.messageHandlers?.[t]??T[t]??T.nativeUIEngine;if(!f){clearTimeout(d),ge.delete(h),v(new Error("Native UI session unavailable"));return}try{f.postMessage(p)}catch(M){clearTimeout(d),ge.delete(h),v(M)}}),jt=(t,r,o,v)=>{if(r===null){$e.get(t)?.(o);return}let h=ge.get(r);!h||!r.startsWith(`${t}:`)||(ge.delete(r),clearTimeout(h.timer),v?h.reject(new Error(v)):h.resolve(o))},St=t=>{ye.get(t)?.show()},Ht=t=>(ye.get(t)?.hide(),!0),xt=async t=>{let r=ye.get(t);ye.delete(t),Ve.delete(t),$e.delete(t);for(let[o,v]of ge)o.startsWith(`${t}:`)&&(ge.delete(o),clearTimeout(v.timer),v.reject(new Error("Native UI session closed")));await r?.destroy()},kt=async t=>{if(ye.has(t.id))return;let r,o=!1,v,h={show:()=>{v="native",r?.show()},hide:()=>{v="none",r?.hide()},destroy:async()=>{o=!0,await r?.destroy()}};ye.set(t.id,h);try{if(document.readyState==="loading"&&await new Promise(p=>document.addEventListener("DOMContentLoaded",()=>p(),{once:!0})),o)return;let d=new Map;t.runtime==="cordova"&&Ve.set(t.id,d),r=await at(t,{send:p=>Mt(t.id,p),listen:async p=>($e.set(t.id,p),{remove:()=>{$e.get(t.id)===p&&$e.delete(t.id)}})},t.runtime==="cordova"?{addListener:async(p,T)=>(d.set(p,T),{remove:()=>{d.delete(p)}})}:void 0),v==="none"?r.hide():v==="native"&&r.show(),o&&await r.destroy()}catch(d){throw ye.get(t.id)===h&&(ye.delete(t.id),Ve.delete(t.id)),d}};return mt(Ct);})();
22
+ `;var Et=(t,i=!1)=>JSON.stringify(t.map(({control:r})=>[r.id,r.kind,r.placement,i?0:r.x,i?0:r.y,r.width,r.height,r.dark,r.rtl])),Pt=async(t,i,r)=>{let v=r.captureDelayMs??50;if(!Number.isFinite(v)||v<0||v>2147483647)throw new RangeError("captureDelayMs must be a finite, nonnegative timer interval");let h="native",d=t.element.ownerDocument,p=d.defaultView,T=Array.from(p.crypto.getRandomValues(new Uint32Array(4)),e=>e.toString(16)).join("-"),f=e=>e.isConnected&&e.ownerDocument===d,L=e=>!!e?.isConnected&&e.ownerDocument===d,C=new Map,j=new Set,B=e=>{j.delete(e),e.style.setProperty("display","none","important"),e.removeAttribute("data-native-ui-projection-image"),e.removeAttribute("src"),le()},S=i.send.bind(i),y="data-native-ui-snapshot",l=`${t.namespace}:sources-change`,g=new Set,c=new Set,D=new Set,x=new WeakMap,m=0,O=e=>JSON.stringify(e.map(o=>{x.has(o.scope)||x.set(o.scope,++m);let n=r.transient&&!r.opaqueUnderlay?o.scope.element.getBoundingClientRect():void 0,s=n?{...o,control:{...o.control,x:o.control.x-n.x,y:o.control.y-n.y}}:o;return[x.get(o.scope),Et([s],!!r.opaqueUnderlay)]})),A=new Map,N=e=>{let o=e.getRootNode();return o.nodeType===11&&"host"in o?o:d},oe=e=>{if(A.has(e))return;let o=d.createElement("style");o.setAttribute("data-native-ui-snapshot-base",""),o.textContent=rt+(e.nodeType===11?it:""),(e.nodeType===11?e:e.head).append(o),A.set(e,o)},F=e=>{let o=[...e.getAnimations({subtree:!0}),...[...se.get(e)??[]].flatMap(n=>n.shadowRoot?.getAnimations()??[])];for(let n of o)"transitionProperty"in n&&n.transitionProperty==="visibility"&&n.cancel()},se=new Map,Se=e=>{let o=se.get(e)??new Set;se.set(e,o);let n=e.hasAttribute("data-native-ui-snapshot-source")||e.hasAttribute("data-native-ui-snapshot-prepared"),s=P=>{if(!P.hasAttribute("data-native-ui-projection-node")){if(P.shadowRoot){o.add(P),oe(P.shadowRoot);for(let M of P.shadowRoot.children)s(M)}for(let M of P.children)s(M)}};s(e);for(let P of o)P.toggleAttribute("data-native-ui-snapshot-content",n);F(e)},W=()=>`${p.innerWidth}:${p.innerHeight}:${p.devicePixelRatio}`,Z=!1,ae=!1,J=0,me=0,R,U,b,q=!1,X=!1,we=0,Oe=0,ee=0,ve=0,z=0,be=-1,V=!1,te=!1,Y,le=()=>{let e=new Set(Y?.candidates.map(n=>n.scope.element));for(let[n,s]of C){let P=!V&&n.isConnected&&e.has(n);if(P&&(b||X||Z))continue;let M=P?2*Math.max(1,R?.scopes.filter(k=>k.element===n).length??0):0,H=Math.max(0,M-s.filter(k=>j.has(k)).length),I=s.filter(k=>j.has(k)||H-- >0?!0:(k.remove(),!1));I.length?C.set(n,I):C.delete(n)}let o=new Set([...Y?.candidates.map(n=>n.scope.element.getRootNode())??[],...b?.scopes.map(n=>n.element.getRootNode())??[],...R?.scopes.map(n=>n.element.getRootNode())??[],...[...j].map(n=>n.getRootNode()),...[...se.values()].flatMap(n=>[...n].map(s=>s.shadowRoot))]);for(let[n,s]of A)n.nodeType===11&&!o.has(n)&&(s.remove(),A.delete(n))},he=new Set,Ie=(e,o,n)=>{let s=()=>{he.delete(s)&&(S({action:e,token:o}).catch(()=>{}),e==="restored"&&le())};he.add(s),n&&!V?p.requestAnimationFrame(()=>p.requestAnimationFrame(s)):s()},de=new Set,xe=()=>{de.forEach(e=>D.delete(e)),de.clear()},He=(e,o=!1)=>{!e||e===R||e===b||(e.images.forEach(n=>{B(n)}),Ie("release",e.data.token,o))},Ee=e=>e.filter(o=>{if(!L(o.scope.element)||![o.element,...o.sources??[]].every(f))return!1;if(o.control.scroll){let n=o.element.getBoundingClientRect(),s=o.control.scroll.clip;if(n.right<=s.x||n.bottom<=s.y||n.left>=s.x+s.width||n.top>=s.y+s.height)return!1}return r.eligible?.(o)??!0}),qe=async()=>{if(ve=0,V||h!=="native"||te||q||b||r.blocked()||!Y||R?.revision===Y.revision&&be===z)return;let{revision:e,candidates:o}=Y,n=ee,s=z,P=W(),M=Ee(o);if(!M.length)return;te=!0;let H,I=!1,k=[];try{let re=!1,ie=S({action:"prepare",revision:r.captureRevision?.()??e,viewportWidth:p.innerWidth,ids:M.map(w=>w.control.id)});ie.then(w=>{re&&w.token&&S({action:"release",token:w.token}).catch(()=>{})}).catch(()=>{});try{H=await pe(ie)}finally{re=!0}if(!H.token||!H.parts?.length)return;let Ce=new Set(M.map(w=>w.control.id));if(H.parts.some(w=>!w.url.startsWith("file:")&&!/^\/__native_ui_engine__\/nativeUI[a-fA-F0-9]+\/[a-fA-F0-9-]+-[0-9]+\.png$/.test(w.url)||!w.ids.length||w.ids.some(G=>!Ce.has(G))||![w.x,w.y,w.width,w.height].every(Number.isFinite)||w.width<=0||w.height<=0)||new Set(H.parts.flatMap(w=>w.ids)).size!==Ce.size||H.parts.some(w=>new Set(w.ids.map(G=>M.find(Me=>Me.control.id===G).scope)).size!==1)||(await pe(Promise.all(H.parts.map(async w=>{let G=M.find(Ye=>w.ids.includes(Ye.control.id)).scope.element,Me=C.get(G);Me||(Me=[],C.set(G,Me));let fe=Me.find(Ye=>!j.has(Ye));return fe||(fe=d.createElement("img"),fe.setAttribute("data-native-ui-projection-node",""),Me.push(fe)),j.add(fe),k.push(fe),fe.src=ot(w.url),await fe.decode(),fe}))),V||h!=="native"||q||b||r.blocked()||ee!==n||W()!==P||Y?.revision!==e||M.some(w=>!L(w.scope.element)||![w.element,...w.sources??[]].every(f))))return;let Re=R,et={data:H,images:k,sources:Array.from(new Set(M.flatMap(w=>[w.element,...w.sources??[]]))),targets:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).element),scopes:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).scope),parents:H.parts.map(w=>M.find(G=>w.ids.includes(G.control.id)).scope.element.parentNode),frames:[],viewport:P,revision:e,layout:O(M)};try{if(!Ue(et))throw new Error("Projection destination is unavailable")}catch(w){Q();try{Ue(),R?.sources.forEach(G=>{D.add(G),de.add(G)})}catch{$()}throw w}R=et,xe(),R.sources.forEach(w=>{D.add(w),de.add(w)}),r.opaqueUnderlay&&S({action:"prepared",token:H.token}).catch(()=>{}),p.dispatchEvent(new Event(l)),be=s,I=!0,He(Re)}catch{}finally{I||k.forEach(re=>{B(re)}),H?.token&&!I&&S({action:"release",token:H.token}).catch(()=>{}),te=!1,Y&&(Y.revision!==e||z!==s)&&ue()}},ue=()=>{p.clearTimeout(ve),!V&&h==="native"&&!b&&!q&&!r.blocked()&&(ve=p.setTimeout(()=>{qe()},v))},Ae,a=(e,o)=>{if(o.some(s=>s.scope.element.ownerDocument!==d||[s.element,...s.sources??[]].some(P=>P.ownerDocument!==d)))throw new TypeError("All projection sources and fallback scopes must share one Document");if(r.blocked())return;!b&&R&&R.layout!==O(Ee(o))&&Le();let n=O(o);Ae!==n&&(Ae=n,z++,ee++),Y?.revision!==e&&ee++,Y={revision:e,candidates:o},le(),(R?.revision!==e||be!==z)&&ue()},u=e=>{!b&&R&&e&&Y?.candidates.some(o=>o.scrollElement===e&&R.sources.includes(o.element))&&Le(),b&&ke(),z++,ee++,ue()},E=await Be(i.listen(({active:e})=>{q=e,ee++,p.clearTimeout(ve),e||ue()})),_=new Set,ce=e=>{se.get(e)?.forEach(o=>o.removeAttribute("data-native-ui-snapshot-content")),_.delete(e)&&e.removeAttribute("data-native-ui-snapshot-prepared"),e.removeAttribute("data-native-ui-snapshot-visible"),e.removeAttribute(y),e.removeAttribute("data-native-ui-snapshot-positioned"),e.removeAttribute("data-native-ui-snapshot-source"),F(e),se.delete(e)},Q=()=>{me++,p.cancelAnimationFrame(J);for(let e of Fe.keys())e.style.setProperty("opacity","0","important");Fe.clear(),J=0,Z=!1,ae=!1,xe(),b?.sources.forEach(e=>{g.delete(e),c.delete(e)}),K.forEach(ce),K.clear(),A.forEach((e,o)=>{(V||o.nodeType===11&&!o.host.isConnected)&&(e.remove(),A.delete(o))})},$=(e=b,o=X)=>{if(b!==e)return;let n=new Set([b,R]);Q(),b=void 0,R=void 0,X=!1,p.clearTimeout(we),n.forEach(s=>He(s,o)),r.wake()},ne=()=>{if(!b)return;if(R!==b){$();return}let e=b;me++,p.cancelAnimationFrame(J),J=0,Z=ae=!1,e.sources.forEach(o=>{g.delete(o),c.delete(o)}),K.forEach(o=>o.removeAttribute("data-native-ui-snapshot-source")),Xe(e,!!r.opaqueUnderlay),b=void 0,X=!1,p.clearTimeout(we),Ie("restored",e.data.token,!0),e.sources.forEach(o=>{D.add(o),de.add(o)}),r.wake()},Pe=()=>{X&&ne(),he.forEach(e=>e())},De=e=>e.scopes.map(o=>L(o.element)?o.element:void 0),K=new Set,Xe=(e,o)=>{for(let n of K)n.toggleAttribute("data-native-ui-snapshot-visible",o),Se(n);e.images.forEach(n=>n.style.setProperty("opacity",o?"1":"0","important"))},Te=new Map,Fe=new Map,ke=()=>{let e=[];for(let[o,n]of Fe){let{target:s,frame:P}=n;if(!s.isConnected){o.remove();continue}let M=s.shadowRoot??s;o.parentNode!==M&&M.insertBefore(o,null);let H=s.getBoundingClientRect(),I=o.getBoundingClientRect(),k=parseFloat(o.style.width)||P.width,re=parseFloat(o.style.height)||P.height,ie=I.width/k||1,Ce=I.height/re||1,Re=n.scale??(n.scale={x:ie,y:Ce});e.push({element:o,left:(parseFloat(o.style.left)||0)+(H.x+P.x*ie/Re.x-I.x)/ie,top:(parseFloat(o.style.top)||0)+(H.y+P.y*Ce/Re.y-I.y)/Ce,width:P.width/Re.x,height:P.height/Re.y})}for(let{element:o,...n}of e)for(let[s,P]of Object.entries(n)){let M=`${P}px`;o.style.getPropertyValue(s)!==M&&o.style.setProperty(s,M,"important")}},Ue=(e=b??R)=>{if(!e||X)return!1;if(!e.sources.every(f)||De(e).some(n=>!n))return Le(),!1;let o=De(e);if(b){if(o.some(s=>!s?.isConnected||!A.has(N(s))))return $(b,!1),!1;let n=new Set;for(let[s,P]of e.targets.entries()){let M=Te.get(P),H=o[s];!M||!H?.isConnected||(H.setAttribute(y,M),H.setAttribute("data-native-ui-snapshot-source",""),n.add(H))}for(let s of K)n.has(s)||ce(s);return K.clear(),n.forEach(s=>K.add(s)),Xe(e,ae),!0}C.forEach(n=>n.forEach(s=>{e.images.includes(s)||(s.style.setProperty("display","none","important"),s.removeAttribute("data-native-ui-projection-image"))})),Te.clear(),Fe.clear(),K.forEach(ce),K.clear();for(let n of new Set(o)){if(!n)continue;K.add(n),oe(N(n));let s=o.flatMap((I,k)=>I===n?[k]:[]),P=`${T}-${s[0]}`;n.setAttribute(y,P),n!==e.targets[s[0]]&&(n.setAttribute("data-native-ui-snapshot-prepared",""),_.add(n)),n.toggleAttribute("data-native-ui-snapshot-visible",!!r.opaqueUnderlay),Se(n);let M=n.getBoundingClientRect();n.toggleAttribute("data-native-ui-snapshot-positioned",p.getComputedStyle(n).position==="static");let H=n.shadowRoot??n;for(let I of[...s].reverse()){let k=e.images[I],re=e.data.parts[I],ie=e.frames[I]??{x:r.opaqueUnderlay?0:re.x-M.x,y:r.opaqueUnderlay?0:re.y-M.y,width:re.width,height:re.height};e.frames[I]=ie,Te.set(e.targets[I],P),k.inert=!0,k.setAttribute("aria-hidden","true"),k.setAttribute("data-native-ui-projection-image",P),k.style.cssText="all:initial!important;position:absolute!important;display:block!important;visibility:visible!important;pointer-events:none!important;image-rendering:pixelated!important;will-change:opacity!important;opacity:0!important;",k.style.setProperty("width",`${ie.width}px`,"important"),k.style.setProperty("height",`${ie.height}px`,"important"),k.style.setProperty("left","0px","important"),k.style.setProperty("top","0px","important"),k.style.setProperty("opacity",r.opaqueUnderlay?"1":"0","important"),k.parentNode!==H&&H.insertBefore(k,null),Fe.set(k,{target:n,frame:ie})}}return e.parents=e.scopes.map(n=>n.element.parentNode),ke(),!0},Je=e=>e.images.map((o,n)=>{let s=o.getBoundingClientRect();return{...e.data.parts[n],x:s.x,y:s.y,width:s.width,height:s.height}}),Ke=()=>{if(Pe(),V||h==="none"||b)return;let e=R;if(!e||e.viewport!==W()||!e.sources.every(f)||r.current&&!r.current(e.targets)||e.targets.some(s=>!Te.has(s))||De(e).some(s=>!s?.isConnected)||[...K].some(s=>!s.isConnected))return;e.scopes.some((s,P)=>s.element.parentNode!==e.parents[P])&&Ue(),ke();let o=++me,n=()=>me===o;Z=!0,ae=!!r.opaqueUnderlay,b=e,ee++,p.clearTimeout(ve),e.sources.forEach(s=>{g.add(s)}),K.forEach(s=>s.setAttribute("data-native-ui-snapshot-source","")),Xe(e,ae),J=p.requestAnimationFrame(()=>{J=0,n()&&(Z=!1,r.wake())}),pe(S({action:"cover",token:e.data.token,...r.transient?{transient:!0,viewportWidth:p.innerWidth,parts:Je(e)}:{}})).then(s=>{if(n()){if(Z=!1,s?.shown!==!0){$(e,!1);return}X||(ae=!0,e.sources.forEach(P=>c.add(P)),Ue(),ke()),p.cancelAnimationFrame(J),J=p.requestAnimationFrame(()=>{J=0,n()&&S({action:"painted",token:e.data.token}).catch(()=>{n()&&$(e,!1)})}),r.wake()}}).catch(()=>{n()&&$(e,!1)})},Ze=()=>{if(!(!b||V||X)){if(!b.sources.every(f)||De(b).some(e=>!e)||r.current&&!r.current(b.targets)){$(b,!1);return}if(!r.blocked()){if(ke(),r.transient){let e=b;if(De(e).some(s=>!s?.isConnected)){$(e,!1);return}let n=Je(e);r.opaqueUnderlay||n.every((s,P)=>s.width===e.data.parts[P].width&&s.height===e.data.parts[P].height)?e.data={...e.data,parts:n}:R=void 0,S({action:"restore",token:e.data.token,viewportWidth:p.innerWidth,parts:n}).catch(()=>{})}Oe=r.revision?.()??Y?.revision??0,X=!0,b.sources.forEach(e=>g.delete(e)),we=p.setTimeout(()=>{X&&$(b,!1)},250),r.wake()}}},lt=(e,o,n)=>{!X||!b||n===void 0||n<=Oe||!r.transient&&e||b.data.parts.every(s=>s.ids.every(P=>o?.includes(P)))&&(ne(),ue())},Le=(e=!1)=>{he.forEach(n=>n()),ee++,p.clearTimeout(ve);let o=R;if(R=void 0,(e||V)&&(U=void 0),r.retainPreparedUntilRelease&&!b&&!e&&!V){if(o){let n={};U=n,pe(S({action:"release",token:o.data.token})).catch(()=>{}).finally(()=>{if(o.images.forEach(s=>{B(s)}),U===n&&(U=void 0,!(R||b))){for(let s of K)s.getAttribute(y)!==Te.get(s)&&(K.delete(s),_.delete(s));Q(),Te.clear(),p.dispatchEvent(new Event(l))}})}if(U)return}He(o),b?$(b,!1):(Q(),Te.clear(),p.dispatchEvent(new Event(l)))},Qe;try{r.events&&(Qe=await ze(r.events,(e,o)=>{if(!V){if(e&&(h=e),h==="none"){Le();return}e==="web"&&Ke(),e==="native"&&(Ze(),ue()),o&&u()}}))}catch(e){throw V=!0,Le(),await pe(Promise.resolve(E.remove())).catch(()=>{}),e}return{get owners(){return[...g]},get visibleOwners(){return[...c]},get preparedOwners(){return[...D]},consider:a,changed:u,moved:ke,get token(){return X?void 0:b?.data.token},begin:Ke,get restoring(){return X},get handoffPending(){return Z},retireRestoration:Pe,end:Ze,updated:lt,invalidate:Le,async destroy(){V=!0,Le(),C.forEach(e=>e.forEach(o=>o.remove())),C.clear(),await Promise.allSettled([pe(Promise.resolve().then(()=>E?.remove())),pe(Promise.resolve().then(()=>Qe?.remove()))])}}},st=async(t,i,r)=>{let v=await Pt(t,i,r),h=v.consider;return Object.assign(v,{consider:(d,p)=>h(d,p.map(T=>({...T,scope:t})))})};var at=(t,i)=>{if(t.nodeType!==1||t.namespaceURI!=="http://www.w3.org/1999/xhtml"||!t.ownerDocument||!("style"in t))throw new TypeError("A Web projection scope requires an HTMLElement fallback");if(t.matches("img, input, textarea, select, video, audio, canvas, iframe, embed, object, br, hr, area, base, link, meta, source, track, wbr"))throw new TypeError("A Web projection fallback must be a container element; use the existing fallback container");return Object.freeze({element:t,namespace:i})};var ct=async(t,i,r={addListener:async(v,h)=>globalThis.Capacitor.addListener(t.plugin,v,h)})=>{let v="view",h=t.receiveListeners,d=!1,p=!1,T="native",f="native",L=tt(document),C=()=>T==="native"&&m&&L.isCovered(m)?"web":T,j=!1,B=!1,S=!1,y=!1,l,g,c,D=!1,x=()=>{let a=D;D=!0;try{c?.begin()}finally{D=a}},m,O={},A,N=0,oe=()=>{N++,A=void 0;let a=Ne(m);a?.owner===O&&(a.projected=!1,a.owner=void 0)},F={listen:a=>i.listen(u=>{a(u),!u.active&&B&&(B=!1,he()),u.precovered&&Ie(u.precovered)}),send:a=>{if(!t.placementHandoff)return i.send(a);let u=Ne(m);if(a.action==="cover"){let $=A===a.token&&u?.owner===O&&u.projected,ne=++N;return A=a.token,u&&(u.owner=O,u.projected=!!$),i.send(a).then(Pe=>(ne===N&&u===Ne(m)&&u?.owner===O&&(u.projected=Pe?.shown===!0),Pe)).catch(Pe=>{throw ne===N&&u?.owner===O&&(oe(),u.invalidate()),Pe})}let E=a.action==="release"&&a.token===A,_=A&&(a.action==="restore"||E||a.action==="reset"||a.action==="visibility"&&a.visible);_&&N++;let ce=N,Q=()=>{ce!==N||u?.owner!==O||(oe(),u.invalidate())};try{let $=_&&u?.owner===O?{...a,token:"token"in a?a.token:A,placement:u.measure()}:a;return i.send($).then(async ne=>(a.action==="release"&&ne?.requiresPlacement&&(u&&(!u.owner||u.owner===O)?ne=await i.send({...a,placement:u.measure()}):(await i.send({action:"visibility",visible:!1}),ne=await i.send(a))),ce===N&&(a.action==="resume"||E||a.action==="reset"||a.action==="visibility")&&oe(),ne)).catch(ne=>{throw Q(),ne})}catch($){return Q(),Promise.reject($)}}},se=0,Se=0,W=0,Z=!1,ae=!1,J=!1,me=!1,R=document.createElement("style"),U=`data-native-ui-session-${t.id.replace(/[^a-zA-Z0-9-]/g,"")}`;R.textContent=`[${U}="native"], [${U}="native"] *, [${U}="none"], [${U}="none"] * {visibility:hidden!important}`,document.documentElement.append(R);let b=()=>{let a=document.querySelectorAll(t.projectionSelector);return a.length===1&&a[0]instanceof HTMLElement?a[0]:void 0},q=()=>{m&&(f==="web"||f==="native"&&S?m.removeAttribute(U):m.setAttribute(U,f))},X=()=>{if(!m?.isConnected)return[];let a=m.getBoundingClientRect(),u={x:a.x,y:a.y,width:a.width,height:a.height},E=l&&Ge(m,l,()=>t.id);return[{element:m,scrollElement:l,control:{id:v,...u,...E?{scroll:E}:{}}}]},we=async()=>{if(d)return;let a=W,u=t.failedFallback==="native"&&C()==="native"&&!!m?.isConnected;await F.send({action:"visibility",visible:u}).catch(()=>{}),!(d||a!==W)&&(u||f==="none"?q():m?.removeAttribute(U))},Oe=()=>{if(!j||f!=="native"||!m?.isConnected||c?.token||c?.restoring)return;let a=t.failedFallback==="native";F.send({action:"visibility",visible:a}).catch(()=>{}),a?q():m.removeAttribute(U)},ee=()=>{if(d||D)return;if(Oe(),f==="web"&&c&&!c.token&&!c.restoring){F.send({action:"visibility",visible:!1}).catch(()=>{}),m?.removeAttribute(U);return}if(Z||!c?.restoring||f!=="native")return;Z=!0;let a=W,u=c;F.send({action:"resume"}).then(()=>{d||a!==W||u!==c||(S=!1,u.updated(void 0,[v],++se),q(),z())}).catch(()=>{a!==W||d||(u.invalidate(),we())}).finally(()=>{Z=!1,ee()})},ve=async()=>{if(d||ae||j)return;if(c?.restoring){ee();return}let a=b();if(a!==m){if(W++,oe(),m?.removeAttribute(U),await c?.destroy(),c=void 0,d)return;m=a,S=!1,V.disconnect(),m&&V.observe(m)}if(de(),f=C(),!m){await F.send({action:"visibility",visible:!1});return}if(!c){ae=!0;let u=W;try{let E=await st(at(m,t.id),F,{wake:ee,captureDelayMs:t.captureDelayMs,retainPreparedUntilRelease:t.nativeDragHandoff,blocked:()=>f!=="native"||j||S&&!c?.token,revision:()=>se,captureRevision:t.captureMode==="view"?()=>Se:void 0,transient:!0,opaqueUnderlay:t.captureMode==="view"});if(d||u!==W){await E.destroy();return}c=E}finally{ae=!1}}if(!d){if(f==="native"&&S){await F.send({action:"visibility",visible:!1}),q();return}if(f==="native"){let u=W;if(await F.send({action:"visibility",visible:!0}),d||u!==W||f!=="native")return;q(),l=[...We(m)].find(Q=>{let $=getComputedStyle(Q);return/auto|scroll/.test($.overflowX+$.overflowY)&&(Q.scrollHeight>Q.clientHeight||Q.scrollWidth>Q.clientWidth)});let E=l&&Ge(m,l,()=>t.id),_=t.nativeDragHandoff&&t.captureMode==="view"&&l?{viewport:l.getBoundingClientRect(),offsetX:l.scrollLeft,offsetY:l.scrollTop,rangeX:Math.max(0,l.scrollWidth-l.clientWidth),rangeY:Math.max(0,l.scrollHeight-l.clientHeight)}:void 0,ce=await F.send({action:"track",viewportWidth:innerWidth,...E?{scroll:E}:{},..._?{gesture:_}:{}});if(d||u!==W)return;y=ce?.tracked===!0,c.consider(t.captureMode==="view"?Se:++se,X())}else await F.send({action:"visibility",visible:!1}),q()}},z=()=>{d||(J=!0,!(!p||me)&&(me=!0,Promise.resolve().then(async()=>{try{for(;J&&!d;)J=!1,await ve()}catch{await we()}finally{me=!1,J&&z()}})))},be=()=>{c?.invalidate(),z()},V=new ResizeObserver(be);window.addEventListener("resize",be);let te=new Set,Y=new WeakSet,le=a=>{let u=a.composedPath()[0]??a.target;if(!(d||f!=="native"||!m||Y.has(a)||u!==document&&![...We(m)].includes(u))){if(Y.add(a),y&&u===l){c?.changed(u);return}j?t.captureMode==="view"?c?.moved():c?.changed():((Z||c?.restoring)&&W++,j=!0,x(),S=t.failedFallback!=="native",c?.token?m.removeAttribute(U):Oe()),he()}};function he(){clearTimeout(g),g=setTimeout(()=>{B||(j=!1,!(d||f!=="native")&&(c?.end(),c?.restoring||z()))},100)}function Ie(a){if(d||f!=="native"||!m?.isConnected||!c||(B=!0,c.token))return;(Z||c.restoring)&&W++,A=a;let u=Ne(m);if(u&&(u.owner=O,u.projected=!0),j=!0,x(),!c.token){j=!1,we();return}he()}let de=()=>{let a=new Set(m?We(m):[]),u=a.size!==te.size||[...a].some(E=>!te.has(E));for(let E of te)a.has(E)||(E.removeEventListener("scroll",le),E.removeEventListener("slotchange",xe),te.delete(E));for(let E of a)te.has(E)||(E.addEventListener("scroll",le,{passive:!0}),E.addEventListener("slotchange",xe),te.add(E));u&&(y=!1,l=void 0,c?.invalidate(),z())},xe=()=>{de(),z()};document.addEventListener("scroll",le,!0);let He=new MutationObserver(a=>{de(),b()!==m?z():m&&a.some(u=>u.type==="childList")&&Ee(C())});He.observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});let Ee=(a,u=!1)=>{if(d||!u&&a===f)return;j=!1,B=!1,clearTimeout(g),f=a,W++;let E=W;f==="none"?F.send({action:"visibility",visible:!1}).then(()=>{f!=="none"||E!==W||d||(c?.invalidate(!0),q())}).catch(()=>{f!=="none"||E!==W||d||(c?.invalidate(!0),q())}):f==="web"?(x(),c?.token||F.send({action:"visibility",visible:!1}).catch(()=>{}),q()):f==="native"&&(c?.end(),c?.restoring||z())},qe=L.subscribe(()=>queueMicrotask(()=>Ee(C()))),ue,Ae=async()=>{if(!d){d=!0,oe(),W++,qe(),He.disconnect(),V.disconnect(),window.removeEventListener("resize",be),document.removeEventListener("scroll",le,!0);for(let a of te)a.removeEventListener("scroll",le),a.removeEventListener("slotchange",xe);te.clear(),clearTimeout(g),m?.removeAttribute(U),R.remove(),await Promise.allSettled([Promise.resolve(ue?.remove()),c?.destroy()])}};try{let a=W;ue=await ze({addListener:(E,_)=>r.addListener(E,_),update:h?.update,projection:h?.projection,accepts:E=>!h?.match||Object.entries(h?.match).every(([_,ce])=>typeof E=="object"&&E!==null&&E[_]===ce)},(E,_)=>{d||(E&&(E==="native"&&(S=!1),T=E,F.send({action:"destination",destination:E}).catch(()=>{}),Ee(C(),!0)),_&&(Se++,c?.changed(),f==="native"&&z()))});let u=await F.send({action:"connect"});return W===a&&["native","web","none"].includes(u?.destination)&&(T=u.destination),f=C(),p=!0,z(),{destroy:Ae,show:()=>{S=!1,T="native",Ee(C(),!0)},hide:()=>{T=f="none",W++,j=!1,B=!1,clearTimeout(g),c?.invalidate(!0),q()}}}catch(a){throw await Ae(),a}};var ye=new Map,ge=new Map,$e=new Map,Tt=Array.from(crypto.getRandomValues(new Uint32Array(4)),t=>t.toString(16)).join("-"),Ve=new Map,Lt=(t,i,r)=>Ve.get(t)?.get(i)?.(r),Mt=0,jt=(t,i)=>new Promise((r,v)=>{let h=`${t}:${Tt}:${++Mt}`,d=setTimeout(()=>{ge.delete(h),v(new Error("Native UI session timed out"))},5e3);ge.set(h,{resolve:r,reject:v,timer:d});let p=JSON.stringify({key:h,request:i}),T=globalThis,f=T.webkit?.messageHandlers?.[t]??T[t]??T.nativeUIEngine;if(!f){clearTimeout(d),ge.delete(h),v(new Error("Native UI session unavailable"));return}try{f.postMessage(p)}catch(L){clearTimeout(d),ge.delete(h),v(L)}}),St=(t,i,r,v)=>{if(i===null){$e.get(t)?.(r);return}let h=ge.get(i);!h||!i.startsWith(`${t}:`)||(ge.delete(i),clearTimeout(h.timer),v?h.reject(new Error(v)):h.resolve(r))},xt=t=>{ye.get(t)?.show()},Ht=t=>(ye.get(t)?.hide(),!0),kt=async t=>{let i=ye.get(t);ye.delete(t),Ve.delete(t),$e.delete(t);for(let[r,v]of ge)r.startsWith(`${t}:`)&&(ge.delete(r),clearTimeout(v.timer),v.reject(new Error("Native UI session closed")));await i?.destroy()},Ct=async t=>{if(ye.has(t.id))return;let i,r=!1,v,h={show:()=>{v="native",i?.show()},hide:()=>{v="none",i?.hide()},destroy:async()=>{r=!0,await i?.destroy()}};ye.set(t.id,h);try{if(document.readyState==="loading"&&await new Promise(p=>document.addEventListener("DOMContentLoaded",()=>p(),{once:!0})),r)return;let d=new Map;t.runtime==="cordova"&&Ve.set(t.id,d),i=await ct(t,{send:p=>jt(t.id,p),listen:async p=>($e.set(t.id,p),{remove:()=>{$e.get(t.id)===p&&$e.delete(t.id)}})},t.runtime==="cordova"?{addListener:async(p,T)=>(d.set(p,T),{remove:()=>{d.delete(p)}})}:void 0),v==="none"?i.hide():v==="native"&&i.show(),r&&await i.destroy()}catch(d){throw ye.get(t.id)===h&&(ye.delete(t.id),Ve.delete(t.id)),d}};return vt(Rt);})();
@@ -14,6 +14,7 @@ public final class NativeUIScrollBindings {
14
14
  for (id, group) in Dictionary(grouping: nodes.filter { $0.scroll != nil }, by: { $0.scroll!.id }) {
15
15
  if group.contains(where: { $0.scroll?.reuse == true }) {
16
16
  if let tracker = previous[id], tracker.replace(group, webView: webView, scale: scale) {
17
+ tracker.render = render
17
18
  trackers[id] = tracker
18
19
  } else { rejected.append(contentsOf: group.map(\.id)) }
19
20
  } else if let tracker = NativeUIScrollTracker(webView: webView, nodes: group, scale: scale, render: render) {
@@ -34,7 +34,7 @@ public final class NativeUIScrollTracker {
34
34
  private let contentOrigin: CGPoint
35
35
  private let viewportCorrection: CGPoint
36
36
  private var frames: [String: CGRect] = [:]
37
- private let render: (String, CGRect, CGRect) -> Void
37
+ var render: (String, CGRect, CGRect) -> Void
38
38
  private var observation: NSKeyValueObservation?
39
39
 
40
40
  public init?(webView: WKWebView, nodes: [NativeUIScrollNode], scale: CGFloat,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webview-native-ui/engine",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Native UI placement, scroll tracking, and Web projection for Capacitor and Cordova plugin maintainers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "lint": "npm run typecheck && eslint . --max-warnings 0 && npm run format:check",
34
34
  "format": "prettier --write \"**/*.{ts,js,mjs,cjs,json,md,yml,yaml,html}\"",
35
35
  "prepublishOnly": "npm run build",
36
- "test:release": "node --test scripts/native-ui-engine-release/publish.test.mjs",
36
+ "test:release": "node --test scripts/native-ui-engine-release/*.test.mjs",
37
37
  "test:package": "node scripts/verify-package.mjs",
38
38
  "release": "np --no-publish --no-tests --branch main",
39
39
  "test:cordova": "node scripts/verify-cordova.mjs",