@xyo-network/xl1-cli-lib 1.14.4 → 1.15.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/dist/node/index.mjs +146 -78
  2. package/dist/node/index.mjs.map +1 -1
  3. package/dist/node/orchestration/initServices.d.ts.map +1 -1
  4. package/dist/node/orchestration/map/BalanceSummary/index.d.ts +1 -0
  5. package/dist/node/orchestration/map/BalanceSummary/index.d.ts.map +1 -1
  6. package/dist/node/orchestration/map/BalanceSummary/{local.d.ts → initLocalBalanceSummaryMap.d.ts} +1 -1
  7. package/dist/node/orchestration/map/BalanceSummary/initLocalBalanceSummaryMap.d.ts.map +1 -0
  8. package/dist/node/orchestration/map/BalanceSummary/initLocalTransferSummaryMap.d.ts +7 -0
  9. package/dist/node/orchestration/map/BalanceSummary/initLocalTransferSummaryMap.d.ts.map +1 -0
  10. package/dist/node/orchestration/map/BalanceSummary/initTransferSummaryMap.d.ts +7 -0
  11. package/dist/node/orchestration/map/BalanceSummary/initTransferSummaryMap.d.ts.map +1 -0
  12. package/dist/node/orchestration/services/implementation/evm/initEvmProvider.d.ts +2 -2
  13. package/dist/node/orchestration/services/implementation/evm/initEvmProvider.d.ts.map +1 -1
  14. package/dist/node/orchestration/services/implementation/head/createBootstrapHead.d.ts +2 -2
  15. package/dist/node/orchestration/services/implementation/head/createBootstrapHead.d.ts.map +1 -1
  16. package/dist/node/orchestration/services/implementation/head/createForkedHead/getFirstBlockForNewChain.d.ts.map +1 -1
  17. package/dist/node/orchestration/services/implementation/head/head.d.ts.map +1 -1
  18. package/dist/node/orchestration/services/implementation/index.d.ts +1 -0
  19. package/dist/node/orchestration/services/implementation/index.d.ts.map +1 -1
  20. package/dist/node/orchestration/services/implementation/time.d.ts +4 -0
  21. package/dist/node/orchestration/services/implementation/time.d.ts.map +1 -0
  22. package/dist/node/orchestration/services/implementation/transfer.d.ts +4 -0
  23. package/dist/node/orchestration/services/implementation/transfer.d.ts.map +1 -0
  24. package/dist/node/runCLI.d.ts.map +1 -1
  25. package/dist/node/xl1.mjs +145 -78
  26. package/dist/node/xl1.mjs.map +1 -1
  27. package/package.json +8 -7
  28. package/src/optionsFromGlobalZodRegistry.ts +1 -1
  29. package/src/orchestration/initServices.ts +32 -16
  30. package/src/orchestration/map/BalanceSummary/index.ts +1 -0
  31. package/src/orchestration/map/BalanceSummary/initBalanceSummaryMap.ts +1 -1
  32. package/src/orchestration/map/BalanceSummary/initLocalTransferSummaryMap.ts +21 -0
  33. package/src/orchestration/map/BalanceSummary/initTransferSummaryMap.ts +22 -0
  34. package/src/orchestration/services/implementation/evm/initEvmProvider.ts +2 -1
  35. package/src/orchestration/services/implementation/head/createBootstrapHead.ts +27 -5
  36. package/src/orchestration/services/implementation/head/createForkedHead/config/getBridgeDestinationDetails.ts +3 -3
  37. package/src/orchestration/services/implementation/head/createForkedHead/getFirstBlockForNewChain.ts +5 -6
  38. package/src/orchestration/services/implementation/head/head.ts +4 -3
  39. package/src/orchestration/services/implementation/index.ts +1 -0
  40. package/src/orchestration/services/implementation/time.ts +23 -0
  41. package/src/orchestration/services/implementation/transfer.ts +13 -0
  42. package/src/runCLI.ts +1 -0
  43. package/dist/node/orchestration/map/BalanceSummary/local.d.ts.map +0 -1
  44. /package/src/orchestration/map/BalanceSummary/{local.ts → initLocalBalanceSummaryMap.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/xl1-cli-lib",
3
- "version": "1.14.4",
3
+ "version": "1.15.0",
4
4
  "description": "XYO Layer One CLI Library",
5
5
  "homepage": "https://xylabs.com",
6
6
  "bugs": {
@@ -55,27 +55,28 @@
55
55
  "@xyo-network/archivist-lmdb": "~5.1.2",
56
56
  "@xyo-network/archivist-memory": "~5.1.2",
57
57
  "@xyo-network/archivist-model": "~5.1.2",
58
- "@xyo-network/chain-api": "~1.14.4",
59
- "@xyo-network/chain-sdk": "~1.14.4",
58
+ "@xyo-network/chain-api": "~1.15.0",
59
+ "@xyo-network/chain-sdk": "~1.15.0",
60
60
  "@xyo-network/payload-builder": "~5.1.2",
61
61
  "@xyo-network/payload-model": "~5.1.2",
62
62
  "@xyo-network/wallet": "~5.1.2",
63
63
  "@xyo-network/wallet-model": "~5.1.2",
64
- "@xyo-network/xl1-protocol": "~1.12.22",
65
- "@xyo-network/xl1-protocol-sdk": "~1.14.4",
64
+ "@xyo-network/xl1-protocol": "~1.12.32",
65
+ "@xyo-network/xl1-protocol-sdk": "~1.15.0",
66
66
  "async-mutex": "~0.5.0",
67
67
  "cosmiconfig": "~9.0.0",
68
68
  "dotenv": "~17.2.2",
69
69
  "ethers": "~6.15.0",
70
70
  "lmdb": "~3.4.2",
71
71
  "yargs": "~18.0.0",
72
- "zod": "~4.1.5"
72
+ "zod": "~4.1.8"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@xylabs/ts-scripts-yarn3": "~7.1.7",
76
76
  "@xylabs/tsconfig": "~7.1.7",
77
77
  "@xylabs/vitest-extended": "~5.0.11",
78
- "eslint": "^9.34.0",
78
+ "@xyo-network/account-model": "~5.1.2",
79
+ "eslint": "^9.35.0",
79
80
  "nodemon": "~3.1.10",
80
81
  "rimraf": "~6.0.1",
81
82
  "tslib": "~2.8.1",
@@ -9,7 +9,7 @@ const usageMetaToOptions = (meta: UsageMeta): Options => {
9
9
 
10
10
  export const optionsFromGlobalZodRegistry = (): Record<string, Options> => {
11
11
  const opts: Record<string, Options> = {}
12
- for (const schema of globalRegistry._map.values()) {
12
+ for (const schema of Object.values(globalRegistry._map)) {
13
13
  if (isUsageMeta(schema)) {
14
14
  if (schema.hidden) continue // skip hidden options
15
15
  opts[schema.title] = usageMetaToOptions(schema)
@@ -5,7 +5,7 @@ import type { Logger } from '@xylabs/logger'
5
5
  import { isDefined } from '@xylabs/typeof'
6
6
  import type { BaseBlockProducerServiceParams, XyoValidatorParams } from '@xyo-network/chain-sdk'
7
7
  import {
8
- balanceSummaryRepositoryFromMap, BaseTimeSyncService, initTelemetry, startupSpanAsync, validateHydratedBlockState,
8
+ balanceSummaryRepositoryFromMap, initTelemetry, startupSpanAsync, validateHydratedBlockState,
9
9
  } from '@xyo-network/chain-sdk'
10
10
  import type { ChainServiceCollectionV2, Config } from '@xyo-network/xl1-protocol-sdk'
11
11
 
@@ -15,10 +15,12 @@ import {
15
15
  } from './archivists/index.ts'
16
16
  import type { ChainInitializableParams } from './ChainInitializableParams.ts'
17
17
  import { initHealthEndpoints } from './health/index.ts'
18
- import { initBalanceSummaryMap } from './map/index.ts'
18
+ import { initBalanceSummaryMap, initTransferSummaryMap } from './map/index.ts'
19
19
  import {
20
- initAccount, initBalanceService, initBlockProducer, initBlockRewardService, initChainIterator, initChainService, initElectionService, initHead,
20
+ initAccount, initBalanceService, initBlockProducer,
21
+ initBlockRewardService, initChainIterator, initChainService, initElectionService, initHead,
21
22
  initPendingTransactions, initStakeIntentService,
23
+ initTimeService,
22
24
  } from './services/index.ts'
23
25
  import { RuntimeStatusMonitor } from './status/index.ts'
24
26
 
@@ -81,6 +83,7 @@ export const initServices = async (context: InitServicesContext): Promise<ChainS
81
83
  stakeIntentStateArchivist,
82
84
  chainService,
83
85
  balanceSummaryMap,
86
+ transferSummaryMap,
84
87
  ] = await Promise.all([
85
88
  startupSpanAsync(
86
89
  'ChainFinalizedArchivist',
@@ -112,6 +115,10 @@ export const initServices = async (context: InitServicesContext): Promise<ChainS
112
115
  'BalanceSummaryMap',
113
116
  () => initBalanceSummaryMap(initParams),
114
117
  ),
118
+ startupSpanAsync(
119
+ 'TransferSummaryMap',
120
+ () => initTransferSummaryMap(initParams),
121
+ ),
115
122
  ])
116
123
 
117
124
  const chainId = chainService.chainId
@@ -164,17 +171,28 @@ export const initServices = async (context: InitServicesContext): Promise<ChainS
164
171
  ),
165
172
  ])
166
173
 
167
- const stakeIntentService = await startupSpanAsync(
168
- 'StakeIntentService',
169
- () => initStakeIntentService({
170
- name: 'StakeIntentService' as CreatableName,
171
- chainArchivist,
172
- chainIterator,
173
- chainStakeViewer,
174
- stakeIntentStateArchivist,
175
- ...initParams,
176
- }),
177
- )
174
+ const [stakeIntentService, time] = await Promise.all([
175
+ startupSpanAsync(
176
+ 'StakeIntentService',
177
+ () => initStakeIntentService({
178
+ name: 'StakeIntentService' as CreatableName,
179
+ chainArchivist,
180
+ chainIterator,
181
+ chainStakeViewer,
182
+ stakeIntentStateArchivist,
183
+ ...initParams,
184
+ }),
185
+ ),
186
+ startupSpanAsync(
187
+ 'TimeService',
188
+ () => initTimeService({
189
+ name: 'TimeService' as CreatableName,
190
+ chainArchivist,
191
+ chainIterator,
192
+ ...initParams,
193
+ }),
194
+ ),
195
+ ])
178
196
 
179
197
  const electionService = await startupSpanAsync(
180
198
  'ElectionService',
@@ -200,8 +218,6 @@ export const initServices = async (context: InitServicesContext): Promise<ChainS
200
218
  ...initParams,
201
219
  }
202
220
 
203
- const time = await BaseTimeSyncService.create({ chainArchivist, chainIterator })
204
-
205
221
  const rewardAddress = isDefined(config.producer.rewardAddress)
206
222
  ? assertEx(asAddress(config.producer.rewardAddress), () => 'Invalid block reward address provided')
207
223
  : account.address
@@ -1 +1,2 @@
1
1
  export * from './initBalanceSummaryMap.ts'
2
+ export * from './initTransferSummaryMap.ts'
@@ -7,7 +7,7 @@ import type { BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
7
7
  import { Mutex } from 'async-mutex'
8
8
 
9
9
  import type { ChainInitializableParams } from '../../ChainInitializableParams.ts'
10
- import { initLocalBalanceSummaryMap } from './local.ts'
10
+ import { initLocalBalanceSummaryMap } from './initLocalBalanceSummaryMap.ts'
11
11
 
12
12
  const mutex = new Mutex()
13
13
  let singleton: MapType<Hash, WithStorageMeta<BalancesStepSummary>> | undefined
@@ -0,0 +1,21 @@
1
+ import type { Hash } from '@xylabs/hex'
2
+ import { isDefined } from '@xylabs/typeof'
3
+ import type { MapType } from '@xyo-network/chain-sdk'
4
+ import type { WithStorageMeta } from '@xyo-network/payload-model'
5
+ import type { BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
6
+ import { Mutex } from 'async-mutex'
7
+
8
+ import type { ChainInitializableParams } from '../../ChainInitializableParams.ts'
9
+ import { getLocalPersistentMap } from '../localPersistentMap.ts'
10
+
11
+ const mutex = new Mutex()
12
+ let singleton: MapType<Hash, WithStorageMeta<BalancesStepSummary>> | undefined
13
+
14
+ export const initLocalTransferSummaryMap = async (params: ChainInitializableParams): Promise<MapType<Hash, WithStorageMeta<BalancesStepSummary>>> => {
15
+ return await mutex.runExclusive(async () => {
16
+ if (isDefined(singleton)) return singleton
17
+ const { root } = params.config.storage
18
+ singleton = await getLocalPersistentMap<Hash, WithStorageMeta<BalancesStepSummary>>('transfer', 'summary', root)
19
+ return singleton
20
+ })
21
+ }
@@ -0,0 +1,22 @@
1
+ import type { Hash } from '@xylabs/hex'
2
+ import { isDefined } from '@xylabs/typeof'
3
+ import type { MapType } from '@xyo-network/chain-sdk'
4
+ import { startupSpanAsync } from '@xyo-network/chain-sdk'
5
+ import type { WithStorageMeta } from '@xyo-network/payload-model'
6
+ import type { BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
7
+ import { Mutex } from 'async-mutex'
8
+
9
+ import type { ChainInitializableParams } from '../../ChainInitializableParams.ts'
10
+ import { initLocalTransferSummaryMap } from './initLocalTransferSummaryMap.ts'
11
+
12
+ const mutex = new Mutex()
13
+ let singleton: MapType<Hash, WithStorageMeta<BalancesStepSummary>> | undefined
14
+
15
+ export async function initTransferSummaryMap(params: ChainInitializableParams): Promise<MapType<Hash, WithStorageMeta<BalancesStepSummary>>> {
16
+ return await mutex.runExclusive(async () => {
17
+ if (isDefined(singleton)) return singleton
18
+ const local = await startupSpanAsync('TransferSummaryMap:initLocal', () => initLocalTransferSummaryMap(params))
19
+ singleton = local
20
+ return singleton
21
+ })
22
+ }
@@ -1,6 +1,7 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
2
  import type { Logger } from '@xylabs/logger'
3
3
  import type { Config } from '@xyo-network/xl1-protocol-sdk'
4
+ import type { Provider } from 'ethers'
4
5
  import type { JsonRpcProvider } from 'ethers/providers'
5
6
 
6
7
  import { canUseInfuraProvider, initInfuraProvider } from './initInfuraProvider.ts'
@@ -8,7 +9,7 @@ import { canUseJsonRpcProvider, initJsonRpcProvider } from './initJsonRpcProvide
8
9
 
9
10
  let provider: Promise<JsonRpcProvider> | undefined
10
11
 
11
- export const initEvmProvider = async ({ config }: { config: Config; logger?: Logger }) => {
12
+ export const initEvmProvider = async ({ config }: { config: Config; logger?: Logger }): Promise<Provider> => {
12
13
  if (provider) return provider
13
14
  if (canUseInfuraProvider(config)) {
14
15
  provider = initInfuraProvider(config)
@@ -1,8 +1,30 @@
1
- import { ZERO_ADDRESS } from '@xylabs/hex'
2
- import { createGenesisBlock } from '@xyo-network/chain-sdk'
1
+ import {
2
+ buildNextBlock, createDeclarationIntent, createGenesisBlock,
3
+ } from '@xyo-network/chain-sdk'
3
4
  import type { WalletInstance } from '@xyo-network/wallet-model'
4
- import type { HydratedBlock } from '@xyo-network/xl1-protocol'
5
+ import type { ChainService, HydratedBlock } from '@xyo-network/xl1-protocol'
5
6
 
6
- export const createBootstrapHead = async (account: WalletInstance): Promise<HydratedBlock> => {
7
- return await createGenesisBlock(account, ZERO_ADDRESS, 10_000_000n, account.address)
7
+ export const createBootstrapHead = async (account: WalletInstance, chainService: ChainService): Promise<HydratedBlock[]> => {
8
+ const chainId = chainService.chainId
9
+ const chain: HydratedBlock[] = []
10
+
11
+ // Create genesis block
12
+ const genesisBlock = await createGenesisBlock(account, chainId, 10_000_000n, account.address)
13
+ chain.push(genesisBlock)
14
+
15
+ // Create producer declaration block
16
+ const producerDeclarationPayload = createDeclarationIntent(
17
+ account.address,
18
+ 'producer',
19
+ genesisBlock[0].block,
20
+ genesisBlock[0].block + 10_000,
21
+ )
22
+ const producerDeclarationBlock = await buildNextBlock(
23
+ genesisBlock[0],
24
+ [],
25
+ [producerDeclarationPayload],
26
+ [account],
27
+ )
28
+ chain.push(producerDeclarationBlock)
29
+ return chain
8
30
  }
@@ -7,9 +7,9 @@ import { getForkBlockRewardHex } from './getForkDetails.ts'
7
7
  // const bridgeDestAddress = toHex('0xe53218d47913b5f9E58bb74F0a0eD790bbF21972')
8
8
  // const destConfirmation = toHex('0x4fa05d7e799f36f1d45c441a4866eb4570a00a753a39377f404a8d113c01a657') // Eth TX for mint
9
9
  const ethChainId = toHex('0x1')
10
- const bridgeableTokenContract = toHex('0x7789e11BB83b398A8Cca8E8D582B33F91499D6f5')
11
- const bridgeDestAddress = toHex('0xe53218d47913b5f9E58bb74F0a0eD790bbF21972')
12
- const destConfirmation = toHex('0x772ee028f9ad291ec692912c1a33ecd4409e71383fe06f6ebf39f7cdbb779069') // Eth TX for mint
10
+ const bridgeableTokenContract = toHex('0xf72aE3E0DA743033AbD7A407557D684c1aE66aed')
11
+ const bridgeDestAddress = toHex('0x0e65b65B10C791942665030402c35023d88B14dA')
12
+ const destConfirmation = toHex('0x950861b10523b52cdbb4a9ee52ed26601db555d2652bfec21c709e5e70d5b7d3') // Eth TX for mint
13
13
 
14
14
  export const getBridgeDestChainId = () => ethChainId
15
15
  export const getBridgeDestToken = () => bridgeableTokenContract
@@ -1,13 +1,13 @@
1
1
  import type { BuildNextBlockOptions } from '@xyo-network/chain-sdk'
2
- import { buildBlock } from '@xyo-network/chain-sdk'
2
+ import {
3
+ AttoXL1, buildBlock, XYO_STEP_REWARD_ADDRESS,
4
+ } from '@xyo-network/chain-sdk'
3
5
  import type { WithHashStorageMeta } from '@xyo-network/payload-model'
4
6
  import type { WalletInstance } from '@xyo-network/wallet-model'
5
7
  import type {
6
8
  BlockBoundWitness, ChainService, HydratedBlock,
7
9
  } from '@xyo-network/xl1-protocol'
8
10
 
9
- import { getForkBlockReward } from './config/index.ts'
10
-
11
11
  /**
12
12
  * Get the first block for the new forked chain.
13
13
  * @param forkBlock The block to fork from
@@ -24,7 +24,6 @@ export const getFirstBlockForNewChain = async (
24
24
  _hash: previousBlockHash, block: previousBlockNumber, step_hashes: previousStepHashes, protocol,
25
25
  } = forkBlock
26
26
  const chainId = chainService.chainId
27
- const forkBlockReward = getForkBlockReward()
28
27
  const options: BuildNextBlockOptions = {
29
28
  blockPayloads: [],
30
29
  chainId,
@@ -34,8 +33,8 @@ export const getFirstBlockForNewChain = async (
34
33
  signers: [account],
35
34
  txs: [],
36
35
  protocol,
37
- reward: forkBlockReward,
38
- rewardAddress: account.address,
36
+ stepRewardAddress: XYO_STEP_REWARD_ADDRESS,
37
+ stepRewardPoolBalance: AttoXL1(0n),
39
38
  }
40
39
  // NOTE: Can not use buildNextBlock because we need to control the chain id change here
41
40
  return await buildBlock(options)
@@ -43,9 +43,10 @@ export const initHead: Initializable<{
43
43
  }
44
44
  } else {
45
45
  // If there is no head, create one
46
- const genesisBlock = await createBootstrapHead(account)
47
- await submitNewChain([genesisBlock], chainArchivist, chainSubmissionsArchivistWrite)
48
- head = genesisBlock[0]
46
+ const chain = await createBootstrapHead(account, chainService)
47
+ await submitNewChain(chain, chainArchivist, chainSubmissionsArchivistWrite)
48
+ const newBlock = assertEx(chain.at(-1), () => new Error('Failed to get new head after genesis'))
49
+ head = newBlock[0]
49
50
  }
50
51
  headSingleton = head
51
52
  return headSingleton
@@ -7,4 +7,5 @@ export * from './iterator.ts'
7
7
  export * from './pendingTransactions.ts'
8
8
  export * from './producer.ts'
9
9
  export * from './reward.ts'
10
+ export * from './time.ts'
10
11
  export * from './validator.ts'
@@ -0,0 +1,23 @@
1
+ import type { Promisable } from '@xylabs/promise'
2
+ import type { BaseTimeServiceParams } from '@xyo-network/chain-sdk'
3
+ import { BaseTimeSyncService } from '@xyo-network/chain-sdk'
4
+ import type { Initializable, TimeSyncServiceV2 } from '@xyo-network/xl1-protocol'
5
+
6
+ import { canUseEvmProvider, initEvmProvider } from './evm/index.ts'
7
+
8
+ let timeSyncServiceSingleton: Promisable<TimeSyncServiceV2> | undefined
9
+
10
+ export const initTimeService: Initializable<BaseTimeServiceParams, TimeSyncServiceV2> = async ({
11
+ chainArchivist, chainIterator, config, logger, meterProvider, traceProvider,
12
+ }) => {
13
+ if (timeSyncServiceSingleton) return timeSyncServiceSingleton
14
+
15
+ // Configure provider for optional Ethereum time sync
16
+ const ethProvider = canUseEvmProvider({ config }) ? await initEvmProvider({ config }) : undefined
17
+
18
+ // Create service
19
+ timeSyncServiceSingleton = BaseTimeSyncService.create({
20
+ chainArchivist, chainIterator, ethProvider, logger, meterProvider, traceProvider,
21
+ })
22
+ return await timeSyncServiceSingleton
23
+ }
@@ -0,0 +1,13 @@
1
+ import type { Promisable } from '@xylabs/promise'
2
+ import type { BaseAccountTransferServiceParams } from '@xyo-network/chain-sdk'
3
+ import { BaseAccountTransfersService } from '@xyo-network/chain-sdk'
4
+ import type { AccountTransfersService, Initializable } from '@xyo-network/xl1-protocol'
5
+
6
+ let transferServiceSingleton: Promisable<AccountTransfersService> | undefined
7
+
8
+ export const initTransferService: Initializable<BaseAccountTransferServiceParams, AccountTransfersService>
9
+ = async (params): Promise<AccountTransfersService> => {
10
+ if (transferServiceSingleton) return transferServiceSingleton
11
+ transferServiceSingleton = await BaseAccountTransfersService.create(params)
12
+ return transferServiceSingleton
13
+ }
package/src/runCLI.ts CHANGED
@@ -66,6 +66,7 @@ Usage:
66
66
  $0 <command> [options]`)
67
67
  .parserConfiguration({
68
68
  'dot-notation': true, // foo.bar → { foo: { bar } }
69
+ 'parse-numbers': false, // Don't auto-parse numbers to allow strings like "0x1"
69
70
  'populate--': true, // Populate -- with all options so we can detected user-supplied vs defaults
70
71
  })
71
72
  .env('XL1')
@@ -1 +0,0 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../../../src/orchestration/map/BalanceSummary/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAGxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AAMjF,eAAO,MAAM,0BAA0B,GAAU,QAAQ,wBAAwB,KAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAO9I,CAAA"}