@dynamatix/gb-schemas 2.3.261 → 2.3.263
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/applicants/applicant-direct-debit.model.d.ts +0 -3
- package/dist/applicants/applicant-direct-debit.model.d.ts.map +1 -1
- package/dist/applicants/applicant-direct-debit.model.js +0 -1
- package/dist/applicants/applicant-welcome-call.model.d.ts.map +1 -1
- package/dist/applicants/applicant-welcome-call.model.js +171 -38
- package/dist/applicants/applicant.model.d.ts +0 -3
- package/dist/applicants/applicant.model.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -34,7 +34,6 @@ declare const applicantDirectDebitSchema: mongoose.Schema<any, mongoose.Model<an
|
|
|
34
34
|
updatedAt: NativeDate;
|
|
35
35
|
} & {
|
|
36
36
|
isConfirmDeclaration: string;
|
|
37
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
38
37
|
addressLine1?: string | null | undefined;
|
|
39
38
|
addressLine2?: string | null | undefined;
|
|
40
39
|
accountNumber?: string | null | undefined;
|
|
@@ -51,7 +50,6 @@ declare const applicantDirectDebitSchema: mongoose.Schema<any, mongoose.Model<an
|
|
|
51
50
|
updatedAt: NativeDate;
|
|
52
51
|
} & {
|
|
53
52
|
isConfirmDeclaration: string;
|
|
54
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
55
53
|
addressLine1?: string | null | undefined;
|
|
56
54
|
addressLine2?: string | null | undefined;
|
|
57
55
|
accountNumber?: string | null | undefined;
|
|
@@ -68,7 +66,6 @@ declare const applicantDirectDebitSchema: mongoose.Schema<any, mongoose.Model<an
|
|
|
68
66
|
updatedAt: NativeDate;
|
|
69
67
|
} & {
|
|
70
68
|
isConfirmDeclaration: string;
|
|
71
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
72
69
|
addressLine1?: string | null | undefined;
|
|
73
70
|
addressLine2?: string | null | undefined;
|
|
74
71
|
accountNumber?: string | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applicant-direct-debit.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant-direct-debit.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAGhC,QAAA,MAAM,0BAA0B
|
|
1
|
+
{"version":3,"file":"applicant-direct-debit.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant-direct-debit.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAGhC,QAAA,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAaR,CAAC;AAEzB,eAAe,0BAA0B,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import mongoose from 'mongoose';
|
|
2
2
|
const applicantDirectDebitSchema = new mongoose.Schema({
|
|
3
|
-
applicationId: { type: mongoose.Schema.Types.ObjectId, ref: 'Application' },
|
|
4
3
|
accountNumber: { type: String },
|
|
5
4
|
addressLine1: { type: String },
|
|
6
5
|
addressLine2: { type: String },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applicant-welcome-call.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant-welcome-call.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"applicant-welcome-call.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant-welcome-call.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AA8hBhC,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAA4D,CAAC;AAEnF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import mongoose from "mongoose";
|
|
2
2
|
import { applyWorkflowPlugin } from "../shared/workflow.plugin";
|
|
3
|
+
import { applyAuditMiddleware } from "@dynamatix/cat-shared/middlewares";
|
|
3
4
|
// Welcome Call Schema
|
|
4
5
|
const welcomeCallSchema = new mongoose.Schema({
|
|
5
6
|
applicantId: { type: mongoose.Schema.Types.ObjectId, ref: "Applicant", required: true },
|
|
@@ -226,12 +227,18 @@ welcomeCallSchema.virtual('customerCurrentResidentialAddress').get(function () {
|
|
|
226
227
|
const applicant = this.applicantId;
|
|
227
228
|
// Use only regular address fields (addressLine1, addressLine2, addressLine3)
|
|
228
229
|
if (applicant.addressLine1) {
|
|
230
|
+
// Get country name from populated addressCountryLid
|
|
231
|
+
let countryName = '';
|
|
232
|
+
if (applicant.addressCountryLid && typeof applicant.addressCountryLid === 'object') {
|
|
233
|
+
countryName = applicant.addressCountryLid.name || '';
|
|
234
|
+
}
|
|
229
235
|
const addressParts = [
|
|
230
236
|
applicant.addressLine1,
|
|
231
237
|
applicant.addressLine2,
|
|
232
238
|
applicant.addressLine3,
|
|
233
239
|
applicant.addressCity,
|
|
234
|
-
applicant.addressPostCode
|
|
240
|
+
applicant.addressPostCode,
|
|
241
|
+
countryName
|
|
235
242
|
].filter(part => part && part.trim() !== '');
|
|
236
243
|
return addressParts.join(', ');
|
|
237
244
|
}
|
|
@@ -257,46 +264,101 @@ welcomeCallSchema.virtual('customerContactNumbers').get(function () {
|
|
|
257
264
|
});
|
|
258
265
|
// Virtual property for all applicants name/DOB when there are multiple applicants
|
|
259
266
|
welcomeCallSchema.virtual('allApplicantsNameAndDOB').get(function () {
|
|
260
|
-
//
|
|
261
|
-
if (this.
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
// Get application and its applicants
|
|
268
|
+
if (this.applicationId && typeof this.applicationId === 'object') {
|
|
269
|
+
const application = this.applicationId;
|
|
270
|
+
// Get all applicants from the application (field name is 'applicants')
|
|
271
|
+
if (application.applicants && Array.isArray(application.applicants) && application.applicants.length > 0) {
|
|
272
|
+
// Get current applicant ID for comparison
|
|
273
|
+
const currentApplicantId = this.applicantId?._id || this.applicantId;
|
|
274
|
+
// Filter out the current applicant to get only OTHER applicants
|
|
275
|
+
const otherApplicants = application.applicants.filter((applicant) => {
|
|
276
|
+
const applicantId = applicant._id || applicant;
|
|
277
|
+
return applicantId.toString() !== currentApplicantId.toString();
|
|
278
|
+
});
|
|
279
|
+
// If no other applicants, return "N/A" (single applicant case)
|
|
280
|
+
if (otherApplicants.length === 0) {
|
|
281
|
+
return 'N/A';
|
|
282
|
+
}
|
|
283
|
+
// Format each other applicant as: firstName,middleName,lastName,dd/mm/yyyy
|
|
284
|
+
const formattedApplicants = otherApplicants.map((applicant) => {
|
|
285
|
+
// Check if applicant is an ObjectId (not populated)
|
|
286
|
+
if (typeof applicant === 'string' || (applicant.constructor && applicant.constructor.name === 'ObjectId')) {
|
|
287
|
+
return null; // Skip unpopulated references
|
|
288
|
+
}
|
|
289
|
+
const firstName = applicant.firstName || '';
|
|
290
|
+
const middleName = applicant.middleName || '';
|
|
291
|
+
const lastName = applicant.lastName || '';
|
|
292
|
+
// Combine first and middle names
|
|
293
|
+
const fullFirstName = middleName ? `${firstName},${middleName}` : firstName;
|
|
294
|
+
// Format date of birth to dd/mm/yyyy
|
|
295
|
+
let formattedDOB = '';
|
|
296
|
+
if (applicant.dateOfBirth) {
|
|
297
|
+
// Check if dateOfBirth is already a formatted string (DD/MM/YYYY)
|
|
298
|
+
if (typeof applicant.dateOfBirth === 'string' && /^\d{2}\/\d{2}\/\d{4}$/.test(applicant.dateOfBirth)) {
|
|
299
|
+
// Already in DD/MM/YYYY format
|
|
300
|
+
formattedDOB = applicant.dateOfBirth;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
// Try to parse as Date object or ISO string
|
|
304
|
+
try {
|
|
305
|
+
const date = new Date(applicant.dateOfBirth);
|
|
306
|
+
// Check if date is valid
|
|
307
|
+
if (!isNaN(date.getTime())) {
|
|
308
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
309
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
310
|
+
const year = date.getFullYear();
|
|
311
|
+
formattedDOB = `${day}/${month}/${year}`;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch (e) {
|
|
315
|
+
// Date parsing failed, try to use as-is if it's a string
|
|
316
|
+
if (typeof applicant.dateOfBirth === 'string') {
|
|
317
|
+
formattedDOB = applicant.dateOfBirth;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return `${fullFirstName},${lastName},${formattedDOB}`;
|
|
323
|
+
}).filter((line) => line && line.trim() !== ',,' && line.trim() !== '');
|
|
324
|
+
// Join all applicants with newline
|
|
325
|
+
return formattedApplicants.join('\n');
|
|
326
|
+
}
|
|
268
327
|
}
|
|
269
|
-
return
|
|
328
|
+
// If application not populated or no applicants, return "N/A"
|
|
329
|
+
return 'N/A';
|
|
270
330
|
});
|
|
271
331
|
// Virtual property for broker name and firm
|
|
272
332
|
welcomeCallSchema.virtual('brokerNameAndFirm').get(function () {
|
|
273
|
-
|
|
274
|
-
|
|
333
|
+
// Access application from welcome call directly
|
|
334
|
+
if (this.applicationId && typeof this.applicationId === 'object') {
|
|
335
|
+
const application = this.applicationId;
|
|
275
336
|
let brokerName = '';
|
|
276
|
-
let
|
|
277
|
-
// Get broker
|
|
278
|
-
if (application
|
|
337
|
+
let tradingName = '';
|
|
338
|
+
// Get broker information
|
|
339
|
+
if (application.brokerId && typeof application.brokerId === 'object') {
|
|
279
340
|
const broker = application.brokerId;
|
|
341
|
+
// Get broker name
|
|
280
342
|
if (broker.firstName && broker.lastName) {
|
|
281
343
|
brokerName = `${broker.firstName} ${broker.lastName}`;
|
|
282
344
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (
|
|
288
|
-
|
|
345
|
+
// Get trading name (try both lowercase and uppercase)
|
|
346
|
+
if (broker.tradingName) {
|
|
347
|
+
tradingName = broker.tradingName;
|
|
348
|
+
}
|
|
349
|
+
else if (broker.TradingName) {
|
|
350
|
+
tradingName = broker.TradingName;
|
|
289
351
|
}
|
|
290
352
|
}
|
|
291
|
-
// Combine in format "Broker name /
|
|
292
|
-
if (brokerName &&
|
|
293
|
-
return `${brokerName} / ${
|
|
353
|
+
// Combine in format "Broker name / Trading Name"
|
|
354
|
+
if (brokerName && tradingName) {
|
|
355
|
+
return `${brokerName} / ${tradingName}`;
|
|
294
356
|
}
|
|
295
357
|
else if (brokerName) {
|
|
296
358
|
return brokerName;
|
|
297
359
|
}
|
|
298
|
-
else if (
|
|
299
|
-
return
|
|
360
|
+
else if (tradingName) {
|
|
361
|
+
return tradingName;
|
|
300
362
|
}
|
|
301
363
|
}
|
|
302
364
|
return null;
|
|
@@ -332,18 +394,24 @@ welcomeCallSchema.virtual('accountHolderAndBank').get(function () {
|
|
|
332
394
|
});
|
|
333
395
|
// virtual property for property address
|
|
334
396
|
welcomeCallSchema.virtual('customerPropertyAddress').get(function () {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
397
|
+
// Get property address from application's security reference
|
|
398
|
+
if (this.applicationId && typeof this.applicationId === 'object') {
|
|
399
|
+
const application = this.applicationId;
|
|
400
|
+
// Access security details through securityId
|
|
401
|
+
if (application.securityId && typeof application.securityId === 'object') {
|
|
402
|
+
const security = application.securityId;
|
|
403
|
+
// Use property address fields from security model
|
|
404
|
+
if (security.propertyAddressLine1) {
|
|
405
|
+
const addressParts = [
|
|
406
|
+
security.propertyAddressLine1,
|
|
407
|
+
security.propertyAddressLine2,
|
|
408
|
+
security.propertyAddressLine3,
|
|
409
|
+
security.propertyAddressCity,
|
|
410
|
+
security.propertyAddressPostCode
|
|
411
|
+
].filter(part => part && part.trim() !== '')
|
|
412
|
+
.map(part => `${part},`);
|
|
413
|
+
return addressParts.join('\n');
|
|
414
|
+
}
|
|
347
415
|
}
|
|
348
416
|
}
|
|
349
417
|
return null;
|
|
@@ -366,6 +434,71 @@ welcomeCallSchema.virtual('applicantEmployer').get(function () {
|
|
|
366
434
|
}
|
|
367
435
|
return null;
|
|
368
436
|
});
|
|
437
|
+
// Virtual property for product name
|
|
438
|
+
welcomeCallSchema.virtual('productName').get(function () {
|
|
439
|
+
// Get product from application
|
|
440
|
+
if (this.applicationId && typeof this.applicationId === 'object') {
|
|
441
|
+
const application = this.applicationId;
|
|
442
|
+
// First check if selectedProduct is on the application directly
|
|
443
|
+
let selectedProduct = application.selectedProduct;
|
|
444
|
+
// If not found on application, check productId
|
|
445
|
+
if (!selectedProduct || selectedProduct.trim() === '') {
|
|
446
|
+
if (application.productId && typeof application.productId === 'object') {
|
|
447
|
+
selectedProduct = application.productId.selectedProduct;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// Extract text before parentheses if selectedProduct has a value
|
|
451
|
+
if (selectedProduct && typeof selectedProduct === 'string' && selectedProduct.trim() !== '') {
|
|
452
|
+
// Extract text before opening parenthesis and trim whitespace
|
|
453
|
+
const match = selectedProduct.match(/^([^(]+)/);
|
|
454
|
+
if (match && match[1]) {
|
|
455
|
+
let productName = match[1].trim();
|
|
456
|
+
// Remove product type words like "Fixed", "Variable", "Tracker", etc.
|
|
457
|
+
// Split by common product type keywords and return only the first part
|
|
458
|
+
const productTypeKeywords = ['Fixed', 'Variable', 'Tracker', 'Discount', 'Capped'];
|
|
459
|
+
for (const keyword of productTypeKeywords) {
|
|
460
|
+
if (productName.includes(keyword)) {
|
|
461
|
+
productName = productName.split(keyword)[0].trim();
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return productName;
|
|
466
|
+
}
|
|
467
|
+
// If no parentheses found, return the whole string trimmed
|
|
468
|
+
return selectedProduct.trim();
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return null;
|
|
472
|
+
});
|
|
473
|
+
// Virtual property for initial rate percentage
|
|
474
|
+
welcomeCallSchema.virtual('initialRatePercentage').get(function () {
|
|
475
|
+
// Get product features from application
|
|
476
|
+
if (this.applicationId && typeof this.applicationId === 'object') {
|
|
477
|
+
const application = this.applicationId;
|
|
478
|
+
// Check if product features are available
|
|
479
|
+
if (application.productFeatures && typeof application.productFeatures === 'object') {
|
|
480
|
+
const productFeatures = application.productFeatures;
|
|
481
|
+
// Get initialRate value
|
|
482
|
+
if (productFeatures.initialRate !== undefined && productFeatures.initialRate !== null) {
|
|
483
|
+
const initialRate = productFeatures.initialRate;
|
|
484
|
+
// Convert to number
|
|
485
|
+
const rateValue = typeof initialRate === 'string' ? parseFloat(initialRate) : initialRate;
|
|
486
|
+
// Check if valid number
|
|
487
|
+
if (!isNaN(rateValue)) {
|
|
488
|
+
// If value is less than 1, it's likely stored as decimal (e.g., 0.0599)
|
|
489
|
+
// Multiply by 100 to get percentage
|
|
490
|
+
// If value is greater than or equal to 1, it's likely already in percentage form (e.g., 5.99)
|
|
491
|
+
// Divide by 100 as requested by user
|
|
492
|
+
const percentageValue = rateValue >= 1 ? rateValue / 100 : rateValue * 100;
|
|
493
|
+
// Format to 2 decimal places and add % sign
|
|
494
|
+
return `${percentageValue.toFixed(2)}%`;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
});
|
|
501
|
+
applyAuditMiddleware(welcomeCallSchema, "ApplicantWelcomeCall");
|
|
369
502
|
// Apply workflow plugin to the schema
|
|
370
503
|
applyWorkflowPlugin(welcomeCallSchema, 'applicantwelcomecall');
|
|
371
504
|
const WelcomeCallModel = mongoose.model('ApplicantWelcomeCall', welcomeCallSchema);
|
|
@@ -1236,7 +1236,6 @@ declare const ApplicantModel: mongoose.Model<{
|
|
|
1236
1236
|
updatedAt: NativeDate;
|
|
1237
1237
|
} & {
|
|
1238
1238
|
isConfirmDeclaration: string;
|
|
1239
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
1240
1239
|
addressLine1?: string | null | undefined;
|
|
1241
1240
|
addressLine2?: string | null | undefined;
|
|
1242
1241
|
accountNumber?: string | null | undefined;
|
|
@@ -1392,7 +1391,6 @@ declare const ApplicantModel: mongoose.Model<{
|
|
|
1392
1391
|
updatedAt: NativeDate;
|
|
1393
1392
|
} & {
|
|
1394
1393
|
isConfirmDeclaration: string;
|
|
1395
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
1396
1394
|
addressLine1?: string | null | undefined;
|
|
1397
1395
|
addressLine2?: string | null | undefined;
|
|
1398
1396
|
accountNumber?: string | null | undefined;
|
|
@@ -1548,7 +1546,6 @@ declare const ApplicantModel: mongoose.Model<{
|
|
|
1548
1546
|
updatedAt: NativeDate;
|
|
1549
1547
|
} & {
|
|
1550
1548
|
isConfirmDeclaration: string;
|
|
1551
|
-
applicationId?: mongoose.Types.ObjectId | null | undefined;
|
|
1552
1549
|
addressLine1?: string | null | undefined;
|
|
1553
1550
|
addressLine2?: string | null | undefined;
|
|
1554
1551
|
accountNumber?: string | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applicant.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAOhC,OAAO,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAC;AAuQ5D,QAAA,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"applicant.model.d.ts","sourceRoot":"","sources":["../../applicants/applicant.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAOhC,OAAO,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAC;AAuQ5D,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAA+C,CAAC;AACpE,eAAe,cAAc,CAAC"}
|