@fivenorth/loop-sdk 0.10.0 → 0.11.1

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/dist/index.js CHANGED
@@ -2092,232 +2092,6 @@ function isUnauthCode(code) {
2092
2092
  return UNAUTH_CODES.has(code);
2093
2093
  }
2094
2094
 
2095
- // src/connection.ts
2096
- class Connection {
2097
- walletUrl = "https://cantonloop.com";
2098
- apiUrl = "https://cantonloop.com";
2099
- ws = null;
2100
- network = "main";
2101
- ticketId = null;
2102
- onMessageHandler = null;
2103
- reconnectPromise = null;
2104
- status = "disconnected";
2105
- constructor({ network, walletUrl, apiUrl }) {
2106
- this.network = network || "main";
2107
- switch (this.network) {
2108
- case "local":
2109
- this.walletUrl = "http://localhost:3000";
2110
- this.apiUrl = "http://localhost:8080";
2111
- break;
2112
- case "devnet":
2113
- case "dev":
2114
- this.walletUrl = "https://devnet.cantonloop.com";
2115
- this.apiUrl = "https://devnet.cantonloop.com";
2116
- break;
2117
- case "testnet":
2118
- case "test":
2119
- this.walletUrl = "https://testnet.cantonloop.com";
2120
- this.apiUrl = "https://testnet.cantonloop.com";
2121
- break;
2122
- case "mainnet":
2123
- case "main":
2124
- this.walletUrl = "https://cantonloop.com";
2125
- this.apiUrl = "https://cantonloop.com";
2126
- break;
2127
- }
2128
- if (walletUrl) {
2129
- this.walletUrl = walletUrl;
2130
- }
2131
- if (apiUrl) {
2132
- this.apiUrl = apiUrl;
2133
- }
2134
- }
2135
- connectInProgress() {
2136
- return this.status === "connecting" || this.status === "connected";
2137
- }
2138
- async getTicket(appName, sessionId, version) {
2139
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/tickets`, {
2140
- method: "POST",
2141
- headers: {
2142
- "Content-Type": "application/json"
2143
- },
2144
- body: JSON.stringify({
2145
- app_name: appName,
2146
- session_id: sessionId,
2147
- version
2148
- })
2149
- });
2150
- if (!response.ok) {
2151
- throw new Error("Failed to get ticket from server.");
2152
- }
2153
- return response.json();
2154
- }
2155
- async getHolding(authToken) {
2156
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account/holding`, {
2157
- method: "GET",
2158
- headers: {
2159
- "Content-Type": "application/json",
2160
- Authorization: `Bearer ${authToken}`
2161
- }
2162
- });
2163
- if (!response.ok) {
2164
- throw new Error("Failed to get holdings.");
2165
- }
2166
- return response.json();
2167
- }
2168
- async getActiveContracts(authToken, params) {
2169
- const url = new URL(`${this.apiUrl}/api/v1/.connect/pair/account/active-contracts`);
2170
- if (params?.templateId) {
2171
- url.searchParams.append("templateId", params.templateId);
2172
- }
2173
- if (params?.interfaceId) {
2174
- url.searchParams.append("interfaceId", params.interfaceId);
2175
- }
2176
- const response = await fetch(url.toString(), {
2177
- method: "GET",
2178
- headers: {
2179
- "Content-Type": "application/json",
2180
- Authorization: `Bearer ${authToken}`
2181
- }
2182
- });
2183
- if (!response.ok) {
2184
- throw new Error("Failed to get active contracts.");
2185
- }
2186
- return response.json();
2187
- }
2188
- async prepareTransfer(authToken, params) {
2189
- const payload = {
2190
- recipient: params.recipient,
2191
- amount: params.amount
2192
- };
2193
- if (params.instrument) {
2194
- if (params.instrument.instrument_admin) {
2195
- payload.instrument_admin = params.instrument.instrument_admin;
2196
- }
2197
- if (params.instrument.instrument_id) {
2198
- payload.instrument_id = params.instrument.instrument_id;
2199
- }
2200
- }
2201
- if (params.requested_at) {
2202
- payload.requested_at = params.requested_at;
2203
- }
2204
- if (params.execute_before) {
2205
- payload.execute_before = params.execute_before;
2206
- }
2207
- if (params.memo) {
2208
- payload.memo = params.memo;
2209
- }
2210
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/transfer`, {
2211
- method: "POST",
2212
- headers: {
2213
- "Content-Type": "application/json",
2214
- Authorization: `Bearer ${authToken}`
2215
- },
2216
- body: JSON.stringify(payload)
2217
- });
2218
- if (!response.ok) {
2219
- throw new Error("Failed to prepare transfer.");
2220
- }
2221
- const data = await response.json();
2222
- return data.payload;
2223
- }
2224
- async verifySession(authToken) {
2225
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account`, {
2226
- method: "GET",
2227
- headers: {
2228
- "Content-Type": "application/json",
2229
- Authorization: `Bearer ${authToken}`
2230
- }
2231
- });
2232
- if (!response.ok) {
2233
- if (response.status === 401 || response.status === 403) {
2234
- throw new UnauthorizedError;
2235
- }
2236
- throw new Error(`Session verification failed with status ${response.status}.`);
2237
- }
2238
- const data = await response.json();
2239
- const email = data?.email;
2240
- if (!data?.party_id || !data?.public_key) {
2241
- throw new Error("Invalid session verification response.");
2242
- }
2243
- const account = {
2244
- party_id: data?.party_id,
2245
- auth_token: authToken,
2246
- public_key: data?.public_key,
2247
- email,
2248
- has_preapproval: data?.has_preapproval,
2249
- has_merge_delegation: data?.has_merge_delegation,
2250
- usdc_bridge_access: data?.usdc_bridge_access
2251
- };
2252
- return account;
2253
- }
2254
- connectWebSocket(ticketId, onMessage) {
2255
- if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ticketId !== ticketId) {
2256
- this.ws.close();
2257
- this.ws = null;
2258
- }
2259
- if (this.status === "connecting" || this.status === "connected") {
2260
- return;
2261
- }
2262
- this.onMessageHandler = onMessage;
2263
- this.ticketId = ticketId;
2264
- this.status = "connecting";
2265
- this.attachWebSocket(ticketId, onMessage);
2266
- }
2267
- reconnect() {
2268
- if (!this.ticketId || !this.onMessageHandler) {
2269
- return Promise.reject(new Error("Cannot reconnect without a known ticket."));
2270
- }
2271
- return new Promise((resolve, reject) => {
2272
- let opened = false;
2273
- this.attachWebSocket(this.ticketId, this.onMessageHandler, () => {
2274
- opened = true;
2275
- resolve();
2276
- }, () => {
2277
- if (opened) {
2278
- return;
2279
- }
2280
- reject(new Error("Failed to reconnect to ticket server."));
2281
- }, () => {
2282
- if (opened) {
2283
- return;
2284
- }
2285
- reject(new Error("Failed to reconnect to ticket server."));
2286
- });
2287
- });
2288
- }
2289
- websocketUrl(ticketId) {
2290
- return `${this.network === "local" ? "ws" : "wss"}://${this.apiUrl.replace("https://", "").replace("http://", "")}/api/v1/.connect/pair/ws/${encodeURIComponent(ticketId)}`;
2291
- }
2292
- attachWebSocket(ticketId, onMessage, onOpen, onError, onClose) {
2293
- const wsUrl = this.websocketUrl(ticketId);
2294
- const ws = new WebSocket(wsUrl);
2295
- ws.onmessage = onMessage;
2296
- ws.onopen = () => {
2297
- this.status = "connected";
2298
- console.log("[LoopSDK] Connected to ticket server.");
2299
- onOpen?.();
2300
- };
2301
- ws.onclose = (event) => {
2302
- this.status = "disconnected";
2303
- if (this.ws === ws) {
2304
- this.ws = null;
2305
- }
2306
- console.log("[LoopSDK] Disconnected from ticket server.");
2307
- onClose?.(event);
2308
- };
2309
- ws.onerror = (event) => {
2310
- this.status = "disconnected";
2311
- ws.close();
2312
- if (this.ws === ws) {
2313
- this.ws = null;
2314
- }
2315
- onError?.(event);
2316
- };
2317
- this.ws = ws;
2318
- }
2319
- }
2320
-
2321
2095
  // src/types.ts
2322
2096
  var MessageType;
2323
2097
  ((MessageType2) => {
@@ -2400,10 +2174,12 @@ class Provider {
2400
2174
  }
2401
2175
  async submitTransaction(payload, options) {
2402
2176
  const requestPayload = options?.estimateTraffic ? { ...payload, estimate_traffic: true } : payload;
2403
- return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, requestPayload, options);
2177
+ const executionMode = options?.executionMode;
2178
+ const finalPayload = executionMode === "wait" ? { ...requestPayload, execution_mode: "wait" } : requestPayload;
2179
+ return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, finalPayload, options);
2404
2180
  }
2405
2181
  async submitAndWaitForTransaction(payload, options) {
2406
- const requestPayload = options?.estimateTraffic ? { ...payload, estimateTraffic: true } : payload;
2182
+ const requestPayload = options?.estimateTraffic ? { ...payload, estimate_traffic: true } : payload;
2407
2183
  return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, { ...requestPayload, execution_mode: "wait" }, options);
2408
2184
  }
2409
2185
  async transfer(recipient, amount, instrument, options) {
@@ -2559,6 +2335,283 @@ class Provider {
2559
2335
  }
2560
2336
  }
2561
2337
 
2338
+ // src/connection.ts
2339
+ class Connection {
2340
+ walletUrl = "https://cantonloop.com";
2341
+ apiUrl = "https://cantonloop.com";
2342
+ ws = null;
2343
+ network = "main";
2344
+ ticketId = null;
2345
+ onMessageHandler = null;
2346
+ reconnectPromise = null;
2347
+ status = "disconnected";
2348
+ constructor({ network, walletUrl, apiUrl }) {
2349
+ this.network = network || "main";
2350
+ switch (this.network) {
2351
+ case "local":
2352
+ this.walletUrl = "http://localhost:3000";
2353
+ this.apiUrl = "http://localhost:8080";
2354
+ break;
2355
+ case "devnet":
2356
+ case "dev":
2357
+ this.walletUrl = "https://devnet.cantonloop.com";
2358
+ this.apiUrl = "https://devnet.cantonloop.com";
2359
+ break;
2360
+ case "testnet":
2361
+ case "test":
2362
+ this.walletUrl = "https://testnet.cantonloop.com";
2363
+ this.apiUrl = "https://testnet.cantonloop.com";
2364
+ break;
2365
+ case "mainnet":
2366
+ case "main":
2367
+ this.walletUrl = "https://cantonloop.com";
2368
+ this.apiUrl = "https://cantonloop.com";
2369
+ break;
2370
+ }
2371
+ if (walletUrl) {
2372
+ this.walletUrl = walletUrl;
2373
+ }
2374
+ if (apiUrl) {
2375
+ this.apiUrl = apiUrl;
2376
+ }
2377
+ }
2378
+ connectInProgress() {
2379
+ return this.status === "connecting" || this.status === "connected";
2380
+ }
2381
+ async getTicket(appName, sessionId, version) {
2382
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/tickets`, {
2383
+ method: "POST",
2384
+ headers: {
2385
+ "Content-Type": "application/json"
2386
+ },
2387
+ body: JSON.stringify({
2388
+ app_name: appName,
2389
+ session_id: sessionId,
2390
+ version
2391
+ })
2392
+ });
2393
+ if (!response.ok) {
2394
+ throw new Error("Failed to get ticket from server.");
2395
+ }
2396
+ return response.json();
2397
+ }
2398
+ async getHolding(authToken) {
2399
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account/holding`, {
2400
+ method: "GET",
2401
+ headers: {
2402
+ "Content-Type": "application/json",
2403
+ Authorization: `Bearer ${authToken}`
2404
+ }
2405
+ });
2406
+ if (!response.ok) {
2407
+ throw new Error("Failed to get holdings. " + await response.text());
2408
+ }
2409
+ return response.json();
2410
+ }
2411
+ async getActiveContracts(authToken, params) {
2412
+ const url = new URL(`${this.apiUrl}/api/v1/.connect/pair/account/active-contracts`);
2413
+ if (params?.templateId) {
2414
+ url.searchParams.append("templateId", params.templateId);
2415
+ }
2416
+ if (params?.interfaceId) {
2417
+ url.searchParams.append("interfaceId", params.interfaceId);
2418
+ }
2419
+ const response = await fetch(url.toString(), {
2420
+ method: "GET",
2421
+ headers: {
2422
+ "Content-Type": "application/json",
2423
+ Authorization: `Bearer ${authToken}`
2424
+ }
2425
+ });
2426
+ if (!response.ok) {
2427
+ throw new Error("Failed to get active contracts.");
2428
+ }
2429
+ return response.json();
2430
+ }
2431
+ async prepareTransfer(authToken, params) {
2432
+ const payload = {
2433
+ recipient: params.recipient,
2434
+ amount: params.amount
2435
+ };
2436
+ if (params.instrument) {
2437
+ if (params.instrument.instrument_admin) {
2438
+ payload.instrument_admin = params.instrument.instrument_admin;
2439
+ }
2440
+ if (params.instrument.instrument_id) {
2441
+ payload.instrument_id = params.instrument.instrument_id;
2442
+ }
2443
+ }
2444
+ if (params.requested_at) {
2445
+ payload.requested_at = params.requested_at;
2446
+ }
2447
+ if (params.execute_before) {
2448
+ payload.execute_before = params.execute_before;
2449
+ }
2450
+ if (params.memo) {
2451
+ payload.memo = params.memo;
2452
+ }
2453
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/transfer`, {
2454
+ method: "POST",
2455
+ headers: {
2456
+ "Content-Type": "application/json",
2457
+ Authorization: `Bearer ${authToken}`
2458
+ },
2459
+ body: JSON.stringify(payload)
2460
+ });
2461
+ if (!response.ok) {
2462
+ console.error("Failed to prepare transfer.", await response.text());
2463
+ throw new Error("Failed to prepare transfer.");
2464
+ }
2465
+ const data = await response.json();
2466
+ return data.payload;
2467
+ }
2468
+ async verifySession(authToken) {
2469
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account`, {
2470
+ method: "GET",
2471
+ headers: {
2472
+ "Content-Type": "application/json",
2473
+ Authorization: `Bearer ${authToken}`
2474
+ }
2475
+ });
2476
+ if (!response.ok) {
2477
+ if (response.status === 401 || response.status === 403) {
2478
+ throw new UnauthorizedError;
2479
+ }
2480
+ throw new Error(`Session verification failed with status ${response.status}.`);
2481
+ }
2482
+ const data = await response.json();
2483
+ const email = data?.email;
2484
+ if (!data?.party_id || !data?.public_key) {
2485
+ throw new Error("Invalid session verification response.");
2486
+ }
2487
+ const account = {
2488
+ party_id: data?.party_id,
2489
+ auth_token: authToken,
2490
+ public_key: data?.public_key,
2491
+ email,
2492
+ has_preapproval: data?.has_preapproval,
2493
+ has_merge_delegation: data?.has_merge_delegation,
2494
+ usdc_bridge_access: data?.usdc_bridge_access
2495
+ };
2496
+ return account;
2497
+ }
2498
+ connectWebSocket(ticketId, onMessage) {
2499
+ if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ticketId !== ticketId) {
2500
+ this.ws.close();
2501
+ this.ws = null;
2502
+ }
2503
+ if (this.status === "connecting" || this.status === "connected") {
2504
+ return;
2505
+ }
2506
+ this.onMessageHandler = onMessage;
2507
+ this.ticketId = ticketId;
2508
+ this.status = "connecting";
2509
+ this.attachWebSocket(ticketId, onMessage);
2510
+ }
2511
+ reconnect() {
2512
+ if (!this.ticketId || !this.onMessageHandler) {
2513
+ return Promise.reject(new Error("Cannot reconnect without a known ticket."));
2514
+ }
2515
+ return new Promise((resolve, reject) => {
2516
+ let opened = false;
2517
+ this.attachWebSocket(this.ticketId, this.onMessageHandler, () => {
2518
+ opened = true;
2519
+ resolve();
2520
+ }, () => {
2521
+ if (opened) {
2522
+ return;
2523
+ }
2524
+ reject(new Error("Failed to reconnect to ticket server."));
2525
+ }, () => {
2526
+ if (opened) {
2527
+ return;
2528
+ }
2529
+ reject(new Error("Failed to reconnect to ticket server."));
2530
+ });
2531
+ });
2532
+ }
2533
+ async exchangeApiKey({ publicKey, signature, epoch }) {
2534
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/apikey`, {
2535
+ method: "POST",
2536
+ headers: {
2537
+ "Content-Type": "application/json"
2538
+ },
2539
+ body: JSON.stringify({
2540
+ public_key: publicKey,
2541
+ signature,
2542
+ epoch
2543
+ })
2544
+ });
2545
+ if (!response.ok) {
2546
+ throw new Error("Failed to get API key from server.");
2547
+ }
2548
+ return response.json();
2549
+ }
2550
+ prepareTransaction(session, params) {
2551
+ return fetch(`${this.apiUrl}/api/v1/.connect/tickets/prepare-transaction`, {
2552
+ method: "POST",
2553
+ headers: {
2554
+ "Content-Type": "application/json",
2555
+ Authorization: `Bearer ${session.userApiKey}`
2556
+ },
2557
+ body: JSON.stringify({
2558
+ payload: params,
2559
+ ticket_id: session.ticketId
2560
+ })
2561
+ }).then((response) => response.json());
2562
+ }
2563
+ async executeTransaction(session, params) {
2564
+ if (!session.ticketId) {
2565
+ throw new Error("Ticket ID is required");
2566
+ }
2567
+ const resp = fetch(`${this.apiUrl}/api/v1/.connect/tickets/execute-transaction`, {
2568
+ method: "POST",
2569
+ headers: {
2570
+ "Content-Type": "application/json",
2571
+ Authorization: `Bearer ${session.userApiKey}`
2572
+ },
2573
+ body: JSON.stringify({
2574
+ ticket_id: session.ticketId,
2575
+ request_id: generateRequestId(),
2576
+ command_id: params.command_id,
2577
+ signature: params.signature,
2578
+ transaction_data: params.transaction_data
2579
+ })
2580
+ });
2581
+ return (await resp).json();
2582
+ }
2583
+ websocketUrl(ticketId) {
2584
+ return `${this.network === "local" ? "ws" : "wss"}://${this.apiUrl.replace("https://", "").replace("http://", "")}/api/v1/.connect/pair/ws/${encodeURIComponent(ticketId)}`;
2585
+ }
2586
+ attachWebSocket(ticketId, onMessage, onOpen, onError, onClose) {
2587
+ const wsUrl = this.websocketUrl(ticketId);
2588
+ const ws = new WebSocket(wsUrl);
2589
+ ws.onmessage = onMessage;
2590
+ ws.onopen = () => {
2591
+ this.status = "connected";
2592
+ console.log("[LoopSDK] Connected to ticket server.");
2593
+ onOpen?.();
2594
+ };
2595
+ ws.onclose = (event) => {
2596
+ this.status = "disconnected";
2597
+ if (this.ws === ws) {
2598
+ this.ws = null;
2599
+ }
2600
+ console.log("[LoopSDK] Disconnected from ticket server.");
2601
+ onClose?.(event);
2602
+ };
2603
+ ws.onerror = (event) => {
2604
+ this.status = "disconnected";
2605
+ ws.close();
2606
+ if (this.ws === ws) {
2607
+ this.ws = null;
2608
+ }
2609
+ onError?.(event);
2610
+ };
2611
+ this.ws = ws;
2612
+ }
2613
+ }
2614
+
2562
2615
  // src/session.ts
2563
2616
  var STORAGE_KEY_LOOP_CONNECT = "loop_connect";
2564
2617
 
@@ -2569,14 +2622,16 @@ class SessionInfo {
2569
2622
  partyId;
2570
2623
  publicKey;
2571
2624
  email;
2625
+ userApiKey;
2572
2626
  _isAuthorized = false;
2573
- constructor({ sessionId, ticketId, authToken, partyId, publicKey, email }) {
2627
+ constructor({ sessionId, ticketId, authToken, partyId, publicKey, email, userApiKey }) {
2574
2628
  this.sessionId = sessionId;
2575
2629
  this.ticketId = ticketId;
2576
2630
  this.authToken = authToken;
2577
2631
  this.partyId = partyId;
2578
2632
  this.publicKey = publicKey;
2579
2633
  this.email = email;
2634
+ this.userApiKey = userApiKey;
2580
2635
  }
2581
2636
  setTicketId(ticketId) {
2582
2637
  this.ticketId = ticketId;
@@ -0,0 +1,61 @@
1
+ import type { Connection } from './connection';
2
+ import type { Holding, ActiveContract, TransferOptions, InstrumentSpec, RunTransactionResponse, TransactionPayload } from './types';
3
+ import { MessageType, type Account } from './types';
4
+ export declare const DEFAULT_REQUEST_TIMEOUT_MS = 300000;
5
+ export type RequestFinishStatus = 'success' | 'rejected' | 'timeout' | 'error';
6
+ export type RequestFinishArgs = {
7
+ status: RequestFinishStatus;
8
+ messageType: MessageType;
9
+ requestLabel?: string;
10
+ requestContext?: unknown;
11
+ errorCode?: string;
12
+ };
13
+ export type ProviderHooks = {
14
+ onRequestStart?: (messageType: MessageType, requestLabel?: string) => unknown | Promise<unknown>;
15
+ onRequestFinish?: (args: RequestFinishArgs) => void;
16
+ onTransactionUpdate?: (payload: RunTransactionResponse, message: any) => void;
17
+ };
18
+ type SubmitOptions = {
19
+ requestTimeout?: number;
20
+ message?: string;
21
+ requestLabel?: string;
22
+ estimateTraffic?: boolean;
23
+ executionMode?: 'async' | 'wait';
24
+ };
25
+ export declare function generateRequestId(): string;
26
+ export declare class Provider {
27
+ connection: Connection;
28
+ party_id: string;
29
+ public_key: string;
30
+ email?: string;
31
+ private auth_token;
32
+ private requests;
33
+ private requestTimeout;
34
+ private hooks?;
35
+ constructor({ connection, party_id, public_key, auth_token, email, hooks }: {
36
+ connection: Connection;
37
+ party_id: string;
38
+ public_key: string;
39
+ auth_token: string;
40
+ email?: string;
41
+ hooks?: ProviderHooks;
42
+ });
43
+ getAuthToken(): string;
44
+ handleResponse(message: any): void;
45
+ getHolding(): Promise<Holding[]>;
46
+ getAccount(): Promise<Account>;
47
+ getActiveContracts(params?: {
48
+ templateId?: string;
49
+ interfaceId?: string;
50
+ }): Promise<ActiveContract[]>;
51
+ submitTransaction(payload: TransactionPayload, options?: SubmitOptions): Promise<any>;
52
+ submitAndWaitForTransaction(payload: TransactionPayload, options?: SubmitOptions): Promise<any>;
53
+ transfer(recipient: string, amount: string | number, instrument?: InstrumentSpec, options?: TransferOptions & {
54
+ executionMode?: 'async' | 'wait';
55
+ }): Promise<any>;
56
+ signMessage(message: string): Promise<any>;
57
+ private ensureConnected;
58
+ private sendRequest;
59
+ }
60
+ export {};
61
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}