appium-mac2-driver 4.3.6 → 4.4.0

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 (56) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/WebDriverAgentMac/IntegrationTests/AMSessionTests.m +14 -0
  3. package/WebDriverAgentMac/WebDriverAgentLib/Commands/FBSessionCommands.m +17 -5
  4. package/WebDriverAgentMac/WebDriverAgentLib/Routing/FBSession.m +5 -1
  5. package/build/lib/driver.d.ts +3 -0
  6. package/build/lib/driver.d.ts.map +1 -1
  7. package/build/lib/driver.js +52 -32
  8. package/build/lib/driver.js.map +1 -1
  9. package/build/lib/session-claim-handler.d.ts +41 -0
  10. package/build/lib/session-claim-handler.d.ts.map +1 -0
  11. package/build/lib/session-claim-handler.js +236 -0
  12. package/build/lib/session-claim-handler.js.map +1 -0
  13. package/build/lib/wda-mac.d.ts +6 -2
  14. package/build/lib/wda-mac.d.ts.map +1 -1
  15. package/build/lib/wda-mac.js +39 -9
  16. package/build/lib/wda-mac.js.map +1 -1
  17. package/lib/driver.ts +55 -31
  18. package/lib/session-claim-handler.ts +306 -0
  19. package/lib/wda-mac.ts +41 -10
  20. package/node_modules/appium-xcode/CHANGELOG.md +7 -0
  21. package/node_modules/appium-xcode/package.json +4 -4
  22. package/node_modules/async-lock/AUTHORS +21 -0
  23. package/node_modules/async-lock/History.md +132 -0
  24. package/node_modules/async-lock/LICENSE +22 -0
  25. package/node_modules/async-lock/README.md +177 -0
  26. package/node_modules/async-lock/index.js +2 -0
  27. package/node_modules/async-lock/lib/index.js +312 -0
  28. package/node_modules/async-lock/package.json +48 -0
  29. package/node_modules/bare-fs/binding.c +1 -1
  30. package/node_modules/bare-fs/index.js +30 -6
  31. package/node_modules/bare-fs/package.json +1 -1
  32. package/node_modules/bare-fs/prebuilds/android-arm/bare-fs.bare +0 -0
  33. package/node_modules/bare-fs/prebuilds/android-arm64/bare-fs.bare +0 -0
  34. package/node_modules/bare-fs/prebuilds/android-ia32/bare-fs.bare +0 -0
  35. package/node_modules/bare-fs/prebuilds/android-x64/bare-fs.bare +0 -0
  36. package/node_modules/bare-fs/prebuilds/darwin-arm64/bare-fs.bare +0 -0
  37. package/node_modules/bare-fs/prebuilds/darwin-x64/bare-fs.bare +0 -0
  38. package/node_modules/bare-fs/prebuilds/ios-arm64/bare-fs.bare +0 -0
  39. package/node_modules/bare-fs/prebuilds/ios-arm64-simulator/bare-fs.bare +0 -0
  40. package/node_modules/bare-fs/prebuilds/ios-x64-simulator/bare-fs.bare +0 -0
  41. package/node_modules/bare-fs/prebuilds/linux-arm64/bare-fs.bare +0 -0
  42. package/node_modules/bare-fs/prebuilds/linux-x64/bare-fs.bare +0 -0
  43. package/node_modules/bare-fs/prebuilds/win32-arm64/bare-fs.bare +0 -0
  44. package/node_modules/bare-fs/prebuilds/win32-x64/bare-fs.bare +0 -0
  45. package/node_modules/readable-stream/lib/internal/shims/process.js +19 -0
  46. package/node_modules/readable-stream/lib/internal/streams/destroy.js +1 -1
  47. package/node_modules/readable-stream/lib/internal/streams/duplexify.js +1 -1
  48. package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +1 -1
  49. package/node_modules/readable-stream/lib/internal/streams/from.js +1 -1
  50. package/node_modules/readable-stream/lib/internal/streams/legacy.js +6 -1
  51. package/node_modules/readable-stream/lib/internal/streams/pipeline.js +1 -1
  52. package/node_modules/readable-stream/lib/internal/streams/readable.js +1 -1
  53. package/node_modules/readable-stream/lib/internal/streams/writable.js +1 -1
  54. package/node_modules/readable-stream/package.json +3 -2
  55. package/node_modules/tar-stream/package.json +7 -7
  56. package/package.json +4 -2
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [4.4.0](https://github.com/appium/appium-mac2-driver/compare/v4.3.6...v4.4.0) (2026-10-11)
2
+
3
+ ### Features
4
+
5
+ * enforce a single session, a new session replaces the previous one ([#426](https://github.com/appium/appium-mac2-driver/issues/426)) ([fb10372](https://github.com/appium/appium-mac2-driver/commit/fb10372c16d861fb7ff9463b345ba6fcb3f67387))
6
+
1
7
  ## [4.3.6](https://github.com/appium/appium-mac2-driver/compare/v4.3.5...v4.3.6) (2026-10-02)
2
8
 
3
9
  ### Bug Fixes
@@ -43,6 +43,20 @@ static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.systempreferences";
43
43
  [super tearDown];
44
44
  }
45
45
 
46
+ - (void)testNewSessionOverridesThePreviousOne
47
+ {
48
+ NSString *oldId = self.session.identifier;
49
+ FBSession *newSession = [FBSession initWithApplication:nil];
50
+ XCTAssertNotEqualObjects(oldId, newSession.identifier);
51
+ XCTAssertEqual(FBSession.activeSession, newSession);
52
+ XCTAssertNil([FBSession sessionWithIdentifier:oldId]);
53
+ // Killing the stale session must not drop the active one
54
+ [self.session kill];
55
+ XCTAssertEqual(FBSession.activeSession, newSession);
56
+ [newSession kill];
57
+ XCTAssertNil(FBSession.activeSession);
58
+ }
59
+
46
60
  - (void)testSettingsAppCanBeOpenedInScopeOfTheCurrentSession
47
61
  {
48
62
  [self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
@@ -99,9 +99,15 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
99
99
  NSString *appPath = requirements[AM_APP_PATH_CAPABILITY];
100
100
  NSString *deepLink = requirements[AM_INITIAL_DEEPLINK_URL_CAPABILITY];
101
101
  BOOL noReset = [requirements[AM_NO_RESET_CAPABILITY] boolValue];
102
- FBSession *session;
102
+
103
+ // XCTest is single-threaded, so there can only be one session. A new one always
104
+ // takes over, and the previous one must be gone before any app gets touched.
105
+ [FBSession.activeSession kill];
106
+
107
+ XCUIApplication *app = nil;
108
+ BOOL didLaunchApp = NO;
103
109
  if (nil == bundleID && nil == appPath && nil == deepLink) {
104
- session = [FBSession initWithApplication:nil];
110
+ // no app to manage
105
111
  } else if (nil != deepLink) {
106
112
  NSURL *url = [NSURL URLWithString:deepLink];
107
113
  NSError *error;
@@ -113,13 +119,12 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
113
119
  traceback:nil]);
114
120
  }
115
121
  if (nil != bundleID) {
116
- session = [FBSession initWithApplication:[[XCUIApplication alloc] initWithBundleIdentifier:bundleID]];
122
+ app = [[XCUIApplication alloc] initWithBundleIdentifier:bundleID];
117
123
  }
118
124
  } else {
119
- XCUIApplication *app = nil != appPath
125
+ app = nil != appPath
120
126
  ? [[XCUIApplication alloc] initWithURL:[NSURL fileURLWithPath:appPath]]
121
127
  : [[XCUIApplication alloc] initWithBundleIdentifier:bundleID];
122
- session = [FBSession initWithApplication:app];
123
128
  if (noReset && app.state > XCUIApplicationStateNotRunning) {
124
129
  [app activate];
125
130
  } else {
@@ -140,6 +145,7 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
140
145
  }
141
146
  app.launchEnvironment = [launchEnv copy];
142
147
  [app launch];
148
+ didLaunchApp = YES;
143
149
  if (app.state <= XCUIApplicationStateNotRunning) {
144
150
  NSString *message = [NSString stringWithFormat:@"Failed to launch '%@' application", appPath ?: bundleID];
145
151
  return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:message
@@ -149,6 +155,10 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
149
155
  if (nil != bundleID && nil != appPath) {
150
156
  NSString *realBundleID = app.am_bundleID;
151
157
  if (![realBundleID isEqualToString:bundleID]) {
158
+ // no session owns the app, so don't leave it behind
159
+ if (didLaunchApp) {
160
+ [app terminate];
161
+ }
152
162
  NSString *message = [NSString stringWithFormat:@"The bundle identifier %@ of the '%@' does not match to the one provided in capabilities: %@",
153
163
  realBundleID, appPath, bundleID];
154
164
  return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:message
@@ -156,6 +166,8 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
156
166
  }
157
167
  }
158
168
  }
169
+ // The session is only registered once startup has fully succeeded
170
+ FBSession *session = [FBSession initWithApplication:app];
159
171
  if (nil != requirements[AM_SKIP_APP_KILL_CAPABILITY]) {
160
172
  session.skipAppTermination = [requirements[AM_SKIP_APP_KILL_CAPABILITY] boolValue];
161
173
  } else if (nil == bundleID) {
@@ -72,6 +72,11 @@ static FBSession *_activeSession = nil;
72
72
  [self.testedApplication terminate];
73
73
  }
74
74
  self.testedApplication = nil;
75
+ [self.elementCache reset];
76
+ // The recording belongs to the active session, so a stale one must not touch it
77
+ if (_activeSession != self) {
78
+ return;
79
+ }
75
80
  FBScreenRecordingContainer *screenRecordingContainer = FBScreenRecordingContainer.sharedInstance;
76
81
  NSUUID *videoRecordingId = screenRecordingContainer.screenRecordingPromise.identifier;
77
82
  if (nil != videoRecordingId) {
@@ -83,7 +88,6 @@ static FBSession *_activeSession = nil;
83
88
  if (nil != screenRecordingContainer.screenRecordingPromise) {
84
89
  [screenRecordingContainer reset];
85
90
  }
86
- [self.elementCache reset];
87
91
  _activeSession = nil;
88
92
  }
89
93
 
@@ -268,6 +268,8 @@ export declare class Mac2Driver extends BaseDriver<Mac2Constraints, StringRecord
268
268
  proxyReqRes: (...args: any) => any;
269
269
  private isProxyActive;
270
270
  private _wda;
271
+ private _wdaSessionId;
272
+ private _hasClaimedHost;
271
273
  constructor(opts?: InitialOpts);
272
274
  get wda(): WDAMacServer;
273
275
  onSettingsUpdate(key: string, value: unknown): Promise<void>;
@@ -279,6 +281,7 @@ export declare class Mac2Driver extends BaseDriver<Mac2Constraints, StringRecord
279
281
  getWindowRect(): Promise<any>;
280
282
  createSession(w3cCaps1: W3CMac2DriverCaps, w3cCaps2?: W3CMac2DriverCaps, w3cCaps3?: W3CMac2DriverCaps, driverData?: DriverData[]): Promise<DefaultCreateSessionResult<Mac2Constraints>>;
281
283
  deleteSession(): Promise<void>;
284
+ private teardownSession;
282
285
  private resetState;
283
286
  }
284
287
  export default Mac2Driver;
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../lib/driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../lib/driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,0BAA0B,EAC1B,UAAU,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EAGd,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AAEpE,OAAO,KAAK,sBAAsB,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,6BAA6B,MAAM,oCAAoC,CAAC;AACpF,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAyB,EAAC,KAAK,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAKxE,OAAO,EAAiB,KAAK,YAAY,EAAC,MAAM,cAAc,CAAC;AA0B/D,KAAK,iBAAiB,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;AACxD,qBAAa,UACX,SAAQ,UAAU,CAAC,eAAe,EAAE,YAAY,CAChD,YAAW,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,YAAY,CAAC;IAEhE,MAAM,CAAC,YAAY;;;;;;;;;;;;;;;;;MAAgB;IACnC,MAAM,CAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAAoB;IAE3C,cAAc,+CAAyC;IACvD,gBAAgB,iDAA2C;IAC3D,iBAAiB,kDAA4C;IAC7D,kBAAkB,mDAA6C;IAE/D,oBAAoB,kDAA4C;IAEhE,OAAO,iCAA2B;IAElC,WAAW,kCAA4B;IAEvC,aAAa,wCAAkC;IAC/C,UAAU,qCAA+B;IACzC,WAAW,sCAAgC;IAC3C,UAAU,qCAA+B;IACzC,eAAe,0CAAoC;IACnD,UAAU,qCAA+B;IACzC,gBAAgB,2CAAqC;IACrD,iBAAiB,4CAAsC;IACvD,wBAAwB,mDAA6C;IACrE,SAAS,oCAA8B;IACvC,iBAAiB,4CAAsC;IACvD,QAAQ,mCAA6B;IACrC,cAAc,yCAAmC;IACjD,iBAAiB,4CAAsC;IACvD,wBAAwB,mDAA6C;IAErE,iBAAiB,6CAAuC;IACxD,iBAAiB,6CAAuC;IACxD,8BAA8B,sDAAgD;IAE9E,aAAa,0CAAoC;IAEjD,oBAAoB,mDAA6C;IACjE,mBAAmB,kDAA4C;IAC/D,yBAAyB,wDAAkD;IAC3E,wBAAwB,uDAAiD;IAEzE,+BAA+B,uEAAiE;IAChG,iCAAiC,yEAAmE;IACpG,8BAA8B,sEAAgE;IAC9F,iBAAiB,yDAAmD;IAEpE,gBAAgB,6CAAuC;IAEvD,WAAW,oCAA8B;IAEzC,uBAAuB,EAAG,6BAA6B,CAAC,4BAA4B,CAAC;IACrF,eAAe,EAAE,oBAAoB,CAAC,cAAc,GAAG,IAAI,CAAQ;IAC5D,WAAW,EAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAE3C,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,eAAe,CAAkB;gBAE7B,IAAI,GAAE,WAA+B;IAsBjD,IAAI,GAAG,IAAI,YAAY,CAYtB;IAEK,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAKvC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE;IAIpD,QAAQ,IAAI,OAAO;IAItB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,QAAe,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC;IAQlC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC;IAIpB,aAAa,CAC1B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,UAAU,CAAC,EAAE,UAAU,EAAE,GACxB,OAAO,CAAC,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAyCxC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;YAM/B,eAAe;IAqC7B,OAAO,CAAC,UAAU;CAWnB;AAED,eAAe,UAAU,CAAC"}
@@ -1,4 +1,4 @@
1
- import { BaseDriver, DeviceSettings } from 'appium/driver.js';
1
+ import { BaseDriver, DeviceSettings, errors } from 'appium/driver.js';
2
2
  import * as appManagemenetCommands from './commands/app-management.js';
3
3
  import * as appleScriptCommands from './commands/applescript.js';
4
4
  import * as auditCommands from './commands/audit.js';
@@ -15,6 +15,7 @@ import MAC2_CONSTRAINTS from './constraints.js';
15
15
  import { executeMethodMap } from './execute-method-map.js';
16
16
  import log from './logger.js';
17
17
  import { newMethodMap } from './method-map.js';
18
+ import { sessionClaimHandler } from './session-claim-handler.js';
18
19
  import { WDA_MAC_SERVER } from './wda-mac.js';
19
20
  const NO_PROXY = [
20
21
  ['GET', new RegExp('^/session/[^/]+/appium')],
@@ -70,6 +71,8 @@ export class Mac2Driver extends BaseDriver {
70
71
  proxyReqRes;
71
72
  isProxyActive = false;
72
73
  _wda = null;
74
+ _wdaSessionId = null;
75
+ _hasClaimedHost = false;
73
76
  constructor(opts = {}) {
74
77
  super(opts);
75
78
  this.desiredCapConstraints = structuredClone(MAC2_CONSTRAINTS);
@@ -91,13 +94,18 @@ export class Mac2Driver extends BaseDriver {
91
94
  if (!this._wda) {
92
95
  throw new Error('WDA server is not initialized');
93
96
  }
97
+ // The WDA server is shared and only supports a single session, so a newer
98
+ // session replaces this one. Never send commands on its behalf after that.
99
+ if (this._wdaSessionId && !this._wda.isSessionActive(this._wdaSessionId)) {
100
+ throw new errors.NoSuchDriverError('This session has been replaced by a newer one, because this driver only supports a single session');
101
+ }
94
102
  return this._wda;
95
103
  }
96
104
  async onSettingsUpdate(key, value) {
97
105
  if (!this._wda) {
98
106
  return;
99
107
  }
100
- return await this._wda.proxy.command('/appium/settings', 'POST', {
108
+ return await this.wda.proxy.command('/appium/settings', 'POST', {
101
109
  settings: { [key]: value },
102
110
  });
103
111
  }
@@ -113,10 +121,7 @@ export class Mac2Driver extends BaseDriver {
113
121
  return true;
114
122
  }
115
123
  async proxyCommand(url, method, body = null) {
116
- if (!this._wda) {
117
- throw new Error('WDA server is not initialized');
118
- }
119
- return await this._wda.proxy.command(url, method, body);
124
+ return await this.wda.proxy.command(url, method, body);
120
125
  }
121
126
  async getStatus() {
122
127
  if (!this._wda) {
@@ -126,10 +131,7 @@ export class Mac2Driver extends BaseDriver {
126
131
  }
127
132
  // needed to make image plugin work
128
133
  async getWindowRect() {
129
- if (!this._wda) {
130
- throw new Error('WDA server is not initialized');
131
- }
132
- return await this._wda.proxy.command('/window/rect', 'GET');
134
+ return await this.wda.proxy.command('/window/rect', 'GET');
133
135
  }
134
136
  async createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData) {
135
137
  const [sessionId, caps] = await super.createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData);
@@ -137,34 +139,49 @@ export class Mac2Driver extends BaseDriver {
137
139
  this.caps = caps;
138
140
  // oxlint-disable-next-line no-self-assign -- narrows this.opts' type for the rest of the method
139
141
  this.opts = this.opts;
140
- try {
141
- const prerun = caps.prerun;
142
- if (prerun) {
143
- if (typeof prerun.command !== 'string' && typeof prerun.script !== 'string') {
144
- throw new Error(`'prerun' capability value must either contain 'script' or 'command' entry of string type`);
145
- }
146
- log.info('Executing prerun AppleScript');
147
- const output = await this.macosExecAppleScript(prerun.script, undefined, prerun.command);
148
- if (output.trim()) {
149
- log.info(`Prerun script output: ${output}`);
142
+ // The host supports a single session: the previous one has to quit first
143
+ await sessionClaimHandler.runExclusive(async () => {
144
+ // The session might have been deleted while it was waiting for its turn
145
+ if (!this._wda || !this.sessionId) {
146
+ throw new errors.NoSuchDriverError('The session has been deleted before it could start');
147
+ }
148
+ try {
149
+ await sessionClaimHandler.registerActiveSession(this);
150
+ await sessionClaimHandler.claimHost(this);
151
+ this._hasClaimedHost = true;
152
+ const prerun = caps.prerun;
153
+ if (prerun) {
154
+ if (typeof prerun.command !== 'string' && typeof prerun.script !== 'string') {
155
+ throw new Error(`'prerun' capability value must either contain 'script' or 'command' entry of string type`);
156
+ }
157
+ log.info('Executing prerun AppleScript');
158
+ const output = await this.macosExecAppleScript(prerun.script, undefined, prerun.command);
159
+ if (output.trim()) {
160
+ log.info(`Prerun script output: ${output}`);
161
+ }
150
162
  }
163
+ this._wdaSessionId = await this.wda.startSession(caps, {
164
+ reqBasePath: this.basePath,
165
+ });
151
166
  }
152
- await this._wda.startSession(caps, {
153
- reqBasePath: this.basePath,
154
- });
155
- }
156
- catch (e) {
157
- await this.deleteSession();
158
- throw e;
159
- }
160
- this.proxyReqRes = this.wda.proxy.proxyReqRes.bind(this._wda.proxy);
167
+ catch (e) {
168
+ await this.deleteSession();
169
+ throw e;
170
+ }
171
+ });
172
+ this.proxyReqRes = (...args) => this.wda.proxy.proxyReqRes.apply(this.wda.proxy, args);
161
173
  this.isProxyActive = true;
162
174
  return [sessionId, caps];
163
175
  }
164
176
  async deleteSession() {
177
+ sessionClaimHandler.unregisterActiveSession(this);
178
+ // A new session waits for the teardown to complete before it starts
179
+ await sessionClaimHandler.trackTeardown(async () => await this.teardownSession());
180
+ }
181
+ async teardownSession() {
165
182
  await this._screenRecorder?.stop(true);
166
183
  if (this._videoChunksBroadcaster.hasPublishers) {
167
- if (this._wda) {
184
+ if (this._wda?.isSessionActive(this._wdaSessionId)) {
168
185
  try {
169
186
  await this.wda.proxy.command('/wda/video/stop', 'POST', {});
170
187
  }
@@ -173,9 +190,10 @@ export class Mac2Driver extends BaseDriver {
173
190
  await this._videoChunksBroadcaster.shutdown(5000);
174
191
  }
175
192
  if (this._wda) {
176
- await this.wda.stopSession();
193
+ await this._wda.stopSession(this._wdaSessionId);
177
194
  }
178
- const postrun = this.opts.postrun;
195
+ // Skip postrun if the host was never acquired, as the previous session might still be using it
196
+ const postrun = this._hasClaimedHost ? this.opts.postrun : undefined;
179
197
  if (postrun) {
180
198
  if (typeof postrun.command !== 'string' && typeof postrun.script !== 'string') {
181
199
  log.error(`'postrun' capability value must either contain 'script' or 'command' entry of string type`);
@@ -198,6 +216,8 @@ export class Mac2Driver extends BaseDriver {
198
216
  }
199
217
  resetState() {
200
218
  this._wda = null;
219
+ this._wdaSessionId = null;
220
+ this._hasClaimedHost = false;
201
221
  this.isProxyActive = false;
202
222
  this._videoChunksBroadcaster = new nativeScreenRecordingCommands.NativeVideoChunksBroadcaster(this.eventEmitter, this.log);
203
223
  this._screenRecorder = null;
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../lib/driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../lib/driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { IAppiumIpc } from '@appium/types';
2
+ import type { Mac2Driver } from './driver.js';
3
+ export type SessionIpcMessage = {
4
+ sessionId: string;
5
+ };
6
+ type IpcProvider = () => Promise<IAppiumIpc | undefined>;
7
+ /** Lets a new session make the previous one quit, over a driver-wide IPC (per-session IPCs are isolated). */
8
+ export declare class SessionClaimHandler {
9
+ private readonly getIpc;
10
+ private readonly releaseWaitMs;
11
+ static readonly CLAIMED_TOPIC = "mac2:sessionClaimed";
12
+ static readonly CONTENDED_TOPIC = "mac2:sessionContended";
13
+ static readonly RELEASED_TOPIC = "mac2:sessionReleased";
14
+ private static readonly STARTUP_LOCK_KEY;
15
+ private static readonly CONTENTION_PROBE_MS;
16
+ private static readonly DEFAULT_RELEASE_WAIT_MS;
17
+ private readonly startupLock;
18
+ private readonly pendingTeardowns;
19
+ private readonly subscriptionsBySessionId;
20
+ constructor(getIpc: IpcProvider, releaseWaitMs?: number);
21
+ /** Serializes session startups so the newest wins. Enter before registering the session. */
22
+ runExclusive<T>(fn: () => Promise<T>): Promise<T>;
23
+ /** Subscribe the session to claim messages from newer sessions. */
24
+ registerActiveSession(driver: Mac2Driver): Promise<void>;
25
+ /** Unsubscribe the session from claim messages. */
26
+ unregisterActiveSession(driver: Mac2Driver): void;
27
+ /** Tracks a session teardown, so that a new session does not start before it is complete. */
28
+ trackTeardown(teardown: () => Promise<void>): Promise<void>;
29
+ /** Make any other active session quit and wait until it has released the host. */
30
+ claimHost(driver: Mac2Driver): Promise<void>;
31
+ private waitForPendingTeardowns;
32
+ private requestRelease;
33
+ private dispatchClaimMessage;
34
+ private handleClaimMessage;
35
+ private terminateSession;
36
+ private publish;
37
+ private getPublisherId;
38
+ }
39
+ export declare const sessionClaimHandler: SessionClaimHandler;
40
+ export {};
41
+ //# sourceMappingURL=session-claim-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-claim-handler.d.ts","sourceRoot":"","sources":["../../lib/session-claim-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAe,UAAU,EAA+B,MAAM,eAAe,CAAC;AAM1F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;AAEzD,6GAA6G;AAC7G,qBAAa,mBAAmB;IAe5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAfhC,MAAM,CAAC,QAAQ,CAAC,aAAa,yBAAyB;IACtD,MAAM,CAAC,QAAQ,CAAC,eAAe,2BAA2B;IAC1D,MAAM,CAAC,QAAQ,CAAC,cAAc,0BAA0B;IAExD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAyB;IAEjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IAExD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAC7D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA0D;gBAGhF,MAAM,EAAE,WAAW,EACnB,aAAa,GAAE,MAAoD;IAGtF,4FAA4F;IACtF,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvD,mEAAmE;IAC7D,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9D,mDAAmD;IACnD,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAUjD,6FAA6F;IACvF,aAAa,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBjE,kFAAkF;IAC5E,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAKpC,uBAAuB;YA2BvB,cAAc;YA8Ed,oBAAoB;YAapB,kBAAkB;YAqBlB,gBAAgB;YAmBhB,OAAO;IAgBrB,OAAO,CAAC,cAAc;CAGvB;AAgBD,eAAO,MAAM,mBAAmB,qBAAyC,CAAC"}
@@ -0,0 +1,236 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ import { errors } from 'appium/driver.js';
3
+ import { node, util } from 'appium/support.js';
4
+ import AsyncLock from 'async-lock';
5
+ import { waitForCondition } from 'asyncbox';
6
+ /** Lets a new session make the previous one quit, over a driver-wide IPC (per-session IPCs are isolated). */
7
+ export class SessionClaimHandler {
8
+ getIpc;
9
+ releaseWaitMs;
10
+ static CLAIMED_TOPIC = 'mac2:sessionClaimed';
11
+ static CONTENDED_TOPIC = 'mac2:sessionContended';
12
+ static RELEASED_TOPIC = 'mac2:sessionReleased';
13
+ static STARTUP_LOCK_KEY = 'mac2:sessionStartup';
14
+ static CONTENTION_PROBE_MS = 10;
15
+ static DEFAULT_RELEASE_WAIT_MS = 15000;
16
+ startupLock = new AsyncLock();
17
+ pendingTeardowns = new Set();
18
+ subscriptionsBySessionId = new Map();
19
+ constructor(getIpc, releaseWaitMs = SessionClaimHandler.DEFAULT_RELEASE_WAIT_MS) {
20
+ this.getIpc = getIpc;
21
+ this.releaseWaitMs = releaseWaitMs;
22
+ }
23
+ /** Serializes session startups so the newest wins. Enter before registering the session. */
24
+ async runExclusive(fn) {
25
+ return await this.startupLock.acquire(SessionClaimHandler.STARTUP_LOCK_KEY, fn);
26
+ }
27
+ /** Subscribe the session to claim messages from newer sessions. */
28
+ async registerActiveSession(driver) {
29
+ const ipc = await this.getIpc();
30
+ const sessionId = driver.sessionId;
31
+ if (!ipc || !sessionId) {
32
+ return;
33
+ }
34
+ this.unregisterActiveSession(driver);
35
+ const subscription = ipc.subscribe(SessionClaimHandler.CLAIMED_TOPIC, this.getPublisherId(driver));
36
+ subscription.on('message', (message) => {
37
+ void this.dispatchClaimMessage(driver, sessionId, message);
38
+ });
39
+ this.subscriptionsBySessionId.set(sessionId, subscription);
40
+ }
41
+ /** Unsubscribe the session from claim messages. */
42
+ unregisterActiveSession(driver) {
43
+ const sessionId = driver.sessionId;
44
+ if (!sessionId) {
45
+ return;
46
+ }
47
+ this.subscriptionsBySessionId.get(sessionId)?.unsubscribe();
48
+ this.subscriptionsBySessionId.delete(sessionId);
49
+ }
50
+ /** Tracks a session teardown, so that a new session does not start before it is complete. */
51
+ async trackTeardown(teardown) {
52
+ const promise = teardown();
53
+ const tracked = (async () => {
54
+ try {
55
+ await promise;
56
+ }
57
+ catch {
58
+ // the failure is reported to the caller of trackTeardown()
59
+ }
60
+ })();
61
+ this.pendingTeardowns.add(tracked);
62
+ try {
63
+ await promise;
64
+ }
65
+ finally {
66
+ this.pendingTeardowns.delete(tracked);
67
+ }
68
+ }
69
+ /** Make any other active session quit and wait until it has released the host. */
70
+ async claimHost(driver) {
71
+ await this.requestRelease(driver);
72
+ await this.waitForPendingTeardowns(driver);
73
+ }
74
+ async waitForPendingTeardowns(driver) {
75
+ if (this.pendingTeardowns.size === 0) {
76
+ return;
77
+ }
78
+ driver.log.debug(`Waiting for ${util.pluralize('session', this.pendingTeardowns.size, true)} to finish quitting`);
79
+ const timer = new AbortController();
80
+ const timedOut = Symbol('timedOut');
81
+ const timeout = (async () => {
82
+ try {
83
+ return await delay(this.releaseWaitMs, timedOut, { signal: timer.signal });
84
+ }
85
+ catch {
86
+ return undefined; // aborted
87
+ }
88
+ })();
89
+ try {
90
+ if ((await Promise.race([Promise.all(this.pendingTeardowns), timeout])) === timedOut) {
91
+ // Starting now could let the old teardown (e.g. postrun) interfere with this session
92
+ throw new errors.SessionNotCreatedError(`The previous session did not finish quitting within ${this.releaseWaitMs}ms`);
93
+ }
94
+ }
95
+ finally {
96
+ timer.abort();
97
+ }
98
+ }
99
+ async requestRelease(driver) {
100
+ const ipc = await this.getIpc();
101
+ if (!ipc) {
102
+ driver.log.debug('Driver-instance IPC is unavailable. Skipping the session claim.');
103
+ return;
104
+ }
105
+ const sessionId = driver.sessionId;
106
+ if (!sessionId) {
107
+ return;
108
+ }
109
+ const contendingSessionIds = new Set();
110
+ const releasedSessionIds = new Set();
111
+ const subscriptions = [];
112
+ try {
113
+ const contendedSubscription = ipc.subscribe(SessionClaimHandler.CONTENDED_TOPIC, this.getPublisherId(driver));
114
+ subscriptions.push(contendedSubscription);
115
+ const releasedSubscription = ipc.subscribe(SessionClaimHandler.RELEASED_TOPIC, this.getPublisherId(driver));
116
+ subscriptions.push(releasedSubscription);
117
+ contendedSubscription.on('message', (message) => {
118
+ if (message.data.sessionId !== sessionId) {
119
+ contendingSessionIds.add(message.data.sessionId);
120
+ }
121
+ });
122
+ releasedSubscription.on('message', (message) => {
123
+ if (message.data.sessionId !== sessionId) {
124
+ releasedSessionIds.add(message.data.sessionId);
125
+ }
126
+ });
127
+ await ipc.publish(SessionClaimHandler.CLAIMED_TOPIC, this.getPublisherId(driver), {
128
+ sessionId,
129
+ });
130
+ // Older sessions reply synchronously to the claim, so a short wait is enough to learn about them
131
+ await delay(SessionClaimHandler.CONTENTION_PROBE_MS);
132
+ if (contendingSessionIds.size === 0) {
133
+ return;
134
+ }
135
+ try {
136
+ await waitForCondition(() => [...contendingSessionIds].every((id) => releasedSessionIds.has(id)), {
137
+ waitMs: this.releaseWaitMs,
138
+ intervalMs: 50,
139
+ });
140
+ driver.log.debug(`Received release confirmation from ${util.pluralize('session', contendingSessionIds.size, true)}`);
141
+ }
142
+ catch {
143
+ const pendingSessionIds = [...contendingSessionIds].filter((id) => !releasedSessionIds.has(id));
144
+ // Starting now could let the old session interfere with this one
145
+ throw new errors.SessionNotCreatedError(`${util.pluralize('session', pendingSessionIds.length, true)} [${pendingSessionIds.join(', ')}] ` +
146
+ `did not quit within ${this.releaseWaitMs}ms`);
147
+ }
148
+ }
149
+ finally {
150
+ subscriptions.forEach((sub) => sub.unsubscribe());
151
+ }
152
+ }
153
+ /** @internal Exposed for unit tests. */
154
+ resetForTesting() {
155
+ this.pendingTeardowns.clear();
156
+ for (const subscription of this.subscriptionsBySessionId.values()) {
157
+ subscription.unsubscribe();
158
+ }
159
+ this.subscriptionsBySessionId.clear();
160
+ }
161
+ async dispatchClaimMessage(driver, sessionId, message) {
162
+ try {
163
+ await this.handleClaimMessage(driver, sessionId, message);
164
+ }
165
+ catch (err) {
166
+ const msg = err instanceof Error ? err.message : String(err);
167
+ driver.log.warn(`Could not handle the session claim IPC message for session '${sessionId}': ${msg}`);
168
+ }
169
+ }
170
+ async handleClaimMessage(driver, sessionId, message) {
171
+ if (message.data.sessionId === sessionId || driver.sessionId !== sessionId) {
172
+ return;
173
+ }
174
+ // Tell the claimer that it has to wait for us
175
+ await this.publish(driver, SessionClaimHandler.CONTENDED_TOPIC, sessionId);
176
+ driver.log.warn(`Session '${message.data.sessionId}' is starting, while this session ('${sessionId}') is still active. ` +
177
+ `Only one session at a time is supported, since XCTest is single-threaded. ` +
178
+ `Consider enabling the Appium server's '--session-override' flag and make sure to properly ` +
179
+ `quit the previous session before starting a new one. Terminating the obsolete session.`);
180
+ await this.terminateSession(driver, sessionId);
181
+ }
182
+ async terminateSession(driver, sessionId) {
183
+ const publisherId = this.getPublisherId(driver);
184
+ const { log } = driver;
185
+ try {
186
+ // Unlike deleteSession(), this also makes the server drop the session from its list
187
+ await driver.startUnexpectedShutdown(new errors.NoSuchDriverError('This session has been replaced by a newer one, because only a single session is supported'));
188
+ }
189
+ catch (err) {
190
+ const msg = err instanceof Error ? err.message : String(err);
191
+ log.warn(`Could not terminate session '${sessionId}' on IPC request: ${msg}`);
192
+ }
193
+ await this.publish(driver, SessionClaimHandler.RELEASED_TOPIC, sessionId, publisherId, log);
194
+ }
195
+ async publish(driver, topic, sessionId, publisherId = this.getPublisherId(driver), log = driver.log) {
196
+ try {
197
+ const ipc = await this.getIpc();
198
+ await ipc?.publish(topic, publisherId, { sessionId });
199
+ }
200
+ catch (err) {
201
+ const msg = err instanceof Error ? err.message : String(err);
202
+ log.warn(`Could not publish '${topic}' message for session '${sessionId}': ${msg}`);
203
+ }
204
+ }
205
+ getPublisherId(driver) {
206
+ return node.getObjectId(driver);
207
+ }
208
+ }
209
+ let sharedIpc;
210
+ async function loadSharedIpc() {
211
+ sharedIpc ??= (async () => {
212
+ try {
213
+ const { AppiumIpc } = (await import('appium/driver.js'));
214
+ return AppiumIpc ? new AppiumIpc() : undefined;
215
+ }
216
+ catch {
217
+ return undefined;
218
+ }
219
+ })();
220
+ return await sharedIpc;
221
+ }
222
+ export const sessionClaimHandler = new SessionClaimHandler(loadSharedIpc);
223
+ /**
224
+ * @internal Exposed for unit tests.
225
+ */
226
+ export function setSharedIpcForTesting(ipc) {
227
+ sharedIpc = Promise.resolve(ipc);
228
+ }
229
+ /**
230
+ * @internal Exposed for unit tests.
231
+ */
232
+ export function resetSharedIpcForTesting() {
233
+ sessionClaimHandler.resetForTesting();
234
+ sharedIpc = undefined;
235
+ }
236
+ //# sourceMappingURL=session-claim-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-claim-handler.js","sourceRoot":"","sources":["../../lib/session-claim-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,IAAI,KAAK,EAAC,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,mBAAmB,CAAC;AAC7C,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAW1C,6GAA6G;AAC7G,MAAM,OAAO,mBAAmB;IAeX;IACA;IAfnB,MAAM,CAAU,aAAa,GAAG,qBAAqB,CAAC;IACtD,MAAM,CAAU,eAAe,GAAG,uBAAuB,CAAC;IAC1D,MAAM,CAAU,cAAc,GAAG,sBAAsB,CAAC;IAEhD,MAAM,CAAU,gBAAgB,GAAG,qBAAqB,CAAC;IAEzD,MAAM,CAAU,mBAAmB,GAAG,EAAE,CAAC;IACzC,MAAM,CAAU,uBAAuB,GAAG,KAAK,CAAC;IAEvC,WAAW,GAAG,IAAI,SAAS,EAAE,CAAC;IAC9B,gBAAgB,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC5C,wBAAwB,GAAG,IAAI,GAAG,EAA+C,CAAC;IAEnG,YACmB,MAAmB,EACnB,gBAAwB,mBAAmB,CAAC,uBAAuB;QADnE,WAAM,GAAN,MAAM,CAAa;QACnB,kBAAa,GAAb,aAAa,CAAsD;IACnF,CAAC;IAEJ,4FAA4F;IAC5F,KAAK,CAAC,YAAY,CAAI,EAAoB;QACxC,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,qBAAqB,CAAC,MAAkB;QAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAChC,mBAAmB,CAAC,aAAa,EACjC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAC5B,CAAC;QACF,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrC,KAAK,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED,mDAAmD;IACnD,uBAAuB,CAAC,MAAkB;QACxC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;QAC5D,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,6FAA6F;IAC7F,KAAK,CAAC,aAAa,CAAC,QAA6B;QAC/C,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,2DAA2D;YAC7D,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,SAAS,CAAC,MAAkB;QAChC,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,MAAkB;QACtD,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClH,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,IAAI,CAAC;gBACH,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAC,CAAC,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC,CAAC,UAAU;YAC9B,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACrF,qFAAqF;gBACrF,MAAM,IAAI,MAAM,CAAC,sBAAsB,CACrC,uDAAuD,IAAI,CAAC,aAAa,IAAI,CAC9E,CAAC;YACJ,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAkB;QAC7C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YACpF,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC7C,MAAM,aAAa,GAA0C,EAAE,CAAC;QAEhE,IAAI,CAAC;YACH,MAAM,qBAAqB,GAAG,GAAG,CAAC,SAAS,CACzC,mBAAmB,CAAC,eAAe,EACnC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAC5B,CAAC;YACF,aAAa,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC1C,MAAM,oBAAoB,GAAG,GAAG,CAAC,SAAS,CACxC,mBAAmB,CAAC,cAAc,EAClC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAC5B,CAAC;YACF,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACzC,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBACzC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC,CAAC,CAAC;YACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC7C,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBACzC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,GAAG,CAAC,OAAO,CAAoB,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;gBACnG,SAAS;aACV,CAAC,CAAC;YACH,iGAAiG;YACjG,MAAM,KAAK,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;YAErD,IAAI,oBAAoB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE;oBAChG,MAAM,EAAE,IAAI,CAAC,aAAa;oBAC1B,UAAU,EAAE,EAAE;iBACf,CAAC,CAAC;gBACH,MAAM,CAAC,GAAG,CAAC,KAAK,CACd,sCAAsC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CACnG,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,iBAAiB,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChG,iEAAiE;gBACjE,MAAM,IAAI,MAAM,CAAC,sBAAsB,CACrC,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBAC/F,uBAAuB,IAAI,CAAC,aAAa,IAAI,CAChD,CAAC;YACJ,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,eAAe;QACb,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,EAAE,CAAC;YAClE,YAAY,CAAC,WAAW,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,MAAkB,EAClB,SAAiB,EACjB,OAAsC;QAEtC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,+DAA+D,SAAS,MAAM,GAAG,EAAE,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC9B,MAAkB,EAClB,SAAiB,EACjB,OAAsC;QAEtC,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC3E,OAAO;QACT,CAAC;QAED,8CAA8C;QAC9C,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAE3E,MAAM,CAAC,GAAG,CAAC,IAAI,CACb,YAAY,OAAO,CAAC,IAAI,CAAC,SAAS,uCAAuC,SAAS,sBAAsB;YACtG,4EAA4E;YAC5E,4FAA4F;YAC5F,wFAAwF,CAC3F,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,MAAkB,EAAE,SAAiB;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,EAAC,GAAG,EAAC,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC;YACH,oFAAoF;YACpF,MAAM,MAAM,CAAC,uBAAuB,CAClC,IAAI,MAAM,CAAC,iBAAiB,CAC1B,2FAA2F,CAC5F,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,GAAG,CAAC,IAAI,CAAC,gCAAgC,SAAS,qBAAqB,GAAG,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAC9F,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAkB,EAClB,KAAa,EACb,SAAiB,EACjB,cAAsB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EACjD,MAAoB,MAAM,CAAC,GAAG;QAE9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,GAAG,EAAE,OAAO,CAAoB,KAAK,EAAE,WAAW,EAAE,EAAC,SAAS,EAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,GAAG,CAAC,IAAI,CAAC,sBAAsB,KAAK,0BAA0B,SAAS,MAAM,GAAG,EAAE,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,MAAkB;QACvC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;;AAGH,IAAI,SAAsD,CAAC;AAE3D,KAAK,UAAU,aAAa;IAC1B,SAAS,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,IAAI,CAAC;YACH,MAAM,EAAC,SAAS,EAAC,GAAG,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAuC,CAAC;YAC7F,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,OAAO,MAAM,SAAS,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,aAAa,CAAC,CAAC;AAE1E;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAA2B;IAChE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,mBAAmB,CAAC,eAAe,EAAE,CAAC;IACtC,SAAS,GAAG,SAAS,CAAC;AACxB,CAAC"}