@uniformdev/canvas 19.210.1-alpha.7 → 19.210.2

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.d.mts CHANGED
@@ -11627,24 +11627,9 @@ declare function createBatchEnhancer<TArgs, TResult>({ handleBatch, shouldQueue,
11627
11627
  declare const compose: (input: ComponentParameterEnhancer<any, any> | ComponentParameterEnhancerFunction<any>, ...composers: ReadonlyArray<ComponentParameterEnhancer<any, any> | ComponentParameterEnhancerFunction<any>>) => ComponentParameterEnhancer<any, any>;
11628
11628
 
11629
11629
  type LimitPolicy = <ReturnValue>(func: () => Promise<ReturnValue>) => Promise<ReturnValue>;
11630
- /**
11631
- * Creates a request limit policy that can be passed to Uniform API clients to limit concurrent requests and handle retries and rate limits
11632
- *
11633
- * Limiting vs Throttling:
11634
- * - Throttling controls how quickly new promises can be started.
11635
- * This is generally what we want for API rate limiting, but it does not care how many promises total are in flight.
11636
- * - Limiting controls how many promises can be in flight at once.
11637
- * This is important when retries are involved because retries are not subject to throttling, and this can result in heavy promise loads.
11638
- *
11639
- * @param throttle - Throttle options to limit how fast requests can be initiated. If false, throttling is disabled.
11640
- * @param retry - Retry options to handle retries. If false, retries are disabled.
11641
- * @param limit - Limit the number of concurrent in-flight requests. If false, the limit is disabled.
11642
- * @returns A function that can be passed to Uniform API clients to limit concurrent requests and handle retries and rate limits
11643
- */
11644
- declare function createLimitPolicy({ throttle, retry, limit, }: {
11630
+ declare function createLimitPolicy({ throttle, retry, }: {
11645
11631
  throttle?: Options | false;
11646
11632
  retry?: Options$1 | false;
11647
- limit?: number | false;
11648
11633
  }): LimitPolicy;
11649
11634
  declare const nullLimitPolicy: LimitPolicy;
11650
11635
 
package/dist/index.d.ts CHANGED
@@ -11627,24 +11627,9 @@ declare function createBatchEnhancer<TArgs, TResult>({ handleBatch, shouldQueue,
11627
11627
  declare const compose: (input: ComponentParameterEnhancer<any, any> | ComponentParameterEnhancerFunction<any>, ...composers: ReadonlyArray<ComponentParameterEnhancer<any, any> | ComponentParameterEnhancerFunction<any>>) => ComponentParameterEnhancer<any, any>;
11628
11628
 
11629
11629
  type LimitPolicy = <ReturnValue>(func: () => Promise<ReturnValue>) => Promise<ReturnValue>;
11630
- /**
11631
- * Creates a request limit policy that can be passed to Uniform API clients to limit concurrent requests and handle retries and rate limits
11632
- *
11633
- * Limiting vs Throttling:
11634
- * - Throttling controls how quickly new promises can be started.
11635
- * This is generally what we want for API rate limiting, but it does not care how many promises total are in flight.
11636
- * - Limiting controls how many promises can be in flight at once.
11637
- * This is important when retries are involved because retries are not subject to throttling, and this can result in heavy promise loads.
11638
- *
11639
- * @param throttle - Throttle options to limit how fast requests can be initiated. If false, throttling is disabled.
11640
- * @param retry - Retry options to handle retries. If false, retries are disabled.
11641
- * @param limit - Limit the number of concurrent in-flight requests. If false, the limit is disabled.
11642
- * @returns A function that can be passed to Uniform API clients to limit concurrent requests and handle retries and rate limits
11643
- */
11644
- declare function createLimitPolicy({ throttle, retry, limit, }: {
11630
+ declare function createLimitPolicy({ throttle, retry, }: {
11645
11631
  throttle?: Options | false;
11646
11632
  retry?: Options$1 | false;
11647
- limit?: number | false;
11648
11633
  }): LimitPolicy;
11649
11634
  declare const nullLimitPolicy: LimitPolicy;
11650
11635
 
package/dist/index.esm.js CHANGED
@@ -30,124 +30,6 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
30
30
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
31
31
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
32
32
 
33
- // ../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js
34
- var require_yocto_queue = __commonJS({
35
- "../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js"(exports, module) {
36
- "use strict";
37
- var Node = class {
38
- /// value;
39
- /// next;
40
- constructor(value) {
41
- this.value = value;
42
- this.next = void 0;
43
- }
44
- };
45
- var Queue = class {
46
- // TODO: Use private class fields when targeting Node.js 12.
47
- // #_head;
48
- // #_tail;
49
- // #_size;
50
- constructor() {
51
- this.clear();
52
- }
53
- enqueue(value) {
54
- const node = new Node(value);
55
- if (this._head) {
56
- this._tail.next = node;
57
- this._tail = node;
58
- } else {
59
- this._head = node;
60
- this._tail = node;
61
- }
62
- this._size++;
63
- }
64
- dequeue() {
65
- const current = this._head;
66
- if (!current) {
67
- return;
68
- }
69
- this._head = this._head.next;
70
- this._size--;
71
- return current.value;
72
- }
73
- clear() {
74
- this._head = void 0;
75
- this._tail = void 0;
76
- this._size = 0;
77
- }
78
- get size() {
79
- return this._size;
80
- }
81
- *[Symbol.iterator]() {
82
- let current = this._head;
83
- while (current) {
84
- yield current.value;
85
- current = current.next;
86
- }
87
- }
88
- };
89
- module.exports = Queue;
90
- }
91
- });
92
-
93
- // ../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js
94
- var require_p_limit = __commonJS({
95
- "../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js"(exports, module) {
96
- "use strict";
97
- var Queue = require_yocto_queue();
98
- var pLimit2 = (concurrency) => {
99
- if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
100
- throw new TypeError("Expected `concurrency` to be a number from 1 and up");
101
- }
102
- const queue = new Queue();
103
- let activeCount = 0;
104
- const next = () => {
105
- activeCount--;
106
- if (queue.size > 0) {
107
- queue.dequeue()();
108
- }
109
- };
110
- const run = async (fn, resolve, ...args) => {
111
- activeCount++;
112
- const result = (async () => fn(...args))();
113
- resolve(result);
114
- try {
115
- await result;
116
- } catch (e) {
117
- }
118
- next();
119
- };
120
- const enqueue = (fn, resolve, ...args) => {
121
- queue.enqueue(run.bind(null, fn, resolve, ...args));
122
- (async () => {
123
- await Promise.resolve();
124
- if (activeCount < concurrency && queue.size > 0) {
125
- queue.dequeue()();
126
- }
127
- })();
128
- };
129
- const generator = (fn, ...args) => new Promise((resolve) => {
130
- enqueue(fn, resolve, ...args);
131
- });
132
- Object.defineProperties(generator, {
133
- activeCount: {
134
- get: () => activeCount
135
- },
136
- pendingCount: {
137
- get: () => queue.size
138
- },
139
- clearQueue: {
140
- value: () => {
141
- queue.clear();
142
- }
143
- }
144
- });
145
- return generator;
146
- };
147
- module.exports = pLimit2;
148
- }
149
- });
150
-
151
33
  // ../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js
152
34
  var require_retry_operation = __commonJS({
153
35
  "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js"(exports, module) {
@@ -383,7 +265,6 @@ var require_retry2 = __commonJS({
383
265
  import { ApiClient } from "@uniformdev/context/api";
384
266
 
385
267
  // src/enhancement/createLimitPolicy.ts
386
- var import_p_limit = __toESM(require_p_limit());
387
268
  import { ApiClientError } from "@uniformdev/context/api";
388
269
 
389
270
  // ../../node_modules/.pnpm/p-retry@5.1.2/node_modules/p-retry/index.js
@@ -550,21 +431,15 @@ function pThrottle({ limit, interval, strict }) {
550
431
  // src/enhancement/createLimitPolicy.ts
551
432
  function createLimitPolicy({
552
433
  throttle = { interval: 1e3, limit: 10 },
553
- retry: retry2 = { retries: 1, factor: 1.66 },
554
- limit = 10
434
+ retry: retry2 = { retries: 1, factor: 1.66 }
555
435
  }) {
556
436
  const throttler = throttle ? pThrottle(throttle) : null;
557
- const limiter = limit ? (0, import_p_limit.default)(limit) : null;
558
437
  return function limitPolicy(func) {
559
438
  let currentFunc = async () => await func();
560
439
  if (throttler) {
561
440
  const throttleFunc = currentFunc;
562
441
  currentFunc = throttler(throttleFunc);
563
442
  }
564
- if (limiter) {
565
- const limitFunc = currentFunc;
566
- currentFunc = () => limiter(limitFunc);
567
- }
568
443
  if (retry2) {
569
444
  const retryFunc = currentFunc;
570
445
  currentFunc = () => pRetry(retryFunc, {
@@ -573,7 +448,7 @@ function createLimitPolicy({
573
448
  if (retry2.onFailedAttempt) {
574
449
  await retry2.onFailedAttempt(error);
575
450
  }
576
- if (error instanceof ApiClientError && typeof error.statusCode === "number" && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429 && error.statusCode !== 408) {
451
+ if (error instanceof ApiClientError && typeof error.statusCode === "number" && error.statusCode.toString().startsWith("4")) {
577
452
  throw error;
578
453
  }
579
454
  }
package/dist/index.js CHANGED
@@ -36,124 +36,6 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
36
36
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
37
37
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
38
38
 
39
- // ../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js
40
- var require_yocto_queue = __commonJS({
41
- "../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js"(exports2, module2) {
42
- "use strict";
43
- var Node = class {
44
- /// value;
45
- /// next;
46
- constructor(value) {
47
- this.value = value;
48
- this.next = void 0;
49
- }
50
- };
51
- var Queue = class {
52
- // TODO: Use private class fields when targeting Node.js 12.
53
- // #_head;
54
- // #_tail;
55
- // #_size;
56
- constructor() {
57
- this.clear();
58
- }
59
- enqueue(value) {
60
- const node = new Node(value);
61
- if (this._head) {
62
- this._tail.next = node;
63
- this._tail = node;
64
- } else {
65
- this._head = node;
66
- this._tail = node;
67
- }
68
- this._size++;
69
- }
70
- dequeue() {
71
- const current = this._head;
72
- if (!current) {
73
- return;
74
- }
75
- this._head = this._head.next;
76
- this._size--;
77
- return current.value;
78
- }
79
- clear() {
80
- this._head = void 0;
81
- this._tail = void 0;
82
- this._size = 0;
83
- }
84
- get size() {
85
- return this._size;
86
- }
87
- *[Symbol.iterator]() {
88
- let current = this._head;
89
- while (current) {
90
- yield current.value;
91
- current = current.next;
92
- }
93
- }
94
- };
95
- module2.exports = Queue;
96
- }
97
- });
98
-
99
- // ../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js
100
- var require_p_limit = __commonJS({
101
- "../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js"(exports2, module2) {
102
- "use strict";
103
- var Queue = require_yocto_queue();
104
- var pLimit2 = (concurrency) => {
105
- if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
106
- throw new TypeError("Expected `concurrency` to be a number from 1 and up");
107
- }
108
- const queue = new Queue();
109
- let activeCount = 0;
110
- const next = () => {
111
- activeCount--;
112
- if (queue.size > 0) {
113
- queue.dequeue()();
114
- }
115
- };
116
- const run = async (fn, resolve, ...args) => {
117
- activeCount++;
118
- const result = (async () => fn(...args))();
119
- resolve(result);
120
- try {
121
- await result;
122
- } catch (e) {
123
- }
124
- next();
125
- };
126
- const enqueue = (fn, resolve, ...args) => {
127
- queue.enqueue(run.bind(null, fn, resolve, ...args));
128
- (async () => {
129
- await Promise.resolve();
130
- if (activeCount < concurrency && queue.size > 0) {
131
- queue.dequeue()();
132
- }
133
- })();
134
- };
135
- const generator = (fn, ...args) => new Promise((resolve) => {
136
- enqueue(fn, resolve, ...args);
137
- });
138
- Object.defineProperties(generator, {
139
- activeCount: {
140
- get: () => activeCount
141
- },
142
- pendingCount: {
143
- get: () => queue.size
144
- },
145
- clearQueue: {
146
- value: () => {
147
- queue.clear();
148
- }
149
- }
150
- });
151
- return generator;
152
- };
153
- module2.exports = pLimit2;
154
- }
155
- });
156
-
157
39
  // ../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js
158
40
  var require_retry_operation = __commonJS({
159
41
  "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js"(exports2, module2) {
@@ -543,7 +425,6 @@ var import_api2 = require("@uniformdev/context/api");
543
425
 
544
426
  // src/enhancement/createLimitPolicy.ts
545
427
  var import_api = require("@uniformdev/context/api");
546
- var import_p_limit = __toESM(require_p_limit());
547
428
 
548
429
  // ../../node_modules/.pnpm/p-retry@5.1.2/node_modules/p-retry/index.js
549
430
  var import_retry = __toESM(require_retry2(), 1);
@@ -709,21 +590,15 @@ function pThrottle({ limit, interval, strict }) {
709
590
  // src/enhancement/createLimitPolicy.ts
710
591
  function createLimitPolicy({
711
592
  throttle = { interval: 1e3, limit: 10 },
712
- retry: retry2 = { retries: 1, factor: 1.66 },
713
- limit = 10
593
+ retry: retry2 = { retries: 1, factor: 1.66 }
714
594
  }) {
715
595
  const throttler = throttle ? pThrottle(throttle) : null;
716
- const limiter = limit ? (0, import_p_limit.default)(limit) : null;
717
596
  return function limitPolicy(func) {
718
597
  let currentFunc = async () => await func();
719
598
  if (throttler) {
720
599
  const throttleFunc = currentFunc;
721
600
  currentFunc = throttler(throttleFunc);
722
601
  }
723
- if (limiter) {
724
- const limitFunc = currentFunc;
725
- currentFunc = () => limiter(limitFunc);
726
- }
727
602
  if (retry2) {
728
603
  const retryFunc = currentFunc;
729
604
  currentFunc = () => pRetry(retryFunc, {
@@ -732,7 +607,7 @@ function createLimitPolicy({
732
607
  if (retry2.onFailedAttempt) {
733
608
  await retry2.onFailedAttempt(error);
734
609
  }
735
- if (error instanceof import_api.ApiClientError && typeof error.statusCode === "number" && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429 && error.statusCode !== 408) {
610
+ if (error instanceof import_api.ApiClientError && typeof error.statusCode === "number" && error.statusCode.toString().startsWith("4")) {
736
611
  throw error;
737
612
  }
738
613
  }
package/dist/index.mjs CHANGED
@@ -30,124 +30,6 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
30
30
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
31
31
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
32
32
 
33
- // ../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js
34
- var require_yocto_queue = __commonJS({
35
- "../../node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js"(exports, module) {
36
- "use strict";
37
- var Node = class {
38
- /// value;
39
- /// next;
40
- constructor(value) {
41
- this.value = value;
42
- this.next = void 0;
43
- }
44
- };
45
- var Queue = class {
46
- // TODO: Use private class fields when targeting Node.js 12.
47
- // #_head;
48
- // #_tail;
49
- // #_size;
50
- constructor() {
51
- this.clear();
52
- }
53
- enqueue(value) {
54
- const node = new Node(value);
55
- if (this._head) {
56
- this._tail.next = node;
57
- this._tail = node;
58
- } else {
59
- this._head = node;
60
- this._tail = node;
61
- }
62
- this._size++;
63
- }
64
- dequeue() {
65
- const current = this._head;
66
- if (!current) {
67
- return;
68
- }
69
- this._head = this._head.next;
70
- this._size--;
71
- return current.value;
72
- }
73
- clear() {
74
- this._head = void 0;
75
- this._tail = void 0;
76
- this._size = 0;
77
- }
78
- get size() {
79
- return this._size;
80
- }
81
- *[Symbol.iterator]() {
82
- let current = this._head;
83
- while (current) {
84
- yield current.value;
85
- current = current.next;
86
- }
87
- }
88
- };
89
- module.exports = Queue;
90
- }
91
- });
92
-
93
- // ../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js
94
- var require_p_limit = __commonJS({
95
- "../../node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js"(exports, module) {
96
- "use strict";
97
- var Queue = require_yocto_queue();
98
- var pLimit2 = (concurrency) => {
99
- if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
100
- throw new TypeError("Expected `concurrency` to be a number from 1 and up");
101
- }
102
- const queue = new Queue();
103
- let activeCount = 0;
104
- const next = () => {
105
- activeCount--;
106
- if (queue.size > 0) {
107
- queue.dequeue()();
108
- }
109
- };
110
- const run = async (fn, resolve, ...args) => {
111
- activeCount++;
112
- const result = (async () => fn(...args))();
113
- resolve(result);
114
- try {
115
- await result;
116
- } catch (e) {
117
- }
118
- next();
119
- };
120
- const enqueue = (fn, resolve, ...args) => {
121
- queue.enqueue(run.bind(null, fn, resolve, ...args));
122
- (async () => {
123
- await Promise.resolve();
124
- if (activeCount < concurrency && queue.size > 0) {
125
- queue.dequeue()();
126
- }
127
- })();
128
- };
129
- const generator = (fn, ...args) => new Promise((resolve) => {
130
- enqueue(fn, resolve, ...args);
131
- });
132
- Object.defineProperties(generator, {
133
- activeCount: {
134
- get: () => activeCount
135
- },
136
- pendingCount: {
137
- get: () => queue.size
138
- },
139
- clearQueue: {
140
- value: () => {
141
- queue.clear();
142
- }
143
- }
144
- });
145
- return generator;
146
- };
147
- module.exports = pLimit2;
148
- }
149
- });
150
-
151
33
  // ../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js
152
34
  var require_retry_operation = __commonJS({
153
35
  "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js"(exports, module) {
@@ -383,7 +265,6 @@ var require_retry2 = __commonJS({
383
265
  import { ApiClient } from "@uniformdev/context/api";
384
266
 
385
267
  // src/enhancement/createLimitPolicy.ts
386
- var import_p_limit = __toESM(require_p_limit());
387
268
  import { ApiClientError } from "@uniformdev/context/api";
388
269
 
389
270
  // ../../node_modules/.pnpm/p-retry@5.1.2/node_modules/p-retry/index.js
@@ -550,21 +431,15 @@ function pThrottle({ limit, interval, strict }) {
550
431
  // src/enhancement/createLimitPolicy.ts
551
432
  function createLimitPolicy({
552
433
  throttle = { interval: 1e3, limit: 10 },
553
- retry: retry2 = { retries: 1, factor: 1.66 },
554
- limit = 10
434
+ retry: retry2 = { retries: 1, factor: 1.66 }
555
435
  }) {
556
436
  const throttler = throttle ? pThrottle(throttle) : null;
557
- const limiter = limit ? (0, import_p_limit.default)(limit) : null;
558
437
  return function limitPolicy(func) {
559
438
  let currentFunc = async () => await func();
560
439
  if (throttler) {
561
440
  const throttleFunc = currentFunc;
562
441
  currentFunc = throttler(throttleFunc);
563
442
  }
564
- if (limiter) {
565
- const limitFunc = currentFunc;
566
- currentFunc = () => limiter(limitFunc);
567
- }
568
443
  if (retry2) {
569
444
  const retryFunc = currentFunc;
570
445
  currentFunc = () => pRetry(retryFunc, {
@@ -573,7 +448,7 @@ function createLimitPolicy({
573
448
  if (retry2.onFailedAttempt) {
574
449
  await retry2.onFailedAttempt(error);
575
450
  }
576
- if (error instanceof ApiClientError && typeof error.statusCode === "number" && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429 && error.statusCode !== 408) {
451
+ if (error instanceof ApiClientError && typeof error.statusCode === "number" && error.statusCode.toString().startsWith("4")) {
577
452
  throw error;
578
453
  }
579
454
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniformdev/canvas",
3
- "version": "19.210.1-alpha.7+5402269e8e",
3
+ "version": "19.210.2",
4
4
  "description": "Common functionality and types for Uniform Canvas",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "main": "./dist/index.js",
@@ -33,15 +33,14 @@
33
33
  "devDependencies": {
34
34
  "@types/retry": "0.12.5",
35
35
  "lexical": "0.17.1",
36
- "p-limit": "3.1.0",
37
36
  "p-retry": "5.1.2",
38
37
  "p-throttle": "5.0.0",
39
38
  "pusher-js": "8.2.0"
40
39
  },
41
40
  "dependencies": {
42
- "@uniformdev/assets": "19.210.1-alpha.7+5402269e8e",
43
- "@uniformdev/context": "19.210.1-alpha.7+5402269e8e",
44
- "@uniformdev/richtext": "19.210.1-alpha.7+5402269e8e",
41
+ "@uniformdev/assets": "19.210.2",
42
+ "@uniformdev/context": "19.210.2",
43
+ "@uniformdev/richtext": "19.210.2",
45
44
  "immer": "10.1.1"
46
45
  },
47
46
  "files": [
@@ -50,5 +49,5 @@
50
49
  "publishConfig": {
51
50
  "access": "public"
52
51
  },
53
- "gitHead": "5402269e8e1d1f8d955c4c2bb30ab7ac1a96e66b"
52
+ "gitHead": "be8f3f0b45faff78be6c5bbc4bd3311c1e9a7591"
54
53
  }