magtool 1.5.37 → 1.5.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/composition.js +81 -78
  2. package/dist/cpt/AiApp.js +117 -0
  3. package/dist/cpt/AiOrg.js +130 -0
  4. package/dist/cpt/AsaAdGroup.js +261 -0
  5. package/dist/cpt/AsaApp.js +126 -0
  6. package/dist/cpt/AsaCampaign.js +268 -0
  7. package/dist/cpt/AsaOrg.js +130 -0
  8. package/dist/cpt/Card.js +92 -0
  9. package/dist/cpt/Country.js +32 -0
  10. package/dist/cpt/CountryItem.js +56 -0
  11. package/dist/cpt/DatePicker.js +246 -0
  12. package/dist/cpt/EChart.js +271 -0
  13. package/dist/cpt/Form.js +75 -0
  14. package/dist/cpt/Header.js +786 -0
  15. package/dist/cpt/Icon.js +24 -0
  16. package/dist/cpt/Image.js +58 -0
  17. package/dist/cpt/Input.js +129 -0
  18. package/dist/cpt/Main.js +230 -0
  19. package/dist/cpt/MultipleSelect.js +143 -0
  20. package/dist/cpt/Nodata.js +39 -0
  21. package/dist/cpt/Org.js +99 -0
  22. package/dist/cpt/Page.js +74 -0
  23. package/dist/cpt/StatusItem.js +68 -0
  24. package/dist/cpt/StatusSelect.js +79 -0
  25. package/dist/cpt/Table.js +123 -0
  26. package/dist/cpt/Textarea.js +132 -0
  27. package/dist/cpt/Timezone.js +128 -0
  28. package/dist/cpt/chip.js +639 -0
  29. package/dist/cpt/component.js +21 -0
  30. package/dist/css/cpt/Card.css +1 -0
  31. package/dist/css/cpt/EChart.css +1 -0
  32. package/dist/css/cpt/Header.css +1 -0
  33. package/dist/css/cpt/Main.css +1 -0
  34. package/dist/css/cpt/MultipleSelect.css +1 -0
  35. package/dist/css/cpt/Nodata.css +1 -0
  36. package/dist/css/cpt/Page.css +1 -0
  37. package/dist/css/cpt/Table.css +1 -0
  38. package/dist/css/cpt/Textarea.css +1 -0
  39. package/dist/css/cpt/chip.css +1 -0
  40. package/dist/css/{magtool.css → css/scss.css} +1 -1
  41. package/dist/index.js +4 -8
  42. package/dist/util.js +5 -5
  43. package/dist/vendor.js +38 -31
  44. package/package.json +1 -1
  45. package/dist/component.js +0 -4427
@@ -0,0 +1,130 @@
1
+ import { defineComponent as D, reactive as G, inject as L, onMounted as O, computed as m, watch as T, resolveComponent as g, createElementBlock as b, openBlock as f, createBlock as h, createCommentVNode as x, createElementVNode as s, unref as i, createVNode as V, withCtx as _, mergeProps as M, Fragment as j, renderList as E, normalizeClass as F, toDisplayString as z } from "vue";
2
+ import { useMap as P } from "asamap";
3
+ const R = { class: "SuperAsaOrg relative" }, U = { class: "inputGroup" }, q = { class: "inputGroupLeft noShrink" }, H = { class: "flexMode vc g4" }, J = { class: "txt-dark5" }, K = D({
4
+ name: "SuperAsaOrg"
5
+ }), Y = /* @__PURE__ */ Object.assign(K, {
6
+ props: {
7
+ app: {
8
+ type: Number,
9
+ default: 0
10
+ },
11
+ changeImmediately: {
12
+ type: Boolean,
13
+ default: !1
14
+ },
15
+ modelValue: {
16
+ type: [Number, String],
17
+ default: 0
18
+ },
19
+ readonly: {
20
+ type: Boolean,
21
+ default: !1
22
+ },
23
+ unTimezone: {
24
+ type: Boolean,
25
+ default: !1
26
+ }
27
+ },
28
+ emits: [
29
+ "update:modelValue",
30
+ "update:name",
31
+ "update:currency",
32
+ "update:readonly",
33
+ "success",
34
+ "error",
35
+ "change"
36
+ ],
37
+ setup(C, { emit: k }) {
38
+ const l = C, a = G({
39
+ loading: !1,
40
+ single: "",
41
+ multiple: [],
42
+ options: []
43
+ }), v = L("store").asa();
44
+ O(() => {
45
+ B();
46
+ });
47
+ const t = k, B = async () => {
48
+ u.value.length ? (a.single || y(u.value[0].id), t("success")) : t("error");
49
+ }, y = (e) => {
50
+ var n, r, c, p;
51
+ t("update:modelValue", e), t("update:name", (n = d.value) == null ? void 0 : n.name), t("update:currency", (r = d.value) == null ? void 0 : r.currency), t("update:timezone", (c = d.value) == null ? void 0 : c.timezone), t("update:readonly", (p = d.value) == null ? void 0 : p.readonly), l.changeImmediately && t("change", e), l.unTimezone || N();
52
+ }, N = () => {
53
+ var n;
54
+ let e = d.value;
55
+ v.saveData("accountTimezone", {
56
+ timezoneName: e == null ? void 0 : e.timezone,
57
+ tip: "Account",
58
+ timezone: (n = P("common.timezone").filter1(
59
+ (r) => r.label === (e == null ? void 0 : e.timezone)
60
+ ).data) == null ? void 0 : n.value
61
+ });
62
+ }, $ = () => {
63
+ a.single = "", t("update:modelValue", ""), t("update:name", ""), t("update:currency", ""), t("update:timezone", ""), t("update:readonly", !1);
64
+ }, w = m(() => window.$l("Campaign Group")), u = m(() => {
65
+ var e;
66
+ return l.app ? ((e = v.appOptions.filter1((n) => n.id === l.app).data) == null ? void 0 : e.orgs) || [] : [];
67
+ }), d = m(() => u.value.filter1((e) => e.id === a.single).data), I = m(() => !l.app);
68
+ return T(
69
+ () => l.modelValue,
70
+ (e) => {
71
+ e ? e !== a.single && (a.single = e, y(e)) : $();
72
+ },
73
+ {
74
+ immediate: !0
75
+ }
76
+ ), (e, n) => {
77
+ const r = g("IconLoading"), c = g("el-button"), p = g("el-option"), S = g("el-select");
78
+ return f(), b("div", R, [
79
+ i(a).loading ? (f(), h(r, { key: 0 })) : x("", !0),
80
+ s("div", U, [
81
+ s("div", q, [
82
+ V(c, {
83
+ circle: "",
84
+ onClick: n[0] || (n[0] = (o) => e.$copy(i(a).single, "ID"))
85
+ }, {
86
+ icon: _(() => [...n[2] || (n[2] = [
87
+ s("i", { class: "imicon im-copy" }, null, -1)
88
+ ])]),
89
+ _: 1
90
+ })
91
+ ]),
92
+ V(S, M({
93
+ modelValue: i(a).single,
94
+ "onUpdate:modelValue": n[1] || (n[1] = (o) => i(a).single = o),
95
+ placeholder: i(w),
96
+ disabled: i(I),
97
+ filterable: ""
98
+ }, e.$attrs, {
99
+ class: "inputGroupRight",
100
+ onChange: y
101
+ }), {
102
+ default: _(() => [
103
+ (f(!0), b(j, null, E(i(u), (o, A) => (f(), h(p, {
104
+ key: A,
105
+ label: `${o.name} (${o.id})`,
106
+ value: o.id,
107
+ disabled: l.readonly && o.readonly
108
+ }, {
109
+ default: _(() => [
110
+ s("div", H, [
111
+ s("i", {
112
+ class: F(["imicon", o.readonly ? "" : "im-writing"])
113
+ }, null, 2),
114
+ s("span", null, z(o.name), 1),
115
+ s("span", J, "(" + z(o.id) + ")", 1)
116
+ ])
117
+ ]),
118
+ _: 2
119
+ }, 1032, ["label", "value", "disabled"]))), 128))
120
+ ]),
121
+ _: 1
122
+ }, 16, ["modelValue", "placeholder", "disabled"])
123
+ ])
124
+ ]);
125
+ };
126
+ }
127
+ });
128
+ export {
129
+ Y as default
130
+ };
@@ -0,0 +1,92 @@
1
+ import { defineComponent as g, getCurrentInstance as p, onMounted as y, reactive as m, createElementBlock as s, openBlock as n, normalizeStyle as c, unref as d, createCommentVNode as f, createElementVNode as r, normalizeClass as a, renderSlot as i, toDisplayString as v } from "vue";
2
+ import { _ as C } from "../vendor.js";
3
+ const h = { class: "fw700" }, S = g({
4
+ name: "MvcCard"
5
+ }), b = /* @__PURE__ */ Object.assign(S, {
6
+ props: {
7
+ title: {
8
+ type: String,
9
+ default: ""
10
+ },
11
+ noheader: {
12
+ type: Boolean,
13
+ default: !1
14
+ },
15
+ nobg: {
16
+ type: Boolean,
17
+ default: !1
18
+ },
19
+ headerClass: {
20
+ type: String,
21
+ default: ""
22
+ },
23
+ bodyClass: {
24
+ type: String,
25
+ default: ""
26
+ },
27
+ bodyStyle: {
28
+ type: String,
29
+ default: ""
30
+ },
31
+ footerClass: {
32
+ type: String,
33
+ default: ""
34
+ },
35
+ color: {
36
+ type: String,
37
+ default: "",
38
+ validate: (l) => ["primary", "green", "red", "purple", "orange", "blue"].indexOf(l) > -1
39
+ },
40
+ headerHide: {
41
+ type: Boolean,
42
+ default: !1
43
+ }
44
+ },
45
+ setup(l) {
46
+ const e = l, { proxy: _ } = p(), u = () => {
47
+ t.toggle = !t.toggle;
48
+ };
49
+ y(() => {
50
+ t.toggle = e.headerHide;
51
+ });
52
+ const t = m({
53
+ toggle: !1
54
+ });
55
+ return (o, k) => (n(), s("div", {
56
+ class: "MvcCard",
57
+ style: c(d(t).cardStyle)
58
+ }, [
59
+ e.noheader ? f("", !0) : (n(), s("div", {
60
+ key: 0,
61
+ ref: "header",
62
+ class: a(["cardHeader flexMode vc fs18 txt-dark9", e.headerClass])
63
+ }, [
64
+ r("i", {
65
+ class: a(["mr4 block imicon im-arrow-right fw700 fs14 transition3 hover", !d(t).toggle && "rotateZ90"]),
66
+ onClick: u
67
+ }, null, 2),
68
+ r("div", h, v(o.$l(e.title)), 1),
69
+ i(o.$slots, "header", {}, void 0, !0)
70
+ ], 2)),
71
+ r("div", {
72
+ class: a(["cardArea transition3", [e.nobg && "nobg", d(t).toggle && "miniArea"]])
73
+ }, [
74
+ r("div", {
75
+ class: a(["cardBody relative nobar", e.bodyClass]),
76
+ style: c(e.bodyStyle)
77
+ }, [
78
+ i(o.$slots, "default", {}, void 0, !0)
79
+ ], 6),
80
+ o.$slots.footer ? (n(), s("div", {
81
+ key: 0,
82
+ class: a(["cardFooter", e.footerClass])
83
+ }, [
84
+ i(o.$slots, "footer", {}, void 0, !0)
85
+ ], 2)) : f("", !0)
86
+ ], 2)
87
+ ], 4));
88
+ }
89
+ }), M = /* @__PURE__ */ C(b, [["__scopeId", "data-v-348c485a"]]);
90
+ export {
91
+ M as default
92
+ };
@@ -0,0 +1,32 @@
1
+ import { defineComponent as m, defineAsyncComponent as p, computed as r, createElementBlock as y, openBlock as s, normalizeClass as C, createBlock as f, resolveDynamicComponent as d, unref as e, mergeProps as g } from "vue";
2
+ const _ = m({
3
+ name: "SuperCountry"
4
+ }), h = /* @__PURE__ */ Object.assign(_, {
5
+ props: {
6
+ type: {
7
+ type: String,
8
+ default: "aso"
9
+ },
10
+ nowrap: {
11
+ type: Boolean,
12
+ default: !1
13
+ }
14
+ },
15
+ setup(a) {
16
+ const l = p(() => import("./chip.js").then((t) => t.C)), c = p(() => import("./chip.js").then((t) => t.a)), u = {
17
+ CountryAso: l,
18
+ CountryDiy: c
19
+ }, o = a, i = r(() => u["Country" + window.$toUpperCamel(o.type)]), n = r(() => o.nowrap);
20
+ return (t, w) => (s(), y("div", {
21
+ class: C(["SuperCountry", o.nowrap && "nowrap"])
22
+ }, [
23
+ (s(), f(d(e(i)), g(t.$attrs, {
24
+ "collapse-tags": e(n),
25
+ "collapse-tags-tooltip": e(n)
26
+ }), null, 16, ["collapse-tags", "collapse-tags-tooltip"]))
27
+ ], 2));
28
+ }
29
+ });
30
+ export {
31
+ h as default
32
+ };
@@ -0,0 +1,56 @@
1
+ import { defineComponent as y, reactive as f, inject as _, computed as t, createElementBlock as a, openBlock as l, unref as n, createElementVNode as b, createCommentVNode as g, normalizeStyle as S, normalizeClass as h, toDisplayString as w } from "vue";
2
+ import { useMap as c } from "asamap";
3
+ const v = ["title"], x = {
4
+ key: 0,
5
+ class: "pl4"
6
+ }, C = y({
7
+ name: "SuperCountryItem"
8
+ }), O = /* @__PURE__ */ Object.assign(C, {
9
+ props: {
10
+ name: {
11
+ type: String,
12
+ default: ""
13
+ },
14
+ nolabel: {
15
+ type: Boolean,
16
+ default: !1
17
+ },
18
+ size: {
19
+ type: [String, Number],
20
+ default: 16
21
+ },
22
+ radius: {
23
+ type: [String, Number],
24
+ default: 8
25
+ }
26
+ },
27
+ setup(u) {
28
+ const o = u;
29
+ f({});
30
+ const i = _("store").common(), r = t(() => {
31
+ const e = o.name.toLowerCase();
32
+ return i.countryObj[e] || c("country.countryAllObj")[e] || {};
33
+ }), m = t(() => `fi-${r.value.value_lower}`);
34
+ t(() => window.$getLang());
35
+ const s = t(() => window.$l(r.value.label)), p = t(() => {
36
+ const e = parseInt(o.size);
37
+ return {
38
+ width: e + "px",
39
+ height: e + "px"
40
+ };
41
+ }), d = t(() => `radius${Number(o.radius) || 2}`);
42
+ return c("country.countryAllObj"), (e, N) => (l(), a("div", {
43
+ class: "SuperCountryItem flexMode vc g4",
44
+ title: n(s)
45
+ }, [
46
+ b("span", {
47
+ class: h(["box-shadow-gray3 fi fis noShrink", [n(m), n(d)]]),
48
+ style: S(n(p))
49
+ }, null, 6),
50
+ o.nolabel ? g("", !0) : (l(), a("span", x, w(n(s)), 1))
51
+ ], 8, v));
52
+ }
53
+ });
54
+ export {
55
+ O as default
56
+ };
@@ -0,0 +1,246 @@
1
+ import { defineComponent as E, reactive as O, onMounted as j, computed as n, watch as A, resolveComponent as z, createElementBlock as J, openBlock as P, createVNode as W, unref as o } from "vue";
2
+ import { dayjs as F } from "element-plus";
3
+ const I = { class: "SuperDatePicker" }, U = E({
4
+ name: "SuperDatePicker"
5
+ }), H = /* @__PURE__ */ Object.assign(U, {
6
+ props: {
7
+ source: {
8
+ type: String,
9
+ default: ""
10
+ },
11
+ modelValue: {
12
+ type: [String, Array],
13
+ default: () => []
14
+ },
15
+ withToday: {
16
+ type: Boolean,
17
+ default: !1
18
+ },
19
+ defaultDate: {
20
+ type: Array,
21
+ default: () => [-7, -1]
22
+ },
23
+ // 开始,结束的分割符号,也是v-model str时的分割符号
24
+ separator: {
25
+ type: String,
26
+ default: "~"
27
+ },
28
+ offset: {
29
+ type: [String, Number],
30
+ default: 0
31
+ },
32
+ range: {
33
+ type: [String, Number],
34
+ default: 180
35
+ },
36
+ limit: {
37
+ type: [String, Number],
38
+ default: 30
39
+ },
40
+ // today, yersterday, thisweek, last7days, thismonth, last30days, lastmonth
41
+ shortcuts: {
42
+ type: [Object, Boolean],
43
+ default: !1
44
+ },
45
+ placement: {
46
+ type: String,
47
+ default: "bottom"
48
+ },
49
+ disabled: {
50
+ type: Boolean,
51
+ default: !1
52
+ },
53
+ size: {
54
+ type: String,
55
+ default: "large"
56
+ }
57
+ },
58
+ emits: ["change", "update:modelValue"],
59
+ setup(M, { expose: $, emit: g }) {
60
+ F.en.weekStart = 7;
61
+ const d = M, r = O({
62
+ type: "",
63
+ date: [],
64
+ shortBtn: [],
65
+ firstStamp: 0
66
+ });
67
+ j(() => {
68
+ if (!p.value.length) {
69
+ const e = d.defaultDate[0], t = d.defaultDate[1];
70
+ r.date = [
71
+ window.$m().add(e, "days").format("YYYY-MM-DD"),
72
+ window.$m().add(t, "days").format("YYYY-MM-DD")
73
+ ], f(r.date);
74
+ }
75
+ v();
76
+ });
77
+ const m = g, S = (e) => {
78
+ let { limit: t, range: a } = d;
79
+ t = Number(t), a = Number(a);
80
+ const { firstStamp: s } = r, i = t * 864e5;
81
+ let u = +window.$m().add(-a, "d"), c = +window.$m();
82
+ if (d.source === "report" && !s)
83
+ return e > c;
84
+ if (s) {
85
+ if (d.source !== "report") {
86
+ let D = s - i;
87
+ D > u && (u = D);
88
+ } else
89
+ u = s - i;
90
+ let h = s + i;
91
+ h < c && (c = h);
92
+ }
93
+ return e < u || e > c;
94
+ }, b = (e) => {
95
+ e[1] === null ? r.firstStamp = +e[0] : r.firstStamp = 0;
96
+ }, f = (e) => {
97
+ const t = y(e);
98
+ m("change", t, "cpt");
99
+ }, v = () => {
100
+ const { shortcuts: e } = d;
101
+ let t = {};
102
+ if (e === !1)
103
+ r.shortBtn = [];
104
+ else {
105
+ e === !0 ? t = Y : t = {
106
+ ...Y,
107
+ ...e
108
+ };
109
+ const a = [];
110
+ t.today && a.push(k()), t.yesterday && a.push(C()), t.thisweek && a.push(T()), t.last7days && a.push(V()), t.todaylast7days && a.push(B()), t.thismonth && a.push(_()), t.last30days && a.push(x()), t.lastmonth && a.push(L()), r.shortBtn = a;
111
+ }
112
+ }, k = () => ({
113
+ text: window.$l("Today"),
114
+ value: () => {
115
+ const e = window.$m().format("YYYY-MM-DD");
116
+ return [e, e];
117
+ },
118
+ onClick: (e) => {
119
+ }
120
+ }), C = () => ({
121
+ text: window.$l("Yesterday"),
122
+ value: () => {
123
+ const e = window.$m().add(-1, "days").format("YYYY-MM-DD");
124
+ return [e, e];
125
+ },
126
+ onClick: (e) => {
127
+ }
128
+ }), T = () => ({
129
+ text: window.$l("This Week"),
130
+ value: () => {
131
+ let e = 0, t = window.$m().weekday(0), a = window.$m().add(e, "days");
132
+ return +t > +a && (t = t.format("YYYY-MM-DD"), a = t), [t, a];
133
+ },
134
+ onClick: (e) => {
135
+ }
136
+ }), V = () => ({
137
+ text: window.$l("Last 7 Days"),
138
+ value: () => {
139
+ let e = -7, t = -1;
140
+ return d.widthToday && (e += 1, t += 1), [
141
+ window.$m().add(e, "days").format("YYYY-MM-DD"),
142
+ window.$m().add(t, "days").format("YYYY-MM-DD")
143
+ ];
144
+ },
145
+ onClick: (e) => {
146
+ }
147
+ }), B = () => ({
148
+ text: window.$l("Last 7 Days (with Today)"),
149
+ value: () => [
150
+ window.$m().add(-6, "days").format("YYYY-MM-DD"),
151
+ window.$m().add(0, "days").format("YYYY-MM-DD")
152
+ ],
153
+ onClick: (e) => {
154
+ }
155
+ }), _ = () => ({
156
+ text: window.$l("This Month"),
157
+ value: () => {
158
+ let e = 0, t = window.$m().date(1), a = window.$m().add(e, "days");
159
+ return +t > +a && (t = t.format("YYYY-MM-DD"), a = t), [t, a];
160
+ },
161
+ onClick: (e) => {
162
+ }
163
+ }), x = () => ({
164
+ text: window.$l("Last 30 Days"),
165
+ value: () => {
166
+ let e = -30, t = -1;
167
+ return d.widthToday && (e += 1, t += 1), [
168
+ window.$m().add(e, "days").format("YYYY-MM-DD"),
169
+ window.$m().add(t, "days").format("YYYY-MM-DD")
170
+ ];
171
+ },
172
+ onClick: (e) => {
173
+ }
174
+ }), L = () => ({
175
+ text: window.$l("Last Month"),
176
+ value: () => [
177
+ window.$m().date(1).add(-1, "days").date(1).format("YYYY-MM-DD"),
178
+ window.$m().date(1).add(-1, "days").format("YYYY-MM-DD")
179
+ ],
180
+ onClick: (e) => {
181
+ }
182
+ }), y = (e, t = !1) => {
183
+ t && (r.date = e);
184
+ let a;
185
+ return l.value === "Array" ? a = e : l.value === "Object" ? a = {
186
+ startDate: e[0],
187
+ endDate: e[1]
188
+ } : a = e[0] + d.separator + e[1], m("update:modelValue", a), a;
189
+ }, N = n(() => window.$getLang()), l = n(() => window.$getType(d.modelValue)), p = n(() => l.value === "Array" ? d.modelValue : l.value === "Object" ? [d.modelValue.startDate, d.modelValue.endDate] : d.modelValue ? d.modelValue.split(d.separator) : []), w = n(() => ({
190
+ start: window.$l("Start Date"),
191
+ end: window.$l("End Date")
192
+ }));
193
+ n(() => {
194
+ let { disabledDate: e, offset: t } = d, a = 0;
195
+ t = Number(t) || 0;
196
+ const s = window.$getType(e);
197
+ return s !== "Function" && s !== "Array" && (a = parseInt(e) || 0, a > -1 && (a = -1), a > t && (a = t)), a;
198
+ });
199
+ const Y = {
200
+ today: !0,
201
+ yesterday: !0,
202
+ thisweek: !1,
203
+ last7days: !0,
204
+ todaylast7days: !1,
205
+ thismonth: !0,
206
+ last30days: !0,
207
+ lastmonth: !0
208
+ };
209
+ return A(
210
+ () => p.value,
211
+ (e, t) => {
212
+ e.length && JSON.stringify(e) !== JSON.stringify(r.date) && (r.date = e, f(e));
213
+ }
214
+ ), $({
215
+ setDate: y
216
+ }), (e, t) => {
217
+ const a = z("el-date-picker");
218
+ return P(), J("div", I, [
219
+ W(a, {
220
+ modelValue: o(r).date,
221
+ "onUpdate:modelValue": t[0] || (t[0] = (s) => o(r).date = s),
222
+ class: "wp100",
223
+ "popper-class": o(N),
224
+ type: "daterange",
225
+ "value-format": "YYYY-MM-DD",
226
+ editable: !1,
227
+ size: d.size,
228
+ clearable: !1,
229
+ "range-separator": d.separator,
230
+ shortcuts: o(r).shortBtn,
231
+ "end-placeholder": e.$l(o(w).end),
232
+ "start-placeholder": e.$l(o(w).start),
233
+ "disabled-date": S,
234
+ placement: d.placement,
235
+ disabled: d.disabled,
236
+ source: d.source,
237
+ onChange: f,
238
+ onCalendarChange: b
239
+ }, null, 8, ["modelValue", "popper-class", "size", "range-separator", "shortcuts", "end-placeholder", "start-placeholder", "placement", "disabled", "source"])
240
+ ]);
241
+ };
242
+ }
243
+ });
244
+ export {
245
+ H as default
246
+ };