@tapflowio/ios-agent 0.29.0 → 0.31.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 (71) hide show
  1. package/bin/guest-helper +0 -0
  2. package/bin/screencapture-helper +0 -0
  3. package/dist/AudioCaptureStreamer.d.ts +3 -2
  4. package/dist/AudioCaptureStreamer.d.ts.map +1 -1
  5. package/dist/AudioCaptureStreamer.js +16 -10
  6. package/dist/AudioCaptureStreamer.js.map +1 -1
  7. package/dist/DeviceChromeLoader.d.ts +28 -1
  8. package/dist/DeviceChromeLoader.d.ts.map +1 -1
  9. package/dist/DeviceChromeLoader.js +118 -37
  10. package/dist/DeviceChromeLoader.js.map +1 -1
  11. package/dist/FoldableInput.d.ts +58 -0
  12. package/dist/FoldableInput.d.ts.map +1 -0
  13. package/dist/FoldableInput.js +166 -0
  14. package/dist/FoldableInput.js.map +1 -0
  15. package/dist/GuestHelper.d.ts +109 -0
  16. package/dist/GuestHelper.d.ts.map +1 -0
  17. package/dist/GuestHelper.js +437 -0
  18. package/dist/GuestHelper.js.map +1 -0
  19. package/dist/IOSAgent.d.ts +126 -4
  20. package/dist/IOSAgent.d.ts.map +1 -1
  21. package/dist/IOSAgent.js +673 -62
  22. package/dist/IOSAgent.js.map +1 -1
  23. package/dist/InputChannel.d.ts +38 -0
  24. package/dist/InputChannel.d.ts.map +1 -0
  25. package/dist/InputChannel.js +7 -0
  26. package/dist/InputChannel.js.map +1 -0
  27. package/dist/PanelState.d.ts +72 -0
  28. package/dist/PanelState.d.ts.map +1 -0
  29. package/dist/PanelState.js +192 -0
  30. package/dist/PanelState.js.map +1 -0
  31. package/dist/PhysicalOrientation.d.ts +58 -0
  32. package/dist/PhysicalOrientation.d.ts.map +1 -0
  33. package/dist/PhysicalOrientation.js +155 -0
  34. package/dist/PhysicalOrientation.js.map +1 -0
  35. package/dist/ScreenCaptureStreamer.d.ts +12 -1
  36. package/dist/ScreenCaptureStreamer.d.ts.map +1 -1
  37. package/dist/ScreenCaptureStreamer.js +28 -3
  38. package/dist/ScreenCaptureStreamer.js.map +1 -1
  39. package/dist/SimProcessTree.d.ts +3 -1
  40. package/dist/SimProcessTree.d.ts.map +1 -1
  41. package/dist/SimProcessTree.js +14 -4
  42. package/dist/SimProcessTree.js.map +1 -1
  43. package/dist/SimctlWrapper.d.ts +20 -2
  44. package/dist/SimctlWrapper.d.ts.map +1 -1
  45. package/dist/SimctlWrapper.js +53 -3
  46. package/dist/SimctlWrapper.js.map +1 -1
  47. package/dist/SimulatorNetwork.d.ts +3 -2
  48. package/dist/SimulatorNetwork.d.ts.map +1 -1
  49. package/dist/SimulatorNetwork.js +3 -2
  50. package/dist/SimulatorNetwork.js.map +1 -1
  51. package/dist/TouchHelper.d.ts +3 -2
  52. package/dist/TouchHelper.d.ts.map +1 -1
  53. package/dist/TouchHelper.js +4 -6
  54. package/dist/TouchHelper.js.map +1 -1
  55. package/dist/TypePanels.d.ts +33 -0
  56. package/dist/TypePanels.d.ts.map +1 -0
  57. package/dist/TypePanels.js +68 -0
  58. package/dist/TypePanels.js.map +1 -0
  59. package/dist/launchArgs.d.ts +6 -0
  60. package/dist/launchArgs.d.ts.map +1 -0
  61. package/dist/launchArgs.js +21 -0
  62. package/dist/launchArgs.js.map +1 -0
  63. package/dist/panels.d.ts +52 -0
  64. package/dist/panels.d.ts.map +1 -0
  65. package/dist/panels.js +68 -0
  66. package/dist/panels.js.map +1 -0
  67. package/dist/simctl.d.ts +3 -0
  68. package/dist/simctl.d.ts.map +1 -1
  69. package/dist/simctl.js +1 -1
  70. package/dist/simctl.js.map +1 -1
  71. package/package.json +6 -5
@@ -0,0 +1,437 @@
1
+ import { execFile, spawn } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { promisify } from 'util';
5
+ import { createLogger } from '@tapflowio/agent-core';
6
+ const logger = createLogger('ios-agent:guest-helper');
7
+ const execFileAsync = promisify(execFile);
8
+ // `bin/guest-helper` runs INSIDE the simulator (an iphonesimulator executable), so it is started through
9
+ // `simctl spawn`, never directly. See `src/guest-helper.m` for its protocol and why it exists.
10
+ export const GUEST_HELPER_BINARY = join(import.meta.dirname, '..', 'bin', 'guest-helper');
11
+ // The same rolling window as TouchHelper, for the same reason it gives.
12
+ const RESPAWN_LIMIT = 3;
13
+ const RESPAWN_WINDOW_MS = 30_000;
14
+ // `ready` comes after `simctl spawn` has started the guest process, the helper has registered its
15
+ // services, and a 300 ms settle (a tap within 50 ms of registering is dropped, measured on Xcode 27.1).
16
+ // The spawn alone measured ~0.6–0.9 s. **The bound is for a wedge, not a slow Mac**: on an 8 GB Mac mini
17
+ // swapping 1.8 GB with a Duo up, the agent's own loop stalled 3.2 s, and an 8 s bound replaced three
18
+ // healthy-but-slow helpers in a row.
19
+ const READY_DEADLINE_MS = 15_000;
20
+ // A command the helper answers with `done`: the fold sweep plays inside the helper (0.8 s), a key is held
21
+ // for its own duration. Past this margin on top of that, the helper is treated as wedged and replaced —
22
+ // generous for the reason READY_DEADLINE_MS gives: a 5 s margin replaced a helper mid-stall.
23
+ const COMMAND_MARGIN_MS = 10_000;
24
+ // A fold's margin, longer: the sweep can sit blocked while the device changes panel. Measured on that Mac
25
+ // mini with a session streaming: a sweep went unanswered past 10.8 s although its panel lit at 10.6 s, so
26
+ // the helper was replaced just after it had folded the device — and the next press, landing while the new
27
+ // helper started, was refused. A late answer to a fold is harmless; it is what was asked for.
28
+ const HINGE_MARGIN_MS = 30_000;
29
+ const STOP_SIGKILL_AFTER_MS = 1_000;
30
+ export const defaultGuestHelperNative = {
31
+ spawn(udid, args) {
32
+ // Detached so a terminal's Ctrl-C, which signals the whole process group, cannot take `simctl spawn`
33
+ // down before the agent's own cleanup runs — the guest would then be orphaned with nobody left to
34
+ // know its pid.
35
+ return spawn('xcrun', ['simctl', 'spawn', udid, GUEST_HELPER_BINARY, ...args], {
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ detached: true,
38
+ });
39
+ },
40
+ async findOrphans(udid) {
41
+ // **Found by search, not by memory.** An agent killed with -9 restarts knowing no pids, and a
42
+ // `simctl spawn` that died alone leaves the guest running (measured) — a respawn would then register
43
+ // a second set of services on the same displays. The udid in argv is what makes the match ours.
44
+ const marker = `--udid ${udid}`;
45
+ let out;
46
+ try {
47
+ out = (await execFileAsync('/usr/bin/pgrep', ['-f', `guest-helper ${marker}`], { timeout: 5_000 })).stdout;
48
+ }
49
+ catch {
50
+ return []; // pgrep exits 1 when nothing matches
51
+ }
52
+ const pids = [];
53
+ for (const pid of out.split('\n').map(Number).filter((n) => Number.isInteger(n) && n > 0 && n !== process.pid)) {
54
+ try {
55
+ const cmd = (await execFileAsync('/bin/ps', ['-o', 'command=', '-p', String(pid)], { timeout: 5_000 })).stdout;
56
+ if (cmd.includes(GUEST_HELPER_BINARY) && cmd.includes(marker))
57
+ pids.push(pid);
58
+ }
59
+ catch { /* gone between the two calls */ }
60
+ }
61
+ return pids;
62
+ },
63
+ killPid(pid, signal) {
64
+ try {
65
+ process.kill(pid, signal);
66
+ }
67
+ catch { /* already gone, or not ours */ }
68
+ },
69
+ async unavailableReason() {
70
+ if (!existsSync(GUEST_HELPER_BINARY))
71
+ return `${GUEST_HELPER_BINARY} is missing — reinstall @tapflowio/ios-agent`;
72
+ try {
73
+ await execFileAsync('xcrun', ['--find', 'devicectl'], { timeout: 10_000 });
74
+ }
75
+ catch {
76
+ return 'devicectl was not found — install Xcode and select it with xcode-select';
77
+ }
78
+ return null;
79
+ },
80
+ };
81
+ /**
82
+ * The host side of `guest-helper`: one per multi-panel device, resident for the device's life.
83
+ *
84
+ * Its lifecycle follows TouchHelper's rules — readiness gates writes, a gesture belongs to the process
85
+ * that took its opening frame, deaths are replaced eagerly within a rolling budget — with three
86
+ * differences the guest process forces:
87
+ * - the process the agent spawns is `simctl spawn`, not the helper; the helper's own pid arrives on
88
+ * stdout and is killed separately, because the two do not die together;
89
+ * - earlier helpers for the same device are found with `pgrep` and killed before every spawn;
90
+ * - `fatal` is final: it means the runtime refused the private API, and spawning again would only
91
+ * hear the same answer.
92
+ *
93
+ * **Running out of the respawn budget is not final**, which is TouchHelper's rule too ("it self-clears,
94
+ * so a session that briefly could not start a helper is not left without input until the device is
95
+ * rebooted"). A first version made it final, and a Mac short of memory turned one slow minute into a
96
+ * device with no input for the rest of its boot. The helper waits for the window to clear and launches
97
+ * again, answering `starting` meanwhile.
98
+ */
99
+ export class GuestHelper {
100
+ udid;
101
+ touchscreens;
102
+ native;
103
+ options;
104
+ proc = null;
105
+ guestPid = null;
106
+ gestureProc = null;
107
+ ready = false;
108
+ stopped = false;
109
+ unavailable = null;
110
+ fatalReason = null;
111
+ spawns = [];
112
+ pending = [];
113
+ readyTimer = null;
114
+ readyWaiters = [];
115
+ generation = 0;
116
+ // Set while waiting out the respawn window after the budget ran out; cleared by the launch it schedules.
117
+ cooldown = null;
118
+ // The reason the helper last went out of service, until a ready says it is back.
119
+ outage = null;
120
+ // Between `start()` (or a respawn) and the spawn: sweeping orphans and reading the panels. Input sent
121
+ // then is told to wait, not that the channel is gone.
122
+ launching = false;
123
+ /**
124
+ * `touchscreens` is asked on every launch, not once: display UUIDs change on every boot, and a respawn
125
+ * after the device rebooted under the agent must register the new ones.
126
+ */
127
+ constructor(udid, touchscreens, native = defaultGuestHelperNative, options = {}) {
128
+ this.udid = udid;
129
+ this.touchscreens = touchscreens;
130
+ this.native = native;
131
+ this.options = options;
132
+ }
133
+ async start() {
134
+ this.stopped = false;
135
+ await this.launch();
136
+ }
137
+ stop() {
138
+ this.stopped = true;
139
+ this.launching = false;
140
+ if (this.cooldown) {
141
+ clearTimeout(this.cooldown);
142
+ this.cooldown = null;
143
+ }
144
+ this.generation++;
145
+ this.clearReadyDeadline();
146
+ this.failPending();
147
+ const proc = this.proc;
148
+ const guestPid = this.guestPid;
149
+ this.proc = null;
150
+ this.guestPid = null;
151
+ this.gestureProc = null;
152
+ this.ready = false;
153
+ this.settleReadyWaiters(false);
154
+ // EOF is the first line of defence (the helper exits on it, measured); the signals cover a helper
155
+ // that is wedged and a `simctl spawn` that outlives its child.
156
+ proc?.stdin?.end();
157
+ if (proc)
158
+ this.signalProcess(proc, 'SIGTERM');
159
+ if (guestPid)
160
+ this.native.killPid(guestPid, 'SIGTERM');
161
+ const timer = setTimeout(() => {
162
+ if (proc)
163
+ this.signalProcess(proc, 'SIGKILL');
164
+ if (guestPid)
165
+ this.native.killPid(guestPid, 'SIGKILL');
166
+ }, STOP_SIGKILL_AFTER_MS);
167
+ timer.unref?.();
168
+ }
169
+ inputState() {
170
+ if (this.proc && this.ready)
171
+ return 'ready';
172
+ if ((this.proc || this.launching || this.cooldown) && !this.unavailable)
173
+ return 'starting';
174
+ return 'unavailable';
175
+ }
176
+ /** Resolves true once the helper is ready, false if it becomes unavailable or is stopped first. */
177
+ whenReady() {
178
+ if (this.inputState() === 'ready')
179
+ return Promise.resolve(true);
180
+ if (this.unavailable || this.stopped)
181
+ return Promise.resolve(false);
182
+ return new Promise((resolve) => this.readyWaiters.push(resolve));
183
+ }
184
+ /** Why the helper cannot serve — for good, or for now — or null. */
185
+ unavailableReason() {
186
+ return this.unavailable ?? this.outage;
187
+ }
188
+ ownsGesture() {
189
+ return this.proc !== null && this.proc === this.gestureProc;
190
+ }
191
+ /** One finger on the panel whose display UUID is `screen`. Acked on the write, like Indigo: the helper
192
+ * answers a touch only when it fails, and a drag is too many lines a second to wait on. */
193
+ touch(screen, phase, x, y, edge) {
194
+ return this.gestureFrame(phase, `touch ${screen} ${phase} ${x} ${y} ${edge ? 1 : 0}`);
195
+ }
196
+ pinch(screen, phase, x1, y1, x2, y2) {
197
+ return this.gestureFrame(phase, `pinch ${screen} ${phase} ${x1} ${y1} ${x2} ${y2}`);
198
+ }
199
+ hinge(fromDeg, toDeg, durationMs) {
200
+ return this.command(`hinge ${fromDeg} ${toDeg} ${durationMs}`, durationMs, HINGE_MARGIN_MS);
201
+ }
202
+ orient(value) {
203
+ return this.command(`orient ${value}`, 0);
204
+ }
205
+ key(usagePage, usage, holdMs, modifiers = []) {
206
+ const mods = modifiers.map(([p, u]) => ` ${p} ${u}`).join('');
207
+ return this.command(`key ${usagePage} ${usage} ${holdMs}${mods}`, holdMs);
208
+ }
209
+ /** Half of a held press — a long-press lasts as long as the tester holds it, like TouchHelper's
210
+ * `pressButtonDown`/`Up`. */
211
+ keyDown(usagePage, usage) {
212
+ return this.command(`keydown ${usagePage} ${usage}`, 0);
213
+ }
214
+ keyUp(usagePage, usage) {
215
+ return this.command(`keyup ${usagePage} ${usage}`, 0);
216
+ }
217
+ gestureFrame(phase, line) {
218
+ if (phase === 'd') {
219
+ const sent = this.write(line);
220
+ // Only a delivered down owns the gesture — TouchHelper's `openGesture` explains why recording it
221
+ // unconditionally lets a fresh process receive an up for a touch it never saw.
222
+ this.gestureProc = sent ? this.proc : null;
223
+ return sent;
224
+ }
225
+ if (!this.ownsGesture())
226
+ return false;
227
+ return this.write(line);
228
+ }
229
+ command(line, playMs, marginMs = COMMAND_MARGIN_MS) {
230
+ const proc = this.proc;
231
+ if (!proc || !this.write(line))
232
+ return Promise.resolve(false);
233
+ return new Promise((resolve) => {
234
+ const timer = setTimeout(() => {
235
+ const at = this.pending.findIndex((p) => p.timer === timer);
236
+ if (at !== -1)
237
+ this.pending.splice(at, 1);
238
+ resolve(false);
239
+ if (this.proc !== proc)
240
+ return;
241
+ logger.error(`no answer to "${line}" within ${playMs + marginMs}ms — replacing the helper`);
242
+ // The guest would still act on a queued command after we gave up on it, so it goes, not only
243
+ // the simctl process that carries its pipe.
244
+ if (this.guestPid)
245
+ this.native.killPid(this.guestPid, 'SIGKILL');
246
+ this.signalProcess(proc, 'SIGKILL');
247
+ }, playMs + marginMs);
248
+ timer.unref?.();
249
+ this.pending.push({ resolve, timer });
250
+ });
251
+ }
252
+ write(line) {
253
+ if (this.inputState() !== 'ready')
254
+ return false;
255
+ this.proc?.stdin?.write(`${line}\n`);
256
+ return true;
257
+ }
258
+ async launch() {
259
+ const generation = ++this.generation;
260
+ this.launching = true;
261
+ let screens;
262
+ try {
263
+ for (const pid of await this.native.findOrphans(this.udid)) {
264
+ logger.warn(`killing a leftover guest-helper (pid ${pid}) for ${this.udid}`);
265
+ this.native.killPid(pid, 'SIGKILL');
266
+ }
267
+ screens = await this.touchscreens();
268
+ }
269
+ catch (e) {
270
+ if (generation === this.generation)
271
+ this.launching = false;
272
+ if (!this.stopped && generation === this.generation) {
273
+ // Not final: `simctl io enumerate` can fail while a busy Mac is still bringing the device up.
274
+ this.spawns.push(Date.now());
275
+ this.retryLater(`could not read the device's panels: ${e instanceof Error ? e.message : String(e)}`);
276
+ }
277
+ return;
278
+ }
279
+ if (generation !== this.generation)
280
+ return;
281
+ this.launching = false;
282
+ if (this.stopped)
283
+ return;
284
+ this.spawns.push(Date.now());
285
+ this.ready = false;
286
+ this.guestPid = null;
287
+ const proc = this.native.spawn(this.udid, [
288
+ '--udid', this.udid, ...screens.flatMap((uuid) => ['--touchscreen', uuid]),
289
+ ]);
290
+ // A pid is the only synchronous sign the exec happened — TouchHelper's `spawnHelper` has the measurement.
291
+ if (proc.pid === undefined) {
292
+ proc.on('error', (e) => logger.error(`spawn error: ${e.message}`));
293
+ this.proc = null;
294
+ this.becomeUnavailable('could not start guest-helper through simctl spawn');
295
+ return;
296
+ }
297
+ this.proc = proc;
298
+ this.armReadyDeadline(proc);
299
+ let partial = '';
300
+ proc.stdout?.on('data', (d) => {
301
+ const lines = (partial + d.toString()).split('\n');
302
+ partial = lines.pop() ?? '';
303
+ for (const line of lines)
304
+ this.onLine(proc, line.trim());
305
+ });
306
+ proc.stderr?.on('data', (d) => logger.error(d.toString().trim()));
307
+ proc.on('exit', (code) => {
308
+ logger.warn(`guest-helper for ${this.udid} exited with code ${code ?? 'null'}`);
309
+ this.handleDeath(proc);
310
+ });
311
+ proc.on('error', (e) => {
312
+ logger.error(`spawn error: ${e.message}`);
313
+ this.handleDeath(proc);
314
+ });
315
+ }
316
+ onLine(proc, line) {
317
+ if (this.proc !== proc || !line)
318
+ return;
319
+ const [word, ...rest] = line.split(' ');
320
+ if (word === 'pid') {
321
+ const pid = Number(rest[0]);
322
+ if (Number.isInteger(pid) && pid > 0)
323
+ this.guestPid = pid;
324
+ }
325
+ else if (word === 'ready') {
326
+ this.ready = true;
327
+ this.clearReadyDeadline();
328
+ this.settleReadyWaiters(true);
329
+ if (this.outage) {
330
+ logger.info(`guest-helper back in service for ${this.udid}`);
331
+ this.outage = null;
332
+ this.options.onAvailable?.();
333
+ }
334
+ }
335
+ else if (word === 'done') {
336
+ this.pending.shift()?.resolve(rest[0] === '0');
337
+ }
338
+ else if (word === 'err') {
339
+ // A touch frame the guest refused. Touches are acked on the write, so this only gets logged.
340
+ logger.warn(`guest-helper refused: ${rest.slice(1).join(' ')} (status ${rest[0]})`);
341
+ }
342
+ else if (word === 'fatal') {
343
+ this.fatalReason = rest.join(' ') || 'guest-helper could not start';
344
+ this.becomeUnavailable(this.fatalReason);
345
+ }
346
+ }
347
+ handleDeath(proc) {
348
+ if (this.proc !== proc)
349
+ return;
350
+ this.clearReadyDeadline();
351
+ this.failPending();
352
+ this.proc = null;
353
+ this.guestPid = null;
354
+ this.ready = false;
355
+ if (this.stopped || this.fatalReason)
356
+ return;
357
+ const now = Date.now();
358
+ this.spawns = this.spawns.filter((t) => now - t < RESPAWN_WINDOW_MS);
359
+ if (this.spawns.length >= RESPAWN_LIMIT) {
360
+ this.retryLater(`guest-helper died ${RESPAWN_LIMIT} times in ${RESPAWN_WINDOW_MS / 1000}s`);
361
+ return;
362
+ }
363
+ void this.launch();
364
+ }
365
+ /** Out of service until the respawn window has room again, then launch. */
366
+ retryLater(reason) {
367
+ if (this.cooldown || this.stopped)
368
+ return;
369
+ const now = Date.now();
370
+ this.spawns = this.spawns.filter((t) => now - t < RESPAWN_WINDOW_MS);
371
+ const wait = this.spawns.length >= RESPAWN_LIMIT ? RESPAWN_WINDOW_MS - (now - this.spawns[0]) + 50 : 0;
372
+ logger.warn(`guest-helper out of service for ${this.udid}: ${reason} — trying again in ${Math.round(wait / 1000)}s`);
373
+ this.noteOutage(reason);
374
+ const timer = setTimeout(() => {
375
+ if (this.cooldown !== timer)
376
+ return;
377
+ this.cooldown = null;
378
+ if (!this.stopped)
379
+ void this.launch();
380
+ }, wait);
381
+ timer.unref?.();
382
+ this.cooldown = timer;
383
+ }
384
+ noteOutage(reason) {
385
+ if (this.outage)
386
+ return;
387
+ this.outage = reason;
388
+ this.options.onUnavailable?.(reason);
389
+ }
390
+ /** For good: the runtime refused the helper, or it could not be exec'd at all. */
391
+ becomeUnavailable(reason) {
392
+ if (this.unavailable)
393
+ return;
394
+ this.unavailable = reason;
395
+ this.ready = false;
396
+ this.settleReadyWaiters(false);
397
+ logger.error(`guest-helper unavailable for ${this.udid}: ${reason}`);
398
+ this.outage = null;
399
+ this.noteOutage(reason);
400
+ }
401
+ armReadyDeadline(proc) {
402
+ this.clearReadyDeadline();
403
+ const timer = setTimeout(() => {
404
+ if (this.proc !== proc || this.ready)
405
+ return;
406
+ logger.error(`no ready from guest-helper within ${READY_DEADLINE_MS}ms — replacing it`);
407
+ if (this.guestPid)
408
+ this.native.killPid(this.guestPid, 'SIGKILL');
409
+ this.signalProcess(proc, 'SIGKILL');
410
+ }, READY_DEADLINE_MS);
411
+ timer.unref?.();
412
+ this.readyTimer = timer;
413
+ }
414
+ clearReadyDeadline() {
415
+ if (this.readyTimer) {
416
+ clearTimeout(this.readyTimer);
417
+ this.readyTimer = null;
418
+ }
419
+ }
420
+ failPending() {
421
+ for (const p of this.pending.splice(0)) {
422
+ clearTimeout(p.timer);
423
+ p.resolve(false);
424
+ }
425
+ }
426
+ settleReadyWaiters(ok) {
427
+ for (const resolve of this.readyWaiters.splice(0))
428
+ resolve(ok);
429
+ }
430
+ /** `simctl spawn` was started detached, so it leads its own process group. */
431
+ signalProcess(proc, signal) {
432
+ if (proc.pid)
433
+ this.native.killPid(-proc.pid, signal);
434
+ proc.kill(signal);
435
+ }
436
+ }
437
+ //# sourceMappingURL=GuestHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GuestHelper.js","sourceRoot":"","sources":["../src/GuestHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAA;AACrD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAEzC,yGAAyG;AACzG,+FAA+F;AAC/F,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,CAAA;AAEzF,wEAAwE;AACxE,MAAM,aAAa,GAAG,CAAC,CAAA;AACvB,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAEhC,kGAAkG;AAClG,wGAAwG;AACxG,yGAAyG;AACzG,qGAAqG;AACrG,qCAAqC;AACrC,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAEhC,0GAA0G;AAC1G,wGAAwG;AACxG,6FAA6F;AAC7F,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAChC,0GAA0G;AAC1G,0GAA0G;AAC1G,0GAA0G;AAC1G,8FAA8F;AAC9F,MAAM,eAAe,GAAG,MAAM,CAAA;AAE9B,MAAM,qBAAqB,GAAG,KAAK,CAAA;AAsBnC,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,KAAK,CAAC,IAAI,EAAE,IAAI;QACd,qGAAqG;QACrG,kGAAkG;QAClG,gBAAgB;QAChB,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,EAAE;YAC7E,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,QAAQ,EAAE,IAAI;SACf,CAAC,CAAA;IACJ,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,IAAI;QACpB,8FAA8F;QAC9F,qGAAqG;QACrG,gGAAgG;QAChG,MAAM,MAAM,GAAG,UAAU,IAAI,EAAE,CAAA;QAC/B,IAAI,GAAW,CAAA;QACf,IAAI,CAAC;YACH,GAAG,GAAG,CAAC,MAAM,aAAa,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,gBAAgB,MAAM,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;QAC5G,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA,CAAC,qCAAqC;QACjD,CAAC;QACD,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/G,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,CAAC,MAAM,aAAa,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;gBAC9G,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC/E,CAAC;YAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,MAAM;QACjB,IAAI,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;IAC7E,CAAC;IACD,KAAK,CAAC,iBAAiB;QACrB,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;YAAE,OAAO,GAAG,mBAAmB,8CAA8C,CAAA;QACjH,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,yEAAyE,CAAA;QAClF,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF,CAAA;AAeD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,WAAW;IA0BH;IACA;IACA;IACA;IA5BX,IAAI,GAAwB,IAAI,CAAA;IAChC,QAAQ,GAAkB,IAAI,CAAA;IAC9B,WAAW,GAAwB,IAAI,CAAA;IACvC,KAAK,GAAG,KAAK,CAAA;IACb,OAAO,GAAG,KAAK,CAAA;IACf,WAAW,GAAkB,IAAI,CAAA;IACjC,WAAW,GAAkB,IAAI,CAAA;IACjC,MAAM,GAAa,EAAE,CAAA;IACrB,OAAO,GAAc,EAAE,CAAA;IACvB,UAAU,GAAyC,IAAI,CAAA;IACvD,YAAY,GAAiC,EAAE,CAAA;IAC/C,UAAU,GAAG,CAAC,CAAA;IACtB,yGAAyG;IACjG,QAAQ,GAAyC,IAAI,CAAA;IAC7D,iFAAiF;IACzE,MAAM,GAAkB,IAAI,CAAA;IACpC,sGAAsG;IACtG,sDAAsD;IAC9C,SAAS,GAAG,KAAK,CAAA;IAEzB;;;OAGG;IACH,YACmB,IAAY,EACZ,YAAqC,EACrC,SAA4B,wBAAwB,EACpD,UAA8B,EAAE;QAHhC,SAAI,GAAJ,IAAI,CAAQ;QACZ,iBAAY,GAAZ,YAAY,CAAyB;QACrC,WAAM,GAAN,MAAM,CAA8C;QACpD,YAAO,GAAP,OAAO,CAAyB;IAChD,CAAC;IAEJ,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;IACrB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QAAC,CAAC;QACxE,IAAI,CAAC,UAAU,EAAE,CAAA;QACjB,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACzB,IAAI,CAAC,WAAW,EAAE,CAAA;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAC9B,kGAAkG;QAClG,+DAA+D;QAC/D,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;QAClB,IAAI,IAAI;YAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC7C,IAAI,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;QACtD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI;gBAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAC7C,IAAI,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;QACxD,CAAC,EAAE,qBAAqB,CAAC,CAAA;QACzB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;IACjB,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,CAAA;QAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,UAAU,CAAA;QAC1F,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,mGAAmG;IACnG,SAAS;QACP,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC/D,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;IAClE,CAAC;IAED,oEAAoE;IACpE,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAA;IACxC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAA;IAC7D,CAAC;IAED;gGAC4F;IAC5F,KAAK,CAAC,MAAc,EAAE,KAAiB,EAAE,CAAS,EAAE,CAAS,EAAE,IAAa;QAC1E,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,KAAiB,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;QACrF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,MAAM,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,KAAa,EAAE,UAAkB;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,OAAO,IAAI,KAAK,IAAI,UAAU,EAAE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IAC7F,CAAC;IAED,MAAM,CAAC,KAAuB;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3C,CAAC;IAED,GAAG,CAAC,SAAiB,EAAE,KAAa,EAAE,MAAc,EAAE,YAAqC,EAAE;QAC3F,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,SAAS,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,EAAE,EAAE,MAAM,CAAC,CAAA;IAC3E,CAAC;IAED;kCAC8B;IAC9B,OAAO,CAAC,SAAiB,EAAE,KAAa;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,SAAS,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,SAAiB,EAAE,KAAa;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,SAAS,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;IACvD,CAAC;IAEO,YAAY,CAAC,KAAiB,EAAE,IAAY;QAClD,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC7B,iGAAiG;YACjG,+EAA+E;YAC/E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;YAC1C,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO,KAAK,CAAA;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEO,OAAO,CAAC,IAAY,EAAE,MAAc,EAAE,QAAQ,GAAG,iBAAiB;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;gBAC3D,IAAI,EAAE,KAAK,CAAC,CAAC;oBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;gBACzC,OAAO,CAAC,KAAK,CAAC,CAAA;gBACd,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;oBAAE,OAAM;gBAC9B,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,YAAY,MAAM,GAAG,QAAQ,2BAA2B,CAAC,CAAA;gBAC3F,6FAA6F;gBAC7F,4CAA4C;gBAC5C,IAAI,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;gBAChE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YACrC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAA;YACrB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,IAAY;QACxB,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,OAAO;YAAE,OAAO,KAAK,CAAA;QAC/C,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,KAAK,CAAC,MAAM;QAClB,MAAM,UAAU,GAAG,EAAE,IAAI,CAAC,UAAU,CAAA;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QACrB,IAAI,OAAiB,CAAA;QACrB,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3D,MAAM,CAAC,IAAI,CAAC,wCAAwC,GAAG,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC5E,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YACrC,CAAC;YACD,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;YAC1D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpD,8FAA8F;gBAC9F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;gBAC5B,IAAI,CAAC,UAAU,CAAC,uCAAuC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YACtG,CAAC;YACD,OAAM;QACR,CAAC;QACD,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;YAAE,OAAM;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QAExB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;YACxC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;SAC3E,CAAC,CAAA;QACF,0GAA0G;QAC1G,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAClE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,iBAAiB,CAAC,mDAAmD,CAAC,CAAA;YAC3E,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAE3B,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE;YACpC,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAClD,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA;YAC3B,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACzE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,qBAAqB,IAAI,IAAI,MAAM,EAAE,CAAC,CAAA;YAC/E,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACrB,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;YACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,MAAM,CAAC,IAAkB,EAAE,IAAY;QAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;YAAE,OAAM;QACvC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3B,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;gBAAE,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAA;QAC3D,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,kBAAkB,EAAE,CAAA;YACzB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;YAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC5D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;gBAClB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAA;YAC9B,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAA;QAChD,CAAC;aAAM,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YAC1B,6FAA6F;YAC7F,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACrF,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,8BAA8B,CAAA;YACnE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,IAAkB;QACpC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,OAAM;QAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACzB,IAAI,CAAC,WAAW,EAAE,CAAA;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW;YAAE,OAAM;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAA;QACpE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;YACxC,IAAI,CAAC,UAAU,CAAC,qBAAqB,aAAa,aAAa,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAA;YAC3F,OAAM;QACR,CAAC;QACD,KAAK,IAAI,CAAC,MAAM,EAAE,CAAA;IACpB,CAAC;IAED,2EAA2E;IACnE,UAAU,CAAC,MAAc;QAC/B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAA;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QACtG,MAAM,CAAC,IAAI,CAAC,mCAAmC,IAAI,CAAC,IAAI,KAAK,MAAM,sBAAsB,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;QACpH,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QACvB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK;gBAAE,OAAM;YACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,KAAK,IAAI,CAAC,MAAM,EAAE,CAAA;QACvC,CAAC,EAAE,IAAI,CAAC,CAAA;QACR,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;QACf,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;IACvB,CAAC;IAEO,UAAU,CAAC,MAAc;QAC/B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAM;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAA;IACtC,CAAC;IAED,kFAAkF;IAC1E,iBAAiB,CAAC,MAAc;QACtC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAM;QAC5B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAC9B,MAAM,CAAC,KAAK,CAAC,gCAAgC,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAA;QACpE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IACzB,CAAC;IAEO,gBAAgB,CAAC,IAAkB;QACzC,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACzB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAM;YAC5C,MAAM,CAAC,KAAK,CAAC,qCAAqC,iBAAiB,mBAAmB,CAAC,CAAA;YACvF,IAAI,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YAChE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACrC,CAAC,EAAE,iBAAiB,CAAC,CAAA;QACrB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;QACf,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;IACzB,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QAAC,CAAC;IAChF,CAAC;IAEO,WAAW;QACjB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAAC,CAAC;IACrF,CAAC;IAEO,kBAAkB,CAAC,EAAW;QACpC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,8EAA8E;IACtE,aAAa,CAAC,IAAkB,EAAE,MAAsB;QAC9D,IAAI,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACpD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC;CACF"}
@@ -1,9 +1,13 @@
1
- import type { Device, DeviceAgent, NetworkControlCapability, NetworkStatePayload, UIElement } from '@tapflowio/agent-core';
1
+ import type { Device, DeviceAgent, DevicePosture, NetworkControlCapability, NetworkStatePayload, PosturableAgent, UIElement } from '@tapflowio/agent-core';
2
+ import type { LaunchOptions } from '@tapflowio/protocol';
2
3
  export declare const IOS_BUTTON_ALIASES: Record<string, string>;
3
4
  import { type SleepBlocker } from '@tapflowio/agent-core/utils';
4
5
  import { SimctlWrapper } from './SimctlWrapper.js';
5
6
  import { SimulatorNetwork } from './SimulatorNetwork.js';
6
7
  import { LeanStore } from './LeanStore.js';
8
+ import { type GuestHelperNative } from './GuestHelper.js';
9
+ import { PanelState } from './PanelState.js';
10
+ import { PhysicalOrientation } from './PhysicalOrientation.js';
7
11
  import { DeviceChromeLoader } from './DeviceChromeLoader.js';
8
12
  /** Lean mode needs an iOS runtime of 18.5 or later, where launchd honours the host-side overrides
9
13
  * across reboots. tvOS, watchOS and visionOS devices come through the same list and are left alone. */
@@ -31,8 +35,25 @@ export interface IOSAgentOptions {
31
35
  /** Device frame loading. Under vitest the default points at directories that do not exist, so a suite never
32
36
  * reads the developer's Xcode chrome or spends seconds rendering it. */
33
37
  chromeLoader?: DeviceChromeLoader;
38
+ /** Which panel a multi-panel device shows (devicectl). Injectable so a suite never runs devicectl. */
39
+ panelState?: PanelState;
40
+ /** Which way a multi-panel device is held (devicectl). Injectable for the same reason. */
41
+ physicalOrientation?: PhysicalOrientation;
42
+ /** How a multi-panel device's in-simulator helper is spawned and found. Injectable for the same reason. */
43
+ guestHelperNative?: GuestHelperNative;
44
+ /** How long a fold may take to light its panel before it counts as failed. Injectable so a suite does not
45
+ * wait the real 10 s on the path where it never does. */
46
+ foldSettleMs?: number;
47
+ /** How often a multi-panel device's lit panel is read while a session is on it, to follow a fold made
48
+ * outside tapflow (DeviceHub). Injectable for the same reason. */
49
+ panelPollMs?: number;
50
+ /** The same, once nothing has moved for `panelQuietMs`. Injectable for the same reason. */
51
+ panelIdlePollMs?: number;
52
+ panelQuietMs?: number;
53
+ /** How long a boot waits for a multi-panel device's helper to be ready. Injectable for the same reason. */
54
+ helperBootReadyMs?: number;
34
55
  }
35
- export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
56
+ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability, PosturableAgent {
36
57
  private readonly simctl;
37
58
  private readonly network;
38
59
  private readonly fps;
@@ -96,6 +117,24 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
96
117
  */
97
118
  private readonly ownedDevices;
98
119
  private lastBundleIds;
120
+ private multiPanelDevices;
121
+ private deviceTypeIds;
122
+ private readonly guests;
123
+ private readonly guestScreens;
124
+ private readonly panelState;
125
+ private readonly physical;
126
+ private readonly typePanels;
127
+ private readonly guestHelperNative;
128
+ private readonly foldSettleMs;
129
+ private readonly panelPollMs;
130
+ private readonly panelIdlePollMs;
131
+ private readonly panelQuietMs;
132
+ private readonly helperBootReadyMs;
133
+ private readonly panelPolls;
134
+ private readonly panelActivity;
135
+ private readonly panelRechecks;
136
+ private readonly posturing;
137
+ private readonly reportedPosture;
99
138
  private readonly uiTreeReader;
100
139
  private readonly sleepBlocker;
101
140
  /** What the next "relay disconnected" line reports: when the relay last pinged, and the socket's last error. */
@@ -108,6 +147,7 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
108
147
  * falling back to nothing would blank a form factor it already had until the next reconnect. */
109
148
  private formFactors;
110
149
  private resourcesTimer;
150
+ private resourcesInFlight;
111
151
  private readonly resources;
112
152
  private _stopping;
113
153
  private _reconnectTimer;
@@ -128,6 +168,9 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
128
168
  disconnect(): void;
129
169
  /** `loss` is absent when a reconnect attempt failed: there is no close to describe, only a retry. */
130
170
  private _scheduleReconnect;
171
+ /** Samples off the event loop, then reports. One sample at a time per socket, so a slow one (bounded by its
172
+ * 1 s timeout) is not stacked by the next tick; keyed by socket, so a reconnect is not skipped behind the
173
+ * old socket's sample. Slots and the clock are read after the sample, when the report leaves. */
131
174
  private reportResources;
132
175
  private cleanupDeviceState;
133
176
  private stopAudioCapture;
@@ -197,6 +240,85 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
197
240
  */
198
241
  private clearPasteboardQueued;
199
242
  private ensureTouchHelper;
243
+ /**
244
+ * **The one place a device's input path is chosen** (see `InputChannel`). A device with more than one
245
+ * integrated panel gets `FoldableInput` over its in-simulator helper; every other device gets the Indigo
246
+ * `TouchHelper` it always had. A multi-panel device is never given a `TouchHelper`: its writes would
247
+ * answer success and land on a dark panel or nowhere.
248
+ */
249
+ private createInputChannel;
250
+ private ensureGuest;
251
+ /** The lit panel of a multi-panel device, from the last devicectl reading and this boot's panels. */
252
+ private litPanel;
253
+ /**
254
+ * How far the viewer turns a multi-panel device (`ChromeData.streamRotation`): the way it is held, plus the
255
+ * lit panel's own native turn — the Duo's unfolded panel is drawn turned 270, so a device held upright
256
+ * shows it turned 90 (measured: portrait → rot90 … landscapeLeft → rot0). Undefined for a single-panel
257
+ * device, and until both the orientation and the lit panel have been read.
258
+ */
259
+ private chromeRotation;
260
+ /** The cached frame with this send's turn and scale — never written into the loader's shared object. */
261
+ private forViewer;
262
+ /** The lit panel's frame for `DeviceChromeLoader`, or undefined for a single-panel device or an unknown panel. */
263
+ private chromePanel;
264
+ /** Point every stream of this device at its lit panel, and give its viewers that panel's frame. */
265
+ private applyLitPanel;
266
+ /**
267
+ * Load the lit panel's frame and send it as `session:chrome` to every session on this device whose frame
268
+ * it is not already. `session:chrome` is re-sendable by contract (protocol `InputPosture`), and the relay
269
+ * caches the last one for a re-joining viewer.
270
+ */
271
+ private resendChrome;
272
+ /** The display UUID of the panel a multi-panel device is showing, or null if not known yet. */
273
+ private litScreen;
274
+ /**
275
+ * Follow a fold made outside tapflow (DeviceHub's picker) while a session is on the device: read the lit
276
+ * panel, re-point the capture and the frame, and report the posture if it moved. Skipped while tapflow's own
277
+ * fold is in flight, which reports for itself.
278
+ */
279
+ private startPanelPoll;
280
+ private schedulePanelPoll;
281
+ /** The device's panel or orientation is moving, or about to: the poll goes back to its fast rate now, not
282
+ * after the slow wait already scheduled. */
283
+ private panelMoved;
284
+ private followPanel;
285
+ /** The device's teardown: shut down, erased, or the agent leaving. Not a relay reconnect — see `guests`. */
286
+ private stopGuest;
287
+ listPostures(deviceId: string): Promise<DevicePosture[]>;
288
+ getPosture(deviceId: string): Promise<DevicePosture | null>;
289
+ setPosture(deviceId: string, postureId: string): Promise<void>;
290
+ /**
291
+ * Turn a multi-panel device the way it is held, through the helper (Purple and `devicectl orientation set`
292
+ * do nothing on the Duo — measured). From the orientation read back now, never one remembered: a quarter
293
+ * turn `direction`, or an older viewer's `target` — where either landscape meets landscape, so asking for
294
+ * it never flips one into the other, and portrait means upright. Then waits for devicectl to say so, which
295
+ * is what the re-sent chrome reports; a turn that does not land is logged and the chrome says where the
296
+ * device really is.
297
+ */
298
+ private turnHeld;
299
+ /**
300
+ * Where a single-panel device is held: read (devicectl on Xcode 27, the guest helper before — see
301
+ * `defaultPhysicalOrientationNative`), else the last known — the last reading, or what tapflow last set on a
302
+ * host where neither source answers. Read every time, never marked unreadable: one failure right after a
303
+ * boot would otherwise have left the device on memory for the life of the agent (review finding).
304
+ */
305
+ private heldSingle;
306
+ /** Turn a device nobody can say the orientation of upright, so there is one to turn from. */
307
+ private standUp;
308
+ /**
309
+ * Turn a single-panel device, through Purple: a quarter turn `direction` from where it is held, or an older
310
+ * viewer's `target`. **That viewer draws landscape as 270**, so `landscape` means exactly `landscapeLeft` —
311
+ * the other landscape would show it upside down — and is met only there; `portrait` means upright. A device
312
+ * whose orientation cannot be read or remembered (an agent restarted under it) is stood up first.
313
+ */
314
+ private turnSingle;
315
+ /** Re-send the frame each session on this device already has, with the turn it is held at now. */
316
+ private resendTurn;
317
+ /** `closed` while the cover is lit, `open` while the unfolded panel is. */
318
+ private postureOf;
319
+ /** Tell the viewer which postures exist and which one the device is in — read from the device, so a fold
320
+ * made outside tapflow shows too. Sent at boot, after a change (failed or not), and on the helper dying. */
321
+ private sendPostures;
200
322
  private readonly clipboardQueue;
201
323
  private readonly parkedSentinels;
202
324
  private markSentinel;
@@ -316,7 +438,7 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
316
438
  */
317
439
  setNetworkOffline(offline: boolean): Promise<NetworkStatePayload>;
318
440
  networkState(): Promise<NetworkStatePayload>;
319
- launchApp(bundleId: string): Promise<void>;
441
+ launchApp(bundleId: string, options?: LaunchOptions): Promise<void>;
320
442
  /** The one booted session, or undefined when there is no unambiguous answer. Callers that can
321
443
  * reasonably do nothing (input) use this; callers that owe the user a result use
322
444
  * `soleDeviceState`, which throws instead. */
@@ -367,7 +489,7 @@ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
367
489
  private audioEnabled;
368
490
  private startAudioCapture;
369
491
  private launchWholeSimTap;
370
- private refreshAudioPids;
492
+ private refreshAudio;
371
493
  private pumpAudio;
372
494
  screenshot(): Promise<Buffer>;
373
495
  stream(): ReadableStream<Buffer>;