@rebilly/instruments 4.8.1 → 4.8.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.
Files changed (139) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.min.js +1 -1
  4. package/package.json +5 -1
  5. package/.babelrc +0 -26
  6. package/project.json +0 -31
  7. package/rollup.config.mjs +0 -79
  8. package/src/data/options-schema/index.js +0 -112
  9. package/src/data/options-schema/schemas/options-schema.js +0 -448
  10. package/src/events/base-event.js +0 -47
  11. package/src/events/events.spec.js +0 -11
  12. package/src/events/index.js +0 -15
  13. package/src/functions/destroy.js +0 -29
  14. package/src/functions/destroy.spec.js +0 -63
  15. package/src/functions/mount/fetch-data.js +0 -236
  16. package/src/functions/mount/fetch-data.spec.js +0 -317
  17. package/src/functions/mount/get-lead-source-data.js +0 -46
  18. package/src/functions/mount/get-lead-source-data.spec.js +0 -38
  19. package/src/functions/mount/index.js +0 -105
  20. package/src/functions/mount/mount.spec.js +0 -96
  21. package/src/functions/mount/setup-element.js +0 -29
  22. package/src/functions/mount/setup-framepay-theme.js +0 -104
  23. package/src/functions/mount/setup-framepay.js +0 -26
  24. package/src/functions/mount/setup-i18n.js +0 -21
  25. package/src/functions/mount/setup-options.js +0 -100
  26. package/src/functions/mount/setup-options.spec.js +0 -353
  27. package/src/functions/mount/setup-storefront.js +0 -23
  28. package/src/functions/mount/setup-styles-vars.js +0 -30
  29. package/src/functions/mount/setup-user-flow.js +0 -60
  30. package/src/functions/on.js +0 -22
  31. package/src/functions/on.spec.js +0 -75
  32. package/src/functions/purchase.js +0 -173
  33. package/src/functions/purchase.spec.js +0 -80
  34. package/src/functions/setup.js +0 -66
  35. package/src/functions/setup.spec.js +0 -111
  36. package/src/functions/show.js +0 -30
  37. package/src/functions/show.spec.js +0 -62
  38. package/src/functions/update.js +0 -40
  39. package/src/functions/update.spec.js +0 -104
  40. package/src/i18n/en.json +0 -35
  41. package/src/i18n/es.json +0 -32
  42. package/src/i18n/i18n.spec.js +0 -27
  43. package/src/i18n/index.js +0 -59
  44. package/src/index.js +0 -3
  45. package/src/instance.js +0 -48
  46. package/src/instance.spec.js +0 -44
  47. package/src/loader/index.js +0 -145
  48. package/src/loader/loader.spec.js +0 -74
  49. package/src/state/iframes.js +0 -23
  50. package/src/state/index.js +0 -64
  51. package/src/storefront/account-and-website.js +0 -18
  52. package/src/storefront/account-and-website.spec.js +0 -73
  53. package/src/storefront/deposit-requests.js +0 -12
  54. package/src/storefront/fetch-plans-from-addons-bumpOffer.js +0 -30
  55. package/src/storefront/fetch-products-from-plans.js +0 -59
  56. package/src/storefront/fetch-products-from-plans.spec.js +0 -113
  57. package/src/storefront/index.js +0 -78
  58. package/src/storefront/invoices.js +0 -23
  59. package/src/storefront/invoices.spec.js +0 -92
  60. package/src/storefront/models/account-model.js +0 -36
  61. package/src/storefront/models/base-model.js +0 -7
  62. package/src/storefront/models/deposit-request-model.js +0 -24
  63. package/src/storefront/models/invoice-model.js +0 -20
  64. package/src/storefront/models/payment-metadata.js +0 -7
  65. package/src/storefront/models/plan-model.js +0 -94
  66. package/src/storefront/models/product-model.js +0 -3
  67. package/src/storefront/models/ready-to-pay-model.js +0 -76
  68. package/src/storefront/models/summary-model.js +0 -56
  69. package/src/storefront/models/transaction-model.js +0 -16
  70. package/src/storefront/models/website-model.js +0 -3
  71. package/src/storefront/payment-instruments.js +0 -47
  72. package/src/storefront/payment-instruments.spec.js +0 -88
  73. package/src/storefront/purchase.js +0 -60
  74. package/src/storefront/purchase.spec.js +0 -53
  75. package/src/storefront/ready-to-pay.js +0 -96
  76. package/src/storefront/ready-to-pay.spec.js +0 -76
  77. package/src/storefront/storefront.spec.js +0 -14
  78. package/src/storefront/summary.js +0 -114
  79. package/src/storefront/summary.spec.js +0 -136
  80. package/src/storefront/transactions.js +0 -12
  81. package/src/style/base/__snapshots__/theme.spec.js.snap +0 -143
  82. package/src/style/base/default-theme.js +0 -955
  83. package/src/style/base/index.js +0 -688
  84. package/src/style/base/theme.js +0 -30
  85. package/src/style/base/theme.spec.js +0 -19
  86. package/src/style/index.js +0 -11
  87. package/src/style/utils/border.js +0 -47
  88. package/src/style/utils/color-values.js +0 -35
  89. package/src/style/utils/minifyCss.js +0 -14
  90. package/src/utils/add-dom-element.js +0 -17
  91. package/src/utils/format-currency.js +0 -8
  92. package/src/utils/has-valid-css-selector.js +0 -4
  93. package/src/utils/index.js +0 -15
  94. package/src/utils/is-dom-element.js +0 -3
  95. package/src/utils/process-property-as-dom-element.js +0 -31
  96. package/src/utils/quantity.js +0 -47
  97. package/src/utils/sleep.js +0 -5
  98. package/src/views/amount-selector.js +0 -46
  99. package/src/views/common/iframe/base-iframe.js +0 -66
  100. package/src/views/common/iframe/events/change-iframe-src-handler.js +0 -6
  101. package/src/views/common/iframe/events/dispatch-event-handler.js +0 -8
  102. package/src/views/common/iframe/events/resize-component-handler.js +0 -9
  103. package/src/views/common/iframe/events/show-error-handler.js +0 -5
  104. package/src/views/common/iframe/events/stop-loader-handler.js +0 -9
  105. package/src/views/common/iframe/events/update-addons-handler.js +0 -23
  106. package/src/views/common/iframe/events/update-coupons-handler.js +0 -12
  107. package/src/views/common/iframe/events/update-items-handler.js +0 -34
  108. package/src/views/common/iframe/index.js +0 -5
  109. package/src/views/common/iframe/modal-iframe.js +0 -82
  110. package/src/views/common/iframe/view-iframe.js +0 -23
  111. package/src/views/common/render-utilities.js +0 -4
  112. package/src/views/confirmation.js +0 -45
  113. package/src/views/errors.js +0 -115
  114. package/src/views/form.js +0 -61
  115. package/src/views/method-selector/__snapshots__/method-selector.spec.js.snap +0 -135
  116. package/src/views/method-selector/express-methods.js +0 -52
  117. package/src/views/method-selector/generate-digital-wallet.js +0 -53
  118. package/src/views/method-selector/generate-digital-wallet.spec.js +0 -121
  119. package/src/views/method-selector/generate-framepay-config.js +0 -56
  120. package/src/views/method-selector/generate-framepay-config.spec.js +0 -216
  121. package/src/views/method-selector/get-method-data.js +0 -11
  122. package/src/views/method-selector/get-payment-methods.js +0 -25
  123. package/src/views/method-selector/get-payment-methods.spec.js +0 -41
  124. package/src/views/method-selector/index.js +0 -223
  125. package/src/views/method-selector/method-selector.spec.js +0 -20
  126. package/src/views/method-selector/mount-bump-offer.js +0 -120
  127. package/src/views/method-selector/mount-express-methods.js +0 -107
  128. package/src/views/modal.js +0 -103
  129. package/src/views/result.js +0 -24
  130. package/src/views/summary.js +0 -38
  131. package/tests/async-utilities.js +0 -22
  132. package/tests/mocks/framepay-mock.js +0 -15
  133. package/tests/mocks/rebilly-api-mock.js +0 -11
  134. package/tests/mocks/rebilly-instruments-mock.js +0 -141
  135. package/tests/mocks/storefront-api-mock.js +0 -62
  136. package/tests/mocks/storefront-mock.js +0 -20
  137. package/tests/msw/server.js +0 -14
  138. package/tests/setup-test.js +0 -30
  139. package/vitest.config.js +0 -18
@@ -1,448 +0,0 @@
1
- export default {
2
- title: 'Mount Options Schema',
3
- type: 'object',
4
- properties: {
5
- form: {
6
- type: 'string',
7
- default: '.rebilly-instruments',
8
- },
9
- summary: {
10
- type: 'string',
11
- default: '.rebilly-instruments-summary',
12
- },
13
- apiMode: {
14
- type: 'string',
15
- enum: ['sandbox', 'live'],
16
- },
17
- publishableKey: { type: 'string' },
18
- jwt: { type: 'string' },
19
- websiteId: { type: 'string' },
20
- organizationId: { type: 'string' },
21
- items: {
22
- type: 'array',
23
- items: {
24
- type: 'object',
25
- properties: {
26
- planId: { type: 'string' },
27
- thumbnail: { type: 'string' },
28
- },
29
- oneOf: [
30
- {
31
- properties: {
32
- quantity: { type: 'number' },
33
- },
34
- },
35
- {
36
- properties: {
37
- quantity: {
38
- type: 'object',
39
- properties: {
40
- default: { type: 'number' },
41
- minimum: { type: 'number' },
42
- maximum: { type: 'number' },
43
- multipleOf: { type: 'number' },
44
- },
45
- },
46
- },
47
- },
48
- ],
49
- required: ['planId', 'quantity'],
50
- },
51
- minItems: 1,
52
- },
53
- addons: {
54
- type: 'array',
55
- items: {
56
- type: 'object',
57
- properties: {
58
- planId: { type: 'string' },
59
- quantity: { type: 'number' },
60
- thumbnail: { type: 'string' },
61
- },
62
- required: ['planId', 'quantity'],
63
- },
64
- default: [],
65
- },
66
- bumpOffer: {
67
- type: 'array',
68
- items: {
69
- type: 'object',
70
- properties: {
71
- planId: { type: 'string' },
72
- quantity: { type: 'number' },
73
- thumbnail: { type: 'string' },
74
- },
75
- required: ['planId', 'quantity'],
76
- },
77
- default: [],
78
- },
79
- money: {
80
- type: 'object',
81
- properties: {
82
- amount: {
83
- type: 'number',
84
- },
85
- currency: {
86
- type: 'string',
87
- minLength: 3,
88
- maxLength: 3,
89
- },
90
- },
91
- required: ['amount', 'currency'],
92
- },
93
- invoiceId: { type: 'string' },
94
- transactionId: { type: 'string' },
95
- deposit: {
96
- oneOf: [
97
- {
98
- type: 'object',
99
- properties: {
100
- depositRequestId: { type: 'string' },
101
- },
102
- required: ['depositRequestId'],
103
- },
104
- {
105
- type: 'object',
106
- properties: {
107
- currency: {
108
- type: 'string',
109
- minLength: 3,
110
- maxLength: 3,
111
- },
112
- amount: {
113
- type: 'number',
114
- },
115
- buttons: {
116
- type: 'array',
117
- items: {
118
- type: 'number',
119
- },
120
- },
121
- editable: { type: 'boolean' },
122
- customAmount: {
123
- type: 'object',
124
- properties: {
125
- minimum: { type: 'number' },
126
- maximum: { type: 'number' },
127
- multipleOf: { type: 'number' },
128
- },
129
- },
130
- },
131
- anyOf: [
132
- {
133
- required: ['amount'],
134
- },
135
- {
136
- required: ['buttons'],
137
- },
138
- ],
139
- required: ['currency'],
140
- },
141
- ],
142
- },
143
- transactionType: {
144
- type: 'string',
145
- enum: ['purchase', 'setup'],
146
- default: 'purchase',
147
- },
148
- css: { type: 'string' },
149
- theme: {
150
- type: 'object',
151
- properties: {
152
- labels: {
153
- type: 'string',
154
- enum: ['stacked', 'floating'],
155
- default: 'stacked',
156
- },
157
- // TODO: split file add schema for all tokens
158
- },
159
- default: {},
160
- },
161
- countryCode: {
162
- type: 'string',
163
- default: 'US',
164
- },
165
- locale: {
166
- type: 'string',
167
- default: 'auto',
168
- },
169
- i18n: {
170
- type: 'object',
171
- patternProperties: {
172
- '^[a-z]{2}(-[A-Z]{2})?$': {
173
- type: 'object',
174
- properties: {
175
- // TODO: split file add schema for all translation keys
176
- summary: { type: 'object' },
177
- form: { type: 'object' },
178
- confirmation: { type: 'object' },
179
- result: { type: 'object' },
180
- validations: { type: 'object' },
181
- paymentMethods: { type: 'object' },
182
- },
183
- },
184
- },
185
- },
186
- paymentInstruments: {
187
- type: 'object',
188
- properties: {
189
- compactExpressInstruments: {
190
- type: 'boolean',
191
- default: false,
192
- },
193
- address: {
194
- type: 'object',
195
- properties: {
196
- name: {
197
- type: 'string',
198
- enum: ['default', 'combined', 'stacked'],
199
- default: 'default',
200
- },
201
- region: {
202
- type: 'string',
203
- enum: ['default', 'split', 'stacked'],
204
- default: 'default',
205
- },
206
- show: {
207
- type: 'array',
208
- default: [],
209
- items: {
210
- type: 'string',
211
- enum: [
212
- 'all',
213
- 'email',
214
- 'organization',
215
- 'phoneNumber',
216
- 'city',
217
- 'country',
218
- 'region',
219
- 'postalCode',
220
- 'address',
221
- 'address2',
222
- ],
223
- },
224
- },
225
- hide: {
226
- type: 'array',
227
- default: [],
228
- items: {
229
- type: 'string',
230
- enum: [
231
- 'all',
232
- 'email',
233
- 'organization',
234
- 'phoneNumber',
235
- 'city',
236
- 'country',
237
- 'region',
238
- 'postalCode',
239
- 'address',
240
- 'address2',
241
- ],
242
- },
243
- },
244
- require: {
245
- type: 'array',
246
- default: [],
247
- items: {
248
- type: 'string',
249
- enum: [
250
- 'organization',
251
- 'email',
252
- 'phoneNumber',
253
- 'address',
254
- 'address2',
255
- 'city',
256
- 'country',
257
- 'region',
258
- 'postalCode',
259
- ],
260
- },
261
- },
262
- },
263
- default: {},
264
- },
265
- paypal: {
266
- type: 'object',
267
- properties: {
268
- buttonHeight: {
269
- type: 'number',
270
- default: 48,
271
- },
272
- },
273
- default: {},
274
- },
275
- googlePay: {
276
- type: 'object',
277
- properties: {
278
- displayOptions: {
279
- type: 'object',
280
- properties: {
281
- buttonColor: {
282
- type: 'string',
283
- default: 'black',
284
- },
285
- buttonHeight: {
286
- type: 'string',
287
- pattern: '^[0-9]+px$',
288
- default: '48px',
289
- },
290
- buttonType: {
291
- type: 'string',
292
- default: 'plain',
293
- },
294
- },
295
- default: {},
296
- },
297
- },
298
- default: {},
299
- },
300
- applePay: {
301
- type: 'object',
302
- properties: {
303
- displayOptions: {
304
- type: 'object',
305
- properties: {
306
- buttonColor: {
307
- type: 'string',
308
- default: 'black',
309
- },
310
- buttonHeight: {
311
- type: 'string',
312
- pattern: '^[0-9]+px$',
313
- default: '48px',
314
- },
315
- buttonType: {
316
- type: 'string',
317
- default: 'plain',
318
- },
319
- },
320
- default: {},
321
- },
322
- },
323
- default: {},
324
- },
325
- paymentCard: {
326
- type: 'object',
327
- properties: {
328
- popup: {
329
- type: 'boolean',
330
- default: false,
331
- },
332
- },
333
- default: {},
334
- },
335
- },
336
- default: {},
337
- },
338
- features: {
339
- type: 'object',
340
- properties: {
341
- autoConfirmation: {
342
- type: 'boolean',
343
- default: true,
344
- },
345
- autoResult: {
346
- type: 'boolean',
347
- default: true,
348
- },
349
- fullPageRedirect: {
350
- type: 'boolean',
351
- default: false,
352
- },
353
- showCoupons: {
354
- type: 'array',
355
- items: {
356
- type: 'string',
357
- enum: ['summary', 'confirmation'],
358
- },
359
- },
360
- },
361
- default: {},
362
- },
363
- _dev: {
364
- type: 'object',
365
- properties: {
366
- paymentMethodsUrl: {
367
- type: 'string',
368
- default: 'https://forms.local.rebilly.dev:3000',
369
- },
370
- liveUrl: { type: 'string' },
371
- sandboxUrl: { type: 'string' },
372
- framePayScriptLink: { type: 'string' },
373
- framePayStyleLink: { type: 'string' },
374
- },
375
- },
376
- },
377
- required: ['apiMode'],
378
- dependentRequired: {
379
- invoiceId: ['jwt'],
380
- transactionId: ['jwt'],
381
- deposit: ['jwt'],
382
- },
383
- anyOf: [
384
- {
385
- if: { required: ['items'] },
386
- then: {
387
- properties: {
388
- transactionId: false,
389
- invoiceId: false,
390
- deposit: false,
391
- money: false,
392
- },
393
- },
394
- else: false,
395
- },
396
- {
397
- if: { required: ['money'] },
398
- then: {
399
- properties: {
400
- transactionId: false,
401
- invoiceId: false,
402
- deposit: false,
403
- items: false,
404
- },
405
- },
406
- else: false,
407
- },
408
- {
409
- if: { required: ['transactionId'] },
410
- then: {
411
- properties: {
412
- invoiceId: false,
413
- deposit: false,
414
- items: false,
415
- money: false,
416
- },
417
- },
418
- else: false,
419
- },
420
- {
421
- if: { required: ['invoiceId'] },
422
- then: {
423
- properties: {
424
- transactionId: false,
425
- deposit: false,
426
- items: false,
427
- money: false,
428
- },
429
- },
430
- else: false,
431
- },
432
- {
433
- if: { required: ['deposit'] },
434
- then: {
435
- properties: {
436
- invoiceId: false,
437
- transactionId: false,
438
- items: false,
439
- money: false,
440
- },
441
- },
442
- else: false,
443
- },
444
- {
445
- required: ['jwt'],
446
- },
447
- ],
448
- };
@@ -1,47 +0,0 @@
1
- export class RegisteredListeners {
2
- _listeners = {};
3
-
4
- add(eventName, callback) {
5
- document.addEventListener(eventName, callback, false);
6
-
7
- if (!(eventName in this._listeners)) {
8
- this._listeners[eventName] = [];
9
- }
10
- this._listeners[eventName].push(callback);
11
- }
12
-
13
- removeAll() {
14
- Object.keys(this._listeners).forEach((eventName) => {
15
- this._listeners[eventName].forEach((callback) =>
16
- document.removeEventListener(eventName, callback, false),
17
- );
18
- });
19
- this._listeners = {};
20
- }
21
- }
22
-
23
- export const registeredListeners = new RegisteredListeners();
24
-
25
- export default class BaseEvent {
26
- /**
27
- * @param {string} name
28
- */
29
- constructor(name) {
30
- // Using namespaced internal name as a protection mechanism
31
- const PREFIX = 'rebilly-instruments-';
32
- this.internalName = PREFIX + name;
33
- }
34
-
35
- addEventListener(callback) {
36
- const innerCallback = ({ detail }) => callback(detail);
37
- registeredListeners.add(this.internalName, innerCallback);
38
- }
39
-
40
- dispatch(detail) {
41
- const event = new CustomEvent(this.internalName, {
42
- bubbles: true,
43
- detail,
44
- });
45
- document.dispatchEvent(event);
46
- }
47
- }
@@ -1,11 +0,0 @@
1
- import kebabCase from 'lodash.kebabcase';
2
- import events, { publicEventNames } from '@/events';
3
-
4
- it('Should export all public event names', async () => {
5
- Object.keys(events).forEach((internalEventName) => {
6
- expect(events[internalEventName].internalName).toEqual(
7
- `rebilly-instruments-${kebabCase(internalEventName)}`,
8
- );
9
- expect(kebabCase(internalEventName) in publicEventNames);
10
- });
11
- });
@@ -1,15 +0,0 @@
1
- import kebabCase from 'lodash.kebabcase';
2
- import BaseEvent from './base-event';
3
-
4
- const events = {
5
- dataReady: new BaseEvent('data-ready'),
6
- instrumentReady: new BaseEvent('instrument-ready'),
7
- purchaseCompleted: new BaseEvent('purchase-completed'),
8
- setupCompleted: new BaseEvent('setup-completed'),
9
- };
10
-
11
- export default events;
12
-
13
- export const publicEventNames = Object.keys(events).map((internalName) =>
14
- kebabCase(internalName),
15
- );
@@ -1,29 +0,0 @@
1
- import { cancellation } from 'rebilly-js-sdk';
2
- import { registeredListeners } from '../events/base-event';
3
- import { sleep } from '../utils';
4
- import state from '../state';
5
- import iframes from '../state/iframes';
6
-
7
- export async function destroy() {
8
- // wait to allow for cancellation to catch any pending api requests
9
- const sleepMilliseconds = 1000;
10
- await sleep(sleepMilliseconds);
11
-
12
- Object.keys(iframes).forEach((frame) => {
13
- if (iframes.hasFrame(frame)) {
14
- iframes[frame].destroy();
15
- iframes[frame] = null;
16
- }
17
- });
18
-
19
- registeredListeners.removeAll(document);
20
-
21
- state.hasMounted = false;
22
-
23
- if (state.summary) {
24
- state.summary.textContent = '';
25
- }
26
- state.form.textContent = '';
27
- cancellation.cancelAll();
28
- state.loader.clearAll();
29
- }
@@ -1,63 +0,0 @@
1
- import Events, { publicEventNames } from '@/events';
2
- import BaseEvent from '@/events/base-event';
3
- import { RenderMockRebillyInstruments } from 'tests/mocks/rebilly-instruments-mock';
4
-
5
- describe('RebillyInstruments Destroy', () => {
6
- it('should be able to destroy instance', async () => {
7
- const rebillyInstruments = await RenderMockRebillyInstruments();
8
-
9
- const formElement = document.querySelector('.form-selector');
10
- const summaryElement = document.querySelector('.summary-selector');
11
-
12
- expect(formElement.innerHTML).not.toEqual('');
13
- expect(summaryElement.innerHTML).not.toEqual('');
14
-
15
- await rebillyInstruments.destroy();
16
-
17
- expect(formElement.innerHTML).toEqual('');
18
- expect(summaryElement.innerHTML).toEqual('');
19
- });
20
-
21
- it('should remove registered listeners', async () => {
22
- const rebillyInstruments = await RenderMockRebillyInstruments();
23
-
24
- const fakeEventListener = vi.fn();
25
- Events.fakeEvent = new BaseEvent('fake-event');
26
- publicEventNames.push('fake-event');
27
- rebillyInstruments.on('fake-event', fakeEventListener);
28
-
29
- Events.fakeEvent.dispatch();
30
-
31
- expect(fakeEventListener).toHaveBeenCalledTimes(1);
32
-
33
- fakeEventListener.mockClear();
34
- await rebillyInstruments.destroy();
35
-
36
- Events.fakeEvent.dispatch();
37
- expect(fakeEventListener).not.toHaveBeenCalled();
38
- });
39
-
40
- it('should remove multiple listeners on the same event', async () => {
41
- const rebillyInstruments = await RenderMockRebillyInstruments();
42
-
43
- const fakeEventListener = vi.fn();
44
- const anotherFakeEventListener = vi.fn();
45
- Events.fakeEvent = new BaseEvent('fake-event');
46
- publicEventNames.push('fake-event');
47
- rebillyInstruments.on('fake-event', fakeEventListener);
48
- rebillyInstruments.on('fake-event', anotherFakeEventListener);
49
-
50
- Events.fakeEvent.dispatch();
51
-
52
- expect(fakeEventListener).toHaveBeenCalledTimes(1);
53
- expect(anotherFakeEventListener).toHaveBeenCalledTimes(1);
54
-
55
- fakeEventListener.mockClear();
56
- anotherFakeEventListener.mockClear();
57
- await rebillyInstruments.destroy();
58
-
59
- Events.fakeEvent.dispatch();
60
- expect(fakeEventListener).not.toHaveBeenCalled();
61
- expect(anotherFakeEventListener).not.toHaveBeenCalled();
62
- });
63
- });