medusajs-documents-plugin 0.0.0-stage → 1.1.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/.medusa/server/src/admin/index.js +2441 -0
- package/.medusa/server/src/admin/index.mjs +2442 -0
- package/.medusa/server/src/api/admin/documents/[id]/document/route.js +36 -0
- package/.medusa/server/src/api/admin/documents/[id]/send/route.js +41 -0
- package/.medusa/server/src/api/admin/documents/[id]/sync-zoho/route.js +68 -0
- package/.medusa/server/src/api/admin/documents/custom/route.js +48 -0
- package/.medusa/server/src/api/admin/documents/manual/route.js +46 -0
- package/.medusa/server/src/api/admin/documents/route.js +36 -0
- package/.medusa/server/src/api/admin/documents/settings/route.js +44 -0
- package/.medusa/server/src/api/admin/documents/templates/preview/route.js +159 -0
- package/.medusa/server/src/api/admin/documents/zoho/list/route.js +51 -0
- package/.medusa/server/src/api/documents/[id]/document/route.js +36 -0
- package/.medusa/server/src/api/documents/r/[code]/route.js +29 -0
- package/.medusa/server/src/api/documents/templates/preview/route.js +159 -0
- package/.medusa/server/src/api/store/documents/r/[code]/route.js +22 -0
- package/.medusa/server/src/index.js +27 -0
- package/.medusa/server/src/modules/documents/index.js +13 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20261012164601.js +23 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20261014150000.js +20 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20261015160000.js +46 -0
- package/.medusa/server/src/modules/documents/models/document-link.js +12 -0
- package/.medusa/server/src/modules/documents/models/document-record.js +33 -0
- package/.medusa/server/src/modules/documents/models/document-settings.js +79 -0
- package/.medusa/server/src/modules/documents/service.js +587 -0
- package/.medusa/server/src/services/notification-sender.js +612 -0
- package/.medusa/server/src/services/order-notification-templates.js +510 -0
- package/.medusa/server/src/services/pdf-post-processor.js +64 -0
- package/.medusa/server/src/services/pdfkit-generator.js +438 -0
- package/.medusa/server/src/services/zoho-books.js +221 -0
- package/.medusa/server/src/subscribers/order-documents.js +424 -0
- package/.medusa/server/src/subscribers/repair-documents.js +216 -0
- package/.medusa/server/src/utils/integrate.js +37 -0
- package/.medusa/server/src/utils/payment-link.js +69 -0
- package/.medusa/server/src/workflows/create-manual-document.js +27 -0
- package/.medusa/server/src/workflows/generate-document.js +24 -0
- package/.medusa/server/src/workflows/index.js +20 -0
- package/.medusa/server/src/workflows/send-document-notification.js +41 -0
- package/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +201 -2
- package/package.json +86 -4
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderNotificationTemplates = void 0;
|
|
4
|
+
const notification_sender_1 = require("./notification-sender");
|
|
5
|
+
class OrderNotificationTemplates {
|
|
6
|
+
// -------------------------------------------------------------
|
|
7
|
+
// Default Email Subjects
|
|
8
|
+
// -------------------------------------------------------------
|
|
9
|
+
static getDefaultSubject(event, vars) {
|
|
10
|
+
switch (event) {
|
|
11
|
+
case "order.placed":
|
|
12
|
+
return `Order Confirmation #${vars.display_id} - ${vars.company_name}`;
|
|
13
|
+
case "order.payment_captured":
|
|
14
|
+
case "payment.captured":
|
|
15
|
+
return `Payment Receipt for Order #${vars.display_id} - ${vars.company_name}`;
|
|
16
|
+
case "order.fulfillment_created":
|
|
17
|
+
case "fulfillment.created":
|
|
18
|
+
case "order.shipment_created":
|
|
19
|
+
case "shipment.created":
|
|
20
|
+
return `Your Order #${vars.display_id} Has Shipped! - ${vars.company_name}`;
|
|
21
|
+
case "order.canceled":
|
|
22
|
+
case "order.cancelled":
|
|
23
|
+
return `Update: Order #${vars.display_id} Has Been Canceled - ${vars.company_name}`;
|
|
24
|
+
case "order.completed":
|
|
25
|
+
return `Your Order #${vars.display_id} is Complete - ${vars.company_name}`;
|
|
26
|
+
default:
|
|
27
|
+
return `Update for Order #${vars.display_id} - ${vars.company_name}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// -------------------------------------------------------------
|
|
31
|
+
// Default Email HTML Templates
|
|
32
|
+
// -------------------------------------------------------------
|
|
33
|
+
static getDefaultEmailHtml(event, vars) {
|
|
34
|
+
const baseHeader = `
|
|
35
|
+
<div style="background-color: #0f172a; padding: 28px 24px; text-align: center; border-top-left-radius: 8px; border-top-right-radius: 8px;">
|
|
36
|
+
<h1 style="color: #ffffff; margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.5px;">${vars.company_name}</h1>
|
|
37
|
+
<p style="color: #94a3b8; margin: 6px 0 0 0; font-size: 13px;">Official Store Notification</p>
|
|
38
|
+
</div>
|
|
39
|
+
`;
|
|
40
|
+
const baseFooter = `
|
|
41
|
+
<div style="background-color: #f8fafc; padding: 20px 24px; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; border-top: 1px solid #e2e8f0; font-size: 13px; color: #64748b; text-align: center;">
|
|
42
|
+
<p style="margin: 0 0 6px 0;">Need assistance? Reply directly or contact <a href="mailto:${vars.support_email || "support@store.com"}" style="color: #2563eb; text-decoration: underline;">${vars.support_email || "our support team"}</a>.</p>
|
|
43
|
+
<p style="margin: 0; font-size: 12px; color: #94a3b8;">© ${new Date().getFullYear()} ${vars.company_name}. All rights reserved.</p>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
let bodyContent = "";
|
|
47
|
+
switch (event) {
|
|
48
|
+
case "order.placed": {
|
|
49
|
+
bodyContent = `
|
|
50
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
51
|
+
<div style="display: inline-block; padding: 4px 12px; background-color: #ecfdf5; border: 1px solid #a7f3d0; border-radius: 9999px; font-size: 12px; font-weight: 600; color: #047857; margin-bottom: 16px;">
|
|
52
|
+
✓ Order Confirmed
|
|
53
|
+
</div>
|
|
54
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Thank you for your order, ${vars.customer_name}!</h2>
|
|
55
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
56
|
+
We have received order <strong>#${vars.display_id}</strong> and are preparing it for packaging. Below is your order confirmation and tax invoice link.
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<!-- Order Details Card -->
|
|
60
|
+
<div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 18px; margin-bottom: 24px;">
|
|
61
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 12px; font-size: 13px;">
|
|
62
|
+
<span style="color: #64748b;">Order Number:</span>
|
|
63
|
+
<strong style="color: #0f172a;">#${vars.display_id}</strong>
|
|
64
|
+
</div>
|
|
65
|
+
${vars.shipping_address ? `
|
|
66
|
+
<div style="border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 12px; font-size: 13px;">
|
|
67
|
+
<span style="color: #64748b; display: block; margin-bottom: 4px;">Shipping Address:</span>
|
|
68
|
+
<strong style="color: #0f172a; line-height: 1.4;">${vars.shipping_address}</strong>
|
|
69
|
+
</div>` : ""}
|
|
70
|
+
<div style="display: flex; justify-content: space-between; font-size: 14px;">
|
|
71
|
+
<span style="color: #64748b;">Order Total:</span>
|
|
72
|
+
<strong style="color: #0f172a; font-size: 16px;">${vars.total_amount}</strong>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- Items Table -->
|
|
77
|
+
<div style="margin-bottom: 24px;">
|
|
78
|
+
<h3 style="margin: 0 0 12px 0; font-size: 15px; color: #0f172a; font-weight: 600;">Purchased Items</h3>
|
|
79
|
+
${vars.items_html}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<!-- Action Buttons -->
|
|
83
|
+
${vars.payment_button || ""}
|
|
84
|
+
${vars.download_button || (vars.document_link ? `
|
|
85
|
+
<div style="margin: 18px 0; text-align: center;">
|
|
86
|
+
<a href="${vars.document_link}" style="background-color: #0f172a; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600; display: inline-block; font-size: 14px;">
|
|
87
|
+
📄 Download Tax Invoice (PDF)
|
|
88
|
+
</a>
|
|
89
|
+
</div>
|
|
90
|
+
` : "")}
|
|
91
|
+
|
|
92
|
+
<p style="margin: 24px 0 0 0; color: #64748b; font-size: 14px; line-height: 1.6;">
|
|
93
|
+
<strong>What happens next?</strong> Our warehouse team will fulfill your order. You will receive another notification with tracking details as soon as your parcel is on its way.
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case "order.payment_captured":
|
|
100
|
+
case "payment.captured": {
|
|
101
|
+
const hasRemaining = vars.remaining_balance &&
|
|
102
|
+
vars.remaining_balance !== "$0.00" &&
|
|
103
|
+
vars.remaining_balance !== "0" &&
|
|
104
|
+
vars.remaining_balance !== "£0.00" &&
|
|
105
|
+
vars.remaining_balance !== "0.00";
|
|
106
|
+
bodyContent = `
|
|
107
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
108
|
+
<div style="display: inline-block; padding: 4px 12px; background-color: #ecfdf5; border: 1px solid #a7f3d0; border-radius: 9999px; font-size: 12px; font-weight: 600; color: #047857; margin-bottom: 16px;">
|
|
109
|
+
✓ Payment Received
|
|
110
|
+
</div>
|
|
111
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Payment Confirmed</h2>
|
|
112
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
113
|
+
Hello ${vars.customer_name}, we've successfully processed your payment for order <strong>#${vars.display_id}</strong>.
|
|
114
|
+
</p>
|
|
115
|
+
|
|
116
|
+
<div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 18px; margin-bottom: 24px;">
|
|
117
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; font-size: 13px;">
|
|
118
|
+
<span style="color: #64748b;">Amount Paid:</span>
|
|
119
|
+
<strong style="color: #047857; font-size: 15px;">${vars.amount_paid || vars.total_amount}</strong>
|
|
120
|
+
</div>
|
|
121
|
+
${vars.payment_method ? `
|
|
122
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; font-size: 13px;">
|
|
123
|
+
<span style="color: #64748b;">Payment Method:</span>
|
|
124
|
+
<strong style="color: #0f172a;">${vars.payment_method}</strong>
|
|
125
|
+
</div>` : ""}
|
|
126
|
+
${vars.payment_reference ? `
|
|
127
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; font-size: 13px;">
|
|
128
|
+
<span style="color: #64748b;">Payment Reference:</span>
|
|
129
|
+
<strong style="color: #0f172a;">${vars.payment_reference}</strong>
|
|
130
|
+
</div>` : ""}
|
|
131
|
+
${hasRemaining ? `
|
|
132
|
+
<div style="display: flex; justify-content: space-between; font-size: 13px; color: #b45309;">
|
|
133
|
+
<span>Remaining Balance:</span>
|
|
134
|
+
<strong>${vars.remaining_balance}</strong>
|
|
135
|
+
</div>` : `
|
|
136
|
+
<div style="display: flex; justify-content: space-between; font-size: 13px;">
|
|
137
|
+
<span style="color: #64748b;">Remaining Balance:</span>
|
|
138
|
+
<strong style="color: #047857;">Paid in Full</strong>
|
|
139
|
+
</div>`}
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
${vars.payment_button || ""}
|
|
143
|
+
|
|
144
|
+
${vars.download_button || (vars.document_link ? `
|
|
145
|
+
<div style="margin: 20px 0; text-align: center;">
|
|
146
|
+
<a href="${vars.document_link}" style="background-color: #2563eb; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600; display: inline-block; font-size: 14px;">
|
|
147
|
+
🧾 Download Payment Receipt (PDF)
|
|
148
|
+
</a>
|
|
149
|
+
</div>
|
|
150
|
+
` : "")}
|
|
151
|
+
|
|
152
|
+
<p style="margin: 20px 0 0 0; color: #64748b; font-size: 14px; line-height: 1.6;">
|
|
153
|
+
Your order is being processed for dispatch. We will notify you with full tracking information once your package has been handed to the courier.
|
|
154
|
+
</p>
|
|
155
|
+
</div>
|
|
156
|
+
`;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "order.fulfillment_created":
|
|
160
|
+
case "fulfillment.created":
|
|
161
|
+
case "order.shipment_created":
|
|
162
|
+
case "shipment.created": {
|
|
163
|
+
bodyContent = `
|
|
164
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
165
|
+
<div style="display: inline-block; padding: 4px 12px; background-color: #eff6ff; border: 1px solid #bfdbfe; border-radius: 9999px; font-size: 12px; font-weight: 600; color: #1d4ed8; margin-bottom: 16px;">
|
|
166
|
+
🚚 Dispatched & In Transit
|
|
167
|
+
</div>
|
|
168
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Good news, ${vars.customer_name}!</h2>
|
|
169
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
170
|
+
Your items for order <strong>#${vars.display_id}</strong> have been packed and handed over to our courier partner.
|
|
171
|
+
</p>
|
|
172
|
+
|
|
173
|
+
<div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 18px; margin-bottom: 24px;">
|
|
174
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; font-size: 13px;">
|
|
175
|
+
<span style="color: #64748b;">Carrier:</span>
|
|
176
|
+
<strong style="color: #0f172a;">${vars.carrier || "Standard Delivery"}</strong>
|
|
177
|
+
</div>
|
|
178
|
+
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; font-size: 13px;">
|
|
179
|
+
<span style="color: #64748b;">Tracking Number:</span>
|
|
180
|
+
<strong style="color: #0f172a; font-family: monospace;">${vars.tracking_number || "Available in portal"}</strong>
|
|
181
|
+
</div>
|
|
182
|
+
${vars.delivery_estimate ? `
|
|
183
|
+
<div style="display: flex; justify-content: space-between; font-size: 13px;">
|
|
184
|
+
<span style="color: #64748b;">Estimated Delivery:</span>
|
|
185
|
+
<strong style="color: #0f172a;">${vars.delivery_estimate}</strong>
|
|
186
|
+
</div>` : ""}
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<!-- Action Buttons -->
|
|
190
|
+
${vars.tracking_button || (vars.tracking_url ? `
|
|
191
|
+
<div style="margin: 20px 0; text-align: center;">
|
|
192
|
+
<a href="${vars.tracking_url}" style="background-color: #2563eb; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600; display: inline-block; font-size: 14px;">
|
|
193
|
+
📍 Track Your Package
|
|
194
|
+
</a>
|
|
195
|
+
</div>
|
|
196
|
+
` : "")}
|
|
197
|
+
|
|
198
|
+
${vars.download_button || (vars.document_link ? `
|
|
199
|
+
<div style="margin: 12px 0; text-align: center;">
|
|
200
|
+
<a href="${vars.document_link}" style="color: #475569; text-decoration: underline; font-size: 13px;">
|
|
201
|
+
📄 View Packing Slip / Delivery Note
|
|
202
|
+
</a>
|
|
203
|
+
</div>
|
|
204
|
+
` : "")}
|
|
205
|
+
</div>
|
|
206
|
+
`;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
case "order.canceled":
|
|
210
|
+
case "order.cancelled": {
|
|
211
|
+
bodyContent = `
|
|
212
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
213
|
+
<div style="display: inline-block; padding: 4px 12px; background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 9999px; font-size: 12px; font-weight: 600; color: #b91c1c; margin-bottom: 16px;">
|
|
214
|
+
✕ Order Canceled
|
|
215
|
+
</div>
|
|
216
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Order #${vars.display_id} Canceled</h2>
|
|
217
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
218
|
+
Hello ${vars.customer_name}, this notification confirms that your order <strong>#${vars.display_id}</strong> has been canceled.
|
|
219
|
+
</p>
|
|
220
|
+
|
|
221
|
+
${vars.cancellation_reason ? `
|
|
222
|
+
<div style="background-color: #fff7ed; border-left: 4px solid #f97316; padding: 14px 16px; margin-bottom: 20px; border-radius: 4px;">
|
|
223
|
+
<p style="margin: 0; font-size: 13px; color: #9a3412;"><strong>Reason:</strong> ${vars.cancellation_reason}</p>
|
|
224
|
+
</div>` : ""}
|
|
225
|
+
|
|
226
|
+
<div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 18px; margin-bottom: 24px;">
|
|
227
|
+
<p style="margin: 0 0 8px 0; font-weight: 600; color: #0f172a; font-size: 14px;">Refund & Billing Information</p>
|
|
228
|
+
<p style="margin: 0; font-size: 13px; color: #475569; line-height: 1.5;">
|
|
229
|
+
If payment was already collected for this order, a full refund of <strong>${vars.total_amount}</strong> has been initiated to your original payment method. Please allow 3–5 business days for banking processing.
|
|
230
|
+
</p>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<p style="margin: 20px 0 0 0; color: #64748b; font-size: 14px; line-height: 1.6;">
|
|
234
|
+
If you did not request this cancellation or believe this occurred in error, please contact our support team right away.
|
|
235
|
+
</p>
|
|
236
|
+
</div>
|
|
237
|
+
`;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case "order.completed": {
|
|
241
|
+
bodyContent = `
|
|
242
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
243
|
+
<div style="display: inline-block; padding: 4px 12px; background-color: #ecfdf5; border: 1px solid #a7f3d0; border-radius: 9999px; font-size: 12px; font-weight: 600; color: #047857; margin-bottom: 16px;">
|
|
244
|
+
✓ Order Complete
|
|
245
|
+
</div>
|
|
246
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Your Order #${vars.display_id} is Complete!</h2>
|
|
247
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
248
|
+
Hello ${vars.customer_name}, thank you for choosing ${vars.company_name}. We hope you are delighted with your items!
|
|
249
|
+
</p>
|
|
250
|
+
${vars.download_button || ""}
|
|
251
|
+
<p style="margin: 20px 0 0 0; color: #64748b; font-size: 14px; line-height: 1.6;">
|
|
252
|
+
If you have any questions, feedback, or need warranty support, please don't hesitate to reach out.
|
|
253
|
+
</p>
|
|
254
|
+
</div>
|
|
255
|
+
`;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
default: {
|
|
259
|
+
bodyContent = `
|
|
260
|
+
<div style="padding: 28px 24px; background-color: #ffffff;">
|
|
261
|
+
<h2 style="margin: 0 0 12px 0; color: #0f172a; font-size: 20px; font-weight: 600;">Order Update #${vars.display_id}</h2>
|
|
262
|
+
<p style="margin: 0 0 20px 0; color: #475569; font-size: 15px; line-height: 1.6;">
|
|
263
|
+
Hello ${vars.customer_name}, your order has been updated.
|
|
264
|
+
</p>
|
|
265
|
+
${vars.download_button || ""}
|
|
266
|
+
</div>
|
|
267
|
+
`;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return `
|
|
271
|
+
<!DOCTYPE html>
|
|
272
|
+
<html lang="en">
|
|
273
|
+
<head>
|
|
274
|
+
<meta charset="utf-8">
|
|
275
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
276
|
+
<title>${vars.company_name}</title>
|
|
277
|
+
</head>
|
|
278
|
+
<body style="margin: 0; padding: 20px 10px; background-color: #f1f5f9; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
|
|
279
|
+
<div style="max-width: 580px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);">
|
|
280
|
+
${baseHeader}
|
|
281
|
+
${bodyContent}
|
|
282
|
+
${baseFooter}
|
|
283
|
+
</div>
|
|
284
|
+
</body>
|
|
285
|
+
</html>
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
// -------------------------------------------------------------
|
|
289
|
+
// Default SMS Text Templates
|
|
290
|
+
// -------------------------------------------------------------
|
|
291
|
+
static getDefaultSmsText(event, vars) {
|
|
292
|
+
const hasRemaining = vars.remaining_balance &&
|
|
293
|
+
vars.remaining_balance !== "$0.00" &&
|
|
294
|
+
vars.remaining_balance !== "0" &&
|
|
295
|
+
vars.remaining_balance !== "£0.00" &&
|
|
296
|
+
vars.remaining_balance !== "0.00";
|
|
297
|
+
switch (event) {
|
|
298
|
+
case "order.placed": {
|
|
299
|
+
let msg = `[${vars.company_name}] Hi ${vars.customer_name}, order #${vars.display_id} confirmed! Total: ${vars.total_amount}.`;
|
|
300
|
+
if (vars.payment_link) {
|
|
301
|
+
msg += ` Pay balance: ${vars.payment_link}`;
|
|
302
|
+
}
|
|
303
|
+
if (vars.document_link) {
|
|
304
|
+
msg += ` Invoice: ${vars.document_link}`;
|
|
305
|
+
}
|
|
306
|
+
return msg;
|
|
307
|
+
}
|
|
308
|
+
case "order.payment_captured":
|
|
309
|
+
case "payment.captured": {
|
|
310
|
+
let msg = `[${vars.company_name}] Hi ${vars.customer_name}, payment of ${vars.amount_paid || vars.total_amount} received for order #${vars.display_id}.`;
|
|
311
|
+
if (hasRemaining && vars.payment_link) {
|
|
312
|
+
msg += ` Bal: ${vars.remaining_balance}. Pay: ${vars.payment_link}`;
|
|
313
|
+
}
|
|
314
|
+
if (vars.document_link) {
|
|
315
|
+
msg += ` Receipt: ${vars.document_link}`;
|
|
316
|
+
}
|
|
317
|
+
return msg;
|
|
318
|
+
}
|
|
319
|
+
case "order.fulfillment_created":
|
|
320
|
+
case "fulfillment.created":
|
|
321
|
+
case "order.shipment_created":
|
|
322
|
+
case "shipment.created": {
|
|
323
|
+
let msg = `[${vars.company_name}] Hi ${vars.customer_name}, order #${vars.display_id} has shipped via ${vars.carrier || "Courier"}!`;
|
|
324
|
+
if (vars.tracking_url) {
|
|
325
|
+
msg += ` Track: ${vars.tracking_url}`;
|
|
326
|
+
}
|
|
327
|
+
else if (vars.tracking_number) {
|
|
328
|
+
msg += ` Tracking: ${vars.tracking_number}`;
|
|
329
|
+
}
|
|
330
|
+
return msg;
|
|
331
|
+
}
|
|
332
|
+
case "order.canceled":
|
|
333
|
+
case "order.cancelled": {
|
|
334
|
+
return `[${vars.company_name}] Order #${vars.display_id} has been canceled. If charged, a refund of ${vars.total_amount} has been initiated to your original payment method.`;
|
|
335
|
+
}
|
|
336
|
+
case "order.completed": {
|
|
337
|
+
return `[${vars.company_name}] Hi ${vars.customer_name}, order #${vars.display_id} is completed. Thank you for shopping with ${vars.company_name}!`;
|
|
338
|
+
}
|
|
339
|
+
default:
|
|
340
|
+
return `[${vars.company_name}] Update for order #${vars.display_id}: Total ${vars.total_amount}. View: ${vars.document_link || vars.storefront_url}`;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
// -------------------------------------------------------------
|
|
344
|
+
// Default WhatsApp Text Templates
|
|
345
|
+
// -------------------------------------------------------------
|
|
346
|
+
static getDefaultWhatsAppText(event, vars) {
|
|
347
|
+
const hasRemaining = vars.remaining_balance &&
|
|
348
|
+
vars.remaining_balance !== "$0.00" &&
|
|
349
|
+
vars.remaining_balance !== "0" &&
|
|
350
|
+
vars.remaining_balance !== "£0.00" &&
|
|
351
|
+
vars.remaining_balance !== "0.00";
|
|
352
|
+
switch (event) {
|
|
353
|
+
case "order.placed": {
|
|
354
|
+
let text = `*Order Confirmation - ${vars.company_name}*\n\nHello *${vars.customer_name}*,\nThank you for your order! We've received order *#${vars.display_id}*.\n\n📦 *Items:*\n${vars.items_summary}\n\n💰 *Total:* ${vars.total_amount}`;
|
|
355
|
+
if (vars.shipping_address) {
|
|
356
|
+
text += `\n📍 *Shipping to:* ${vars.shipping_address}`;
|
|
357
|
+
}
|
|
358
|
+
if (vars.payment_link) {
|
|
359
|
+
text += `\n\n💳 *Pay Balance:* ${vars.payment_link}`;
|
|
360
|
+
}
|
|
361
|
+
if (vars.document_link) {
|
|
362
|
+
text += `\n📄 *Tax Invoice:* ${vars.document_link}`;
|
|
363
|
+
}
|
|
364
|
+
text += `\n\nWe will notify you as soon as your items are on the way!`;
|
|
365
|
+
return text;
|
|
366
|
+
}
|
|
367
|
+
case "order.payment_captured":
|
|
368
|
+
case "payment.captured": {
|
|
369
|
+
let text = `*Payment Received - ${vars.company_name}*\n\nHello *${vars.customer_name}*,\nWe have received your payment for order *#${vars.display_id}*.\n\n💰 *Amount Paid:* ${vars.amount_paid || vars.total_amount}`;
|
|
370
|
+
if (vars.payment_method) {
|
|
371
|
+
text += `\n💳 *Method:* ${vars.payment_method}`;
|
|
372
|
+
}
|
|
373
|
+
if (vars.payment_reference) {
|
|
374
|
+
text += `\n🔖 *Ref:* ${vars.payment_reference}`;
|
|
375
|
+
}
|
|
376
|
+
if (hasRemaining) {
|
|
377
|
+
text += `\n⚠️ *Remaining Balance:* ${vars.remaining_balance}`;
|
|
378
|
+
if (vars.payment_link) {
|
|
379
|
+
text += `\n👉 *Pay Balance:* ${vars.payment_link}`;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (vars.document_link) {
|
|
383
|
+
text += `\n🧾 *Receipt:* ${vars.document_link}`;
|
|
384
|
+
}
|
|
385
|
+
text += `\n\nYour order is now moving into fulfillment. Thank you!`;
|
|
386
|
+
return text;
|
|
387
|
+
}
|
|
388
|
+
case "order.fulfillment_created":
|
|
389
|
+
case "fulfillment.created":
|
|
390
|
+
case "order.shipment_created":
|
|
391
|
+
case "shipment.created": {
|
|
392
|
+
let text = `*Order Dispatched - ${vars.company_name}*\n\nHello *${vars.customer_name}*,\nGood news! Your order *#${vars.display_id}* has shipped.\n\n🚚 *Carrier:* ${vars.carrier || "Courier"}`;
|
|
393
|
+
if (vars.tracking_number) {
|
|
394
|
+
text += `\n🔍 *Tracking #:* ${vars.tracking_number}`;
|
|
395
|
+
}
|
|
396
|
+
if (vars.tracking_url) {
|
|
397
|
+
text += `\n📍 *Live Tracking:* ${vars.tracking_url}`;
|
|
398
|
+
}
|
|
399
|
+
if (vars.document_link) {
|
|
400
|
+
text += `\n📄 *Packing Slip:* ${vars.document_link}`;
|
|
401
|
+
}
|
|
402
|
+
text += `\n\nThank you for choosing ${vars.company_name}!`;
|
|
403
|
+
return text;
|
|
404
|
+
}
|
|
405
|
+
case "order.canceled":
|
|
406
|
+
case "order.cancelled": {
|
|
407
|
+
let text = `*Order Canceled - ${vars.company_name}*\n\nHello *${vars.customer_name}*,\nYour order *#${vars.display_id}* has been canceled.`;
|
|
408
|
+
if (vars.cancellation_reason) {
|
|
409
|
+
text += `\n\n*Reason:* ${vars.cancellation_reason}`;
|
|
410
|
+
}
|
|
411
|
+
text += `\n\n💳 *Refund Notice:* If you were already charged, a refund of ${vars.total_amount} is being processed to your original payment method within 3–5 business days.\n\nNeed help? Contact us at ${vars.support_email || "support"}.`;
|
|
412
|
+
return text;
|
|
413
|
+
}
|
|
414
|
+
case "order.completed": {
|
|
415
|
+
return `*Order Complete - ${vars.company_name}*\n\nHello *${vars.customer_name}*,\nYour order *#${vars.display_id}* is complete. Thank you for choosing ${vars.company_name}! If you need any assistance, feel free to reply to this message.`;
|
|
416
|
+
}
|
|
417
|
+
default:
|
|
418
|
+
return `*Update for Order #${vars.display_id}* (${vars.company_name})\nTotal: ${vars.total_amount}\nView: ${vars.document_link || vars.storefront_url}`;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
// -------------------------------------------------------------
|
|
422
|
+
// Resolves Content (Custom Setting Template or Built-in Default)
|
|
423
|
+
// -------------------------------------------------------------
|
|
424
|
+
static resolveNotificationContent(event, vars, settings) {
|
|
425
|
+
// 1. Email Subject
|
|
426
|
+
let customSubjectKey = "";
|
|
427
|
+
let customEmailBodyKey = "";
|
|
428
|
+
let customSmsBodyKey = "";
|
|
429
|
+
let customWaBodyKey = "";
|
|
430
|
+
if (event === "order.placed") {
|
|
431
|
+
customSubjectKey = "order_placed_email_subject";
|
|
432
|
+
customEmailBodyKey = "order_placed_email_template";
|
|
433
|
+
customSmsBodyKey = "order_placed_sms_template";
|
|
434
|
+
customWaBodyKey = "order_placed_whatsapp_template";
|
|
435
|
+
}
|
|
436
|
+
else if (event === "order.payment_captured" || event === "payment.captured") {
|
|
437
|
+
customSubjectKey = "order_payment_email_subject";
|
|
438
|
+
customEmailBodyKey = "order_payment_email_template";
|
|
439
|
+
customSmsBodyKey = "order_payment_sms_template";
|
|
440
|
+
customWaBodyKey = "order_payment_whatsapp_template";
|
|
441
|
+
}
|
|
442
|
+
else if (event === "order.fulfillment_created" ||
|
|
443
|
+
event === "fulfillment.created" ||
|
|
444
|
+
event === "order.shipment_created" ||
|
|
445
|
+
event === "shipment.created") {
|
|
446
|
+
customSubjectKey = "order_fulfillment_email_subject";
|
|
447
|
+
customEmailBodyKey = "order_fulfillment_email_template";
|
|
448
|
+
customSmsBodyKey = "order_fulfillment_sms_template";
|
|
449
|
+
customWaBodyKey = "order_fulfillment_whatsapp_template";
|
|
450
|
+
}
|
|
451
|
+
else if (event === "order.canceled" || event === "order.cancelled") {
|
|
452
|
+
customSubjectKey = "order_canceled_email_subject";
|
|
453
|
+
customEmailBodyKey = "order_canceled_email_template";
|
|
454
|
+
customSmsBodyKey = "order_canceled_sms_template";
|
|
455
|
+
customWaBodyKey = "order_canceled_whatsapp_template";
|
|
456
|
+
}
|
|
457
|
+
const defaultSubject = this.getDefaultSubject(event, vars);
|
|
458
|
+
const subject = settings?.[customSubjectKey] && settings[customSubjectKey].trim()
|
|
459
|
+
? (0, notification_sender_1.renderTemplatePlaceholders)(settings[customSubjectKey], vars)
|
|
460
|
+
: defaultSubject;
|
|
461
|
+
// 2. Email HTML
|
|
462
|
+
let emailHtml = "";
|
|
463
|
+
if (settings?.[customEmailBodyKey] && settings[customEmailBodyKey].trim()) {
|
|
464
|
+
let customHtml = (0, notification_sender_1.renderTemplatePlaceholders)(settings[customEmailBodyKey], vars);
|
|
465
|
+
if (!customHtml.includes("<html") && !customHtml.includes("<!DOCTYPE")) {
|
|
466
|
+
// Wrap in professional responsive wrapper if user provided a partial snippet
|
|
467
|
+
emailHtml = `
|
|
468
|
+
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color: #0f172a; max-width: 580px; margin: 0 auto; line-height: 1.6; border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden; background-color: #ffffff;">
|
|
469
|
+
<div style="background-color: #0f172a; padding: 24px; color: #ffffff; text-align: center;">
|
|
470
|
+
<h1 style="margin: 0; font-size: 20px;">${vars.company_name}</h1>
|
|
471
|
+
<p style="margin: 4px 0 0 0; opacity: 0.8; font-size: 13px;">Order #${vars.display_id}</p>
|
|
472
|
+
</div>
|
|
473
|
+
<div style="padding: 24px;">
|
|
474
|
+
${customHtml}
|
|
475
|
+
</div>
|
|
476
|
+
<div style="background-color: #f8fafc; padding: 16px; text-align: center; font-size: 12px; color: #94a3b8; border-top: 1px solid #e2e8f0;">
|
|
477
|
+
© ${new Date().getFullYear()} ${vars.company_name}
|
|
478
|
+
</div>
|
|
479
|
+
</div>
|
|
480
|
+
`;
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
emailHtml = customHtml;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
emailHtml = this.getDefaultEmailHtml(event, vars);
|
|
488
|
+
}
|
|
489
|
+
// 3. SMS Text
|
|
490
|
+
let smsText = "";
|
|
491
|
+
if (settings?.[customSmsBodyKey] && settings[customSmsBodyKey].trim()) {
|
|
492
|
+
smsText = (0, notification_sender_1.renderTemplatePlaceholders)(settings[customSmsBodyKey], vars);
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
smsText = this.getDefaultSmsText(event, vars);
|
|
496
|
+
}
|
|
497
|
+
// 4. WhatsApp Text
|
|
498
|
+
let whatsappText = "";
|
|
499
|
+
if (settings?.[customWaBodyKey] && settings[customWaBodyKey].trim()) {
|
|
500
|
+
whatsappText = (0, notification_sender_1.renderTemplatePlaceholders)(settings[customWaBodyKey], vars);
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
whatsappText = this.getDefaultWhatsAppText(event, vars);
|
|
504
|
+
}
|
|
505
|
+
return { subject, emailHtml, smsText, whatsappText };
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
exports.OrderNotificationTemplates = OrderNotificationTemplates;
|
|
509
|
+
exports.default = OrderNotificationTemplates;
|
|
510
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItbm90aWZpY2F0aW9uLXRlbXBsYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9vcmRlci1ub3RpZmljYXRpb24tdGVtcGxhdGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtEQUFtRTtBQXdEbkUsTUFBYSwwQkFBMEI7SUFDckMsZ0VBQWdFO0lBQ2hFLHlCQUF5QjtJQUN6QixnRUFBZ0U7SUFDaEUsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQWlDLEVBQUUsSUFBZ0M7UUFDMUYsUUFBUSxLQUFLLEVBQUUsQ0FBQztZQUNkLEtBQUssY0FBYztnQkFDakIsT0FBTyx1QkFBdUIsSUFBSSxDQUFDLFVBQVUsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDekUsS0FBSyx3QkFBd0IsQ0FBQztZQUM5QixLQUFLLGtCQUFrQjtnQkFDckIsT0FBTyw4QkFBOEIsSUFBSSxDQUFDLFVBQVUsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDaEYsS0FBSywyQkFBMkIsQ0FBQztZQUNqQyxLQUFLLHFCQUFxQixDQUFDO1lBQzNCLEtBQUssd0JBQXdCLENBQUM7WUFDOUIsS0FBSyxrQkFBa0I7Z0JBQ3JCLE9BQU8sZUFBZSxJQUFJLENBQUMsVUFBVSxtQkFBbUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzlFLEtBQUssZ0JBQWdCLENBQUM7WUFDdEIsS0FBSyxpQkFBaUI7Z0JBQ3BCLE9BQU8sa0JBQWtCLElBQUksQ0FBQyxVQUFVLHdCQUF3QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEYsS0FBSyxpQkFBaUI7Z0JBQ3BCLE9BQU8sZUFBZSxJQUFJLENBQUMsVUFBVSxrQkFBa0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzdFO2dCQUNFLE9BQU8scUJBQXFCLElBQUksQ0FBQyxVQUFVLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFD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
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.postProcessPdf = postProcessPdf;
|
|
7
|
+
const pdf_lib_1 = require("pdf-lib");
|
|
8
|
+
const qrcode_1 = __importDefault(require("qrcode"));
|
|
9
|
+
/**
|
|
10
|
+
* Post-processes PDF buffers to embed QR codes and clean up headers/footers.
|
|
11
|
+
* (Note: Watermarks removed per user instruction)
|
|
12
|
+
*/
|
|
13
|
+
async function postProcessPdf(pdfBuffer, options = {}) {
|
|
14
|
+
try {
|
|
15
|
+
const pdfDoc = await pdf_lib_1.PDFDocument.load(pdfBuffer);
|
|
16
|
+
// 1. Generate & Embed QR Code if URL is provided
|
|
17
|
+
let qrImage = null;
|
|
18
|
+
if (options.qrUrl) {
|
|
19
|
+
try {
|
|
20
|
+
const qrBufferLib = await qrcode_1.default.toBuffer(options.qrUrl, {
|
|
21
|
+
errorCorrectionLevel: "H",
|
|
22
|
+
type: "png",
|
|
23
|
+
margin: 1,
|
|
24
|
+
width: 75,
|
|
25
|
+
});
|
|
26
|
+
qrImage = await pdfDoc.embedPng(qrBufferLib);
|
|
27
|
+
}
|
|
28
|
+
catch (qrErr) {
|
|
29
|
+
console.error("[postProcessPdf] QR Code generation error:", qrErr);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const pages = pdfDoc.getPages();
|
|
33
|
+
if (pages.length > 0 && qrImage) {
|
|
34
|
+
const firstPage = pages[0];
|
|
35
|
+
// Draw QR Code on top right
|
|
36
|
+
firstPage.drawImage(qrImage, {
|
|
37
|
+
x: firstPage.getWidth() - 105,
|
|
38
|
+
y: 40,
|
|
39
|
+
width: 65,
|
|
40
|
+
height: 65,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// 2. Obscure external footer (e.g. "Powered by Zoho Books") if requested
|
|
44
|
+
if (options.obscureZohoFooter) {
|
|
45
|
+
for (const page of pages) {
|
|
46
|
+
page.drawRectangle({
|
|
47
|
+
x: 0,
|
|
48
|
+
y: 0,
|
|
49
|
+
width: page.getWidth(),
|
|
50
|
+
height: 35,
|
|
51
|
+
color: (0, pdf_lib_1.rgb)(1, 1, 1),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const modifiedPdfBytes = await pdfDoc.save();
|
|
56
|
+
return Buffer.from(modifiedPdfBytes);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error("[postProcessPdf] Error processing PDF:", err?.message || err);
|
|
60
|
+
return pdfBuffer; // fallback cleanly to original buffer
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.default = postProcessPdf;
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLXBvc3QtcHJvY2Vzc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3NlcnZpY2VzL3BkZi1wb3N0LXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVlBLHdDQXVEQztBQW5FRCxxQ0FBd0Q7QUFDeEQsb0RBQTRCO0FBTzVCOzs7R0FHRztBQUNJLEtBQUssVUFBVSxjQUFjLENBQ2xDLFNBQWlCLEVBQ2pCLFVBQThCLEVBQUU7SUFFaEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxxQkFBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUUvQyxpREFBaUQ7UUFDakQsSUFBSSxPQUFPLEdBQVEsSUFBSSxDQUFDO1FBQ3hCLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQztnQkFDSCxNQUFNLFdBQVcsR0FBRyxNQUFNLGdCQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUU7b0JBQ3ZELG9CQUFvQixFQUFFLEdBQUc7b0JBQ3pCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxDQUFDO29CQUNULEtBQUssRUFBRSxFQUFFO2lCQUNWLENBQUMsQ0FBQztnQkFDSCxPQUFPLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQy9DLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNENBQTRDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckUsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFaEMsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNoQyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0IsNEJBQTRCO1lBQzVCLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFO2dCQUMzQixDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLEdBQUc7Z0JBQzdCLENBQUMsRUFBRSxFQUFFO2dCQUNMLEtBQUssRUFBRSxFQUFFO2dCQUNULE1BQU0sRUFBRSxFQUFFO2FBQ1gsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELHlFQUF5RTtRQUN6RSxJQUFJLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzlCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUM7b0JBQ2pCLENBQUMsRUFBRSxDQUFDO29CQUNKLENBQUMsRUFBRSxDQUFDO29CQUNKLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUN0QixNQUFNLEVBQUUsRUFBRTtvQkFDVixLQUFLLEVBQUUsSUFBQSxhQUFHLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7aUJBQ3BCLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM3QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRSxPQUFPLElBQUksR0FBRyxDQUFDLENBQUM7UUFDN0UsT0FBTyxTQUFTLENBQUMsQ0FBQyxzQ0FBc0M7SUFDMUQsQ0FBQztBQUNILENBQUM7QUFFRCxrQkFBZSxjQUFjLENBQUMifQ==
|