@ledgerhq/device-transport-kit-web-ble 0.0.0-webhid-20250124164153 → 0.0.0-wrong-error-when-in-experimental-provider-20251021162636
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.
- package/README.md +77 -0
- package/lib/esm/api/data/WebBleConfig.js +1 -1
- package/lib/esm/api/data/WebBleConfig.js.map +3 -3
- package/lib/esm/api/model/BleDevice.stub.js +1 -1
- package/lib/esm/api/model/BleDevice.stub.js.map +2 -2
- package/lib/esm/api/transport/WebBleApduSender.js +2 -0
- package/lib/esm/api/transport/WebBleApduSender.js.map +7 -0
- package/lib/esm/api/transport/WebBleApduSender.test.js +2 -0
- package/lib/esm/api/transport/WebBleApduSender.test.js.map +7 -0
- package/lib/esm/api/transport/WebBleTransport.js +1 -1
- package/lib/esm/api/transport/WebBleTransport.js.map +3 -3
- package/lib/esm/api/transport/WebBleTransport.test.js +1 -1
- package/lib/esm/api/transport/WebBleTransport.test.js.map +3 -3
- package/lib/esm/package.json +16 -16
- package/lib/types/api/data/WebBleConfig.d.ts +5 -1
- package/lib/types/api/data/WebBleConfig.d.ts.map +1 -1
- package/lib/types/api/model/BleDevice.stub.d.ts.map +1 -1
- package/lib/types/api/transport/WebBleApduSender.d.ts +39 -0
- package/lib/types/api/transport/WebBleApduSender.d.ts.map +1 -0
- package/lib/types/api/transport/WebBleApduSender.test.d.ts +2 -0
- package/lib/types/api/transport/WebBleApduSender.test.d.ts.map +1 -0
- package/lib/types/api/transport/WebBleTransport.d.ts +23 -72
- package/lib/types/api/transport/WebBleTransport.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/lib/esm/api/transport/BleDeviceConnection.js +0 -2
- package/lib/esm/api/transport/BleDeviceConnection.js.map +0 -7
- package/lib/esm/api/transport/BleDeviceConnection.test.js +0 -2
- package/lib/esm/api/transport/BleDeviceConnection.test.js.map +0 -7
- package/lib/types/api/transport/BleDeviceConnection.d.ts +0 -98
- package/lib/types/api/transport/BleDeviceConnection.d.ts.map +0 -1
- package/lib/types/api/transport/BleDeviceConnection.test.d.ts +0 -2
- package/lib/types/api/transport/BleDeviceConnection.test.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/api/transport/WebBleTransport.test.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ApduReceiverServiceFactory,\n type ApduSenderServiceFactory,\n type DeviceModel,\n type LoggerPublisherService,\n type LoggerSubscriberService,\n NoAccessibleDeviceError,\n OpeningConnectionError,\n StaticDeviceModelDataSource,\n type TransportDiscoveredDevice,\n UnknownDeviceError,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\n\nimport { RECONNECT_DEVICE_TIMEOUT } from \"@api/data/WebBleConfig\";\nimport { bleDeviceStubBuilder } from \"@api/model/BleDevice.stub\";\nimport { BleTransportNotSupportedError } from \"@api/model/Errors\";\nimport { BleDeviceGattServerError } from \"@api/model/Errors\";\n\nimport { WebBleTransport } from \"./WebBleTransport\";\n\nclass LoggerPublisherServiceStub implements LoggerPublisherService {\n subscribers: LoggerSubscriberService[] = [];\n tag: string;\n constructor(subscribers: LoggerSubscriberService[], tag: string) {\n this.subscribers = subscribers;\n this.tag = tag;\n }\n error = jest.fn();\n warn = jest.fn();\n info = jest.fn();\n debug = jest.fn();\n}\n\n// Our StaticDeviceModelDataSource can directly be used in our unit tests\nconst bleDeviceModelDataSource = new StaticDeviceModelDataSource();\nconst logger = new LoggerPublisherServiceStub([], \"web-ble\");\n\nconst stubDevice: BluetoothDevice = bleDeviceStubBuilder();\n\ndescribe(\"WebBleTransport\", () => {\n let transport: WebBleTransport;\n let apduReceiverServiceFactoryStub: ApduReceiverServiceFactory;\n let apduSenderServiceFactoryStub: ApduSenderServiceFactory;\n\n beforeEach(() => {\n apduReceiverServiceFactoryStub = jest.fn();\n apduSenderServiceFactoryStub = jest.fn();\n transport = new WebBleTransport(\n bleDeviceModelDataSource,\n () => logger,\n apduSenderServiceFactoryStub,\n apduReceiverServiceFactoryStub,\n );\n jest.useFakeTimers();\n });\n\n afterEach(() => {\n jest.restoreAllMocks();\n });\n\n const discoverDevice = (\n onSuccess: (discoveredDevice: TransportDiscoveredDevice) => void,\n onError?: (error: unknown) => void,\n ) => {\n transport.startDiscovering().subscribe({\n next: onSuccess,\n error: onError,\n });\n };\n\n describe(\"When Web bluetooth API is not supported\", () => {\n it(\"should not support the transport\", () => {\n expect(transport.isSupported()).toBe(false);\n });\n\n it(\"should emit a startDiscovering error\", (done) => {\n discoverDevice(\n () => {\n done(\"Should not emit any value\");\n },\n (error) => {\n expect(error).toBeInstanceOf(BleTransportNotSupportedError);\n done();\n },\n );\n });\n });\n\n describe(\"When Web Bluetooth API is supported\", () => {\n const mockedRequestDevice = jest.fn();\n\n beforeAll(() => {\n global.navigator = {\n bluetooth: {\n requestDevice: mockedRequestDevice,\n },\n } as unknown as Navigator;\n });\n\n afterAll(() => {\n jest.restoreAllMocks();\n global.navigator = undefined as unknown as Navigator;\n });\n\n it(\"should support the transport\", () => {\n expect(transport.isSupported()).toBe(true);\n });\n\n describe(\"startDiscovering\", () => {\n it(\"should emit device if one new grant access\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce(stubDevice);\n\n discoverDevice(\n (discoveredDevice) => {\n try {\n expect(discoveredDevice).toEqual(\n expect.objectContaining({\n deviceModel: expect.objectContaining({\n id: \"nanoX\",\n productName: \"Ledger Nano X\",\n }) as DeviceModel,\n }),\n );\n\n done();\n } catch (expectError) {\n done(expectError);\n }\n },\n (error) => {\n done(error);\n },\n );\n });\n\n it(\"should throw DeviceNotRecognizedError if the device is not recognized\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce({\n ...stubDevice,\n gatt: {\n ...stubDevice.gatt,\n getPrimaryServices: jest.fn(() => Promise.resolve([])),\n },\n productId: 0x4242,\n });\n\n discoverDevice(\n () => {\n done(\"should not return a device\");\n },\n (error) => {\n expect(error).toBeInstanceOf(BleDeviceGattServerError);\n done();\n },\n );\n });\n\n it(\"should emit an error if the request device is in error\", (done) => {\n const message = \"request device error\";\n mockedRequestDevice.mockImplementationOnce(() => {\n throw new Error(message);\n });\n\n discoverDevice(\n () => {\n done(\"should not return a device\");\n },\n (error) => {\n expect(error).toBeInstanceOf(NoAccessibleDeviceError);\n expect(error).toStrictEqual(\n new NoAccessibleDeviceError(new Error(message)),\n );\n done();\n },\n );\n });\n\n it(\"should emit an error if the user did not grant us access to a device (clicking on cancel on the browser popup for ex)\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce({ forget: jest.fn() });\n\n discoverDevice(\n (discoveredDevice) => {\n done(\n `Should not emit any value, but emitted ${JSON.stringify(\n discoveredDevice,\n )}`,\n );\n },\n (error) => {\n try {\n expect(error).toBeInstanceOf(BleDeviceGattServerError);\n done();\n } catch (expectError) {\n done(expectError);\n }\n },\n );\n });\n });\n\n describe(\"connect\", () => {\n it(\"should throw UnknownDeviceError if no internal device\", async () => {\n const connectParams = {\n deviceId: \"fake\",\n onDisconnect: jest.fn(),\n };\n\n const connect = await transport.connect(connectParams);\n\n expect(connect).toStrictEqual(\n Left(new UnknownDeviceError(\"Unknown device fake\")),\n );\n });\n\n it(\"should throw OpeningConnectionError if the device is already opened\", async () => {\n const device = {\n deviceId: \"fake\",\n onDisconnect: jest.fn(),\n };\n\n const connect = await transport.connect(device);\n\n expect(connect).toStrictEqual(\n Left(new UnknownDeviceError(\"Unknown device fake\")),\n );\n });\n\n it(\"should throw OpeningConnectionError if the device cannot be opened\", (done) => {\n const message = \"cannot be opened\";\n mockedRequestDevice.mockResolvedValueOnce({\n ...stubDevice,\n gatt: {\n connect: () => {\n throw new Error(message);\n },\n },\n });\n\n discoverDevice(\n () => {\n done();\n },\n (error) => {\n expect(error).toBeInstanceOf(OpeningConnectionError);\n done();\n },\n );\n });\n\n it(\"should return the opened device\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce({\n ...stubDevice,\n gatt: {\n ...stubDevice.gatt,\n connected: true,\n },\n });\n\n discoverDevice(\n (discoveredDevice) => {\n transport\n .connect({\n deviceId: discoveredDevice.id,\n onDisconnect: jest.fn(),\n })\n .then((connectedDevice) => {\n connectedDevice\n .ifRight((device) => {\n expect(device).toEqual(\n expect.objectContaining({ id: discoveredDevice.id }),\n );\n done();\n })\n .ifLeft(() => {\n done(connectedDevice);\n });\n })\n .catch((error) => {\n done(error);\n });\n },\n (error) => {\n done(error);\n },\n );\n });\n\n it(\"should return a device if available\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce(stubDevice);\n\n discoverDevice(\n (discoveredDevice) => {\n transport\n .connect({\n deviceId: discoveredDevice.id,\n onDisconnect: jest.fn(),\n })\n .then((connectedDevice) => {\n connectedDevice\n .ifRight((device) => {\n expect(device).toEqual(\n expect.objectContaining({ id: discoveredDevice.id }),\n );\n done();\n })\n .ifLeft(() => {\n done(connectedDevice);\n });\n })\n .catch((error) => {\n done(error);\n });\n },\n (error) => {\n done(error);\n },\n );\n });\n });\n\n describe(\"disconnect\", () => {\n it(\"should disconnect the device\", (done) => {\n mockedRequestDevice.mockResolvedValueOnce(stubDevice);\n\n const onDisconnect = jest.fn();\n\n discoverDevice(\n (discoveredDevice) => {\n transport\n .connect({\n deviceId: discoveredDevice.id,\n onDisconnect,\n })\n .then((connectedDevice) => {\n connectedDevice.ifRight((device) => {\n transport\n .disconnect({ connectedDevice: device })\n .then((value) => {\n expect(value).toStrictEqual(Right(void 0));\n done();\n })\n .catch((error) => {\n done(error);\n });\n });\n });\n },\n (error) => {\n done(error);\n },\n );\n });\n it(\"should call disconnect handler if device is hardware disconnected\", (done) => {\n const onDisconnect = jest.fn();\n const disconnectSpy = jest.spyOn(transport, \"disconnect\");\n mockedRequestDevice.mockResolvedValueOnce(stubDevice);\n\n discoverDevice(\n (discoveredDevice) => {\n transport\n .connect({\n deviceId: discoveredDevice.id,\n onDisconnect,\n })\n .then(() => {\n stubDevice.ongattserverdisconnected(new Event(\"\"));\n jest.advanceTimersByTime(RECONNECT_DEVICE_TIMEOUT);\n expect(disconnectSpy).toHaveBeenCalled();\n done();\n });\n },\n (error) => {\n done(error);\n },\n );\n });\n });\n\n describe(\"reconnect\", () => {\n it(\"should not call disconnection if reconnection happen\", (done) => {\n // given\n const onDisconnect = jest.fn();\n const disconnectSpy = jest.spyOn(transport, \"disconnect\");\n mockedRequestDevice.mockResolvedValueOnce(stubDevice);\n\n // when\n discoverDevice((discoveredDevice) => {\n transport\n .connect({\n deviceId: discoveredDevice.id,\n onDisconnect,\n })\n .then(() => {\n stubDevice.ongattserverdisconnected(new Event(\"\"));\n\n jest.advanceTimersByTime(RECONNECT_DEVICE_TIMEOUT / 3);\n\n // then\n expect(disconnectSpy).toHaveBeenCalledTimes(0);\n done();\n })\n .catch((error) => {\n done(error);\n });\n });\n });\n });\n });\n});\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nvi.mock(\"./WebBleApduSender\", async () => ({\n WebBleApduSender: class {\n constructor(_deps: any, _loggerFactory: any) {}\n setupConnection = vi.fn().mockResolvedValue(undefined);\n },\n}));\n\nvi.mock(\"@ledgerhq/device-management-kit\", async () => {\n const actual = (await vi.importActual(\n \"@ledgerhq/device-management-kit\",\n )) as any;\n return {\n ...actual,\n DeviceConnectionStateMachine: class {\n constructor(_opts: any) {}\n setupConnection = vi.fn().mockResolvedValue(undefined);\n setDependencies = vi.fn();\n sendApdu = vi.fn();\n closeConnection = vi.fn();\n eventDeviceDisconnected = vi.fn();\n eventDeviceConnected = vi.fn();\n eventDeviceDetached = vi.fn();\n eventDeviceAttached = vi.fn();\n },\n };\n});\n\nimport {\n type ApduReceiverServiceFactory,\n type ApduSenderServiceFactory,\n DeviceAlreadyConnectedError,\n type LoggerPublisherService,\n type LoggerSubscriberService,\n OpeningConnectionError,\n StaticDeviceModelDataSource,\n type TransportConnectedDevice,\n UnknownDeviceError,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\nimport { firstValueFrom } from \"rxjs\";\n\nimport { bleDeviceStubBuilder } from \"@api/model/BleDevice.stub\";\n\nimport { WebBleTransport } from \"./WebBleTransport\";\n\nclass LoggerPublisherServiceStub implements LoggerPublisherService {\n subscribers: LoggerSubscriberService[] = [];\n tag: string;\n constructor(subscribers: LoggerSubscriberService[], tag: string) {\n this.subscribers = subscribers;\n this.tag = tag;\n }\n error = vi.fn();\n warn = vi.fn();\n info = vi.fn();\n debug = vi.fn();\n}\n\nconst bleDeviceModelDataSource = new StaticDeviceModelDataSource();\nconst logger = new LoggerPublisherServiceStub([], \"WebBleTransport\");\n\nlet transport: WebBleTransport;\nlet apduReceiverFactory: ApduReceiverServiceFactory;\nlet apduSenderFactory: ApduSenderServiceFactory;\n\nbeforeEach(() => {\n vi.useRealTimers();\n apduReceiverFactory = vi.fn();\n apduSenderFactory = vi.fn();\n transport = new WebBleTransport(\n bleDeviceModelDataSource,\n () => logger,\n apduSenderFactory,\n apduReceiverFactory,\n );\n});\n\nafterEach(() => {\n vi.restoreAllMocks();\n});\n\ndescribe(\"WebBleTransport\", () => {\n describe(\"isSupported\", () => {\n it(\"returns false when navigator.bluetooth is undefined\", () => {\n delete (globalThis as any).navigator;\n\n const result = transport.isSupported();\n\n expect(result).toBe(false);\n });\n\n it(\"returns true when navigator.bluetooth exists\", () => {\n (globalThis as any).navigator = { bluetooth: {} };\n\n const result = transport.isSupported();\n\n expect(result).toBe(true);\n });\n });\n\n describe(\"startDiscovering\", () => {\n let requestDevice: ReturnType<typeof vi.fn>;\n let stubDevice: BluetoothDevice;\n let mockService: any;\n\n const serviceUuid = bleDeviceModelDataSource.getBluetoothServices()[0];\n\n const makeGatt = (service: any) => {\n const gatt: any = {\n connected: false,\n connect: vi.fn().mockImplementation(async () => {\n gatt.connected = true;\n return gatt;\n }),\n disconnect: vi.fn().mockImplementation(() => {\n gatt.connected = false;\n }),\n getPrimaryService: vi.fn().mockImplementation(async (uuid: string) => {\n if (uuid.toLowerCase() === service.uuid.toLowerCase()) {\n return service;\n }\n const err = new Error(\"NotFoundError\");\n (err as any).name = \"NotFoundError\";\n throw err;\n }),\n getPrimaryServices: vi.fn().mockResolvedValue([service]),\n };\n return gatt;\n };\n\n beforeEach(() => {\n stubDevice = bleDeviceStubBuilder();\n mockService = {\n uuid: serviceUuid,\n device: stubDevice,\n getCharacteristic: vi.fn().mockResolvedValue({}),\n };\n\n const gatt = makeGatt(mockService);\n\n Object.defineProperty(stubDevice, \"gatt\", {\n value: gatt,\n writable: true,\n configurable: true,\n });\n\n if (!(stubDevice as any).addEventListener) {\n (stubDevice as any).addEventListener = vi.fn();\n (stubDevice as any).removeEventListener = vi.fn();\n }\n\n requestDevice = vi.fn();\n (globalThis as any).navigator = {\n bluetooth: { requestDevice },\n };\n });\n\n it(\"emits a discovered device when a known device is returned\", async () => {\n // given\n requestDevice.mockResolvedValueOnce(stubDevice);\n\n // when\n const device = await firstValueFrom(transport.startDiscovering());\n\n const expectedModelId =\n bleDeviceModelDataSource.getBluetoothServicesInfos()[serviceUuid!]\n ?.deviceModel.id;\n\n // then\n expect(device).toEqual(\n expect.objectContaining({\n deviceModel: expect.objectContaining({ id: expectedModelId }),\n transport: transport.getIdentifier(),\n }),\n );\n });\n\n it(\"emits UnknownDeviceError when deviceInfo is missing\", async () => {\n // given\n const unknown = bleDeviceStubBuilder();\n const unknownService = {\n uuid: \"invalid-uuid\",\n device: unknown,\n getCharacteristic: vi.fn(),\n };\n\n const gatt: any = {\n connected: false,\n connect: vi.fn().mockImplementation(async () => {\n gatt.connected = true;\n return gatt;\n }),\n disconnect: vi.fn(),\n // returning a service (success) but with an unknown uuid triggers UnknownDeviceError\n getPrimaryService: vi.fn().mockResolvedValue(unknownService),\n getPrimaryServices: vi.fn().mockResolvedValue([unknownService]),\n };\n\n Object.defineProperty(unknown, \"gatt\", {\n value: gatt,\n writable: true,\n configurable: true,\n });\n\n requestDevice.mockResolvedValueOnce(unknown);\n\n // then\n await expect(\n firstValueFrom(transport.startDiscovering()),\n ).rejects.toBeInstanceOf(OpeningConnectionError);\n });\n\n it(\"throws OpeningConnectionError when device has no GATT server\", async () => {\n // given\n const noGattStub = bleDeviceStubBuilder();\n Object.defineProperty(noGattStub, \"gatt\", {\n value: undefined,\n writable: true,\n configurable: true,\n });\n requestDevice.mockResolvedValueOnce(noGattStub);\n\n // then\n await expect(\n firstValueFrom(transport.startDiscovering()),\n ).rejects.toBeInstanceOf(OpeningConnectionError);\n });\n\n it(\"throws OpeningConnectionError when no GATT services are found\", async () => {\n // given\n const noServiceStub = bleDeviceStubBuilder();\n const gatt: any = {\n connected: false,\n connect: vi.fn().mockImplementation(async () => gatt),\n disconnect: vi.fn(),\n getPrimaryService: vi.fn().mockRejectedValue(new Error(\"nope\")),\n getPrimaryServices: vi.fn().mockResolvedValue([]),\n };\n Object.defineProperty(noServiceStub, \"gatt\", {\n value: gatt,\n writable: true,\n configurable: true,\n });\n requestDevice.mockResolvedValueOnce(noServiceStub);\n\n // then\n await expect(\n firstValueFrom(transport.startDiscovering()),\n ).rejects.toBeInstanceOf(OpeningConnectionError);\n });\n });\n\n describe(\"connect/disconnect flow\", () => {\n let requestDevice: ReturnType<typeof vi.fn>;\n let stubDevice: BluetoothDevice;\n let mockService: any;\n\n const serviceUuid = bleDeviceModelDataSource.getBluetoothServices()[0];\n\n const makeGatt = (service: any) => {\n const gatt: any = {\n connected: false,\n connect: vi.fn().mockImplementation(async () => {\n gatt.connected = true;\n return gatt;\n }),\n disconnect: vi.fn().mockImplementation(() => {\n gatt.connected = false;\n }),\n getPrimaryService: vi.fn().mockImplementation(async (uuid: string) => {\n if (uuid.toLowerCase() === service.uuid.toLowerCase()) {\n return service;\n }\n const err = new Error(\"NotFoundError\");\n (err as any).name = \"NotFoundError\";\n throw err;\n }),\n getPrimaryServices: vi.fn().mockResolvedValue([service]),\n };\n return gatt;\n };\n\n beforeEach(() => {\n stubDevice = bleDeviceStubBuilder();\n\n const charNotify: any = { properties: {} };\n const charWrite: any = { properties: { write: true } };\n\n mockService = {\n uuid: serviceUuid,\n device: stubDevice,\n getCharacteristic: vi\n .fn()\n .mockResolvedValueOnce(charNotify)\n .mockResolvedValue(charWrite),\n };\n\n const gatt = makeGatt(mockService);\n\n Object.defineProperty(stubDevice, \"gatt\", {\n value: gatt,\n writable: true,\n configurable: true,\n });\n\n if (!(stubDevice as any).addEventListener) {\n (stubDevice as any).addEventListener = vi.fn();\n (stubDevice as any).removeEventListener = vi.fn();\n }\n\n requestDevice = vi.fn().mockResolvedValue(stubDevice);\n (globalThis as any).navigator = {\n bluetooth: { requestDevice },\n };\n });\n\n it(\"returns UnknownDeviceError when connecting an unknown deviceId\", async () => {\n // given\n const deviceId = \"nonexistent\";\n\n // when\n const result = await transport.connect({\n deviceId,\n onDisconnect: vi.fn(),\n });\n\n // then\n expect(result).toEqual(\n Left(new UnknownDeviceError(`Unknown device ${deviceId}`)),\n );\n });\n\n it(\"connects and returns a connected device on success\", async () => {\n // given\n const discovered = await firstValueFrom(transport.startDiscovering());\n\n // when\n const result = await transport.connect({\n deviceId: discovered.id,\n onDisconnect: vi.fn(),\n });\n\n // then\n expect(result.isRight()).toBe(true);\n const conn = result.extract() as TransportConnectedDevice;\n expect(conn.id).toBe(discovered.id);\n });\n\n it(\"does not allow connecting twice to the same device\", async () => {\n // given\n const discovered = await firstValueFrom(transport.startDiscovering());\n await transport.connect({\n deviceId: discovered.id,\n onDisconnect: vi.fn(),\n });\n\n // when\n const secondAttempt = await transport.connect({\n deviceId: discovered.id,\n onDisconnect: vi.fn(),\n });\n\n // then\n expect(secondAttempt).toEqual(\n Left(\n new DeviceAlreadyConnectedError(\n `Device ${discovered.id} already connected`,\n ),\n ),\n );\n });\n\n it(\"returns OpeningConnectionError when characteristic retrieval fails\", async () => {\n // given\n const badService = {\n uuid: serviceUuid,\n device: stubDevice,\n getCharacteristic: vi.fn().mockRejectedValue(new Error(\"boom\")),\n };\n const badGatt = {\n ...stubDevice.gatt,\n getPrimaryService: vi.fn().mockResolvedValue(badService),\n getPrimaryServices: vi.fn().mockResolvedValue([badService]),\n } as any;\n\n Object.defineProperty(stubDevice, \"gatt\", {\n value: badGatt,\n writable: true,\n configurable: true,\n });\n\n const discovered = await firstValueFrom(transport.startDiscovering());\n\n // when\n const result = await transport.connect({\n deviceId: discovered.id,\n onDisconnect: vi.fn(),\n });\n\n // then\n expect(result.isLeft()).toBe(true);\n expect(result.extract()).toBeInstanceOf(OpeningConnectionError);\n });\n\n it(\"disconnects successfully\", async () => {\n // given\n const discovered = await firstValueFrom(transport.startDiscovering());\n const result = await transport.connect({\n deviceId: discovered.id,\n onDisconnect: vi.fn(),\n });\n const conn = result.extract() as TransportConnectedDevice;\n\n // when\n const disc = await transport.disconnect({ connectedDevice: conn });\n\n // then\n expect(disc).toEqual(Right(undefined));\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DeviceAlreadyConnectedError", "OpeningConnectionError", "StaticDeviceModelDataSource", "UnknownDeviceError", "Left", "Right", "firstValueFrom", "bleDeviceStubBuilder", "WebBleTransport", "_deps", "_loggerFactory", "_opts", "LoggerPublisherServiceStub", "subscribers", "tag", "bleDeviceModelDataSource", "logger", "transport", "apduReceiverFactory", "apduSenderFactory", "result", "requestDevice", "stubDevice", "mockService", "serviceUuid", "makeGatt", "service", "gatt", "uuid", "err", "device", "expectedModelId", "unknown", "unknownService", "noGattStub", "noServiceStub", "charNotify", "charWrite", "deviceId", "discovered", "conn", "secondAttempt", "badService", "badGatt", "disc"]
|
|
7
7
|
}
|
package/lib/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/device-transport-kit-web-ble",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"exports": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"prebuild": "rimraf lib",
|
|
18
|
-
"build": "pnpm
|
|
18
|
+
"build": "pnpm ldmk-tool build --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
|
|
19
19
|
"dev": "concurrently \"pnpm watch:builds\" \"pnpm watch:types\"",
|
|
20
|
-
"watch:builds": "pnpm
|
|
20
|
+
"watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json --platform web",
|
|
21
21
|
"watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\"",
|
|
22
22
|
"lint": "eslint",
|
|
23
23
|
"lint:fix": "pnpm lint --fix",
|
|
@@ -25,29 +25,29 @@
|
|
|
25
25
|
"prettier": "prettier . --check",
|
|
26
26
|
"prettier:fix": "prettier . --write",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
|
-
"test": "
|
|
29
|
-
"test:watch": "
|
|
30
|
-
"test:coverage": "
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:coverage": "vitest run --coverage"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@sentry/minimal": "
|
|
34
|
-
"purify-ts": "
|
|
35
|
-
"uuid": "
|
|
33
|
+
"@sentry/minimal": "catalog:",
|
|
34
|
+
"purify-ts": "catalog:",
|
|
35
|
+
"uuid": "catalog:"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@ledgerhq/device-management-kit": "workspace:*",
|
|
39
|
-
"@ledgerhq/
|
|
39
|
+
"@ledgerhq/ldmk-tool": "workspace:*",
|
|
40
40
|
"@ledgerhq/eslint-config-dsdk": "workspace:*",
|
|
41
|
-
"@ledgerhq/jest-config-dsdk": "workspace:*",
|
|
42
41
|
"@ledgerhq/prettier-config-dsdk": "workspace:*",
|
|
43
42
|
"@ledgerhq/tsconfig-dsdk": "workspace:*",
|
|
44
|
-
"@
|
|
45
|
-
"@types/
|
|
46
|
-
"
|
|
47
|
-
"
|
|
43
|
+
"@ledgerhq/vitest-config-dmk": "workspace:*",
|
|
44
|
+
"@types/uuid": "catalog:",
|
|
45
|
+
"@types/web-bluetooth": "catalog:",
|
|
46
|
+
"rxjs": "catalog:",
|
|
47
|
+
"ts-node": "catalog:"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@ledgerhq/device-management-kit": "workspace:*",
|
|
51
|
-
"rxjs": "
|
|
51
|
+
"rxjs": "catalog:"
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export declare const RECONNECT_DEVICE_TIMEOUT =
|
|
1
|
+
export declare const RECONNECT_DEVICE_TIMEOUT = 15000;
|
|
2
|
+
export declare const ADVERTISING_DELAY = 400;
|
|
3
|
+
export declare const ADVERTISING_TIMEOUT = 1200;
|
|
4
|
+
export declare const REDISCOVER_TIMEOUT = 3000;
|
|
5
|
+
export declare const RECONNECTION_LOOP_BACKOFF = 500;
|
|
2
6
|
//# sourceMappingURL=WebBleConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebBleConfig.d.ts","sourceRoot":"","sources":["../../../../src/api/data/WebBleConfig.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"WebBleConfig.d.ts","sourceRoot":"","sources":["../../../../src/api/data/WebBleConfig.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAC9C,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,eAAO,MAAM,yBAAyB,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BleDevice.stub.d.ts","sourceRoot":"","sources":["../../../../src/api/model/BleDevice.stub.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,4BAA4B,
|
|
1
|
+
{"version":3,"file":"BleDevice.stub.d.ts","sourceRoot":"","sources":["../../../../src/api/model/BleDevice.stub.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,4BAA4B,GACvC,QAAO,OAAO,CAAC,iCAAiC,CAAM,KACrD,iCAQsC,CAAC;AAE1C,eAAO,MAAM,oBAAoB,GAC/B,QAAO,OAAO,CAAC,eAAe,CAAM,KACnC,eAaD,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ApduReceiverServiceFactory, type ApduResponse, type ApduSenderServiceFactory, type DeviceApduSender, type DmkError, type LoggerPublisherService } from "@ledgerhq/device-management-kit";
|
|
2
|
+
import { type Either } from "purify-ts";
|
|
3
|
+
export type WebBleApduSenderDependencies = {
|
|
4
|
+
writeCharacteristic: BluetoothRemoteGATTCharacteristic;
|
|
5
|
+
notifyCharacteristic: BluetoothRemoteGATTCharacteristic;
|
|
6
|
+
};
|
|
7
|
+
export declare const MTU_OP = 8;
|
|
8
|
+
export declare class WebBleApduSender implements DeviceApduSender<WebBleApduSenderDependencies> {
|
|
9
|
+
private _dependencies;
|
|
10
|
+
private _apduFrameSegmenter;
|
|
11
|
+
private _apduSenderFactory;
|
|
12
|
+
private _apduReceiverFactory;
|
|
13
|
+
private _apduFrameReceiver;
|
|
14
|
+
private _logger;
|
|
15
|
+
private _mtuNegotiated$;
|
|
16
|
+
private _notificationsReady;
|
|
17
|
+
private _mtuRequestInProgress;
|
|
18
|
+
private _pendingResponseResolver;
|
|
19
|
+
constructor(initialDependencies: WebBleApduSenderDependencies & {
|
|
20
|
+
apduSenderFactory: ApduSenderServiceFactory;
|
|
21
|
+
apduReceiverFactory: ApduReceiverServiceFactory;
|
|
22
|
+
}, loggerFactory: (tag: string) => LoggerPublisherService);
|
|
23
|
+
sendApdu(apdu: Uint8Array, triggersDisconnection?: boolean, abortTimeout?: number): Promise<Either<DmkError, ApduResponse>>;
|
|
24
|
+
closeConnection(): void;
|
|
25
|
+
getDependencies(): WebBleApduSenderDependencies;
|
|
26
|
+
setDependencies(deps: WebBleApduSenderDependencies): void;
|
|
27
|
+
setupConnection(): Promise<void>;
|
|
28
|
+
private _isGattConnected;
|
|
29
|
+
private _isGattDisconnectedError;
|
|
30
|
+
private _failPendingSend;
|
|
31
|
+
private _markLinkUnavailable;
|
|
32
|
+
private _sleep;
|
|
33
|
+
private _handleNotification;
|
|
34
|
+
private _handleMtuNegotiationFrame;
|
|
35
|
+
private _handleApduFrame;
|
|
36
|
+
private _writeToGattCharacteristic;
|
|
37
|
+
private _waitUntilMtuNegotiated;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=WebBleApduSender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebBleApduSender.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/WebBleApduSender.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAGrB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAE5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAsB,MAAM,WAAW,CAAC;AAG5D,MAAM,MAAM,4BAA4B,GAAG;IACzC,mBAAmB,EAAE,iCAAiC,CAAC;IACvD,oBAAoB,EAAE,iCAAiC,CAAC;CACzD,CAAC;AAEF,eAAO,MAAM,MAAM,IAAO,CAAC;AAE3B,qBAAa,gBACX,YAAW,gBAAgB,CAAC,4BAA4B,CAAC;IAEzD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,mBAAmB,CAA2C;IACtE,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,oBAAoB,CAA6B;IACzD,OAAO,CAAC,kBAAkB,CAAsB;IAChD,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,wBAAwB,CAEd;gBAGhB,mBAAmB,EAAE,4BAA4B,GAAG;QAClD,iBAAiB,EAAE,wBAAwB,CAAC;QAC5C,mBAAmB,EAAE,0BAA0B,CAAC;KACjD,EACD,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB;IAY3C,QAAQ,CACnB,IAAI,EAAE,UAAU,EAChB,qBAAqB,CAAC,EAAE,OAAO,EAC/B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAsEnC,eAAe,IAAI,IAAI;IAwBvB,eAAe,IAAI,4BAA4B;IAI/C,eAAe,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI;IA4BnD,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAsE7C,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,wBAAwB;IAsBhC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB;YAiBd,MAAM;IAIpB,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,gBAAgB;YAgBV,0BAA0B;YAiC1B,uBAAuB;CAkCtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebBleApduSender.test.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/WebBleApduSender.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,91 +1,42 @@
|
|
|
1
|
-
import { type ApduReceiverServiceFactory, type ApduSenderServiceFactory, type ConnectError, type
|
|
1
|
+
import { type ApduReceiverServiceFactory, type ApduSenderServiceFactory, type ConnectError, type DeviceModelDataSource, type DmkError, type LoggerPublisherService, type Transport, TransportConnectedDevice, type TransportDiscoveredDevice, type TransportFactory, type TransportIdentifier } from "@ledgerhq/device-management-kit";
|
|
2
2
|
import { type Either } from "purify-ts";
|
|
3
3
|
import { type Observable } from "rxjs";
|
|
4
4
|
export declare const webBleIdentifier: TransportIdentifier;
|
|
5
5
|
export declare class WebBleTransport implements Transport {
|
|
6
6
|
private readonly _deviceModelDataSource;
|
|
7
|
-
private
|
|
7
|
+
private loggerFactory;
|
|
8
8
|
private readonly _apduSenderFactory;
|
|
9
9
|
private readonly _apduReceiverFactory;
|
|
10
|
-
private readonly _connectedDevices;
|
|
11
|
-
private readonly _internalDevicesById;
|
|
12
|
-
private _deviceConnectionById;
|
|
13
|
-
private _disconnectionHandlersById;
|
|
14
10
|
private _logger;
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* Get the Bluetooth API if supported or error
|
|
20
|
-
* @returns `Either<BleTransportNotSupportedError, Bluetooth>`
|
|
21
|
-
*/
|
|
22
|
-
private getBluetoothApi;
|
|
11
|
+
private _connectionStateMachinesByDeviceId;
|
|
12
|
+
private _deviceRegistryById;
|
|
13
|
+
private _discoveredDevices$;
|
|
14
|
+
constructor(_deviceModelDataSource: DeviceModelDataSource, loggerFactory: (tag: string) => LoggerPublisherService, _apduSenderFactory: ApduSenderServiceFactory, _apduReceiverFactory: ApduReceiverServiceFactory);
|
|
23
15
|
isSupported(): boolean;
|
|
24
16
|
getIdentifier(): TransportIdentifier;
|
|
25
|
-
listenToKnownDevices(): Observable<TransportDiscoveredDevice[]>;
|
|
26
|
-
/**
|
|
27
|
-
* Get Bluetooth GATT Primary service that is used to get writeCharacteristic and notifyCharacteristic
|
|
28
|
-
* @param bleDevice
|
|
29
|
-
* @private
|
|
30
|
-
*/
|
|
31
|
-
private getBleGattService;
|
|
32
|
-
/**
|
|
33
|
-
* BleDeviceInfos to map primary service uuid to device model & characteristics uuid
|
|
34
|
-
* @param bleGattService
|
|
35
|
-
* @private
|
|
36
|
-
*/
|
|
37
|
-
private getBleDeviceInfos;
|
|
38
|
-
/**
|
|
39
|
-
* Prompt device selection in navigator
|
|
40
|
-
*
|
|
41
|
-
* @private
|
|
42
|
-
*/
|
|
43
|
-
private promptDeviceAccess;
|
|
44
|
-
/**
|
|
45
|
-
* Generate a discovered device from BluetoothDevice, BleGATT primary service and BLE device infos
|
|
46
|
-
* @param bleDeviceInfos
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
private getDiscoveredDeviceFrom;
|
|
50
|
-
/**
|
|
51
|
-
* Generate an InternalDevice from a unique id, a BluetoothDevice, BleGATT primary service and BLE device infos
|
|
52
|
-
* @param discoveredDevice
|
|
53
|
-
* @param bleDevice
|
|
54
|
-
* @param bleDeviceInfos
|
|
55
|
-
* @param bleGattService
|
|
56
|
-
* @private
|
|
57
|
-
*/
|
|
58
|
-
private setInternalDeviceFrom;
|
|
59
|
-
/**
|
|
60
|
-
* Main method to get a device from a button click handler
|
|
61
|
-
* The GATT connection is done here in order to populate TransportDiscoveredDevice with deviceModel
|
|
62
|
-
*/
|
|
63
17
|
startDiscovering(): Observable<TransportDiscoveredDevice>;
|
|
64
18
|
stopDiscovering(): void;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
deviceId: DeviceId;
|
|
71
|
-
onDisconnect: DisconnectHandler;
|
|
19
|
+
listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]>;
|
|
20
|
+
connect(params: {
|
|
21
|
+
deviceId: string;
|
|
22
|
+
onDisconnect: (deviceId: string) => void;
|
|
23
|
+
onReconnect?: (deviceId: string) => Promise<void> | void;
|
|
72
24
|
}): Promise<Either<ConnectError, TransportConnectedDevice>>;
|
|
73
|
-
/**
|
|
74
|
-
* Get the device disconnected handler
|
|
75
|
-
* @param internalDevice WebBleInternalDevice
|
|
76
|
-
* @param deviceConnection BleDeviceConnection
|
|
77
|
-
* @returns async () => void
|
|
78
|
-
* @private
|
|
79
|
-
*/
|
|
80
|
-
private _getDeviceDisconnectedHandler;
|
|
81
|
-
/**
|
|
82
|
-
* Disconnect from a BLE device and delete its handlers
|
|
83
|
-
*
|
|
84
|
-
* @param params { connectedDevice: TransportConnectedDevice }
|
|
85
|
-
*/
|
|
86
25
|
disconnect(params: {
|
|
87
26
|
connectedDevice: TransportConnectedDevice;
|
|
88
27
|
}): Promise<Either<DmkError, void>>;
|
|
28
|
+
private _handleGattServerDisconnected;
|
|
29
|
+
private _waitForAdvertisementInRange;
|
|
30
|
+
private _rediscoverPermittedDevice;
|
|
31
|
+
private _tryToReconnect;
|
|
32
|
+
private _safelyCancelGattConnection;
|
|
33
|
+
private _identifyLedgerGattService;
|
|
34
|
+
private _getPrimaryLedgerGattService;
|
|
35
|
+
private _resolveLedgerServiceCharacteristics;
|
|
36
|
+
private _findWritableCharacteristic;
|
|
37
|
+
private _publishDiscoveredDevices;
|
|
38
|
+
private _withTimeout;
|
|
39
|
+
private _sleep;
|
|
89
40
|
}
|
|
90
41
|
export declare const webBleTransportFactory: TransportFactory;
|
|
91
42
|
//# sourceMappingURL=WebBleTransport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebBleTransport.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/WebBleTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"WebBleTransport.d.ts","sourceRoot":"","sources":["../../../../src/api/transport/WebBleTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAGjB,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EAEb,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EACd,wBAAwB,EAExB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAEzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAe,MAAM,WAAW,CAAC;AACrD,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAgB9D,eAAO,MAAM,gBAAgB,EAAE,mBAAwC,CAAC;AAexE,qBAAa,eAAgB,YAAW,SAAS;IAa7C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAfvC,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,kCAAkC,CAGtC;IACJ,OAAO,CAAC,mBAAmB,CAA0C;IACrE,OAAO,CAAC,mBAAmB,CAErB;gBAGa,sBAAsB,EAAE,qBAAqB,EACtD,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB,EAC7C,kBAAkB,EAAE,wBAAwB,EAC5C,oBAAoB,EAAE,0BAA0B;IAKnE,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,mBAAmB;IAIpC,gBAAgB,IAAI,UAAU,CAAC,yBAAyB,CAAC;IAoCzD,eAAe,IAAI,IAAI;IAIvB,wBAAwB,IAAI,UAAU,CAAC,yBAAyB,EAAE,CAAC;IAK7D,OAAO,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QACzC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAC1D,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IAmHrD,UAAU,CAAC,MAAM,EAAE;QACvB,eAAe,EAAE,wBAAwB,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IA0BnC,OAAO,CAAC,6BAA6B;YAQvB,4BAA4B;YAyC5B,0BAA0B;YA4B1B,eAAe;YAgGf,2BAA2B;YAQ3B,0BAA0B;YAkB1B,4BAA4B;YAyD5B,oCAAoC;YAiBpC,2BAA2B;IA6BzC,OAAO,CAAC,yBAAyB;IAqBjC,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,MAAM;CAGf;AAED,eAAO,MAAM,sBAAsB,EAAE,gBAWlC,CAAC"}
|