@codee-sh/medusa-plugin-automations 1.0.0 → 1.0.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/_chunks/__admin-extensions__-DIB2k6nJ +10452 -0
- package/.medusa/server/src/admin/_chunks/__admin-extensions__-rqdPN7M1 +10450 -0
- package/.medusa/server/src/admin/_chunks/base-config-DbRWuXsL +7891 -0
- package/.medusa/server/src/admin/_chunks/base-config-ro-vFPBg +7908 -0
- package/.medusa/server/src/admin/index.js +2 -9930
- package/.medusa/server/src/admin/index.mjs +2 -9927
- package/.medusa/server/src/api/admin/mpn/automations/actions/route.js +4 -4
- package/.medusa/server/src/api/admin/mpn/automations/available-actions/route.js +1 -1
- package/.medusa/server/src/api/admin/mpn/automations/available-events/route.js +1 -1
- package/.medusa/server/src/api/admin/mpn/automations/available-triggers/route.js +1 -1
- package/.medusa/server/src/api/admin/mpn/automations/route.js +13 -15
- package/.medusa/server/src/api/admin/mpn/automations/rules/route.js +12 -7
- package/.medusa/server/src/api/middlewares.js +6 -3
- package/.medusa/server/src/hooks/api/automations/automations.js +3 -3
- package/.medusa/server/src/hooks/api/automations-actions/automations-actions.js +3 -3
- package/.medusa/server/src/hooks/api/automations-rules/automations-rules.js +3 -3
- package/.medusa/server/src/hooks/api/available-actions/actions.js +3 -3
- package/.medusa/server/src/hooks/api/available-events/events.js +3 -3
- package/.medusa/server/src/hooks/api/available-triggers/triggers.js +3 -3
- package/.medusa/server/src/modules/mpn-automation/actions-handlers/base-action-handler.js +32 -0
- package/.medusa/server/src/modules/mpn-automation/actions-handlers/email-action-handler.js +71 -0
- package/.medusa/server/src/modules/mpn-automation/actions-handlers/index.js +10 -0
- package/.medusa/server/src/modules/mpn-automation/actions-handlers/slack-action-handler.js +43 -0
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127115228.js +1 -1
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127193345.js +1 -1
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251127195615.js +1 -1
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251130144047.js +1 -1
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251207172856.js +24 -0
- package/.medusa/server/src/modules/mpn-automation/migrations/Migration20251208090654.js +14 -0
- package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_rule.js +3 -2
- package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_rule_value.js +3 -4
- package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_state.js +2 -3
- package/.medusa/server/src/modules/mpn-automation/models/mpn_automation_trigger.js +11 -6
- package/.medusa/server/src/modules/mpn-automation/models/npm_automation_action.js +1 -1
- package/.medusa/server/src/modules/mpn-automation/services/service.js +77 -16
- package/.medusa/server/src/modules/mpn-automation/types/action-handler.js +3 -0
- package/.medusa/server/src/modules/mpn-automation/types/index.js +20 -0
- package/.medusa/server/src/modules/mpn-automation/{interfaces.js → types/interfaces.js} +1 -1
- package/.medusa/server/src/modules/mpn-automation/types/types.js +193 -0
- package/.medusa/server/src/providers/slack/index.js +8 -0
- package/.medusa/server/src/providers/slack/service.js +99 -0
- package/.medusa/server/src/subscribers/inventory-item-updated.js +1 -1
- package/.medusa/server/src/subscribers/inventory-level-updated.js +6 -5
- package/.medusa/server/src/subscribers/inventory-reservation-item-updated.js +1 -1
- package/.medusa/server/src/subscribers/mpn.automation.action.email.executed.js +6 -5
- package/.medusa/server/src/subscribers/mpn.automation.action.slack.executed.js +43 -0
- package/.medusa/server/src/subscribers/order-completed.js +2 -2
- package/.medusa/server/src/subscribers/order-placed.js +2 -2
- package/.medusa/server/src/subscribers/payment-captured.js +2 -2
- package/.medusa/server/src/utils/index.js +1 -1
- package/.medusa/server/src/utils/plugins.js +4 -2
- package/.medusa/server/src/utils/types/index.js +3 -3
- package/.medusa/server/src/utils/validate-rules.js +1 -1
- package/.medusa/server/src/workflows/inventory/get-inventory-level-by-id.js +1 -1
- package/.medusa/server/src/workflows/inventory/steps/get-inventory-level-by-id.js +1 -1
- package/.medusa/server/src/workflows/mpn-automation/create-automation.js +1 -1
- package/.medusa/server/src/workflows/mpn-automation/delete-automation.js +14 -0
- package/.medusa/server/src/workflows/mpn-automation/edit-automation-actions.js +2 -2
- package/.medusa/server/src/workflows/mpn-automation/edit-automation-rules.js +2 -2
- package/.medusa/server/src/workflows/mpn-automation/edit-automation.js +1 -1
- package/.medusa/server/src/workflows/mpn-automation/index.js +3 -1
- package/.medusa/server/src/workflows/mpn-automation/run-automation.js +32 -25
- package/.medusa/server/src/workflows/mpn-automation/save-automation-state.js +16 -0
- package/.medusa/server/src/workflows/mpn-automation/send-email-action.js +1 -1
- package/.medusa/server/src/workflows/mpn-automation/send-slack-action.js +69 -0
- package/.medusa/server/src/workflows/mpn-automation/steps/create-automation.js +2 -2
- package/.medusa/server/src/workflows/mpn-automation/steps/delete-automation.js +14 -0
- package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation-actions.js +4 -2
- package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation-rules.js +11 -7
- package/.medusa/server/src/workflows/mpn-automation/steps/edit-automation.js +2 -2
- package/.medusa/server/src/workflows/mpn-automation/steps/index.js +3 -1
- package/.medusa/server/src/workflows/mpn-automation/steps/retrieve-automation-triggers-by-event.js +2 -4
- package/.medusa/server/src/workflows/mpn-automation/steps/run-automation-actions.js +39 -50
- package/.medusa/server/src/workflows/mpn-automation/steps/save-automation-state.js +40 -0
- package/.medusa/server/src/workflows/mpn-automation/steps/validate-automation-triggers.js +8 -6
- package/.medusa/server/src/workflows/mpn-automation/validate-automation-triggers-by-event.js +6 -6
- package/.medusa/server/src/workflows/notifications/index.js +1 -1
- package/.medusa/server/src/workflows/notifications/send-email.js +1 -1
- package/.medusa/server/src/workflows/notifications/send-slack.js +44 -0
- package/.medusa/server/src/workflows/notifications/steps/send-email.js +6 -3
- package/.medusa/server/src/workflows/notifications/steps/send-slack.js +74 -0
- package/.medusa/server/src/workflows/steps/log-step.js +1 -1
- package/README.md +22 -11
- package/package.json +4 -2
- package/.medusa/server/src/modules/mpn-automation/types.js +0 -199
package/README.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# Medusa plugin automations
|
|
2
2
|
|
|
3
|
-
A comprehensive
|
|
3
|
+
A comprehensive automation plugin for Medusa v2 that provides a flexible rule-based automation system with triggers, conditions, and actions. Create automated workflows that can send notifications (email, Slack), execute custom actions, or trigger other processes based on events, schedules, or manual triggers with customizable rules.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Automation Triggers**: Create
|
|
7
|
+
- **Automation Triggers**: Create automations triggered by events, schedules, or manual actions
|
|
8
|
+
- **Automation Management**: Create, edit, and delete automation triggers with automatic cleanup of related data
|
|
8
9
|
- **Rule-Based Conditions**: Define complex conditions using rule attributes (e.g., inventory levels, order status)
|
|
10
|
+
- **Multiple Action Types**: Execute various actions including email notifications, Slack messages, SMS, push notifications, and custom actions
|
|
9
11
|
- **Event Subscribers**: Built-in subscribers for common Medusa events (inventory updates, order events, payment events)
|
|
10
12
|
- **Admin Panel**: Manage automations directly from Medusa Admin
|
|
11
13
|
- **Flexible Rules**: Support for multiple rule types and operators (equals, greater than, less than, contains, etc.)
|
|
14
|
+
- **Slack Notifications**: Rich Slack notifications with Block Kit support including headers, action buttons, and dividers
|
|
15
|
+
- **Extensible Actions**: Add custom action handlers to extend automation capabilities
|
|
12
16
|
- **Type-Safe**: Full TypeScript support with exported types and workflows
|
|
13
|
-
- **Extensible**: Add custom rule attributes and extend functionality via plugin options
|
|
14
17
|
|
|
15
18
|
## Compatibility
|
|
16
19
|
|
|
@@ -61,18 +64,26 @@ Navigate to **Notifications > Automations** in your Medusa Admin dashboard, or d
|
|
|
61
64
|
|
|
62
65
|
Automations are triggered by:
|
|
63
66
|
- **Events**: Medusa events (e.g., `inventory.inventory-level.updated`, `order.placed`)
|
|
64
|
-
- **Schedule**: Time-based triggers with configurable intervals
|
|
67
|
+
- **Schedule**: Time-based triggers with configurable intervals (In progress)
|
|
65
68
|
- **Manual**: Triggered manually from the admin panel
|
|
66
69
|
|
|
67
70
|
### Rules and Conditions
|
|
68
71
|
|
|
69
|
-
Each automation can have multiple rules that define when
|
|
72
|
+
Each automation can have multiple rules that define when actions should be executed:
|
|
70
73
|
|
|
71
|
-
- **Rule Attributes**: Available attributes for conditions
|
|
74
|
+
- **Rule Attributes**: Available attributes for conditions
|
|
72
75
|
- **Operators**: Comparison operators (equals, greater than, less than, contains, in, etc.)
|
|
73
76
|
- **Rule Values**: Values to compare against
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
### Actions
|
|
79
|
+
|
|
80
|
+
When automation rules pass, actions are executed. Supported action types include:
|
|
81
|
+
|
|
82
|
+
- **Email**: Send email notifications
|
|
83
|
+
- **Slack**: Send Slack messages with Block Kit formatting
|
|
84
|
+
- **Custom**: Extend with custom action handlers
|
|
85
|
+
|
|
86
|
+
See [Configuration Documentation](./docs/configuration.md) for details on built-in subscribers, available actions, and extending functionality.
|
|
76
87
|
|
|
77
88
|
## Admin Panel
|
|
78
89
|
|
|
@@ -87,13 +98,13 @@ Access the automations management interface in Medusa Admin at `/app/notificatio
|
|
|
87
98
|
|
|
88
99
|
The plugin exports the following:
|
|
89
100
|
|
|
90
|
-
- `@codee-sh/medusa-plugin-
|
|
91
|
-
- `@codee-sh/medusa-plugin-
|
|
92
|
-
- `@codee-sh/medusa-plugin-
|
|
101
|
+
- `@codee-sh/medusa-plugin-automations/workflows` - Workflow functions for automation management
|
|
102
|
+
- `@codee-sh/medusa-plugin-automations/modules/mpn-automation` - Automation module service
|
|
103
|
+
- `@codee-sh/medusa-plugin-automations/utils` - Utility functions
|
|
93
104
|
|
|
94
105
|
## Related Plugins
|
|
95
106
|
|
|
96
|
-
For email templates and rendering functionality, see [@codee-sh/medusa-plugin-
|
|
107
|
+
For email templates and rendering functionality, see [@codee-sh/medusa-plugin-automations-emails](https://github.com/codee-sh/medusa-plugin-notification-emails).
|
|
97
108
|
|
|
98
109
|
## License
|
|
99
110
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codee-sh/medusa-plugin-automations",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Medusa plugin for automations.",
|
|
5
5
|
"author": "Codee (https://codee.dev)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
"dev": "medusa plugin:develop",
|
|
38
38
|
"prepublishOnly": "medusa plugin:build",
|
|
39
39
|
"publish-local": "npx medusa plugin:publish",
|
|
40
|
-
"publish-package": "dotenv npm publish --access public"
|
|
40
|
+
"publish-package": "dotenv npm publish --access public",
|
|
41
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
42
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\""
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@medusajs/admin-sdk": "2.8.8",
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ALL_EVENTS = exports.EVENT_ORDER_TYPES = exports.EVENT_CUSTOMER_TYPES = exports.EVENT_INVENTORY_TYPES = exports.INVENTORY_LEVEL_ATTRIBUTES = exports.INVENTORY_ITEM_ATTRIBUTES = exports.ACTION_TYPES = exports.TRIGGER_TYPES = exports.OPERATOR_TYPES = exports.OperatorType = exports.ActionType = exports.TriggerType = void 0;
|
|
4
|
-
var TriggerType;
|
|
5
|
-
(function (TriggerType) {
|
|
6
|
-
TriggerType["EVENT"] = "event";
|
|
7
|
-
TriggerType["SCHEDULE"] = "schedule";
|
|
8
|
-
TriggerType["MANUAL"] = "manual";
|
|
9
|
-
})(TriggerType || (exports.TriggerType = TriggerType = {}));
|
|
10
|
-
var ActionType;
|
|
11
|
-
(function (ActionType) {
|
|
12
|
-
ActionType["EMAIL"] = "email";
|
|
13
|
-
ActionType["SMS"] = "sms";
|
|
14
|
-
ActionType["PUSH"] = "push";
|
|
15
|
-
ActionType["IN_APP"] = "in_app";
|
|
16
|
-
ActionType["SLACK"] = "slack";
|
|
17
|
-
ActionType["ADMIN"] = "admin";
|
|
18
|
-
})(ActionType || (exports.ActionType = ActionType = {}));
|
|
19
|
-
var OperatorType;
|
|
20
|
-
(function (OperatorType) {
|
|
21
|
-
OperatorType["EQUAL"] = "eq";
|
|
22
|
-
OperatorType["NOT_EQUAL"] = "neq";
|
|
23
|
-
OperatorType["GREATER_THAN"] = "gt";
|
|
24
|
-
OperatorType["LESS_THAN"] = "lt";
|
|
25
|
-
OperatorType["GREATER_THAN_OR_EQUAL"] = "gte";
|
|
26
|
-
OperatorType["LESS_THAN_OR_EQUAL"] = "lte";
|
|
27
|
-
})(OperatorType || (exports.OperatorType = OperatorType = {}));
|
|
28
|
-
exports.OPERATOR_TYPES = [
|
|
29
|
-
{
|
|
30
|
-
value: OperatorType.EQUAL,
|
|
31
|
-
label: "Equal"
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: OperatorType.NOT_EQUAL,
|
|
35
|
-
label: "Not Equal"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: OperatorType.GREATER_THAN,
|
|
39
|
-
label: "Greater Than"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
value: OperatorType.LESS_THAN,
|
|
43
|
-
label: "Less Than"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
value: OperatorType.GREATER_THAN_OR_EQUAL,
|
|
47
|
-
label: "Greater Than or Equal"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
value: OperatorType.LESS_THAN_OR_EQUAL,
|
|
51
|
-
label: "Less Than or Equal"
|
|
52
|
-
},
|
|
53
|
-
];
|
|
54
|
-
exports.TRIGGER_TYPES = [
|
|
55
|
-
{
|
|
56
|
-
value: TriggerType.EVENT,
|
|
57
|
-
label: "Event"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
value: TriggerType.SCHEDULE,
|
|
61
|
-
label: "Schedule"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
value: TriggerType.MANUAL,
|
|
65
|
-
label: "Manual"
|
|
66
|
-
}
|
|
67
|
-
];
|
|
68
|
-
exports.ACTION_TYPES = [
|
|
69
|
-
{
|
|
70
|
-
value: ActionType.EMAIL,
|
|
71
|
-
label: "Email"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
value: ActionType.SMS,
|
|
75
|
-
label: "SMS"
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
value: ActionType.PUSH,
|
|
79
|
-
label: "Push"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
value: ActionType.IN_APP,
|
|
83
|
-
label: "In App"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
value: ActionType.SLACK,
|
|
87
|
-
label: "Slack"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
value: ActionType.ADMIN,
|
|
91
|
-
label: "Admin"
|
|
92
|
-
},
|
|
93
|
-
];
|
|
94
|
-
exports.INVENTORY_ITEM_ATTRIBUTES = [
|
|
95
|
-
{
|
|
96
|
-
value: "inventory_item.stocked_quantity",
|
|
97
|
-
label: "Stocked Quantity"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
value: "inventory_item.reserved_quantity",
|
|
101
|
-
label: "Reserved Quantity"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
value: "inventory_item.available_quantity",
|
|
105
|
-
label: "Available Quantity"
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
value: "inventory_item.incoming_quantity",
|
|
109
|
-
label: "Incoming Quantity"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
value: "inventory_item.location_id",
|
|
113
|
-
label: "Location ID"
|
|
114
|
-
},
|
|
115
|
-
];
|
|
116
|
-
exports.INVENTORY_LEVEL_ATTRIBUTES = [
|
|
117
|
-
{
|
|
118
|
-
value: "inventory_level.stocked_quantity",
|
|
119
|
-
label: "Stocked Quantity"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
value: "inventory_level.reserved_quantity",
|
|
123
|
-
label: "Reserved Quantity"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
value: "inventory_level.available_quantity",
|
|
127
|
-
label: "Available Quantity"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
value: "inventory_level.incoming_quantity",
|
|
131
|
-
label: "Incoming Quantity"
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
value: "inventory_level.location_id",
|
|
135
|
-
label: "Location ID"
|
|
136
|
-
},
|
|
137
|
-
];
|
|
138
|
-
exports.EVENT_INVENTORY_TYPES = [
|
|
139
|
-
{
|
|
140
|
-
value: "inventory.inventory-level.created",
|
|
141
|
-
label: "Inventory Level Created",
|
|
142
|
-
attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
value: "inventory.inventory-level.updated",
|
|
146
|
-
label: "Inventory Level Updated",
|
|
147
|
-
attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
value: "inventory.inventory-level.deleted",
|
|
151
|
-
label: "Inventory Level Deleted",
|
|
152
|
-
attributes: exports.INVENTORY_LEVEL_ATTRIBUTES
|
|
153
|
-
}
|
|
154
|
-
];
|
|
155
|
-
exports.EVENT_CUSTOMER_TYPES = [
|
|
156
|
-
{
|
|
157
|
-
value: "customer.created",
|
|
158
|
-
label: "Customer Created"
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
value: "customer.updated",
|
|
162
|
-
label: "Customer Updated"
|
|
163
|
-
}
|
|
164
|
-
];
|
|
165
|
-
exports.EVENT_ORDER_TYPES = [
|
|
166
|
-
{
|
|
167
|
-
value: "order.placed",
|
|
168
|
-
label: "Order Placed"
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
value: "order.completed",
|
|
172
|
-
label: "Order Completed"
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
value: "order.shipped",
|
|
176
|
-
label: "Order Shipped"
|
|
177
|
-
}
|
|
178
|
-
];
|
|
179
|
-
exports.ALL_EVENTS = [
|
|
180
|
-
{
|
|
181
|
-
name: "Inventory",
|
|
182
|
-
events: [
|
|
183
|
-
...exports.EVENT_INVENTORY_TYPES,
|
|
184
|
-
]
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
name: "Customer",
|
|
188
|
-
events: [
|
|
189
|
-
...exports.EVENT_CUSTOMER_TYPES,
|
|
190
|
-
]
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
name: "Order",
|
|
194
|
-
events: [
|
|
195
|
-
...exports.EVENT_ORDER_TYPES,
|
|
196
|
-
]
|
|
197
|
-
}
|
|
198
|
-
];
|
|
199
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9tcG4tYXV0b21hdGlvbi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEwQkEsSUFBWSxXQUlYO0FBSkQsV0FBWSxXQUFXO0lBQ3JCLDhCQUFlLENBQUE7SUFDZixvQ0FBcUIsQ0FBQTtJQUNyQixnQ0FBaUIsQ0FBQTtBQUNuQixDQUFDLEVBSlcsV0FBVywyQkFBWCxXQUFXLFFBSXRCO0FBRUQsSUFBWSxVQU9YO0FBUEQsV0FBWSxVQUFVO0lBQ3BCLDZCQUFlLENBQUE7SUFDZix5QkFBVyxDQUFBO0lBQ1gsMkJBQWEsQ0FBQTtJQUNiLCtCQUFpQixDQUFBO0lBQ2pCLDZCQUFlLENBQUE7SUFDZiw2QkFBZSxDQUFBO0FBQ2pCLENBQUMsRUFQVyxVQUFVLDBCQUFWLFVBQVUsUUFPckI7QUFFRCxJQUFZLFlBT1g7QUFQRCxXQUFZLFlBQVk7SUFDdEIsNEJBQVksQ0FBQTtJQUNaLGlDQUFpQixDQUFBO0lBQ2pCLG1DQUFtQixDQUFBO0lBQ25CLGdDQUFnQixDQUFBO0lBQ2hCLDZDQUE2QixDQUFBO0lBQzdCLDBDQUEwQixDQUFBO0FBQzVCLENBQUMsRUFQVyxZQUFZLDRCQUFaLFlBQVksUUFPdkI7QUFFWSxRQUFBLGNBQWMsR0FBRztJQUM1QjtRQUNFLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSztRQUN6QixLQUFLLEVBQUUsT0FBTztLQUNmO0lBQ0Q7UUFDRSxLQUFLLEVBQUUsWUFBWSxDQUFDLFNBQVM7UUFDN0IsS0FBSyxFQUFFLFdBQVc7S0FDbkI7SUFDRDtRQUNFLEtBQUssRUFBRSxZQUFZLENBQUMsWUFBWTtRQUNoQyxLQUFLLEVBQUUsY0FBYztLQUN0QjtJQUNEO1FBQ0UsS0FBSyxFQUFFLFlBQVksQ0FBQyxTQUFTO1FBQzdCLEtBQUssRUFBRSxXQUFXO0tBQ25CO0lBQ0Q7UUFDRSxLQUFLLEVBQUUsWUFBWSxDQUFDLHFC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
|