@100mslive/react-native-hms 1.12.2 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/android/build.gradle +70 -12
  2. package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +8 -8
  3. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt +38 -12
  4. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManagerImpl.kt +185 -0
  5. package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +20 -10
  6. package/android/src/main/java/com/reactnativehmssdk/{HMSManager.kt → HMSManagerImpl.kt} +28 -111
  7. package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +3 -3
  8. package/android/src/main/java/com/reactnativehmssdk/HMSReactNativeEvent.kt +29 -0
  9. package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManagerImpl.kt +119 -0
  10. package/android/src/main/java/com/reactnativehmssdk/HMSView.kt +33 -5
  11. package/android/src/main/java/com/reactnativehmssdk/HmsScreenshareActivity.kt +9 -9
  12. package/android/src/main/java/com/reactnativehmssdk/HmssdkPackage.kt +42 -3
  13. package/android/src/newarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +128 -0
  14. package/android/src/newarch/java/com/reactnativehmssdk/HMSManager.kt +332 -0
  15. package/android/src/newarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +102 -0
  16. package/android/src/oldarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +61 -0
  17. package/android/src/oldarch/java/com/reactnativehmssdk/HMSManager.kt +351 -0
  18. package/android/src/oldarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +87 -0
  19. package/ios/HMSHLSPlayerComponentView.mm +325 -0
  20. package/ios/HMSHLSPlayerManager.m +10 -0
  21. package/ios/HMSHLSPlayerManager.swift +91 -79
  22. package/ios/HMSManager.m +13 -0
  23. package/ios/HMSManager.mm +365 -0
  24. package/ios/HMSManager.swift +109 -103
  25. package/ios/HMSView.m +9 -0
  26. package/ios/HMSView.swift +44 -14
  27. package/ios/HMSViewComponentView.mm +229 -0
  28. package/lib/commonjs/classes/HmsView.js +45 -48
  29. package/lib/commonjs/classes/HmsView.js.map +1 -1
  30. package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js +46 -26
  31. package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
  32. package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +5 -4
  33. package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
  34. package/lib/commonjs/modules/HMSManagerModule.js +3 -10
  35. package/lib/commonjs/modules/HMSManagerModule.js.map +1 -1
  36. package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js +75 -0
  37. package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
  38. package/lib/commonjs/specs/HMSViewNativeComponent.js +55 -0
  39. package/lib/commonjs/specs/HMSViewNativeComponent.js.map +1 -0
  40. package/lib/commonjs/specs/NativeHMSManager.js +38 -0
  41. package/lib/commonjs/specs/NativeHMSManager.js.map +1 -0
  42. package/lib/module/classes/HmsView.js +46 -49
  43. package/lib/module/classes/HmsView.js.map +1 -1
  44. package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js +48 -28
  45. package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
  46. package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +3 -3
  47. package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
  48. package/lib/module/modules/HMSManagerModule.js +1 -9
  49. package/lib/module/modules/HMSManagerModule.js.map +1 -1
  50. package/lib/module/specs/HMSHLSPlayerNativeComponent.js +69 -0
  51. package/lib/module/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
  52. package/lib/module/specs/HMSViewNativeComponent.js +49 -0
  53. package/lib/module/specs/HMSViewNativeComponent.js.map +1 -0
  54. package/lib/module/specs/NativeHMSManager.js +33 -0
  55. package/lib/module/specs/NativeHMSManager.js.map +1 -0
  56. package/lib/typescript/components/HMSHLSPlayer/RCTHMSHLSPlayer.d.ts +6 -9
  57. package/lib/typescript/specs/HMSHLSPlayerNativeComponent.d.ts +115 -0
  58. package/lib/typescript/specs/HMSViewNativeComponent.d.ts +97 -0
  59. package/lib/typescript/specs/NativeHMSManager.d.ts +147 -0
  60. package/package.json +16 -1
  61. package/react-native-hms.podspec +43 -0
  62. package/src/classes/HmsView.tsx +60 -78
  63. package/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx +62 -128
  64. package/src/components/HMSHLSPlayer/RCTHMSHLSPlayer.ts +8 -13
  65. package/src/modules/HMSManagerModule.ts +1 -14
  66. package/src/specs/HMSHLSPlayerNativeComponent.ts +203 -0
  67. package/src/specs/HMSViewNativeComponent.ts +119 -0
  68. package/src/specs/NativeHMSManager.ts +307 -0
  69. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +0 -144
  70. package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt +0 -111
package/ios/HMSView.m CHANGED
@@ -1,6 +1,13 @@
1
1
  #import "React/RCTViewManager.h"
2
2
  #import <Foundation/Foundation.h>
3
3
 
4
+ // Under the New Architecture, `<HMSView />` is rendered via the Fabric
5
+ // component view in HMSViewComponentView.mm. The legacy paper
6
+ // `RCT_EXTERN_MODULE` + `RCT_EXPORT_VIEW_PROPERTY` declarations below
7
+ // are only used in old-arch / interop mode, so we guard the whole
8
+ // block with `#if !RCT_NEW_ARCH_ENABLED` to prevent double-registration.
9
+ #if !RCT_NEW_ARCH_ENABLED
10
+
4
11
  @interface RCT_EXTERN_MODULE(HMSView, RCTViewManager)
5
12
 
6
13
  RCT_EXPORT_VIEW_PROPERTY(data, NSDictionary);
@@ -10,3 +17,5 @@ RCT_EXTERN_METHOD(capture:(nonnull NSNumber *)node requestId:(nonnull NSNumber *
10
17
  RCT_EXPORT_VIEW_PROPERTY(autoSimulcast, BOOL);
11
18
 
12
19
  @end
20
+
21
+ #endif // !RCT_NEW_ARCH_ENABLED
package/ios/HMSView.swift CHANGED
@@ -2,9 +2,9 @@ import HMSSDK
2
2
  import AVKit
3
3
 
4
4
  @objc(HMSView)
5
- class HMSView: RCTViewManager {
5
+ public class HMSView: RCTViewManager {
6
6
 
7
- override func view() -> (HmssdkDisplayView) {
7
+ override public func view() -> (HmssdkDisplayView) {
8
8
  let view = HmssdkDisplayView()
9
9
  let hms = getHmsFromBridge()
10
10
 
@@ -17,20 +17,38 @@ class HMSView: RCTViewManager {
17
17
  return HMSManager.shared?.hmsCollection ?? [String: HMSRNSDK]()
18
18
  }
19
19
 
20
- override class func requiresMainQueueSetup() -> Bool {
20
+ public override class func requiresMainQueueSetup() -> Bool {
21
21
  true
22
22
  }
23
23
 
24
- @objc func capture(_ node: NSNumber, requestId: NSNumber) {
24
+ @objc public func capture(_ node: NSNumber, requestId: NSNumber) {
25
25
  DispatchQueue.main.async {
26
- if let component = self.bridge.uiManager.view(forReactTag: node) as? HmssdkDisplayView {
27
- component.captureHmsView(requestId)
26
+ // Under the New Architecture's Fabric path, the `capture`
27
+ // imperative is dispatched directly to `HMSViewComponentView`
28
+ // (see ios/HMSViewComponentView.mm) and this method is not
29
+ // called. Under old arch and interop, we use self.bridge
30
+ // (which is nil under bridgeless) to safely look up the view
31
+ // by react tag. Under bridgeless mode, self.bridge is
32
+ // nil and this code path is unreachable anyway because the
33
+ // Fabric path is in use.
34
+ guard let bridge = self.bridge else {
35
+ // Bridgeless mode: self.bridge is nil and the Fabric path
36
+ // (HMSViewComponentView.mm) handles `capture` directly. If
37
+ // this old-arch fallback fires under bridgeless, something
38
+ // has misregistered the command — log so it isn't silent.
39
+ NSLog("[HMSView] capture: bridge is nil — Fabric path expected to handle this")
40
+ return
41
+ }
42
+ guard let component = bridge.uiManager.view(forReactTag: node) as? HmssdkDisplayView else {
43
+ NSLog("[HMSView] capture: no HmssdkDisplayView found for reactTag=\(node)")
44
+ return
28
45
  }
46
+ component.captureHmsView(requestId)
29
47
  }
30
48
  }
31
49
  }
32
50
 
33
- class HmssdkDisplayView: UIView {
51
+ public class HmssdkDisplayView: UIView {
34
52
 
35
53
  lazy var videoView: HMSVideoView = {
36
54
  let videoView = HMSVideoView()
@@ -40,21 +58,33 @@ class HmssdkDisplayView: UIView {
40
58
  return videoView
41
59
  }()
42
60
 
43
- var hmsCollection = [String: HMSRNSDK]()
61
+ // Read live from HMSManager.shared on every access. Previously this
62
+ // was a stored property snapshotted at view creation, which left the
63
+ // view holding references to destroyed HMSRNSDK instances after a
64
+ // leave → rejoin cycle (the SDK destroys & recreates instances; the
65
+ // view's snapshot stayed stale → track lookup returned nil → black
66
+ // screen). Reading live keeps the view in sync with whatever HMS
67
+ // instance is currently active. Works for both old arch and Fabric.
68
+ var hmsCollection: [String: HMSRNSDK] {
69
+ return HMSManager.shared?.hmsCollection ?? [String: HMSRNSDK]()
70
+ }
44
71
 
72
+ // Kept as a no-op for backward compatibility with the paper view
73
+ // manager's `view()` factory, which still calls this. The actual
74
+ // lookup is now live via the computed `hmsCollection` above.
45
75
  func setHms(_ hmsInstance: [String: HMSRNSDK]) {
46
- hmsCollection = hmsInstance
76
+ // Intentionally empty — hmsCollection is now computed.
47
77
  }
48
78
 
49
- @objc var onDataReturned: RCTDirectEventBlock?
79
+ @objc public var onDataReturned: RCTDirectEventBlock?
50
80
 
51
- @objc var autoSimulcast: Bool = true {
81
+ @objc public var autoSimulcast: Bool = true {
52
82
  didSet {
53
83
  videoView.disableAutoSimulcastLayerSelect = !autoSimulcast
54
84
  }
55
85
  }
56
86
 
57
- @objc var scaleType: String = "ASPECT_FILL" {
87
+ @objc public var scaleType: String = "ASPECT_FILL" {
58
88
  didSet {
59
89
  switch scaleType {
60
90
  case "ASPECT_FIT":
@@ -73,7 +103,7 @@ class HmssdkDisplayView: UIView {
73
103
  }
74
104
  }
75
105
 
76
- @objc var data: NSDictionary = [:] {
106
+ @objc public var data: NSDictionary = [:] {
77
107
  didSet {
78
108
 
79
109
  if let mirror = data.value(forKey: "mirror") as? Bool {
@@ -114,7 +144,7 @@ class HmssdkDisplayView: UIView {
114
144
  return nil
115
145
  }
116
146
 
117
- @objc func captureHmsView( _ requestId: NSNumber) {
147
+ @objc public func captureHmsView( _ requestId: NSNumber) {
118
148
  guard let onDataReturnedUnwrapped = onDataReturned else {
119
149
  print(#function, "Can't send any data to JS side, `onDataReturned` is nil!")
120
150
  return
@@ -0,0 +1,229 @@
1
+ //
2
+ // HMSViewComponentView.mm
3
+ //
4
+ // Fabric component view for `<HMSView />` — the native video tile.
5
+ //
6
+ // Phase 1 / 1B group 2 of the New Architecture migration. This file
7
+ // implements the Fabric counterpart to the existing paper-side
8
+ // `HMSView` (RCTViewManager) + `HmssdkDisplayView` (UIView subclass).
9
+ //
10
+ // Architecture overview:
11
+ // - Under New Architecture, RN renders native views via Fabric.
12
+ // - Fabric expects a class that subclasses `RCTViewComponentView`,
13
+ // conforms to a generated protocol (e.g. `RCTHMSViewViewProtocol`),
14
+ // and overrides `updateProps:`, `handleCommand:args:`, etc.
15
+ // - The actual UI (camera surface) is still the existing Swift
16
+ // `HmssdkDisplayView` — we host it inside this Fabric wrapper as
17
+ // a sub-view, forwarding props and commands to it.
18
+ //
19
+ // Event-emission pattern (Pattern A — block-prop interception):
20
+ // - `HmssdkDisplayView` already has `@objc var onDataReturned:
21
+ // RCTDirectEventBlock?` (the legacy paper event mechanism).
22
+ // - In `initWithFrame:`, we set that block to a translator block
23
+ // that converts the NSDictionary payload from Swift into the
24
+ // typed C++ struct expected by the Fabric event emitter.
25
+ // - This means Swift code is UNCHANGED — it still calls its block
26
+ // prop the same way it always has. The .mm wrapper intercepts.
27
+ // - Industry standard for migrating Swift-based RN libraries to
28
+ // Fabric without rewriting Swift code.
29
+ //
30
+ // Important caveats for the consumer-side first build:
31
+ // - The `react/renderer/components/RNHmsSpec/...` headers below are
32
+ // generated by Codegen at the consumer's `pod install` time. They
33
+ // do NOT exist in the SDK source tree.
34
+ // - The `react_native_hms-Swift.h` header is auto-generated by the
35
+ // Swift compiler in the consumer's build. The exact name depends
36
+ // on CocoaPods' module-name normalization.
37
+ // - `HMSViewCls()` at the bottom is the public C function that the
38
+ // Fabric component-views plugin registry calls to register this
39
+ // class.
40
+ //
41
+
42
+ #ifdef RCT_NEW_ARCH_ENABLED
43
+
44
+ #import <React/RCTViewComponentView.h>
45
+ #import <React/RCTConversions.h>
46
+
47
+ #import <react/renderer/components/RNHmsSpec/ComponentDescriptors.h>
48
+ #import <react/renderer/components/RNHmsSpec/EventEmitters.h>
49
+ #import <react/renderer/components/RNHmsSpec/Props.h>
50
+ #import <react/renderer/components/RNHmsSpec/RCTComponentViewHelpers.h>
51
+
52
+ #import "RCTFabricComponentsPlugins.h"
53
+
54
+ // Auto-generated Swift bridging header. Path may need adjustment based
55
+ // on CocoaPods' module-name normalization.
56
+ #import "react_native_hms-Swift.h"
57
+
58
+ using namespace facebook::react;
59
+
60
+ @interface HMSViewComponentView : RCTViewComponentView <RCTHMSViewViewProtocol>
61
+ @end
62
+
63
+ @implementation HMSViewComponentView {
64
+ // The Swift UIView that does the actual video rendering. Owned and
65
+ // hosted as our `contentView`.
66
+ HmssdkDisplayView *_view;
67
+ }
68
+
69
+ #pragma mark - Component descriptor registration
70
+
71
+ // Tells Fabric which generated component descriptor maps to this class.
72
+ // `HMSViewComponentDescriptor` is generated by Codegen from the TS spec
73
+ // `src/specs/HMSViewNativeComponent.ts`.
74
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
75
+ return concreteComponentDescriptorProvider<HMSViewComponentDescriptor>();
76
+ }
77
+
78
+ #pragma mark - View lifecycle
79
+
80
+ - (instancetype)initWithFrame:(CGRect)frame {
81
+ if (self = [super initWithFrame:frame]) {
82
+ // Initialize default props from the generated `HMSViewProps` struct.
83
+ static const auto defaultProps = std::make_shared<const HMSViewProps>();
84
+ _props = defaultProps;
85
+
86
+ // Instantiate the Swift view directly. `HmssdkDisplayView.hmsCollection`
87
+ // is now a *computed* property that reads live from `HMSManager.shared`
88
+ // on every access, so no explicit wiring is needed — the lookup
89
+ // automatically reflects the currently-active HMS instance even after
90
+ // leave → rejoin cycles.
91
+ _view = [[HmssdkDisplayView alloc] init];
92
+ self.contentView = _view;
93
+
94
+ // ─────────────────────────────────────────────────────────────────
95
+ // Pattern A — block-prop interception for event emission.
96
+ //
97
+ // `HmssdkDisplayView` exposes `@objc var onDataReturned:
98
+ // RCTDirectEventBlock?` (the legacy paper event mechanism). Under
99
+ // Fabric, events flow through a typed C++ event emitter held in
100
+ // `_eventEmitter` (set by Fabric via `updateEventEmitter:`).
101
+ //
102
+ // The block below bridges the two: when the Swift view calls
103
+ // `onDataReturned([...])`, this translator converts the dictionary
104
+ // into the generated `OnDataReturned` C++ struct and dispatches
105
+ // through the Fabric event emitter.
106
+ //
107
+ // This pattern requires NO Swift changes and works transparently
108
+ // alongside the legacy paper code path (which sets the block
109
+ // through the old `RCTDirectEventBlock` view-manager mechanism).
110
+ // ─────────────────────────────────────────────────────────────────
111
+ __weak __typeof(self) weakSelf = self;
112
+ _view.onDataReturned = ^(NSDictionary *body) {
113
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
114
+ if (!strongSelf || !strongSelf->_eventEmitter) {
115
+ return;
116
+ }
117
+ // Cast the type-erased _eventEmitter to our component's typed
118
+ // event emitter (generated by Codegen).
119
+ auto emitter = std::dynamic_pointer_cast<HMSViewEventEmitter const>(
120
+ strongSelf->_eventEmitter);
121
+ if (!emitter) {
122
+ return;
123
+ }
124
+ // Convert NSDictionary payload → typed C++ struct.
125
+ // The shape matches `OnDataReturnedPayload` from
126
+ // src/specs/HMSViewNativeComponent.ts.
127
+ HMSViewEventEmitter::OnDataReturned event = {};
128
+ if (body[@"requestId"]) {
129
+ event.requestId = [body[@"requestId"] intValue];
130
+ }
131
+ if ([body[@"result"] isKindOfClass:[NSString class]]) {
132
+ event.result = [body[@"result"] UTF8String];
133
+ } else if ([body[@"error"] isKindOfClass:[NSArray class]] &&
134
+ [(NSArray *)body[@"error"] count] >= 2) {
135
+ // Swift sends error as ["6001", "message"] tuple; flatten to
136
+ // a string for the Fabric payload.
137
+ NSString *errMessage =
138
+ [(NSArray *)body[@"error"] componentsJoinedByString:@": "];
139
+ event.error = [errMessage UTF8String];
140
+ }
141
+ emitter->onDataReturned(event);
142
+ };
143
+
144
+ // Note: `onChange` (resolution-change event) is not wired here.
145
+ // The Swift `HmssdkDisplayView` does not currently fire a
146
+ // resolution-change callback on iOS — the equivalent
147
+ // `topChange`/`onChange` event is an Android-only behavior in the
148
+ // existing SDK (see `HMSSDKViewManager.kt`). If iOS gains this
149
+ // event in the future, add a second block-intercept here.
150
+ }
151
+ return self;
152
+ }
153
+
154
+ #pragma mark - Prop dispatch
155
+ //
156
+ // Called by Fabric whenever any prop changes. We diff old vs new and
157
+ // forward each changed prop to the Swift view. This is the Fabric
158
+ // equivalent of the paper view manager's `setX:forView:` setters.
159
+
160
+ - (void)updateProps:(Props::Shared const &)props
161
+ oldProps:(Props::Shared const &)oldProps {
162
+ const auto &oldViewProps =
163
+ *std::static_pointer_cast<HMSViewProps const>(_props);
164
+ const auto &newViewProps = *std::static_pointer_cast<HMSViewProps const>(props);
165
+
166
+ // scaleType (string)
167
+ if (oldViewProps.scaleType != newViewProps.scaleType) {
168
+ _view.scaleType = RCTNSStringFromString(newViewProps.scaleType);
169
+ }
170
+
171
+ // autoSimulcast (bool)
172
+ if (oldViewProps.autoSimulcast != newViewProps.autoSimulcast) {
173
+ _view.autoSimulcast = newViewProps.autoSimulcast;
174
+ }
175
+
176
+ // setZOrderMediaOverlay is Android-only — Swift HmssdkDisplayView
177
+ // does not implement it on iOS. Silently ignore changes.
178
+
179
+ // data (struct of trackId, id, mirror, scaleType)
180
+ // Swift expects an NSDictionary, so reconstruct one and assign it on
181
+ // every updateProps call — NOT only when the struct values differ.
182
+ //
183
+ // Why: HmssdkDisplayView.data is a `didSet` setter that, among other
184
+ // things, looks up the HMSVideoTrack by trackId in the active room.
185
+ // For remote peers, the track isn't in the room at first mount —
186
+ // it arrives later via SDK peer/track update events. Paper called
187
+ // setData: on every render, so the lookup retried until the track
188
+ // appeared; an equality-based optimization here would re-create the
189
+ // bug where remote video never appears even though the same trackId
190
+ // becomes valid on a later render.
191
+ const auto &newData = newViewProps.data;
192
+ _view.data = @{
193
+ @"trackId" : RCTNSStringFromString(newData.trackId),
194
+ @"id" : RCTNSStringFromString(newData.id),
195
+ @"mirror" : @(newData.mirror),
196
+ @"scaleType" : RCTNSStringFromString(newData.scaleType),
197
+ };
198
+
199
+ [super updateProps:props oldProps:oldProps];
200
+ }
201
+
202
+ #pragma mark - Imperative commands
203
+
204
+ // Generic command dispatcher. The `RCTHMSViewHandleCommand` helper is
205
+ // generated by Codegen and dispatches to `capture:` below based on the
206
+ // command name from the JS spec.
207
+ - (void)handleCommand:(NSString const *)commandName args:(NSArray const *)args {
208
+ RCTHMSViewHandleCommand(self, commandName, args);
209
+ }
210
+
211
+ // Implementation of the `capture` imperative command from the spec.
212
+ // Dispatched here by `RCTHMSViewHandleCommand` when JS calls
213
+ // `Commands.capture(viewRef, requestId)`.
214
+ - (void)capture:(NSInteger)requestId {
215
+ [_view captureHmsView:@(requestId)];
216
+ }
217
+
218
+ @end
219
+
220
+ #pragma mark - Plugin registration
221
+
222
+ // Public C function that the Fabric component-views plugin registry
223
+ // calls (via RCTFabricComponentsPlugins) to register this class as
224
+ // the implementation of `<HMSView />`.
225
+ Class<RCTComponentViewProtocol> HMSViewCls(void) {
226
+ return HMSViewComponentView.class;
227
+ }
228
+
229
+ #endif // RCT_NEW_ARCH_ENABLED
@@ -6,38 +6,11 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.HmsViewComponent = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
+ var _HMSViewNativeComponent = _interopRequireWildcard(require("../specs/HMSViewNativeComponent"));
9
10
  var _HMSConstants = require("./HMSConstants");
10
11
  var _HMSVideoViewMode = require("./HMSVideoViewMode");
11
12
  var _hmsviews = require("../hooks/hmsviews");
12
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
- /**
14
- * Interface defining the properties for the `HmsView` component.
15
- *
16
- * This interface specifies the structure of the props that the `HmsView` component expects. It includes
17
- * properties for configuring the video track display, such as the track ID, mirroring options,
18
- * and scale type. It also includes properties for handling events and customizing the component's style.
19
- *
20
- * @interface HmsViewProps
21
- * @property {Object} data - An object containing the track ID, instance ID, mirroring option, and scale type for the video or audio track.
22
- * @property {string} data.trackId - The unique identifier for the track to be displayed.
23
- * @property {string} data.id - The identifier for the `HmsViewComponent` instance.
24
- * @property {boolean} data.mirror - Indicates whether the video should be mirrored. This is commonly used for local video tracks.
25
- * @property {HMSVideoViewMode} data.scaleType - Determines how the video fits within the bounds of the view (e.g., aspect fill, aspect fit).
26
- * @property {boolean} autoSimulcast - Enables automatic simulcast layer switching based on network conditions, if supported.
27
- * @property {boolean} setZOrderMediaOverlay - When true, the video view will be rendered above the regular view hierarchy.
28
- * @property {ViewStyle} style - Custom styles to apply to the view.
29
- * @property {Function} onChange - A callback function that is invoked when the `HmsView` component emits a change event.
30
- * @property {Function} onDataReturned - A callback function that is invoked when the `HmsView` component returns data in response to a capture frame event.
31
- *
32
- * @see {https://www.100ms.live/docs/react-native/v2/how-to-guides/set-up-video-conferencing/render-video/overview}
33
- */
34
-
35
- // Imports the `HmsView` component from the native side using the `requireNativeComponent` function.
36
- // This component is used to render video tracks in the application.
37
- const HmsView = (0, _reactNative.requireNativeComponent)('HMSView');
38
- let _nextRequestId = 1;
39
- let _requestMap = new Map();
40
-
41
14
  /**
42
15
  * Defines the properties for the `HmsViewComponent`.
43
16
  *
@@ -67,12 +40,24 @@ const HmsViewComponent = exports.HmsViewComponent = /*#__PURE__*/_react.default.
67
40
  } = props;
68
41
  const hmsViewRef = (0, _react.useRef)();
69
42
  const [applyStyles_ANDROID, setApplyStyles_ANDROID] = (0, _react.useState)(false);
70
- const data = {
43
+ // Memoized so the object reference is stable across renders unless one
44
+ // of the inputs actually changes. Fabric diffs view props by reference
45
+ // before doing a deep compare — a fresh `{...}` on every render would
46
+ // trigger redundant native prop updates.
47
+ const data = (0, _react.useMemo)(() => ({
71
48
  trackId,
72
49
  id,
73
50
  mirror,
74
51
  scaleType
75
- };
52
+ }), [trackId, id, mirror, scaleType]);
53
+
54
+ // Per-instance request/response state for the `capture` imperative.
55
+ // Each `<HmsView />` gets its own counter + pending-promise map so:
56
+ // - requestIds can't collide across multiple HmsView instances
57
+ // - pending promises are scoped to this view and cleaned up when
58
+ // it unmounts (see the useEffect below)
59
+ const nextRequestId = (0, _react.useRef)(1);
60
+ const requestMap = (0, _react.useMemo)(() => new Map(), []);
76
61
 
77
62
  /**
78
63
  * This method is passed to `onChange` prop of `HmsView` Native Component.
@@ -96,38 +81,35 @@ const HmsViewComponent = exports.HmsViewComponent = /*#__PURE__*/_react.default.
96
81
  * It is invoked when `HmsView` emits 'captureFrame' event.
97
82
  */
98
83
  const _onDataReturned = event => {
99
- // We grab the relevant data out of our event.
100
- let {
84
+ const {
101
85
  requestId,
102
86
  result,
103
87
  error
104
88
  } = event.nativeEvent;
105
- // Then we get the promise we saved earlier for the given request ID.
106
- let promise = _requestMap.get(requestId);
89
+ const promise = requestMap.get(requestId);
90
+ if (!promise) {
91
+ // No pending request — typically a late event after unmount/cleanup
92
+ // rejected it, or a stale requestId from a previous mount.
93
+ return;
94
+ }
107
95
  if (result) {
108
- // If it was successful, we resolve the promise.
109
96
  promise.resolve(result);
110
97
  } else {
111
- // Otherwise, we reject it.
112
98
  promise.reject(error);
113
99
  }
114
- // Finally, we clean up our request map.
115
- _requestMap.delete(requestId);
100
+ requestMap.delete(requestId);
116
101
  };
117
102
  const capture = async () => {
118
- const viewManagerConfig = _reactNative.UIManager.getViewManagerConfig('HMSView');
119
- let requestId = _nextRequestId++;
120
- let requestMap = _requestMap;
121
-
122
- // We create a promise here that will be resolved once `_onRequestDone` is
123
- // called.
124
- let promise = new Promise(function (resolve, reject) {
103
+ const requestId = nextRequestId.current++;
104
+ const promise = new Promise((resolve, reject) => {
125
105
  requestMap.set(requestId, {
126
106
  resolve,
127
107
  reject
128
108
  });
129
109
  });
130
- _reactNative.UIManager.dispatchViewManagerCommand((0, _reactNative.findNodeHandle)(hmsViewRef.current), viewManagerConfig.Commands.capture, [requestId]);
110
+ if (hmsViewRef.current) {
111
+ _HMSViewNativeComponent.Commands.capture(hmsViewRef.current, requestId);
112
+ }
131
113
  return promise;
132
114
  };
133
115
  (0, _react.useImperativeHandle)(ref, () => {
@@ -135,9 +117,24 @@ const HmsViewComponent = exports.HmsViewComponent = /*#__PURE__*/_react.default.
135
117
  capture
136
118
  };
137
119
  });
138
- return /*#__PURE__*/_react.default.createElement(HmsView, {
120
+
121
+ // Reject any in-flight capture promises on unmount. Under bridgeless
122
+ // mode the native side may not be able to deliver the captureFrame
123
+ // event back (event dispatcher returns null when the React tag is
124
+ // gone), which would leave promises hanging in the map forever.
125
+ (0, _react.useEffect)(() => {
126
+ return () => {
127
+ requestMap.forEach(({
128
+ reject
129
+ }) => {
130
+ reject(new Error('HmsView unmounted before capture completed'));
131
+ });
132
+ requestMap.clear();
133
+ };
134
+ }, [requestMap]);
135
+ return /*#__PURE__*/_react.default.createElement(_HMSViewNativeComponent.default, {
139
136
  ref: hmsViewRef,
140
- onChange: onChange,
137
+ onResolutionChange: onChange,
141
138
  data: data,
142
139
  style: _reactNative.Platform.OS === 'android' ? applyStyles_ANDROID ? style : {} : style,
143
140
  autoSimulcast: autoSimulcast,
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_HMSConstants","_HMSVideoViewMode","_hmsviews","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","HmsView","requireNativeComponent","_nextRequestId","_requestMap","Map","HmsViewComponent","exports","React","forwardRef","props","ref","trackId","style","styles","hmsView","id","HMSConstants","DEFAULT_SDK_ID","mirror","setZOrderMediaOverlay","autoSimulcast","scaleType","HMSVideoViewMode","ASPECT_FILL","hmsViewRef","useRef","applyStyles_ANDROID","setApplyStyles_ANDROID","useState","data","onChange","nativeEvent","event","setHmsViewsResolutionsState","_onDataReturned","requestId","result","error","promise","resolve","reject","delete","capture","viewManagerConfig","UIManager","getViewManagerConfig","requestMap","Promise","dispatchViewManagerCommand","findNodeHandle","current","Commands","useImperativeHandle","createElement","Platform","OS","onDataReturned","StyleSheet","create","flex"],"sources":["HmsView.tsx"],"sourcesContent":["import React, { useState, useImperativeHandle, useRef } from 'react';\nimport {\n findNodeHandle,\n requireNativeComponent,\n StyleSheet,\n UIManager,\n Platform,\n} from 'react-native';\nimport type { NativeSyntheticEvent, ViewStyle } from 'react-native';\nimport { HMSConstants } from './HMSConstants';\nimport { HMSVideoViewMode } from './HMSVideoViewMode';\nimport { setHmsViewsResolutionsState } from '../hooks/hmsviews';\n\n/**\n * Interface defining the properties for the `HmsView` component.\n *\n * This interface specifies the structure of the props that the `HmsView` component expects. It includes\n * properties for configuring the video track display, such as the track ID, mirroring options,\n * and scale type. It also includes properties for handling events and customizing the component's style.\n *\n * @interface HmsViewProps\n * @property {Object} data - An object containing the track ID, instance ID, mirroring option, and scale type for the video or audio track.\n * @property {string} data.trackId - The unique identifier for the track to be displayed.\n * @property {string} data.id - The identifier for the `HmsViewComponent` instance.\n * @property {boolean} data.mirror - Indicates whether the video should be mirrored. This is commonly used for local video tracks.\n * @property {HMSVideoViewMode} data.scaleType - Determines how the video fits within the bounds of the view (e.g., aspect fill, aspect fit).\n * @property {boolean} autoSimulcast - Enables automatic simulcast layer switching based on network conditions, if supported.\n * @property {boolean} setZOrderMediaOverlay - When true, the video view will be rendered above the regular view hierarchy.\n * @property {ViewStyle} style - Custom styles to apply to the view.\n * @property {Function} onChange - A callback function that is invoked when the `HmsView` component emits a change event.\n * @property {Function} onDataReturned - A callback function that is invoked when the `HmsView` component returns data in response to a capture frame event.\n *\n * @see {https://www.100ms.live/docs/react-native/v2/how-to-guides/set-up-video-conferencing/render-video/overview}\n */\ninterface HmsViewProps {\n data: {\n trackId: string;\n id: string;\n mirror: boolean;\n scaleType: HMSVideoViewMode;\n };\n autoSimulcast: boolean;\n setZOrderMediaOverlay: boolean;\n scaleType: HMSVideoViewMode;\n style: ViewStyle;\n onChange: Function;\n onDataReturned: Function;\n}\n\n// Imports the `HmsView` component from the native side using the `requireNativeComponent` function.\n// This component is used to render video tracks in the application.\nconst HmsView = requireNativeComponent<HmsViewProps>('HMSView');\nlet _nextRequestId = 1;\nlet _requestMap = new Map();\n\n/**\n * Defines the properties for the `HmsViewComponent`.\n *\n * This interface outlines the props that can be passed to the `HmsViewComponent` to configure its behavior and appearance.\n *\n * @interface HmsComponentProps\n * @property {string} trackId - The unique identifier for the track to be displayed.\n * @property {ViewStyle} [style] - Optional. Custom styles to apply to the view.\n * @property {boolean} [mirror] - Optional. If true, the video will be mirrored. This is commonly used for local video tracks.\n * @property {boolean} [autoSimulcast] - Optional. Enables automatic simulcast layer switching based on network conditions, if supported.\n * @property {HMSVideoViewMode} [scaleType] - Optional. Determines how the video fits within the bounds of the view (e.g., aspect fill, aspect fit).\n * @property {boolean} [setZOrderMediaOverlay] - Optional. When true, the video view will be rendered above the regular view hierarchy.\n * @property {string} id - The identifier for the `HmsViewComponent` instance.\n *\n * @see {https://www.100ms.live/docs/react-native/v2/how-to-guides/set-up-video-conferencing/render-video/overview}\n */\nexport interface HmsComponentProps {\n trackId: string;\n style?: ViewStyle;\n mirror?: boolean;\n autoSimulcast?: boolean;\n scaleType?: HMSVideoViewMode;\n setZOrderMediaOverlay?: boolean;\n id: string;\n}\n\nexport const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(\n (props, ref) => {\n const {\n trackId,\n style = styles.hmsView,\n id = HMSConstants.DEFAULT_SDK_ID,\n mirror = false,\n setZOrderMediaOverlay = false,\n autoSimulcast = true,\n scaleType = HMSVideoViewMode.ASPECT_FILL,\n } = props;\n\n const hmsViewRef: any = useRef();\n const [applyStyles_ANDROID, setApplyStyles_ANDROID] = useState(false);\n const data = {\n trackId,\n id,\n mirror,\n scaleType,\n };\n\n /**\n * This method is passed to `onChange` prop of `HmsView` Native Component.\n * It is invoked when `HmsView` emits 'topChange' event.\n */\n const onChange = ({\n nativeEvent,\n }: NativeSyntheticEvent<{\n data: { height: number; width: number };\n event: 'ON_RESOLUTION_CHANGE_EVENT';\n }>) => {\n const { event, data } = nativeEvent;\n\n setApplyStyles_ANDROID(true);\n\n if (event === 'ON_RESOLUTION_CHANGE_EVENT') {\n setHmsViewsResolutionsState(trackId, data);\n }\n };\n\n /**\n * This method is passed to `onDataReturned` prop of `HmsView` Native Component.\n * It is invoked when `HmsView` emits 'captureFrame' event.\n */\n const _onDataReturned = (event: {\n nativeEvent: { requestId: any; result: any; error: any };\n }) => {\n // We grab the relevant data out of our event.\n let { requestId, result, error } = event.nativeEvent;\n // Then we get the promise we saved earlier for the given request ID.\n let promise = _requestMap.get(requestId);\n if (result) {\n // If it was successful, we resolve the promise.\n promise.resolve(result);\n } else {\n // Otherwise, we reject it.\n promise.reject(error);\n }\n // Finally, we clean up our request map.\n _requestMap.delete(requestId);\n };\n\n const capture = async () => {\n const viewManagerConfig = UIManager.getViewManagerConfig('HMSView');\n\n let requestId = _nextRequestId++;\n let requestMap = _requestMap;\n\n // We create a promise here that will be resolved once `_onRequestDone` is\n // called.\n let promise = new Promise(function (resolve, reject) {\n requestMap.set(requestId, { resolve, reject });\n });\n\n UIManager.dispatchViewManagerCommand(\n findNodeHandle(hmsViewRef.current),\n viewManagerConfig.Commands.capture,\n [requestId]\n );\n return promise;\n };\n\n useImperativeHandle(ref, () => {\n return {\n capture,\n };\n });\n\n return (\n <HmsView\n ref={hmsViewRef}\n onChange={onChange}\n data={data}\n style={\n Platform.OS === 'android' ? (applyStyles_ANDROID ? style : {}) : style\n }\n autoSimulcast={autoSimulcast}\n scaleType={scaleType}\n setZOrderMediaOverlay={setZOrderMediaOverlay}\n onDataReturned={_onDataReturned}\n />\n );\n }\n);\n\nconst styles = StyleSheet.create({\n hmsView: {\n flex: 1,\n },\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_HMSViewNativeComponent","_HMSConstants","_HMSVideoViewMode","_hmsviews","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","HmsViewComponent","exports","React","forwardRef","props","ref","trackId","style","styles","hmsView","id","HMSConstants","DEFAULT_SDK_ID","mirror","setZOrderMediaOverlay","autoSimulcast","scaleType","HMSVideoViewMode","ASPECT_FILL","hmsViewRef","useRef","applyStyles_ANDROID","setApplyStyles_ANDROID","useState","data","useMemo","nextRequestId","requestMap","Map","onChange","nativeEvent","event","setHmsViewsResolutionsState","_onDataReturned","requestId","result","error","promise","resolve","reject","delete","capture","current","Promise","Commands","useImperativeHandle","useEffect","forEach","Error","clear","createElement","onResolutionChange","Platform","OS","onDataReturned","StyleSheet","create","flex"],"sources":["HmsView.tsx"],"sourcesContent":["import React, {\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { StyleSheet, Platform } from 'react-native';\nimport type { NativeSyntheticEvent, ViewStyle } from 'react-native';\nimport HmsView, { Commands } from '../specs/HMSViewNativeComponent';\nimport { HMSConstants } from './HMSConstants';\nimport { HMSVideoViewMode } from './HMSVideoViewMode';\nimport { setHmsViewsResolutionsState } from '../hooks/hmsviews';\n\ntype CapturePromiseMethods = {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n};\n\n/**\n * Defines the properties for the `HmsViewComponent`.\n *\n * This interface outlines the props that can be passed to the `HmsViewComponent` to configure its behavior and appearance.\n *\n * @interface HmsComponentProps\n * @property {string} trackId - The unique identifier for the track to be displayed.\n * @property {ViewStyle} [style] - Optional. Custom styles to apply to the view.\n * @property {boolean} [mirror] - Optional. If true, the video will be mirrored. This is commonly used for local video tracks.\n * @property {boolean} [autoSimulcast] - Optional. Enables automatic simulcast layer switching based on network conditions, if supported.\n * @property {HMSVideoViewMode} [scaleType] - Optional. Determines how the video fits within the bounds of the view (e.g., aspect fill, aspect fit).\n * @property {boolean} [setZOrderMediaOverlay] - Optional. When true, the video view will be rendered above the regular view hierarchy.\n * @property {string} id - The identifier for the `HmsViewComponent` instance.\n *\n * @see {https://www.100ms.live/docs/react-native/v2/how-to-guides/set-up-video-conferencing/render-video/overview}\n */\nexport interface HmsComponentProps {\n trackId: string;\n style?: ViewStyle;\n mirror?: boolean;\n autoSimulcast?: boolean;\n scaleType?: HMSVideoViewMode;\n setZOrderMediaOverlay?: boolean;\n id: string;\n}\n\nexport const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(\n (props, ref) => {\n const {\n trackId,\n style = styles.hmsView,\n id = HMSConstants.DEFAULT_SDK_ID,\n mirror = false,\n setZOrderMediaOverlay = false,\n autoSimulcast = true,\n scaleType = HMSVideoViewMode.ASPECT_FILL,\n } = props;\n\n const hmsViewRef: any = useRef();\n const [applyStyles_ANDROID, setApplyStyles_ANDROID] = useState(false);\n // Memoized so the object reference is stable across renders unless one\n // of the inputs actually changes. Fabric diffs view props by reference\n // before doing a deep compare — a fresh `{...}` on every render would\n // trigger redundant native prop updates.\n const data = useMemo(\n () => ({ trackId, id, mirror, scaleType }),\n [trackId, id, mirror, scaleType]\n );\n\n // Per-instance request/response state for the `capture` imperative.\n // Each `<HmsView />` gets its own counter + pending-promise map so:\n // - requestIds can't collide across multiple HmsView instances\n // - pending promises are scoped to this view and cleaned up when\n // it unmounts (see the useEffect below)\n const nextRequestId = useRef(1);\n const requestMap = useMemo(\n () => new Map<number, CapturePromiseMethods>(),\n []\n );\n\n /**\n * This method is passed to `onChange` prop of `HmsView` Native Component.\n * It is invoked when `HmsView` emits 'topChange' event.\n */\n const onChange = ({\n nativeEvent,\n }: NativeSyntheticEvent<{\n data: { height: number; width: number };\n event: 'ON_RESOLUTION_CHANGE_EVENT';\n }>) => {\n const { event, data } = nativeEvent;\n\n setApplyStyles_ANDROID(true);\n\n if (event === 'ON_RESOLUTION_CHANGE_EVENT') {\n setHmsViewsResolutionsState(trackId, data);\n }\n };\n\n /**\n * This method is passed to `onDataReturned` prop of `HmsView` Native Component.\n * It is invoked when `HmsView` emits 'captureFrame' event.\n */\n const _onDataReturned = (event: {\n nativeEvent: { requestId: any; result: any; error: any };\n }) => {\n const { requestId, result, error } = event.nativeEvent;\n const promise = requestMap.get(requestId);\n if (!promise) {\n // No pending request — typically a late event after unmount/cleanup\n // rejected it, or a stale requestId from a previous mount.\n return;\n }\n if (result) {\n promise.resolve(result);\n } else {\n promise.reject(error);\n }\n requestMap.delete(requestId);\n };\n\n const capture = async () => {\n const requestId = nextRequestId.current++;\n const promise = new Promise((resolve, reject) => {\n requestMap.set(requestId, { resolve, reject });\n });\n\n if (hmsViewRef.current) {\n Commands.capture(hmsViewRef.current, requestId);\n }\n return promise;\n };\n\n useImperativeHandle(ref, () => {\n return {\n capture,\n };\n });\n\n // Reject any in-flight capture promises on unmount. Under bridgeless\n // mode the native side may not be able to deliver the captureFrame\n // event back (event dispatcher returns null when the React tag is\n // gone), which would leave promises hanging in the map forever.\n useEffect(() => {\n return () => {\n requestMap.forEach(({ reject }) => {\n reject(new Error('HmsView unmounted before capture completed'));\n });\n requestMap.clear();\n };\n }, [requestMap]);\n\n return (\n <HmsView\n ref={hmsViewRef}\n onResolutionChange={onChange as any}\n data={data}\n style={\n Platform.OS === 'android' ? (applyStyles_ANDROID ? style : {}) : style\n }\n autoSimulcast={autoSimulcast}\n scaleType={scaleType}\n setZOrderMediaOverlay={setZOrderMediaOverlay}\n onDataReturned={_onDataReturned as any}\n />\n );\n }\n);\n\nconst styles = StyleSheet.create({\n hmsView: {\n flex: 1,\n },\n});\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAOA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,uBAAA,GAAAH,uBAAA,CAAAC,OAAA;AACA,IAAAG,aAAA,GAAAH,OAAA;AACA,IAAAI,iBAAA,GAAAJ,OAAA;AACA,IAAAK,SAAA,GAAAL,OAAA;AAAgE,SAAAD,wBAAAO,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAT,uBAAA,YAAAA,CAAAO,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAOhE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAWO,MAAMkB,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,gBAAGE,cAAK,CAACC,UAAU,CAC9C,CAACC,KAAK,EAAEC,GAAG,KAAK;EACd,MAAM;IACJC,OAAO;IACPC,KAAK,GAAGC,MAAM,CAACC,OAAO;IACtBC,EAAE,GAAGC,0BAAY,CAACC,cAAc;IAChCC,MAAM,GAAG,KAAK;IACdC,qBAAqB,GAAG,KAAK;IAC7BC,aAAa,GAAG,IAAI;IACpBC,SAAS,GAAGC,kCAAgB,CAACC;EAC/B,CAAC,GAAGd,KAAK;EAET,MAAMe,UAAe,GAAG,IAAAC,aAAM,EAAC,CAAC;EAChC,MAAM,CAACC,mBAAmB,EAAEC,sBAAsB,CAAC,GAAG,IAAAC,eAAQ,EAAC,KAAK,CAAC;EACrE;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAG,IAAAC,cAAO,EAClB,OAAO;IAAEnB,OAAO;IAAEI,EAAE;IAAEG,MAAM;IAAEG;EAAU,CAAC,CAAC,EAC1C,CAACV,OAAO,EAAEI,EAAE,EAAEG,MAAM,EAAEG,SAAS,CACjC,CAAC;;EAED;EACA;EACA;EACA;EACA;EACA,MAAMU,aAAa,GAAG,IAAAN,aAAM,EAAC,CAAC,CAAC;EAC/B,MAAMO,UAAU,GAAG,IAAAF,cAAO,EACxB,MAAM,IAAIG,GAAG,CAAgC,CAAC,EAC9C,EACF,CAAC;;EAED;AACJ;AACA;AACA;EACI,MAAMC,QAAQ,GAAGA,CAAC;IAChBC;EAID,CAAC,KAAK;IACL,MAAM;MAAEC,KAAK;MAAEP;IAAK,CAAC,GAAGM,WAAW;IAEnCR,sBAAsB,CAAC,IAAI,CAAC;IAE5B,IAAIS,KAAK,KAAK,4BAA4B,EAAE;MAC1C,IAAAC,qCAA2B,EAAC1B,OAAO,EAAEkB,IAAI,CAAC;IAC5C;EACF,CAAC;;EAED;AACJ;AACA;AACA;EACI,MAAMS,eAAe,GAAIF,KAExB,IAAK;IACJ,MAAM;MAAEG,SAAS;MAAEC,MAAM;MAAEC;IAAM,CAAC,GAAGL,KAAK,CAACD,WAAW;IACtD,MAAMO,OAAO,GAAGV,UAAU,CAAClC,GAAG,CAACyC,SAAS,CAAC;IACzC,IAAI,CAACG,OAAO,EAAE;MACZ;MACA;MACA;IACF;IACA,IAAIF,MAAM,EAAE;MACVE,OAAO,CAACC,OAAO,CAACH,MAAM,CAAC;IACzB,CAAC,MAAM;MACLE,OAAO,CAACE,MAAM,CAACH,KAAK,CAAC;IACvB;IACAT,UAAU,CAACa,MAAM,CAACN,SAAS,CAAC;EAC9B,CAAC;EAED,MAAMO,OAAO,GAAG,MAAAA,CAAA,KAAY;IAC1B,MAAMP,SAAS,GAAGR,aAAa,CAACgB,OAAO,EAAE;IACzC,MAAML,OAAO,GAAG,IAAIM,OAAO,CAAC,CAACL,OAAO,EAAEC,MAAM,KAAK;MAC/CZ,UAAU,CAACjC,GAAG,CAACwC,SAAS,EAAE;QAAEI,OAAO;QAAEC;MAAO,CAAC,CAAC;IAChD,CAAC,CAAC;IAEF,IAAIpB,UAAU,CAACuB,OAAO,EAAE;MACtBE,gCAAQ,CAACH,OAAO,CAACtB,UAAU,CAACuB,OAAO,EAAER,SAAS,CAAC;IACjD;IACA,OAAOG,OAAO;EAChB,CAAC;EAED,IAAAQ,0BAAmB,EAACxC,GAAG,EAAE,MAAM;IAC7B,OAAO;MACLoC;IACF,CAAC;EACH,CAAC,CAAC;;EAEF;EACA;EACA;EACA;EACA,IAAAK,gBAAS,EAAC,MAAM;IACd,OAAO,MAAM;MACXnB,UAAU,CAACoB,OAAO,CAAC,CAAC;QAAER;MAAO,CAAC,KAAK;QACjCA,MAAM,CAAC,IAAIS,KAAK,CAAC,4CAA4C,CAAC,CAAC;MACjE,CAAC,CAAC;MACFrB,UAAU,CAACsB,KAAK,CAAC,CAAC;IACpB,CAAC;EACH,CAAC,EAAE,CAACtB,UAAU,CAAC,CAAC;EAEhB,oBACEtD,MAAA,CAAAkB,OAAA,CAAA2D,aAAA,CAACzE,uBAAA,CAAAc,OAAO;IACNc,GAAG,EAAEc,UAAW;IAChBgC,kBAAkB,EAAEtB,QAAgB;IACpCL,IAAI,EAAEA,IAAK;IACXjB,KAAK,EACH6C,qBAAQ,CAACC,EAAE,KAAK,SAAS,GAAIhC,mBAAmB,GAAGd,KAAK,GAAG,CAAC,CAAC,GAAIA,KAClE;IACDQ,aAAa,EAAEA,aAAc;IAC7BC,SAAS,EAAEA,SAAU;IACrBF,qBAAqB,EAAEA,qBAAsB;IAC7CwC,cAAc,EAAErB;EAAuB,CACxC,CAAC;AAEN,CACF,CAAC;AAED,MAAMzB,MAAM,GAAG+C,uBAAU,CAACC,MAAM,CAAC;EAC/B/C,OAAO,EAAE;IACPgD,IAAI,EAAE;EACR;AACF,CAAC,CAAC","ignoreList":[]}