@dxos/client-services 0.1.23 → 0.1.24

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 (115) hide show
  1. package/dist/lib/browser/chunk-R2FEBB66.mjs +3865 -0
  2. package/dist/lib/browser/chunk-R2FEBB66.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +56 -3066
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/packlets/testing/index.mjs +198 -0
  7. package/dist/lib/browser/packlets/testing/index.mjs.map +7 -0
  8. package/dist/lib/node/index.cjs +1401 -645
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/packlets/testing/index.cjs +3688 -0
  12. package/dist/lib/node/packlets/testing/index.cjs.map +7 -0
  13. package/dist/types/src/packlets/deprecated/profile.d.ts +3 -1
  14. package/dist/types/src/packlets/deprecated/profile.d.ts.map +1 -1
  15. package/dist/types/src/packlets/deprecated/space.d.ts.map +1 -1
  16. package/dist/types/src/packlets/deprecated/system.d.ts +15 -9
  17. package/dist/types/src/packlets/deprecated/system.d.ts.map +1 -1
  18. package/dist/types/src/packlets/devtools/devtools.d.ts +2 -2
  19. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  20. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  21. package/dist/types/src/packlets/devtools/network.d.ts +3 -3
  22. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  23. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  24. package/dist/types/src/packlets/identity/authenticator.d.ts +1 -1
  25. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  26. package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -1
  27. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  28. package/dist/types/src/packlets/identity/identity.d.ts +1 -0
  29. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  30. package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts +11 -3
  31. package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts.map +1 -1
  32. package/dist/types/src/packlets/invitations/invitations.d.ts +1 -1
  33. package/dist/types/src/packlets/invitations/invitations.d.ts.map +1 -1
  34. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
  35. package/dist/types/src/packlets/services/service-context.d.ts +2 -0
  36. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  37. package/dist/types/src/packlets/services/service-context.test.d.ts +2 -0
  38. package/dist/types/src/packlets/services/service-context.test.d.ts.map +1 -0
  39. package/dist/types/src/packlets/services/service-definitions.d.ts +1 -1
  40. package/dist/types/src/packlets/services/service-definitions.d.ts.map +1 -1
  41. package/dist/types/src/packlets/services/service-host.d.ts +9 -6
  42. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  43. package/dist/types/src/packlets/services/service-registry.d.ts +4 -3
  44. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  45. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +9 -2
  46. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  47. package/dist/types/src/packlets/spaces/data-space.d.ts +18 -4
  48. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  49. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +50 -0
  50. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -0
  51. package/dist/types/src/packlets/spaces/notarization-plugin.test.d.ts +2 -0
  52. package/dist/types/src/packlets/spaces/notarization-plugin.test.d.ts.map +1 -0
  53. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -1
  54. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  55. package/dist/types/src/packlets/testing/credential-utils.d.ts +8 -0
  56. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -0
  57. package/dist/types/src/packlets/testing/index.d.ts +2 -0
  58. package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
  59. package/dist/types/src/packlets/testing/invitation-utils.d.ts +3 -0
  60. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -0
  61. package/dist/types/src/packlets/testing/test-builder.d.ts +2 -2
  62. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  63. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +28 -0
  64. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -0
  65. package/dist/types/src/packlets/vault/{iframe-runtime.d.ts → iframe-proxy-runtime.d.ts} +4 -4
  66. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -0
  67. package/dist/types/src/packlets/vault/index.d.ts +4 -1
  68. package/dist/types/src/packlets/vault/index.d.ts.map +1 -1
  69. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +19 -0
  70. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -0
  71. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  72. package/dist/types/src/packlets/vault/worker-session.d.ts +4 -4
  73. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  74. package/package.json +29 -29
  75. package/src/packlets/deprecated/profile.ts +20 -2
  76. package/src/packlets/deprecated/space.ts +41 -37
  77. package/src/packlets/deprecated/system.ts +26 -13
  78. package/src/packlets/devtools/devtools.ts +4 -4
  79. package/src/packlets/devtools/feeds.ts +11 -6
  80. package/src/packlets/devtools/network.ts +20 -9
  81. package/src/packlets/devtools/spaces.ts +7 -6
  82. package/src/packlets/identity/authenticator.ts +11 -6
  83. package/src/packlets/identity/identity-manager.test.ts +24 -15
  84. package/src/packlets/identity/identity-manager.ts +22 -8
  85. package/src/packlets/identity/identity.test.ts +21 -22
  86. package/src/packlets/identity/identity.ts +10 -5
  87. package/src/packlets/invitations/halo-invitations-handler.test.ts +4 -45
  88. package/src/packlets/invitations/halo-invitations-handler.ts +33 -17
  89. package/src/packlets/invitations/invitations.ts +2 -1
  90. package/src/packlets/invitations/space-invitations-handler.test.ts +43 -26
  91. package/src/packlets/invitations/space-invitations-handler.ts +8 -11
  92. package/src/packlets/services/service-context.test.ts +56 -0
  93. package/src/packlets/services/service-context.ts +60 -4
  94. package/src/packlets/services/service-definitions.ts +1 -1
  95. package/src/packlets/services/service-host.test.ts +74 -5
  96. package/src/packlets/services/service-host.ts +85 -23
  97. package/src/packlets/services/service-registry.test.ts +2 -1
  98. package/src/packlets/services/service-registry.ts +5 -1
  99. package/src/packlets/spaces/data-space-manager.test.ts +71 -14
  100. package/src/packlets/spaces/data-space-manager.ts +49 -8
  101. package/src/packlets/spaces/data-space.ts +113 -14
  102. package/src/packlets/spaces/notarization-plugin.test.ts +81 -0
  103. package/src/packlets/spaces/notarization-plugin.ts +211 -0
  104. package/src/packlets/spaces/spaces-service.ts +9 -1
  105. package/src/packlets/testing/credential-utils.ts +28 -0
  106. package/src/packlets/testing/index.ts +2 -0
  107. package/src/packlets/testing/invitation-utils.ts +44 -0
  108. package/src/packlets/testing/test-builder.ts +14 -18
  109. package/src/packlets/vault/iframe-host-runtime.ts +112 -0
  110. package/src/packlets/vault/{iframe-runtime.ts → iframe-proxy-runtime.ts} +3 -3
  111. package/src/packlets/vault/index.ts +4 -1
  112. package/src/packlets/vault/vault-resource-lock.ts +76 -0
  113. package/src/packlets/vault/worker-runtime.ts +13 -3
  114. package/src/packlets/vault/worker-session.ts +17 -17
  115. package/dist/types/src/packlets/vault/iframe-runtime.d.ts.map +0 -1
@@ -0,0 +1,112 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Trigger } from '@dxos/async';
6
+ import { Config } from '@dxos/config';
7
+ import { log, logInfo } from '@dxos/log';
8
+ import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
9
+ import { createWebRTCTransportFactory, NetworkManager } from '@dxos/network-manager';
10
+ import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
11
+ import { MaybePromise } from '@dxos/util';
12
+
13
+ import { clientServiceBundle, ClientServices, ClientServicesHost } from '../services';
14
+
15
+ const LOCK_KEY = 'DXOS_RESOURCE_LOCK';
16
+
17
+ export type IFrameHostRuntimeParams = {
18
+ configProvider: () => MaybePromise<Config>;
19
+ appPort: RpcPort;
20
+ };
21
+
22
+ /**
23
+ * Runs the client services in the main thread.
24
+ *
25
+ * Holds a lock over the client services such that only one instance can run at a time.
26
+ * This should only be used when SharedWorker is not available.
27
+ */
28
+ export class IFrameHostRuntime {
29
+ private readonly _configProvider: () => MaybePromise<Config>;
30
+ private readonly _transportFactory = createWebRTCTransportFactory();
31
+ private readonly _ready = new Trigger<Error | undefined>();
32
+ private readonly _getService: <Service>(
33
+ find: (services: Partial<ClientServices>) => Service | undefined
34
+ ) => Promise<Service>;
35
+
36
+ private readonly _appPort: RpcPort;
37
+ private _clientServices!: ClientServicesHost;
38
+ private _clientRpc!: ProtoRpcPeer<ClientServices>;
39
+ private _config!: Config;
40
+
41
+ @logInfo
42
+ public origin?: string;
43
+
44
+ constructor({ configProvider, appPort }: IFrameHostRuntimeParams) {
45
+ this._configProvider = configProvider;
46
+ this._appPort = appPort;
47
+ this._getService = async (find) => {
48
+ const error = await this._ready.wait();
49
+ if (error) {
50
+ throw error;
51
+ }
52
+
53
+ const service = await find(this._clientServices.services);
54
+ if (!service) {
55
+ throw new Error('Service not found');
56
+ }
57
+
58
+ return service;
59
+ };
60
+ }
61
+
62
+ async start() {
63
+ log('starting...');
64
+ try {
65
+ this._config = await this._configProvider();
66
+ const signalServer = this._config.get('runtime.services.signal.server');
67
+ this._clientServices = new ClientServicesHost({
68
+ lockKey: LOCK_KEY,
69
+ config: this._config,
70
+ networkManager: new NetworkManager({
71
+ log: true,
72
+ signalManager: signalServer
73
+ ? new WebsocketSignalManager([signalServer])
74
+ : new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
75
+ transportFactory: this._transportFactory
76
+ })
77
+ });
78
+
79
+ this._clientRpc = createProtoRpcPeer({
80
+ exposed: clientServiceBundle,
81
+ handlers: {
82
+ DataService: async () => await this._getService((services) => services.DataService),
83
+ DevicesService: async () => await this._getService((services) => services.DevicesService),
84
+ DevtoolsHost: async () => await this._getService((services) => services.DevtoolsHost),
85
+ HaloInvitationsService: async () => await this._getService((services) => services.HaloInvitationsService),
86
+ NetworkService: async () => await this._getService((services) => services.NetworkService),
87
+ ProfileService: async () => await this._getService((services) => services.ProfileService),
88
+ SpaceInvitationsService: async () => await this._getService((services) => services.SpaceInvitationsService),
89
+ SpaceService: async () => await this._getService((services) => services.SpaceService),
90
+ SpacesService: async () => await this._getService((services) => services.SpacesService),
91
+ SystemService: async () => await this._getService((services) => services.SystemService),
92
+ TracingService: async () => await this._getService((services) => services.TracingService)
93
+ },
94
+ port: this._appPort
95
+ });
96
+
97
+ await Promise.all([this._clientServices.open(), this._clientRpc.open()]);
98
+ this._ready.wake(undefined);
99
+ log('started');
100
+ } catch (err: any) {
101
+ this._ready.wake(err);
102
+ log.catch(err);
103
+ }
104
+ }
105
+
106
+ async stop() {
107
+ log('stopping...');
108
+ await this._clientRpc.close();
109
+ await this._clientServices.close();
110
+ log('stopped');
111
+ }
112
+ }
@@ -9,7 +9,7 @@ import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
9
9
  import { iframeServiceBundle, WorkerServiceBundle, workerServiceBundle } from './services';
10
10
 
11
11
  // NOTE: Keep as RpcPorts to avoid dependency on @dxos/rpc-tunnel so we don't depend on browser-specific apis.
12
- export type IframeRuntimeParams = {
12
+ export type IFrameProxyRuntimeParams = {
13
13
  systemPort: RpcPort;
14
14
  workerAppPort: RpcPort;
15
15
  windowAppPort: RpcPort;
@@ -18,14 +18,14 @@ export type IframeRuntimeParams = {
18
18
  /**
19
19
  * Manages the client connection to the shared worker.
20
20
  */
21
- export class IFrameRuntime {
21
+ export class IFrameProxyRuntime {
22
22
  private readonly _systemPort: RpcPort;
23
23
  private readonly _windowAppPort: RpcPort;
24
24
  private readonly _workerAppPort: RpcPort;
25
25
  private readonly _systemRpc: ProtoRpcPeer<WorkerServiceBundle>;
26
26
  private readonly _transportService = new WebRTCTransportService();
27
27
 
28
- constructor({ systemPort, workerAppPort, windowAppPort }: IframeRuntimeParams) {
28
+ constructor({ systemPort, workerAppPort, windowAppPort }: IFrameProxyRuntimeParams) {
29
29
  this._systemPort = systemPort;
30
30
  this._windowAppPort = windowAppPort;
31
31
  this._workerAppPort = workerAppPort;
@@ -2,6 +2,9 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './iframe-runtime';
5
+ export * from './iframe-host-runtime';
6
+ export * from './iframe-proxy-runtime';
7
+ export * from './services';
8
+ export * from './vault-resource-lock';
6
9
  export * from './worker-runtime';
7
10
  export * from './worker-session';
@@ -0,0 +1,76 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { asyncTimeout, Trigger } from '@dxos/async';
6
+ import { log } from '@dxos/log';
7
+ import { MaybePromise } from '@dxos/util';
8
+
9
+ enum Message {
10
+ ACQUIRING = 'acquiring'
11
+ }
12
+
13
+ export type VaultResourceLockOptions = {
14
+ lockKey: string;
15
+ onAcquire?: () => MaybePromise<void>;
16
+ onRelease?: () => MaybePromise<void>;
17
+ };
18
+
19
+ export class VaultResourceLock {
20
+ private readonly _broadcastChannel = new BroadcastChannel('vault-resource-lock');
21
+ private readonly _lockKey: string;
22
+ private readonly _onAcquire: VaultResourceLockOptions['onAcquire'];
23
+ private readonly _onRelease: VaultResourceLockOptions['onRelease'];
24
+ private _releaseTrigger = new Trigger();
25
+
26
+ constructor({ lockKey, onAcquire, onRelease }: VaultResourceLockOptions) {
27
+ this._lockKey = lockKey;
28
+ this._onAcquire = onAcquire;
29
+ this._onRelease = onRelease;
30
+ this._broadcastChannel.onmessage = this._onMessage.bind(this);
31
+ }
32
+
33
+ async acquire() {
34
+ this._broadcastChannel.postMessage({
35
+ message: Message.ACQUIRING
36
+ });
37
+
38
+ try {
39
+ await asyncTimeout(this._requestLock(), 3_000);
40
+ } catch {
41
+ await this._requestLock(true);
42
+ }
43
+ }
44
+
45
+ async release() {
46
+ this._releaseTrigger.wake();
47
+ }
48
+
49
+ private _onMessage(event: MessageEvent<any>) {
50
+ if (event.data.message === Message.ACQUIRING) {
51
+ this._releaseTrigger.wake();
52
+ }
53
+ }
54
+
55
+ private async _requestLock(steal = false) {
56
+ log('requesting lock...', { steal });
57
+ const acquired = new Trigger();
58
+
59
+ void navigator.locks
60
+ .request(this._lockKey, { steal }, async () => {
61
+ await this._onAcquire?.();
62
+ acquired.wake();
63
+ this._releaseTrigger = new Trigger();
64
+ await this._releaseTrigger.wait();
65
+ log('releasing lock...');
66
+ await this._onRelease?.();
67
+ log('released lock');
68
+ })
69
+ .catch(async () => {
70
+ await this._onRelease?.();
71
+ });
72
+
73
+ await acquired.wait();
74
+ log('recieved lock', { steal });
75
+ }
76
+ }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
6
  import { Config } from '@dxos/config';
7
+ import { log } from '@dxos/log';
7
8
  import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
8
9
  import { NetworkManager, WebRTCTransportProxyFactory } from '@dxos/network-manager';
9
10
  import { RpcPort } from '@dxos/rpc';
@@ -37,6 +38,7 @@ export class WorkerRuntime {
37
38
  ) { }
38
39
 
39
40
  async start() {
41
+ log('starting...');
40
42
  try {
41
43
  this._config = await this._configProvider();
42
44
  const signalServer = this._config.get('runtime.services.signal.server');
@@ -53,8 +55,10 @@ export class WorkerRuntime {
53
55
 
54
56
  await this._clientServices.open();
55
57
  this._ready.wake(undefined);
58
+ log('started');
56
59
  } catch (err: any) {
57
60
  this._ready.wake(err);
61
+ log.catch(err);
58
62
  }
59
63
  }
60
64
 
@@ -68,12 +72,18 @@ export class WorkerRuntime {
68
72
  */
69
73
  async createSession({ appPort, systemPort }: CreateSessionParams) {
70
74
  const session = new WorkerSession({
71
- getServices: async () => {
75
+ getService: async (find) => {
72
76
  const error = await this._ready.wait();
73
- if (error !== undefined) {
77
+ if (error) {
74
78
  throw error;
75
79
  }
76
- return this._clientServices;
80
+
81
+ const service = find(this._clientServices.services);
82
+ if (!service) {
83
+ throw new Error('Service not found');
84
+ }
85
+
86
+ return service;
77
87
  },
78
88
  appPort,
79
89
  systemPort,
@@ -10,11 +10,11 @@ import { BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
10
10
  import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
11
11
  import { Callback } from '@dxos/util';
12
12
 
13
- import { clientServiceBundle, ClientServices, ClientServicesHost } from '../services';
13
+ import { clientServiceBundle, ClientServices } from '../services';
14
14
  import { IframeServiceBundle, iframeServiceBundle, workerServiceBundle } from './services';
15
15
 
16
16
  export type WorkerSessionParams = {
17
- getServices: () => Promise<ClientServicesHost>;
17
+ getService: <Service>(find: (services: Partial<ClientServices>) => Service | undefined) => Promise<Service>;
18
18
  systemPort: RpcPort;
19
19
  appPort: RpcPort;
20
20
  readySignal: Trigger<Error | undefined>;
@@ -30,7 +30,7 @@ export class WorkerSession {
30
30
  private readonly _clientRpc: ProtoRpcPeer<ClientServices>;
31
31
  private readonly _iframeRpc: ProtoRpcPeer<IframeServiceBundle>;
32
32
  private readonly _startTrigger = new Trigger();
33
- private readonly _getServices: () => Promise<ClientServicesHost>;
33
+ private readonly _getService: WorkerSessionParams['getService'];
34
34
  private readonly _options: NonNullable<WorkerSessionParams['options']>;
35
35
  private _heartbeatTimer?: NodeJS.Timeout;
36
36
 
@@ -42,7 +42,7 @@ export class WorkerSession {
42
42
  public bridgeService?: BridgeService;
43
43
 
44
44
  constructor({
45
- getServices,
45
+ getService,
46
46
  systemPort,
47
47
  appPort,
48
48
  options = {
@@ -50,24 +50,24 @@ export class WorkerSession {
50
50
  }
51
51
  }: WorkerSessionParams) {
52
52
  assert(options);
53
- assert(getServices);
53
+ assert(getService);
54
54
  this._options = options;
55
- this._getServices = getServices;
55
+ this._getService = getService;
56
56
 
57
57
  this._clientRpc = createProtoRpcPeer({
58
58
  exposed: clientServiceBundle,
59
59
  handlers: {
60
- HaloInvitationsService: async () => (await this._getServices()).services.HaloInvitationsService,
61
- DevicesService: async () => (await this._getServices()).services.DevicesService,
62
- SpaceInvitationsService: async () => (await this._getServices()).services.SpaceInvitationsService,
63
- SpacesService: async () => (await this._getServices()).services.SpacesService,
64
- NetworkService: async () => (await this._getServices()).services.NetworkService,
65
- SpaceService: async () => (await this._getServices()).services.SpaceService,
66
- DataService: async () => (await this._getServices()).services.DataService,
67
- ProfileService: async () => (await this._getServices()).services.ProfileService,
68
- SystemService: async () => (await this._getServices()).services.SystemService,
69
- DevtoolsHost: async () => (await this._getServices()).services.DevtoolsHost,
70
- TracingService: async () => (await this._getServices()).services.TracingService
60
+ DataService: async () => await this._getService((services) => services.DataService),
61
+ DevicesService: async () => await this._getService((services) => services.DevicesService),
62
+ DevtoolsHost: async () => await this._getService((services) => services.DevtoolsHost),
63
+ HaloInvitationsService: async () => await this._getService((services) => services.HaloInvitationsService),
64
+ NetworkService: async () => await this._getService((services) => services.NetworkService),
65
+ ProfileService: async () => await this._getService((services) => services.ProfileService),
66
+ SpaceInvitationsService: async () => await this._getService((services) => services.SpaceInvitationsService),
67
+ SpaceService: async () => await this._getService((services) => services.SpaceService),
68
+ SpacesService: async () => await this._getService((services) => services.SpacesService),
69
+ SystemService: async () => await this._getService((services) => services.SystemService),
70
+ TracingService: async () => await this._getService((services) => services.TracingService)
71
71
  },
72
72
  port: appPort
73
73
  });
@@ -1 +0,0 @@
1
- {"version":3,"file":"iframe-runtime.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/vault/iframe-runtime.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoC,OAAO,EAAE,MAAM,WAAW,CAAC;AAKtE,oBAAY,mBAAmB,GAAG;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgC;gBAEtD,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,mBAAmB;IAwBvE,IAAI,CAAC,MAAM,EAAE,MAAM;IAKnB,KAAK;CAIZ"}