@codee-sh/medusa-plugin-notification-emails 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/emails-previews/contact-form.js +14 -8
- package/.medusa/server/emails-previews/inventory-level.js +8 -4
- package/.medusa/server/emails-previews/order-completed.js +70 -35
- package/.medusa/server/emails-previews/order-placed.js +70 -34
- package/.medusa/server/src/admin/index.js +1684 -262
- package/.medusa/server/src/admin/index.mjs +1684 -262
- package/.medusa/server/src/api/admin/notification-plugin/render-template/route.js +9 -5
- package/.medusa/server/src/subscribers/order-completed.js +10 -6
- package/.medusa/server/src/subscribers/order-placed.js +8 -4
- package/.medusa/server/src/templates/emails/contact-form/config.js +5 -1
- package/.medusa/server/src/templates/emails/email-template-service.js +210 -0
- package/.medusa/server/src/templates/emails/index.js +6 -248
- package/.medusa/server/src/templates/emails/inventory-level/config.js +5 -1
- package/.medusa/server/src/templates/emails/order/completed/config.js +5 -1
- package/.medusa/server/src/templates/emails/order/completed/index.js +1 -2
- package/.medusa/server/src/templates/emails/order/placed/config.js +5 -1
- package/.medusa/server/src/templates/emails/order/updated/config.js +5 -1
- package/.medusa/server/src/templates/emails/types.js +1 -1
- package/.medusa/server/src/templates/shared/abstract-template-service.js +104 -0
- package/.medusa/server/src/templates/shared/index.js +22 -0
- package/.medusa/server/src/templates/shared/types.js +6 -0
- package/.medusa/server/src/templates/slack/index.js +12 -0
- package/.medusa/server/src/templates/slack/inventory-level/config.js +52 -0
- package/.medusa/server/src/templates/slack/inventory-level/index.js +8 -0
- package/.medusa/server/src/templates/slack/inventory-level/translations/en.json +18 -0
- package/.medusa/server/src/templates/slack/inventory-level/translations/pl.json +18 -0
- package/.medusa/server/src/templates/slack/order/archived/config.js +48 -0
- package/.medusa/server/src/templates/slack/order/archived/index.js +7 -0
- package/.medusa/server/src/templates/slack/order/archived/translations/en.json +11 -0
- package/.medusa/server/src/templates/slack/order/archived/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/order/archived/translations/pl.json +11 -0
- package/.medusa/server/src/templates/slack/order/canceled/config.js +48 -0
- package/.medusa/server/src/templates/slack/order/canceled/index.js +7 -0
- package/.medusa/server/src/templates/slack/order/canceled/translations/en.json +11 -0
- package/.medusa/server/src/templates/slack/order/canceled/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/order/canceled/translations/pl.json +11 -0
- package/.medusa/server/src/templates/slack/order/completed/config.js +48 -0
- package/.medusa/server/src/templates/slack/order/completed/index.js +7 -0
- package/.medusa/server/src/templates/slack/order/completed/translations/en.json +11 -0
- package/.medusa/server/src/templates/slack/order/completed/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/order/completed/translations/pl.json +11 -0
- package/.medusa/server/src/templates/slack/order/placed/config.js +48 -0
- package/.medusa/server/src/templates/slack/order/placed/index.js +7 -0
- package/.medusa/server/src/templates/slack/order/placed/translations/en.json +11 -0
- package/.medusa/server/src/templates/slack/order/placed/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/order/placed/translations/pl.json +11 -0
- package/.medusa/server/src/templates/slack/order/updated/config.js +48 -0
- package/.medusa/server/src/templates/slack/order/updated/index.js +7 -0
- package/.medusa/server/src/templates/slack/order/updated/translations/en.json +11 -0
- package/.medusa/server/src/templates/slack/order/updated/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/order/updated/translations/pl.json +11 -0
- package/.medusa/server/src/templates/slack/product/config.js +48 -0
- package/.medusa/server/src/templates/slack/product/index.js +7 -0
- package/.medusa/server/src/templates/slack/product/translations/en.json +14 -0
- package/.medusa/server/src/templates/slack/product/translations/pl.json +14 -0
- package/.medusa/server/src/templates/slack/product-variant/config.js +48 -0
- package/.medusa/server/src/templates/slack/product-variant/index.js +7 -0
- package/.medusa/server/src/templates/slack/product-variant/translations/en.json +14 -0
- package/.medusa/server/src/templates/slack/product-variant/translations/index.js +15 -0
- package/.medusa/server/src/templates/slack/product-variant/translations/pl.json +14 -0
- package/.medusa/server/src/templates/slack/slack-template-service.js +219 -0
- package/.medusa/server/src/templates/slack/types.js +15 -0
- package/.medusa/server/src/utils/i18n/i18n.js +7 -10
- package/.medusa/server/src/utils/index.js +2 -1
- package/.medusa/server/src/utils/omit.js +23 -0
- package/README.md +45 -15
- package/package.json +4 -1
- package/.medusa/server/src/subscribers/payment-captured.js +0 -86
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SlackTemplateService = void 0;
|
|
4
|
+
const abstract_template_service_1 = require("../shared/abstract-template-service");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const inventory_level_1 = require("./inventory-level");
|
|
7
|
+
const product_1 = require("./product");
|
|
8
|
+
const product_variant_1 = require("./product-variant");
|
|
9
|
+
const placed_1 = require("./order/placed");
|
|
10
|
+
const completed_1 = require("./order/completed");
|
|
11
|
+
const updated_1 = require("./order/updated");
|
|
12
|
+
const canceled_1 = require("./order/canceled");
|
|
13
|
+
const archived_1 = require("./order/archived");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
/**
|
|
16
|
+
* Slack template service
|
|
17
|
+
* Handles registration and rendering of Slack templates
|
|
18
|
+
*/
|
|
19
|
+
class SlackTemplateService extends abstract_template_service_1.AbstractTemplateService {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.baseTemplateConfig = {
|
|
23
|
+
getBlocks: async () => {
|
|
24
|
+
// Base template for Slack returns an empty array
|
|
25
|
+
return [];
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
this.interpolateFunction = this.interpolateSlackBlocks.bind(this);
|
|
29
|
+
// Register base template
|
|
30
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.BASE_TEMPLATE, this.baseTemplateConfig);
|
|
31
|
+
// Initialize default templates
|
|
32
|
+
this.initializeDefaultTemplates();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Initialize default Slack templates
|
|
36
|
+
*/
|
|
37
|
+
initializeDefaultTemplates() {
|
|
38
|
+
// Inventory level template
|
|
39
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.INVENTORY_LEVEL, {
|
|
40
|
+
...this.baseTemplateConfig,
|
|
41
|
+
getConfig: () => {
|
|
42
|
+
return {
|
|
43
|
+
blocks: inventory_level_1.templateBlocks,
|
|
44
|
+
translations: inventory_level_1.translations,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
// Product template
|
|
49
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.PRODUCT, {
|
|
50
|
+
...this.baseTemplateConfig,
|
|
51
|
+
getConfig: () => {
|
|
52
|
+
return {
|
|
53
|
+
blocks: product_1.templateBlocks,
|
|
54
|
+
translations: product_1.translations,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Product variant template
|
|
59
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.PRODUCT_VARIANT, {
|
|
60
|
+
...this.baseTemplateConfig,
|
|
61
|
+
getConfig: () => {
|
|
62
|
+
return {
|
|
63
|
+
blocks: product_variant_1.templateBlocks,
|
|
64
|
+
translations: product_variant_1.translations,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
// Order placed template
|
|
69
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.ORDER_PLACED, {
|
|
70
|
+
...this.baseTemplateConfig,
|
|
71
|
+
getConfig: () => {
|
|
72
|
+
return {
|
|
73
|
+
blocks: placed_1.templateBlocks,
|
|
74
|
+
translations: placed_1.translations,
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
// Order completed template
|
|
79
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.ORDER_COMPLETED, {
|
|
80
|
+
...this.baseTemplateConfig,
|
|
81
|
+
getConfig: () => {
|
|
82
|
+
return {
|
|
83
|
+
blocks: completed_1.templateBlocks,
|
|
84
|
+
translations: completed_1.translations,
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
// Order updated template
|
|
89
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.ORDER_UPDATED, {
|
|
90
|
+
...this.baseTemplateConfig,
|
|
91
|
+
getConfig: () => {
|
|
92
|
+
return {
|
|
93
|
+
blocks: updated_1.templateBlocks,
|
|
94
|
+
translations: updated_1.translations,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
// Order canceled template
|
|
99
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.ORDER_CANCELED, {
|
|
100
|
+
...this.baseTemplateConfig,
|
|
101
|
+
getConfig: () => {
|
|
102
|
+
return {
|
|
103
|
+
blocks: canceled_1.templateBlocks,
|
|
104
|
+
translations: canceled_1.translations,
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
// Order archived template
|
|
109
|
+
this.registerTemplate(types_1.TEMPLATES_NAMES.ORDER_ARCHIVED, {
|
|
110
|
+
...this.baseTemplateConfig,
|
|
111
|
+
getConfig: () => {
|
|
112
|
+
return {
|
|
113
|
+
blocks: archived_1.templateBlocks,
|
|
114
|
+
translations: archived_1.translations,
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Recursively interpolate text in SlackBlock[] structure
|
|
121
|
+
* Finds all "text" properties in the entire tree and interpolates them
|
|
122
|
+
*/
|
|
123
|
+
interpolateSlackBlocks(blocks, data, translator, config) {
|
|
124
|
+
return blocks.map((block) => {
|
|
125
|
+
// Create fields array if fieldTemplate and fieldsPath is provided and array is not empty
|
|
126
|
+
if (block.type === "section" && block?.fieldTemplate) {
|
|
127
|
+
const { fieldsPath, fieldTemplate } = block || {};
|
|
128
|
+
if (fieldsPath && fieldTemplate) {
|
|
129
|
+
const array = (0, utils_1.pickValueFromObject)(fieldsPath, data);
|
|
130
|
+
if (Array.isArray(array) && array.length > 0) {
|
|
131
|
+
const interpolatedFieldBlocks = array.map((item) => {
|
|
132
|
+
return this.recursivelyInterpolateText(fieldTemplate, item, translator, {
|
|
133
|
+
arrayPath: fieldsPath,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
block = {
|
|
137
|
+
...(0, utils_1.omit)(block, "fieldsPath", "fieldTemplate"),
|
|
138
|
+
fields: interpolatedFieldBlocks,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return this.recursivelyInterpolateText(block, data, translator, config);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Recursively interpolate all "text" / "url" properties in an object
|
|
148
|
+
*/
|
|
149
|
+
recursivelyInterpolateText(node, data, translator, config) {
|
|
150
|
+
// If it's a string, interpolate it
|
|
151
|
+
if (typeof node === "string") {
|
|
152
|
+
return (0, utils_1.multiInterpolate)(node, data, translator, config);
|
|
153
|
+
}
|
|
154
|
+
// If it's an array, process each element recursively
|
|
155
|
+
if (Array.isArray(node)) {
|
|
156
|
+
return node.map((item) => {
|
|
157
|
+
return this.recursivelyInterpolateText(item, data, translator, config);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// If it's an object, process all properties
|
|
161
|
+
if (node && typeof node === "object") {
|
|
162
|
+
const processed = {};
|
|
163
|
+
for (const [key, value] of Object.entries(node)) {
|
|
164
|
+
// If key is "text" and value is a string, interpolate it
|
|
165
|
+
if ((key === "text" || key === "url") && typeof value === "string") {
|
|
166
|
+
processed[key] = (0, utils_1.multiInterpolate)(value, data, translator, config);
|
|
167
|
+
}
|
|
168
|
+
// If key is "text" and value is an object (e.g., { type: "plain_text", text: "..." })
|
|
169
|
+
else if (key === "text" && value && typeof value === "object") {
|
|
170
|
+
// Recursively process the text object (will interpolate text.text)
|
|
171
|
+
processed[key] = this.recursivelyInterpolateText(value, data, translator, config);
|
|
172
|
+
}
|
|
173
|
+
// If key is "elements" and value is an array
|
|
174
|
+
else if (key === "elements" && Array.isArray(value)) {
|
|
175
|
+
processed[key] = value.map((item) => {
|
|
176
|
+
return this.recursivelyInterpolateText(item, data, translator, config);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// For all other properties, recursively process them
|
|
180
|
+
else {
|
|
181
|
+
processed[key] = this.recursivelyInterpolateText(value, data, translator, config);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return processed;
|
|
185
|
+
}
|
|
186
|
+
return node;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Render Slack template
|
|
190
|
+
*
|
|
191
|
+
* @param params - Render parameters
|
|
192
|
+
* @returns Rendered Slack blocks
|
|
193
|
+
*/
|
|
194
|
+
async render(params) {
|
|
195
|
+
if (!params.templateName) {
|
|
196
|
+
throw new Error("Template name is required");
|
|
197
|
+
}
|
|
198
|
+
// Add backendUrl to data for interpolation
|
|
199
|
+
const dataWithOptions = {
|
|
200
|
+
...params.data,
|
|
201
|
+
backendUrl: params.options?.backendUrl || "",
|
|
202
|
+
};
|
|
203
|
+
const { template, translator, blocks } = this.prepareData({
|
|
204
|
+
templateName: params.templateName,
|
|
205
|
+
data: dataWithOptions,
|
|
206
|
+
options: params.options,
|
|
207
|
+
});
|
|
208
|
+
const options = {
|
|
209
|
+
...params.options,
|
|
210
|
+
blocks,
|
|
211
|
+
};
|
|
212
|
+
// Get blocks from template
|
|
213
|
+
return {
|
|
214
|
+
blocks: options.blocks,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.SlackTemplateService = SlackTemplateService;
|
|
219
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stdGVtcGxhdGUtc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy90ZW1wbGF0ZXMvc2xhY2svc2xhY2stdGVtcGxhdGUtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtRkFHNEM7QUFDNUMsdUNBSW9CO0FBQ3BCLHVEQUcwQjtBQUMxQix1Q0FHa0I7QUFDbEIsdURBRzBCO0FBQzFCLDJDQUd1QjtBQUN2QixpREFHMEI7QUFDMUIsNkNBR3dCO0FBQ3hCLCtDQUd5QjtBQUN6QiwrQ0FHeUI7QUFDekIsbUNBQXlDO0FBRXpDOzs7R0FHRztBQUNILE1BQWEsb0JBQXFCLFNBQVEsbURBQTRCO0lBQ3BFO1FBQ0UsS0FBSyxFQUFFLENBQUE7UUFFUCxJQUFJLENBQUMsa0JBQWtCLEdBQUc7WUFDeEIsU0FBUyxFQUFFLEtBQUssSUFBb0IsRUFBRTtnQkFDcEMsaURBQWlEO2dCQUNqRCxPQUFPLEVBQUUsQ0FBQTtZQUNYLENBQUM7U0FDRixDQUFBO1FBRUQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFakUseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxnQkFBZ0IsQ0FDbkIsdUJBQWUsQ0FBQyxhQUFhLEVBQzdCLElBQUksQ0FBQyxrQkFBa0IsQ0FDeEIsQ0FBQTtRQUVELCtCQUErQjtRQUMvQixJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQTtJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDTywwQkFBMEI7UUFDbEMsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBZSxDQUFDLGVBQWUsRUFBRTtZQUNyRCxHQUFHLElBQUksQ0FBQyxrQkFBa0I7WUFDMUIsU0FBUyxFQUFFLEdBQVEsRUFBRTtnQkFDbkIsT0FBTztvQkFDTCxNQUFNLEVBQUUsZ0NBQTRCO29CQUNwQyxZQUFZLEVB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
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TEMPLATES_NAMES = void 0;
|
|
4
|
+
exports.TEMPLATES_NAMES = {
|
|
5
|
+
BASE_TEMPLATE: "base-template",
|
|
6
|
+
INVENTORY_LEVEL: "inventory-level",
|
|
7
|
+
PRODUCT: "product",
|
|
8
|
+
PRODUCT_VARIANT: "product-variant",
|
|
9
|
+
ORDER_PLACED: "order-placed",
|
|
10
|
+
ORDER_COMPLETED: "order-completed",
|
|
11
|
+
ORDER_UPDATED: "order-updated",
|
|
12
|
+
ORDER_CANCELED: "order-canceled",
|
|
13
|
+
ORDER_ARCHIVED: "order-archived",
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvdGVtcGxhdGVzL3NsYWNrL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVhLFFBQUEsZUFBZSxHQUFHO0lBQzdCLGFBQWEsRUFBRSxlQUFlO0lBQzlCLGVBQWUsRUFBRSxpQkFBaUI7SUFDbEMsT0FBTyxFQUFFLFNBQVM7SUFDbEIsZUFBZSxFQUFFLGlCQUFpQjtJQUNsQyxZQUFZLEVBQUUsY0FBYztJQUM1QixlQUFlLEVBQUUsaUJBQWlCO0lBQ2xDLGFBQWEsRUFBRSxlQUFlO0lBQzlCLGNBQWMsRUFBRSxnQkFBZ0I7SUFDaEMsY0FBYyxFQUFFLGdCQUFnQjtDQUN4QixDQUFDIn0=
|
|
@@ -42,12 +42,14 @@ function getVariableValue(text) {
|
|
|
42
42
|
/**
|
|
43
43
|
* Group interpolate - handles variables with prefixes (data. or translations.)
|
|
44
44
|
*
|
|
45
|
-
* Variables with prefix `data.` are resolved using
|
|
46
|
-
* Variables with prefix `translations.` are resolved using translator.
|
|
45
|
+
* Variables with prefix `data.` are resolved using pickValueFromObject function
|
|
46
|
+
* Variables with prefix `translations.` are resolved using translator.t function
|
|
47
47
|
*
|
|
48
|
-
* @param text - Text with {{data.variable}}
|
|
48
|
+
* @param text - Text with {{data.variable}} or {{translations.key}} placeholders
|
|
49
49
|
* @param data - Data object for interpolation
|
|
50
|
-
* @param translator - Translator instance with
|
|
50
|
+
* @param translator - Translator instance with t method
|
|
51
|
+
* @param config - Configuration object
|
|
52
|
+
* @param config - arrayPath - Array path for data object
|
|
51
53
|
* @returns Interpolated text with all variables resolved
|
|
52
54
|
*
|
|
53
55
|
* @example
|
|
@@ -80,14 +82,10 @@ function multiInterpolate(text, data = {}, translator, config) {
|
|
|
80
82
|
const variable = match[1]; // e.g., "data.order.id"
|
|
81
83
|
let replacement;
|
|
82
84
|
// Check if variable starts with dynamic data prefix
|
|
83
|
-
// console.log('variable', dataPrefixString);
|
|
84
85
|
if (variable.startsWith(`${dataPrefixString}.`)) {
|
|
85
|
-
// Escape dots in prefix for regex
|
|
86
86
|
const escapedPrefix = dataPrefixString.replace(/\./g, '\\.');
|
|
87
87
|
const dataPath = variable.replace(new RegExp(`^${escapedPrefix}\\.`), "");
|
|
88
88
|
const value = (0, index_1.pickValueFromObject)(dataPath, data);
|
|
89
|
-
// Convert value to string, preserving false as "false" and true as "true"
|
|
90
|
-
// String(false) = "false", String(true) = "true", String(0) = "0", etc.
|
|
91
89
|
if (value === undefined || value === null) {
|
|
92
90
|
replacement = undefined;
|
|
93
91
|
}
|
|
@@ -97,7 +95,6 @@ function multiInterpolate(text, data = {}, translator, config) {
|
|
|
97
95
|
}
|
|
98
96
|
// Check if variable starts with translations. prefix
|
|
99
97
|
else if (variable.startsWith("translations.")) {
|
|
100
|
-
// Remove "translations." prefix and use translator.single
|
|
101
98
|
const translationKey = variable.replace(/^translations\./, "");
|
|
102
99
|
replacement = translator.t(translationKey, data);
|
|
103
100
|
replacement = multiInterpolate(replacement, data, translator);
|
|
@@ -173,4 +170,4 @@ function mergeTranslations(baseTranslations, customTranslations) {
|
|
|
173
170
|
}
|
|
174
171
|
return merged;
|
|
175
172
|
}
|
|
176
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
173
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy91dGlscy9pMThuL2kxOG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE4QkEsNENBZ0JDO0FBdUJELDRDQTBEQztBQVdELGNBdUJDO0FBU0QsNENBU0M7QUFVRCw4Q0E4QkM7QUEzTkQsb0NBR2lCO0FBRWpCOzs7R0FHRztBQUVIOzs7Ozs7R0FNRztBQUNILFNBQVMsbUJBQW1CLENBQUMsWUFBaUI7SUFDNUMsSUFBSSxDQUFDLElBQUEsZ0JBQVEsRUFBQyxZQUFZLENBQUMsSUFBSSxDQUFFLFlBQW9CLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUQsT0FBTyxZQUFZLENBQUE7SUFDckIsQ0FBQztJQUVELDZDQUE2QztJQUM3QyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEdBQUcsWUFBbUIsQ0FBQTtJQUNoRCxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQTtBQUNoQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FDOUIsSUFBWTtJQUVaLElBQUksQ0FBQyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDdEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFBO0lBQzNDLENBQUM7SUFFRCxPQUFPO1FBQ0wsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQ3BCLDBCQUEwQixFQUMxQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNiLE9BQU8sR0FBRyxDQUFBO1FBQ1osQ0FBQyxDQUNGO1FBQ0QsUUFBUSxFQUFFLElBQUk7S0FDZixDQUFBO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILFNBQWdCLGdCQUFnQixDQUM5QixJQUFZLEVBQ1osT0FBNEIsRUFBRSxF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
|
|
@@ -24,8 +24,9 @@ __exportStar(require("./is-object"), exports);
|
|
|
24
24
|
__exportStar(require("./attribute-helpers"), exports);
|
|
25
25
|
__exportStar(require("./i18n/i18n"), exports);
|
|
26
26
|
__exportStar(require("./transforms"), exports);
|
|
27
|
+
__exportStar(require("./omit"), exports);
|
|
27
28
|
__exportStar(require("./data/modules"), exports);
|
|
28
29
|
__exportStar(require("./data/currencies"), exports);
|
|
29
30
|
__exportStar(require("./data/countries"), exports);
|
|
30
31
|
__exportStar(require("./data/country-states"), exports);
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlDQUF1QjtBQUN2Qiw4Q0FBNEI7QUFDNUIseURBQXVDO0FBQ3ZDLDRDQUEwQjtBQUMxQiwyREFBeUM7QUFDekMsK0NBQTZCO0FBQzdCLDhDQUE0QjtBQUM1QixzREFBb0M7QUFDcEMsOENBQTRCO0FBQzVCLCtDQUE2QjtBQUM3Qix5Q0FBdUI7QUFDdkIsaURBQStCO0FBQy9CLG9EQUFrQztBQUNsQyxtREFBaUM7QUFDakMsd0RBQXNDIn0=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.omit = omit;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new object without the specified keys
|
|
6
|
+
* Does not mutate the original object
|
|
7
|
+
*
|
|
8
|
+
* @param obj - Source object
|
|
9
|
+
* @param keys - Keys to omit from the object
|
|
10
|
+
* @returns New object without the specified keys
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const obj = { a: 1, b: 2, c: 3 }
|
|
14
|
+
* omit(obj, 'a', 'c') // { b: 2 }
|
|
15
|
+
*/
|
|
16
|
+
function omit(obj, ...keys) {
|
|
17
|
+
const result = { ...obj };
|
|
18
|
+
keys.forEach((key) => {
|
|
19
|
+
delete result[key];
|
|
20
|
+
});
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib21pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9vbWl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBWUEsb0JBU0M7QUFyQkQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixJQUFJLENBQ2xCLEdBQU0sRUFDTixHQUFHLElBQVM7SUFFWixNQUFNLE1BQU0sR0FBRyxFQUFFLEdBQUcsR0FBRyxFQUFFLENBQUE7SUFDekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ25CLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ3BCLENBQUMsQ0FBQyxDQUFBO0lBQ0YsT0FBTyxNQUFvQixDQUFBO0FBQzdCLENBQUMifQ==
|
package/README.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# Medusa plugin notification emails
|
|
2
2
|
|
|
3
|
-
A comprehensive notification plugin for Medusa v2 that provides a flexible
|
|
3
|
+
A comprehensive notification plugin for Medusa v2 that provides a flexible, block-based template system for multiple channels (Email and Slack) with internationalization support, custom translations, and seamless integration with Medusa's notification module.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
7
|
+
- **Multi-Channel Templates**: Pre-built templates for Email and Slack channels
|
|
8
|
+
- **Block-Based System**: Templates are built using a flexible block system that can be stored in a database for future builder functionality
|
|
9
|
+
- **Email Templates**: Customizable email templates built with [React Email](https://react.email) for common use cases
|
|
10
|
+
- **Slack Templates**: Slack Block Kit compatible templates for Slack notifications
|
|
11
|
+
- **Template Service Architecture**: Unified `AbstractTemplateService` with channel-specific implementations (`EmailTemplateService`, `SlackTemplateService`)
|
|
12
|
+
- **Automatic Interpolation**: Smart variable interpolation system that processes `{{data.*}}` and `{{translations.*}}` placeholders recursively
|
|
9
13
|
- **Internationalization**: Built-in support for multiple locales (Polish, English)
|
|
10
14
|
- **Customizable**: Override translations and customize templates without modifying core files
|
|
11
15
|
- **Integration**: Integrates with Medusa's notification module
|
|
@@ -48,27 +52,51 @@ Set up a notification provider - see [Configuration Documentation](./docs/config
|
|
|
48
52
|
|
|
49
53
|
The plugin includes built-in subscribers that automatically send email notifications for various events. You can also use templates directly in your code:
|
|
50
54
|
|
|
55
|
+
#### Email Templates
|
|
56
|
+
|
|
51
57
|
```typescript
|
|
52
|
-
import {
|
|
58
|
+
import { emailService, TEMPLATES_NAMES } from "@codee-sh/medusa-plugin-notification-emails/templates/emails"
|
|
53
59
|
|
|
54
|
-
const { html, text, subject } = await
|
|
55
|
-
TEMPLATES_NAMES.ORDER_PLACED,
|
|
56
|
-
templateData,
|
|
57
|
-
{ locale: "pl" }
|
|
58
|
-
)
|
|
60
|
+
const { html, text, subject } = await emailService.render({
|
|
61
|
+
templateName: TEMPLATES_NAMES.ORDER_PLACED,
|
|
62
|
+
data: templateData,
|
|
63
|
+
options: { locale: "pl" }
|
|
64
|
+
})
|
|
59
65
|
```
|
|
60
66
|
|
|
61
|
-
|
|
67
|
+
#### Slack Templates
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { slackService, TEMPLATES_NAMES } from "@codee-sh/medusa-plugin-notification-emails/templates/slack"
|
|
71
|
+
|
|
72
|
+
const { blocks } = await slackService.render({
|
|
73
|
+
templateName: TEMPLATES_NAMES.INVENTORY_LEVEL,
|
|
74
|
+
data: templateData,
|
|
75
|
+
options: { locale: "en" }
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Note**: Templates use a block-based system where each template is defined as an array of blocks. The system automatically interpolates variables like `{{data.order.id}}` and `{{translations.headerTitle}}` throughout the blocks.
|
|
62
80
|
|
|
63
81
|
See [Templates Documentation](./docs/templates.md) for detailed usage examples.
|
|
64
82
|
|
|
65
83
|
## Available Templates
|
|
66
84
|
|
|
85
|
+
### Email Templates
|
|
86
|
+
|
|
67
87
|
- **[Order Placed](./docs/templates/order-placed.md)** (`order-placed`) - Order confirmation email template
|
|
68
|
-
- **
|
|
88
|
+
- **Order Completed** (`order-completed`) - Order completion notification template
|
|
69
89
|
- **[Contact Form](./docs/templates/contact-form.md)** (`contact-form`) - Contact form submission email template
|
|
90
|
+
- **Order Updated** (`order-updated`) - Order update notification template
|
|
91
|
+
- **Inventory Level** (`inventory-level`) - Inventory level notification template
|
|
92
|
+
|
|
93
|
+
### Slack Templates
|
|
94
|
+
|
|
95
|
+
- **Inventory Level** (`inventory-level`) - Inventory level notification for Slack
|
|
96
|
+
- **Product** (`product`) - Product notification for Slack
|
|
97
|
+
- **Product Variant** (`product-variant`) - Product variant notification for Slack
|
|
70
98
|
|
|
71
|
-
See [Templates Documentation](./docs/templates.md) for general template information.
|
|
99
|
+
See [Templates Documentation](./docs/templates.md) for general template information and [Blocks Documentation](./docs/blocks.md) for details on the block system.
|
|
72
100
|
|
|
73
101
|
## Built-in Subscribers
|
|
74
102
|
|
|
@@ -92,17 +120,19 @@ Access the template preview in Medusa Admin at `/app/notifications/render`. See
|
|
|
92
120
|
## Documentation
|
|
93
121
|
|
|
94
122
|
- [Templates](./docs/templates.md) - Using templates and creating custom subscribers
|
|
123
|
+
- [Blocks System](./docs/blocks.md) - Understanding the block-based template system
|
|
95
124
|
- [Translations](./docs/translations.md) - Internationalization and custom translations
|
|
96
125
|
- [Configuration](./docs/configuration.md) - Plugin configuration options
|
|
97
126
|
- [Admin Panel](./docs/admin.md) - Admin interface usage
|
|
98
|
-
- [Creating Custom Templates](./docs/contributing/creating-templates.md) - Guide for
|
|
127
|
+
- [Creating Custom Templates](./docs/contributing/creating-templates.md) - Guide for creating new templates
|
|
99
128
|
|
|
100
129
|
## Exports
|
|
101
130
|
|
|
102
131
|
The plugin exports the following:
|
|
103
132
|
|
|
104
|
-
- `@codee-sh/medusa-plugin-notification-emails/templates/emails` -
|
|
105
|
-
- `@codee-sh/medusa-plugin-notification-emails/templates/
|
|
133
|
+
- `@codee-sh/medusa-plugin-notification-emails/templates/emails` - Email template service and types
|
|
134
|
+
- `@codee-sh/medusa-plugin-notification-emails/templates/slack` - Slack template service and types
|
|
135
|
+
- `@codee-sh/medusa-plugin-notification-emails/templates/shared` - Shared template utilities
|
|
106
136
|
- `@codee-sh/medusa-plugin-notification-emails/utils` - Utility functions
|
|
107
137
|
|
|
108
138
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codee-sh/medusa-plugin-notification-emails",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Medusa plugin for notifications emails.",
|
|
5
5
|
"author": "Codee Team (https://codee.dev)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
"./templates/emails": "./.medusa/server/src/templates/emails/index.js",
|
|
20
20
|
"./templates/emails/*": "./.medusa/server/src/templates/emails/*/index.js",
|
|
21
21
|
"./templates/emails/types": "./.medusa/server/src/templates/emails/types.js",
|
|
22
|
+
"./templates/slack": "./.medusa/server/src/templates/slack/index.js",
|
|
23
|
+
"./templates/slack/*": "./.medusa/server/src/templates/slack/*/index.js",
|
|
24
|
+
"./templates/slack/types": "./.medusa/server/src/templates/slack/types.js",
|
|
22
25
|
"./utils": "./.medusa/server/src/utils/index.js",
|
|
23
26
|
"./*": "./.medusa/server/src/*.js",
|
|
24
27
|
"./admin": {
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.config = void 0;
|
|
4
|
-
exports.default = paymentCapturedEmailsHandler;
|
|
5
|
-
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
-
const plugins_1 = require("@codee-sh/medusa-plugin-notification-emails/utils/plugins");
|
|
7
|
-
async function paymentCapturedEmailsHandler({ event: { data: { id, trigger_type } }, container, }) {
|
|
8
|
-
const pluginOptions = (0, plugins_1.getPluginOptions)(container, "@codee-sh/medusa-plugin-notification-emails");
|
|
9
|
-
const notificationModuleService = container.resolve(utils_1.Modules.NOTIFICATION);
|
|
10
|
-
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
11
|
-
const triggerType = trigger_type || 'system';
|
|
12
|
-
console.log("id", id);
|
|
13
|
-
if (!id) {
|
|
14
|
-
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_ARGUMENT, "Payment ID is required");
|
|
15
|
-
}
|
|
16
|
-
const { data: [payment] } = await query.graph({
|
|
17
|
-
entity: "payment",
|
|
18
|
-
fields: [
|
|
19
|
-
"*",
|
|
20
|
-
],
|
|
21
|
-
filters: {
|
|
22
|
-
id: id,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
if (!payment) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
console.log("payment", payment);
|
|
29
|
-
console.log("trigger_type", trigger_type);
|
|
30
|
-
// const shippingAddressText = getFormattedAddress({ address: order.shipping_address }).join("<br/>");
|
|
31
|
-
// const billingAddressText = getFormattedAddress({ address: order.billing_address }).join("<br/>");
|
|
32
|
-
// const templateData = {
|
|
33
|
-
// sales_channel: {
|
|
34
|
-
// name: order?.sales_channel?.name,
|
|
35
|
-
// description: order?.sales_channel?.description,
|
|
36
|
-
// },
|
|
37
|
-
// orderNumber: `#${order.display_id}`,
|
|
38
|
-
// customerName: order.email,
|
|
39
|
-
// customerEmail: order.email,
|
|
40
|
-
// orderDate: formatDate({ date: order.created_at, includeTime: true, localeCode: "pl" }),
|
|
41
|
-
// totalAmount: order.items.reduce((acc, item) => acc + (item.variant?.prices?.[0]?.amount || 0) * item.quantity, 0),
|
|
42
|
-
// currency: order.currency_code,
|
|
43
|
-
// items: order.items.map((item) => ({
|
|
44
|
-
// thumbnail: item.thumbnail,
|
|
45
|
-
// title: item.title,
|
|
46
|
-
// quantity: item.quantity,
|
|
47
|
-
// price: getLocaleAmount(item.unit_price, order.currency_code),
|
|
48
|
-
// })),
|
|
49
|
-
// shippingAddress: shippingAddressText,
|
|
50
|
-
// billingAddress: billingAddressText,
|
|
51
|
-
// summary: {
|
|
52
|
-
// total: getLocaleAmount(order.summary.original_order_total, order.currency_code),
|
|
53
|
-
// paid_total: getLocaleAmount(getTotalCaptured(order.payment_collections || []), order.currency_code),
|
|
54
|
-
// tax_total: getLocaleAmount(order.tax_total, order.currency_code),
|
|
55
|
-
// discount_total: getLocaleAmount(order.discount_total, order.currency_code),
|
|
56
|
-
// currency_code: order.currency_code,
|
|
57
|
-
// }
|
|
58
|
-
// };
|
|
59
|
-
// const templateName = TEMPLATES_NAMES.ORDER_PLACED
|
|
60
|
-
// const { html, text, subject } = await renderTemplate(
|
|
61
|
-
// templateName,
|
|
62
|
-
// templateData,
|
|
63
|
-
// {
|
|
64
|
-
// locale: "pl",
|
|
65
|
-
// customTranslations: pluginOptions?.customTranslations?.[templateName]
|
|
66
|
-
// }
|
|
67
|
-
// )
|
|
68
|
-
// const result = await notificationModuleService.createNotifications({
|
|
69
|
-
// to: order.email,
|
|
70
|
-
// channel: "email",
|
|
71
|
-
// template: templateName,
|
|
72
|
-
// trigger_type: triggerType,
|
|
73
|
-
// resource_id: id,
|
|
74
|
-
// resource_type: "order",
|
|
75
|
-
// data: templateData,
|
|
76
|
-
// content: {
|
|
77
|
-
// subject: subject,
|
|
78
|
-
// html,
|
|
79
|
-
// text,
|
|
80
|
-
// },
|
|
81
|
-
// })
|
|
82
|
-
}
|
|
83
|
-
exports.config = {
|
|
84
|
-
event: "payment.captured",
|
|
85
|
-
};
|
|
86
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1jYXB0dXJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9wYXltZW50LWNhcHR1cmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVVBLCtDQTBGQztBQWhHRCxxREFBMkY7QUFJM0YsdUZBQTRGO0FBRTdFLEtBQUssVUFBVSw0QkFBNEIsQ0FBQyxFQUN6RCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFDckMsU0FBUyxHQUM0QztJQUNyRCxNQUFNLGFBQWEsR0FBRyxJQUFBLDBCQUFnQixFQUFDLFNBQVMsRUFBRSw2Q0FBNkMsQ0FBQyxDQUFBO0lBRWhHLE1BQU0seUJBQXlCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDakQsZUFBTyxDQUFDLFlBQVksQ0FDckIsQ0FBQTtJQUNELE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsTUFBTSxXQUFXLEdBQUcsWUFBWSxJQUFJLFFBQVEsQ0FBQTtJQUU1QyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV0QixJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDUixNQUFNLElBQUksbUJBQVcsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSx3QkFBd0IsQ0FBQyxDQUFBO0lBQ3JGLENBQUM7SUFFRCxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDNUMsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFO1lBQ04sR0FBRztTQUNKO1FBQ0QsT0FBTyxFQUFFO1lBQ1AsRUFBRSxFQUFFLEVBQUU7U0FDUDtLQUNGLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE9BQU07SUFDUixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFFMUMsc0dBQXNHO0lBQ3RHLG9HQUFvRztJQUNwRyx5QkFBeUI7SUFDekIscUJBQXFCO0lBQ3JCLHdDQUF3QztJQUN4QyxzREFBc0Q7SUFDdEQsT0FBTztJQUNQLHlDQUF5QztJQUN6QywrQkFBK0I7SUFDL0IsZ0NBQWdDO0lBQ2hDLDRGQUE0RjtJQUM1Rix1SEFBdUg7SUFDdkgsbUNBQW1DO0lBQ25DLHdDQUF3QztJQUN4QyxpQ0FBaUM7SUFDakMseUJBQXlCO0lBQ3pCLCtCQUErQjtJQUMvQixvRUFBb0U7SUFDcEUsU0FBUztJQUNULDBDQUEwQztJQUMxQyx3Q0FBd0M7SUFDeEMsZUFBZTtJQUNmLHVGQUF1RjtJQUN2RiwyR0FBMkc7SUFDM0csd0VBQXdFO0lBQ3hFLGtGQUFrRjtJQUNsRiwwQ0FBMEM7SUFDMUMsTUFBTTtJQUNOLEtBQUs7SUFFTCxvREFBb0Q7SUFFcEQsd0RBQXdEO0lBQ3hELGtCQUFrQjtJQUNsQixrQkFBa0I7SUFDbEIsT0FBTztJQUNQLG9CQUFvQjtJQUNwQiw0RUFBNEU7SUFDNUUsTUFBTTtJQUNOLElBQUk7SUFFSix1RUFBdUU7SUFDdkUscUJBQXFCO0lBQ3JCLHNCQUFzQjtJQUN0Qiw0QkFBNEI7SUFDNUIsK0JBQStCO0lBQy9CLHFCQUFxQjtJQUNyQiw0QkFBNEI7SUFDNUIsd0JBQXdCO0lBQ3hCLGVBQWU7SUFDZix3QkFBd0I7SUFDeEIsWUFBWTtJQUNaLFlBQVk7SUFDWixPQUFPO0lBQ1AsS0FBSztBQUNQLENBQUM7QUFFWSxRQUFBLE1BQU0sR0FBcUI7SUFDdEMsS0FBSyxFQUFFLGtCQUFrQjtDQUMxQixDQUFBIn0=
|