@namzu/sandbox 11.0.0 → 12.0.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 (44) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +47 -7
  3. package/dist/backends/aci-standby-pool/index.d.ts.map +1 -1
  4. package/dist/backends/aci-standby-pool/index.js +3 -1
  5. package/dist/backends/aci-standby-pool/index.js.map +1 -1
  6. package/dist/backends/docker/index.d.ts.map +1 -1
  7. package/dist/backends/docker/index.js +3 -1
  8. package/dist/backends/docker/index.js.map +1 -1
  9. package/dist/backends/firecracker/index.d.ts +15 -14
  10. package/dist/backends/firecracker/index.d.ts.map +1 -1
  11. package/dist/backends/firecracker/index.js +36 -28
  12. package/dist/backends/firecracker/index.js.map +1 -1
  13. package/dist/backends/firecracker/protocol.d.ts +58 -0
  14. package/dist/backends/firecracker/protocol.d.ts.map +1 -1
  15. package/dist/backends/firecracker/protocol.js.map +1 -1
  16. package/dist/backends/firecracker/transport.d.ts +23 -3
  17. package/dist/backends/firecracker/transport.d.ts.map +1 -1
  18. package/dist/backends/firecracker/transport.js +305 -5
  19. package/dist/backends/firecracker/transport.js.map +1 -1
  20. package/dist/backends/http-worker-client.d.ts +3 -7
  21. package/dist/backends/http-worker-client.d.ts.map +1 -1
  22. package/dist/backends/http-worker-client.js +5 -9
  23. package/dist/backends/http-worker-client.js.map +1 -1
  24. package/dist/backends/readiness.d.ts.map +1 -1
  25. package/dist/backends/readiness.js +27 -6
  26. package/dist/backends/readiness.js.map +1 -1
  27. package/dist/backends/remote-execution-controller.d.ts +7 -10
  28. package/dist/backends/remote-execution-controller.d.ts.map +1 -1
  29. package/dist/backends/remote-execution-controller.js +7 -33
  30. package/dist/backends/remote-execution-controller.js.map +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/backends/aci-standby-pool/index.ts +5 -1
  37. package/src/backends/docker/index.ts +5 -1
  38. package/src/backends/firecracker/index.ts +52 -34
  39. package/src/backends/firecracker/protocol.ts +51 -0
  40. package/src/backends/firecracker/transport.ts +339 -8
  41. package/src/backends/http-worker-client.ts +5 -10
  42. package/src/backends/readiness.ts +38 -6
  43. package/src/backends/remote-execution-controller.ts +9 -55
  44. package/src/index.ts +1 -0
@@ -74,6 +74,64 @@ export interface ReadFileRequest {
74
74
  readonly path: string;
75
75
  readonly encoding: 'base64';
76
76
  }
77
+ /** Initial request for one interactive terminal process in the guest. */
78
+ export interface TerminalOpenRequest {
79
+ readonly command?: string;
80
+ readonly args?: readonly string[];
81
+ readonly cwd?: string;
82
+ readonly env?: Record<string, string>;
83
+ readonly cols: number;
84
+ readonly rows: number;
85
+ }
86
+ /** Host → guest messages after the terminal stream reports ready. */
87
+ export type TerminalInputEvent = {
88
+ readonly type: 'input';
89
+ readonly data: string;
90
+ } | {
91
+ readonly type: 'resize';
92
+ readonly cols: number;
93
+ readonly rows: number;
94
+ } | {
95
+ readonly type: 'kill';
96
+ readonly signal?: string;
97
+ };
98
+ /** Guest → host events carried for the lifetime of the terminal stream. */
99
+ export type TerminalOutputEvent = {
100
+ readonly type: 'ready';
101
+ } | {
102
+ readonly type: 'data';
103
+ readonly data: string;
104
+ } | {
105
+ readonly type: 'exit';
106
+ readonly exitCode: number;
107
+ readonly signal?: number;
108
+ } | {
109
+ readonly type: 'error';
110
+ readonly error: string;
111
+ };
112
+ export interface TcpConnectRequest {
113
+ readonly host: '127.0.0.1' | '::1';
114
+ readonly port: number;
115
+ }
116
+ export type TcpInputEvent = {
117
+ readonly type: 'data';
118
+ readonly data: string;
119
+ } | {
120
+ readonly type: 'end';
121
+ } | {
122
+ readonly type: 'destroy';
123
+ };
124
+ export type TcpOutputEvent = {
125
+ readonly type: 'ready';
126
+ } | {
127
+ readonly type: 'data';
128
+ readonly data: string;
129
+ } | {
130
+ readonly type: 'end';
131
+ } | {
132
+ readonly type: 'error';
133
+ readonly error: string;
134
+ };
77
135
  /** `/read-file` response. `content` is base64 on success. */
78
136
  export interface ReadFileResponse {
79
137
  readonly ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
@@ -52,8 +52,8 @@
52
52
  * socket to be silently severed by a resume), which makes the
53
53
  * transport resume-survivable by construction.
54
54
  */
55
- import type { SandboxExecOptions, SandboxExecResult } from '@namzu/sdk';
56
- import { type ExecRequest, type ReadFileRequest, type WriteFileRequest } from './protocol.js';
55
+ import type { OpenTerminalOptions, SandboxExecOptions, SandboxExecResult, SandboxTcpConnectOptions, SandboxTcpConnection, TerminalSession } from '@namzu/sdk';
56
+ import { type ExecRequest, type ReadFileRequest, type TcpConnectRequest, type TerminalOpenRequest, type WriteFileRequest } from './protocol.js';
57
57
  /**
58
58
  * An addressable agent endpoint. The orchestrator hands one of these
59
59
  * back per sandbox (`create()` response → `vsock endpoint`).
@@ -153,6 +153,12 @@ export type AgentRequest = {
153
153
  } | {
154
154
  readonly op: 'write-file';
155
155
  readonly body: WriteFileRequest;
156
+ } | {
157
+ readonly op: 'terminal';
158
+ readonly body: TerminalOpenRequest;
159
+ } | {
160
+ readonly op: 'tcp-connect';
161
+ readonly body: TcpConnectRequest;
156
162
  } | {
157
163
  readonly op: 'healthz';
158
164
  };
@@ -172,6 +178,8 @@ export interface VsockTransportOptions {
172
178
  */
173
179
  readonly readIdleTimeoutMs?: number;
174
180
  }
181
+ /** Exact guest wire version accepted by this Firecracker transport. */
182
+ export declare const FIRECRACKER_AGENT_PROTOCOL_VERSION: 2;
175
183
  declare function frame(payload: string): Buffer;
176
184
  /**
177
185
  * Incremental frame reader. Feed it socket chunks; it yields complete
@@ -250,7 +258,7 @@ export declare class VsockAgentTransport {
250
258
  exec(command: string, argv?: string[], opts?: SandboxExecOptions): Promise<SandboxExecResult>;
251
259
  private reserveExecution;
252
260
  private cancelExecution;
253
- /** Liveness probe. Returns true on an `{ ok: true }` healthz reply. */
261
+ /** Readiness probe. A healthy guest must also speak the exact host protocol. */
254
262
  healthz(signal?: AbortSignal): Promise<boolean>;
255
263
  /**
256
264
  * Poll the agent until a healthz succeeds or the timeout elapses.
@@ -261,6 +269,18 @@ export declare class VsockAgentTransport {
261
269
  waitForReady(timeoutMs: number, pollIntervalMs: number, signal?: AbortSignal): Promise<void>;
262
270
  writeFile(path: string, content: Buffer): Promise<void>;
263
271
  readFile(path: string): Promise<Buffer>;
272
+ /**
273
+ * Open a real PTY owned by the in-VM agent.
274
+ *
275
+ * Unlike `execute`, this keeps one framed connection open for the complete
276
+ * interactive lifetime: guest output and exit events flow toward the host,
277
+ * while input/resize/kill events flow back on the same ordered stream. The
278
+ * browser never reaches this transport directly; the runtime gateway owns
279
+ * the session and its authenticated WebSocket attachment.
280
+ */
281
+ openTerminal(options: OpenTerminalOptions): Promise<TerminalSession>;
282
+ /** Open one TCP stream to a service listening on guest loopback. */
283
+ openTcpConnection(options: SandboxTcpConnectOptions): Promise<SandboxTcpConnection>;
264
284
  }
265
285
  export declare const __framing: {
266
286
  frame: typeof frame;
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/transport.ts"],"names":[],"mappings":"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"}
@@ -55,7 +55,7 @@
55
55
  import net from 'node:net';
56
56
  import tls from 'node:tls';
57
57
  import { OperationDeadline, OperationDeadlineExpired } from '../readiness.js';
58
- import { RemoteCancellationUnknownError, RemoteCancellationUnsupportedError, RemoteExecutionController, RemoteProtocolError, } from '../remote-execution-controller.js';
58
+ import { REMOTE_EXECUTION_PROTOCOL_VERSION, RemoteCancellationUnknownError, RemoteExecutionController, RemoteProtocolError, } from '../remote-execution-controller.js';
59
59
  import { ExecResultAccumulator, parseExecLine, } from './protocol.js';
60
60
  const DEFAULT_CONNECT_TIMEOUT_MS = 5_000;
61
61
  const DEFAULT_CONNECT_RETRY_BUDGET_MS = 30_000;
@@ -69,6 +69,8 @@ const DEFAULT_EXECUTION_TIMEOUT_MS = 5 * 60_000;
69
69
  const EXECUTION_TRANSPORT_GRACE_MS = 10_000;
70
70
  const POST_RESPONSE_CLOSE_TIMEOUT_MS = 1_000;
71
71
  const MAX_TIMER_DELAY_MS = 2_147_483_647;
72
+ /** Exact guest wire version accepted by this Firecracker transport. */
73
+ export const FIRECRACKER_AGENT_PROTOCOL_VERSION = REMOTE_EXECUTION_PROTOCOL_VERSION;
72
74
  /** Framing: 8 hex digits of payload byte length, then `\n`, then payload. */
73
75
  const LENGTH_PREFIX_HEX = 8;
74
76
  function frame(payload) {
@@ -530,7 +532,7 @@ export class VsockAgentTransport {
530
532
  if (response.ok === false &&
531
533
  typeof response.error === 'string' &&
532
534
  response.error.startsWith('unknown_op:')) {
533
- throw new RemoteCancellationUnsupportedError('This microVM agent does not support the execution-cancellation lease protocol. Rebuild the guest image before passing SandboxExecOptions.signal; refusing rather than pretending cancellation is active.');
535
+ throw new RemoteProtocolError(`The microVM guest does not implement Firecracker agent protocol ${FIRECRACKER_AGENT_PROTOCOL_VERSION}. Rebuild the golden image from the same Namzu release before admitting commands.`);
534
536
  }
535
537
  if (response.ok === false && response.error === 'agent_retiring') {
536
538
  throw new RemoteCancellationUnknownError('The microVM agent has fenced itself because an earlier process-group shutdown could not be confirmed; the sandbox must be retired.');
@@ -540,15 +542,23 @@ export class VsockAgentTransport {
540
542
  async cancelExecution(executionId, signal) {
541
543
  return await this.request({ op: 'cancel-execution', body: { executionId } }, signal);
542
544
  }
543
- /** Liveness probe. Returns true on an `{ ok: true }` healthz reply. */
545
+ /** Readiness probe. A healthy guest must also speak the exact host protocol. */
544
546
  async healthz(signal) {
545
547
  try {
546
548
  const res = await this.request({ op: 'healthz' }, signal);
547
- return res.ok === true;
549
+ if (res.ok !== true)
550
+ return false;
551
+ if (res.protocolVersion !== FIRECRACKER_AGENT_PROTOCOL_VERSION) {
552
+ const actual = res.protocolVersion === undefined ? 'missing' : JSON.stringify(res.protocolVersion);
553
+ throw new RemoteProtocolError(`Firecracker guest protocol version mismatch: expected ${FIRECRACKER_AGENT_PROTOCOL_VERSION}, received ${actual}. Rebuild the golden image from the same Namzu release.`);
554
+ }
555
+ return true;
548
556
  }
549
- catch {
557
+ catch (error) {
550
558
  if (signal?.aborted)
551
559
  throw signal.reason;
560
+ if (error instanceof RemoteProtocolError)
561
+ throw error;
552
562
  return false;
553
563
  }
554
564
  }
@@ -569,6 +579,8 @@ export class VsockAgentTransport {
569
579
  }
570
580
  catch (err) {
571
581
  lastErr = err;
582
+ if (err instanceof RemoteProtocolError)
583
+ throw err;
572
584
  if (err instanceof OperationDeadlineExpired)
573
585
  break;
574
586
  }
@@ -602,6 +614,294 @@ export class VsockAgentTransport {
602
614
  }
603
615
  return Buffer.from(res.content, 'base64');
604
616
  }
617
+ /**
618
+ * Open a real PTY owned by the in-VM agent.
619
+ *
620
+ * Unlike `execute`, this keeps one framed connection open for the complete
621
+ * interactive lifetime: guest output and exit events flow toward the host,
622
+ * while input/resize/kill events flow back on the same ordered stream. The
623
+ * browser never reaches this transport directly; the runtime gateway owns
624
+ * the session and its authenticated WebSocket attachment.
625
+ */
626
+ async openTerminal(options) {
627
+ const socket = await this.dial();
628
+ const request = {
629
+ ...(options.command !== undefined ? { command: options.command } : {}),
630
+ ...(options.args !== undefined ? { args: options.args } : {}),
631
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
632
+ ...(options.env !== undefined ? { env: { ...options.env } } : {}),
633
+ cols: options.size.cols,
634
+ rows: options.size.rows,
635
+ };
636
+ return await new Promise((resolve, reject) => {
637
+ const KILL_GRACE_MS = 5_000;
638
+ const reader = new FrameReader();
639
+ const listeners = new Set();
640
+ const buffered = [];
641
+ let bufferedBytes = 0;
642
+ let ready = false;
643
+ let settled = false;
644
+ let killTimer;
645
+ let resolveExit;
646
+ const exited = new Promise((done) => {
647
+ resolveExit = done;
648
+ });
649
+ const idle = new IdleTimer(this.readIdleTimeoutMs, () => {
650
+ finish(new Error(`vsock transport: terminal read idle timeout after ${this.readIdleTimeoutMs}ms`));
651
+ });
652
+ const finish = (error, exit = { exitCode: -1 }) => {
653
+ if (settled)
654
+ return;
655
+ settled = true;
656
+ idle.clear();
657
+ if (killTimer)
658
+ clearTimeout(killTimer);
659
+ socket.destroy();
660
+ listeners.clear();
661
+ resolveExit(exit);
662
+ if (!ready)
663
+ reject(error ?? new Error('terminal exited before readiness'));
664
+ };
665
+ const send = (event) => {
666
+ if (settled)
667
+ return;
668
+ socket.write(frame(JSON.stringify(event)));
669
+ };
670
+ const session = {
671
+ write(data) {
672
+ send({ type: 'input', data });
673
+ },
674
+ resize(size) {
675
+ send({ type: 'resize', cols: size.cols, rows: size.rows });
676
+ },
677
+ onData(listener) {
678
+ listeners.add(listener);
679
+ if (buffered.length > 0) {
680
+ const pending = buffered.splice(0);
681
+ bufferedBytes = 0;
682
+ queueMicrotask(() => {
683
+ if (!listeners.has(listener))
684
+ return;
685
+ for (const chunk of pending)
686
+ listener(chunk);
687
+ });
688
+ }
689
+ return () => listeners.delete(listener);
690
+ },
691
+ exited,
692
+ kill(signal) {
693
+ send({ type: 'kill', ...(signal !== undefined ? { signal } : {}) });
694
+ // A wedged guest must not pin sandbox.destroy() forever. The normal
695
+ // path reports the real exit; the deadline only severs an
696
+ // unresponsive transport so the owning microVM can be reclaimed.
697
+ if (!settled && !killTimer) {
698
+ killTimer = setTimeout(() => finish(null), KILL_GRACE_MS);
699
+ killTimer.unref?.();
700
+ }
701
+ },
702
+ };
703
+ socket.on('data', (chunk) => {
704
+ if (!ready)
705
+ idle.bump();
706
+ let payloads;
707
+ try {
708
+ payloads = reader.push(chunk);
709
+ }
710
+ catch (err) {
711
+ finish(err instanceof Error ? err : new Error(String(err)));
712
+ return;
713
+ }
714
+ for (const payload of payloads) {
715
+ let event;
716
+ try {
717
+ event = JSON.parse(payload);
718
+ }
719
+ catch (err) {
720
+ finish(err instanceof Error ? err : new Error(String(err)));
721
+ return;
722
+ }
723
+ if (event.type === 'ready') {
724
+ if (!ready) {
725
+ ready = true;
726
+ // Once ready, an interactive shell may legitimately sit silent
727
+ // for hours. Runtime/session TTL owns idle cleanup; a transport
728
+ // read timer would incorrectly kill a healthy quiet terminal.
729
+ idle.clear();
730
+ resolve(session);
731
+ }
732
+ continue;
733
+ }
734
+ if (event.type === 'data') {
735
+ if (listeners.size === 0) {
736
+ buffered.push(event.data);
737
+ bufferedBytes += Buffer.byteLength(event.data);
738
+ while (bufferedBytes > 1024 * 1024 && buffered.length > 1) {
739
+ bufferedBytes -= Buffer.byteLength(buffered.shift() ?? '');
740
+ }
741
+ }
742
+ else {
743
+ for (const listener of listeners)
744
+ listener(event.data);
745
+ }
746
+ continue;
747
+ }
748
+ if (event.type === 'exit') {
749
+ finish(null, {
750
+ exitCode: event.exitCode,
751
+ ...(event.signal !== undefined ? { signal: event.signal } : {}),
752
+ });
753
+ return;
754
+ }
755
+ finish(new Error(event.error));
756
+ return;
757
+ }
758
+ });
759
+ socket.once('error', (err) => finish(err));
760
+ socket.once('close', () => finish(new Error('vsock transport: terminal socket closed before exit')));
761
+ idle.bump();
762
+ socket.write(frame(JSON.stringify({
763
+ op: 'terminal',
764
+ body: request,
765
+ })));
766
+ });
767
+ }
768
+ /** Open one TCP stream to a service listening on guest loopback. */
769
+ async openTcpConnection(options) {
770
+ if (!Number.isInteger(options.port) || options.port < 1 || options.port > 65_535) {
771
+ throw new Error('tcp connection port must be an integer in [1, 65535]');
772
+ }
773
+ const host = options.host ?? '127.0.0.1';
774
+ if (host !== '127.0.0.1' && host !== '::1') {
775
+ throw new Error('firecracker TCP connections are restricted to guest loopback');
776
+ }
777
+ const socket = await this.dial();
778
+ const request = { host, port: options.port };
779
+ return await new Promise((resolve, reject) => {
780
+ const reader = new FrameReader();
781
+ const listeners = new Set();
782
+ const buffered = [];
783
+ let bufferedBytes = 0;
784
+ let ready = false;
785
+ let settled = false;
786
+ let resolveClosed;
787
+ const closed = new Promise((done) => {
788
+ resolveClosed = done;
789
+ });
790
+ const idle = new IdleTimer(this.readIdleTimeoutMs, () => {
791
+ finish(new Error(`vsock transport: TCP connect idle timeout after ${this.readIdleTimeoutMs}ms`));
792
+ });
793
+ const finish = (error) => {
794
+ if (settled)
795
+ return;
796
+ settled = true;
797
+ idle.clear();
798
+ socket.destroy();
799
+ listeners.clear();
800
+ resolveClosed();
801
+ if (!ready)
802
+ reject(error ?? new Error('TCP stream closed before readiness'));
803
+ };
804
+ const send = (event) => {
805
+ return !settled && socket.write(frame(JSON.stringify(event)));
806
+ };
807
+ const connection = {
808
+ write(data) {
809
+ const bytes = typeof data === 'string' ? Buffer.from(data) : Buffer.from(data);
810
+ return send({ type: 'data', data: bytes.toString('base64') });
811
+ },
812
+ end() {
813
+ send({ type: 'end' });
814
+ },
815
+ destroy() {
816
+ send({ type: 'destroy' });
817
+ finish(null);
818
+ },
819
+ pause() {
820
+ socket.pause();
821
+ },
822
+ resume() {
823
+ if (!settled)
824
+ socket.resume();
825
+ },
826
+ onData(listener) {
827
+ listeners.add(listener);
828
+ if (buffered.length > 0) {
829
+ const pending = buffered.splice(0);
830
+ bufferedBytes = 0;
831
+ queueMicrotask(() => {
832
+ if (!listeners.has(listener))
833
+ return;
834
+ for (const chunk of pending)
835
+ listener(chunk);
836
+ });
837
+ }
838
+ return () => listeners.delete(listener);
839
+ },
840
+ onDrain(listener) {
841
+ socket.on('drain', listener);
842
+ return () => socket.off('drain', listener);
843
+ },
844
+ closed,
845
+ };
846
+ socket.on('data', (chunk) => {
847
+ if (!ready)
848
+ idle.bump();
849
+ let payloads;
850
+ try {
851
+ payloads = reader.push(chunk);
852
+ }
853
+ catch (error) {
854
+ finish(error instanceof Error ? error : new Error(String(error)));
855
+ return;
856
+ }
857
+ for (const payload of payloads) {
858
+ let event;
859
+ try {
860
+ event = JSON.parse(payload);
861
+ }
862
+ catch (error) {
863
+ finish(error instanceof Error ? error : new Error(String(error)));
864
+ return;
865
+ }
866
+ if (event.type === 'ready') {
867
+ if (!ready) {
868
+ ready = true;
869
+ idle.clear();
870
+ resolve(connection);
871
+ }
872
+ continue;
873
+ }
874
+ if (event.type === 'data') {
875
+ const bytes = Buffer.from(event.data, 'base64');
876
+ if (listeners.size === 0) {
877
+ buffered.push(bytes);
878
+ bufferedBytes += bytes.byteLength;
879
+ while (bufferedBytes > 1024 * 1024 && buffered.length > 1) {
880
+ bufferedBytes -= buffered.shift()?.byteLength ?? 0;
881
+ }
882
+ }
883
+ else {
884
+ for (const listener of listeners)
885
+ listener(bytes);
886
+ }
887
+ continue;
888
+ }
889
+ if (event.type === 'end') {
890
+ finish(null);
891
+ continue;
892
+ }
893
+ finish(new Error(event.error));
894
+ }
895
+ });
896
+ socket.once('error', (error) => finish(error));
897
+ socket.once('close', () => finish(ready ? null : new Error('vsock TCP socket closed before readiness')));
898
+ idle.bump();
899
+ socket.write(frame(JSON.stringify({
900
+ op: 'tcp-connect',
901
+ body: request,
902
+ })));
903
+ });
904
+ }
605
905
  }
606
906
  // ---------------------------------------------------------------------------
607
907
  // Small helpers