@stryke/string-format 0.1.3

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 (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +295 -0
  3. package/dist/acronyms.cjs +7 -0
  4. package/dist/acronyms.d.ts +1 -0
  5. package/dist/acronyms.mjs +1 -0
  6. package/dist/camel-case.cjs +10 -0
  7. package/dist/camel-case.d.ts +10 -0
  8. package/dist/camel-case.mjs +1 -0
  9. package/dist/constant-case.cjs +9 -0
  10. package/dist/constant-case.d.ts +10 -0
  11. package/dist/constant-case.mjs +1 -0
  12. package/dist/deburr.cjs +10 -0
  13. package/dist/deburr.d.ts +20 -0
  14. package/dist/deburr.mjs +1 -0
  15. package/dist/escape.cjs +16 -0
  16. package/dist/escape.d.ts +17 -0
  17. package/dist/escape.mjs +1 -0
  18. package/dist/get-words.cjs +12 -0
  19. package/dist/get-words.d.ts +28 -0
  20. package/dist/get-words.mjs +1 -0
  21. package/dist/index.cjs +214 -0
  22. package/dist/index.d.ts +27 -0
  23. package/dist/index.mjs +1 -0
  24. package/dist/kebab-case.cjs +13 -0
  25. package/dist/kebab-case.d.ts +10 -0
  26. package/dist/kebab-case.mjs +1 -0
  27. package/dist/lower-case-first.cjs +8 -0
  28. package/dist/lower-case-first.d.ts +10 -0
  29. package/dist/lower-case-first.mjs +1 -0
  30. package/dist/normalize-email.cjs +19 -0
  31. package/dist/normalize-email.d.ts +16 -0
  32. package/dist/normalize-email.mjs +1 -0
  33. package/dist/pad.cjs +9 -0
  34. package/dist/pad.d.ts +18 -0
  35. package/dist/pad.mjs +1 -0
  36. package/dist/pascal-case.cjs +8 -0
  37. package/dist/pascal-case.d.ts +10 -0
  38. package/dist/pascal-case.mjs +1 -0
  39. package/dist/period-split.cjs +13 -0
  40. package/dist/period-split.d.ts +10 -0
  41. package/dist/period-split.mjs +1 -0
  42. package/dist/pretty-bytes.cjs +48 -0
  43. package/dist/pretty-bytes.d.ts +148 -0
  44. package/dist/pretty-bytes.mjs +1 -0
  45. package/dist/snake-case.cjs +17 -0
  46. package/dist/snake-case.d.ts +14 -0
  47. package/dist/snake-case.mjs +1 -0
  48. package/dist/start-case.cjs +13 -0
  49. package/dist/start-case.d.ts +20 -0
  50. package/dist/start-case.mjs +1 -0
  51. package/dist/strip-indents.cjs +11 -0
  52. package/dist/strip-indents.d.ts +17 -0
  53. package/dist/strip-indents.mjs +3 -0
  54. package/dist/title-case.cjs +10 -0
  55. package/dist/title-case.d.ts +10 -0
  56. package/dist/title-case.mjs +1 -0
  57. package/dist/unescape.cjs +16 -0
  58. package/dist/unescape.d.ts +16 -0
  59. package/dist/unescape.mjs +1 -0
  60. package/dist/upper-case-first.cjs +8 -0
  61. package/dist/upper-case-first.d.ts +10 -0
  62. package/dist/upper-case-first.mjs +1 -0
  63. package/package.json +337 -0
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.snakeCase = void 0;
7
+ var _types = require("@stryke/types");
8
+ var _upperCaseFirst = require("./upper-case-first.cjs");
9
+ const snakeCase = (t, n) => {
10
+ if (!t) return "";
11
+ const r = t?.replace(/(?<temp1>[A-Z])+/g, e => (0, _upperCaseFirst.upperCaseFirst)(e) ?? _types.EMPTY_STRING).split(/(?=[A-Z])|[\s._-]/).map(e => e.toLowerCase()) ?? [];
12
+ if (r.length === 0) return "";
13
+ if (r.length === 1) return r[0];
14
+ const s = r.reduce((e, i) => `${e}_${i.toLowerCase()}`);
15
+ return n?.splitOnNumber === !1 ? s : s.replace(/(?<temp1>[A-Za-z]\d)/, e => `${e[0]}_${e[1]}`);
16
+ };
17
+ exports.snakeCase = snakeCase;
@@ -0,0 +1,14 @@
1
+ export interface SnakeCaseOptions {
2
+ splitOnNumber: boolean;
3
+ }
4
+ /**
5
+ * Convert the input string to snake case.
6
+ *
7
+ * @remarks
8
+ * "this_is_an_example"
9
+ *
10
+ * @param input - The input string.
11
+ * @param options - Options to control the behavior of the function.
12
+ * @returns The snake-cased string.
13
+ */
14
+ export declare const snakeCase: (input?: string, options?: SnakeCaseOptions) => string;
@@ -0,0 +1 @@
1
+ import{EMPTY_STRING as o}from"@stryke/types";import{upperCaseFirst as a}from"./upper-case-first";export const snakeCase=(t,n)=>{if(!t)return"";const r=t?.replace(/(?<temp1>[A-Z])+/g,e=>a(e)??o).split(/(?=[A-Z])|[\s._-]/).map(e=>e.toLowerCase())??[];if(r.length===0)return"";if(r.length===1)return r[0];const s=r.reduce((e,i)=>`${e}_${i.toLowerCase()}`);return n?.splitOnNumber===!1?s:s.replace(/(?<temp1>[A-Za-z]\d)/,e=>`${e[0]}_${e[1]}`)};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.startCase = startCase;
7
+ var _getWords = require("./get-words.cjs");
8
+ function startCase(o) {
9
+ const e = (0, _getWords.getWords)(o.trim());
10
+ let t = "";
11
+ for (const r of e) r && r[0] && (t && (t += " "), t += r === r.toUpperCase() ? r : r[0].toUpperCase() + r.slice(1).toLowerCase());
12
+ return t;
13
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Converts the first character of each word in a string to uppercase and the remaining characters to lowercase.
3
+ *
4
+ * @remarks
5
+ * "This Is An Example"
6
+ *
7
+ * Start case is the naming convention in which each word is written with an initial capital letter.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const result1 = startCase('hello world'); // result will be 'Hello World'
12
+ * const result2 = startCase('HELLO WORLD'); // result will be 'Hello World'
13
+ * const result3 = startCase('hello-world'); // result will be 'Hello World'
14
+ * const result4 = startCase('hello_world'); // result will be 'Hello World'
15
+ * ```
16
+ *
17
+ * @param str - The string to convert.
18
+ * @returns The converted string.
19
+ */
20
+ export declare function startCase(str: string): string;
@@ -0,0 +1 @@
1
+ import{getWords as s}from"./get-words";export function startCase(o){const e=s(o.trim());let t="";for(const r of e)r&&r[0]&&(t&&(t+=" "),t+=r===r.toUpperCase()?r:r[0].toUpperCase()+r.slice(1).toLowerCase());return t}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.stripIndents = stripIndents;
7
+ function stripIndents(n, ...r) {
8
+ return String.raw(n, ...r).split(`
9
+ `).map(t => t.trim()).join(`
10
+ `).trim();
11
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Removes indents, which is useful for printing warning and messages.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * stripIndents`
7
+ * Options:
8
+ * - option1
9
+ * - option2
10
+ * `
11
+ * ```
12
+ *
13
+ * @param strings - Template strings
14
+ * @param values - Additional values
15
+ * @returns The stripped string
16
+ */
17
+ export declare function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
@@ -0,0 +1,3 @@
1
+ export function stripIndents(n,...r){return String.raw(n,...r).split(`
2
+ `).map(t=>t.trim()).join(`
3
+ `).trim()}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.titleCase = void 0;
7
+ var _acronyms = require("./acronyms.cjs");
8
+ var _upperCaseFirst = require("./upper-case-first.cjs");
9
+ const titleCase = e => e ? e.split(/(?=[A-Z])|[\s._-]/).map(r => r.trim()).filter(Boolean).map(r => _acronyms.ACRONYMS.includes(r) ? r.toUpperCase() : (0, _upperCaseFirst.upperCaseFirst)(r.toLowerCase())).join(" ") : "";
10
+ exports.titleCase = titleCase;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Convert the input string to title case.
3
+ *
4
+ * @remarks
5
+ * "This Is An Example"
6
+ *
7
+ * @param input - The input string.
8
+ * @returns The title cased string.
9
+ */
10
+ export declare const titleCase: (input?: string) => string | undefined;
@@ -0,0 +1 @@
1
+ import{ACRONYMS as t}from"./acronyms";import{upperCaseFirst as i}from"./upper-case-first";export const titleCase=e=>e?e.split(/(?=[A-Z])|[\s._-]/).map(r=>r.trim()).filter(Boolean).map(r=>t.includes(r)?r.toUpperCase():i(r.toLowerCase())).join(" "):"";
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.unescape = unescape;
7
+ const n = {
8
+ "&amp;": "&",
9
+ "&lt;": "<",
10
+ "&gt;": ">",
11
+ "&quot;": '"',
12
+ "&#39;": "'"
13
+ };
14
+ function unescape(t) {
15
+ return t.replace(/&(?:amp|lt|gt|quot|#(?<temp1>0+)?39);/g, e => n[e] || "'");
16
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Converts the HTML entities `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `str` to their corresponding characters.
3
+ * It is the inverse of `escape`.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * unescape('This is a &lt;div&gt; element.'); // returns 'This is a <div> element.'
8
+ * unescape('This is a &quot;quote&quot;'); // returns 'This is a "quote"'
9
+ * unescape('This is a &#39;quote&#39;'); // returns 'This is a 'quote''
10
+ * unescape('This is a &amp; symbol'); // returns 'This is a & symbol'
11
+ * ```
12
+ *
13
+ * @param str - The string to unescape.
14
+ * @returns Returns the unescaped string.
15
+ */
16
+ export declare function unescape(str: string): string;
@@ -0,0 +1 @@
1
+ const n={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"};export function unescape(t){return t.replace(/&(?:amp|lt|gt|quot|#(?<temp1>0+)?39);/g,e=>n[e]||"'")}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.upperCaseFirst = void 0;
7
+ const upperCaseFirst = e => e && e.charAt(0).toUpperCase() + e.slice(1);
8
+ exports.upperCaseFirst = upperCaseFirst;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Upper case the first character of an input string.
3
+ *
4
+ * @remarks
5
+ * "Thisisanexample"
6
+ *
7
+ * @param input - The input string.
8
+ * @returns The capitalized string.
9
+ */
10
+ export declare const upperCaseFirst: (input?: string) => string | undefined;
@@ -0,0 +1 @@
1
+ export const upperCaseFirst=e=>e&&e.charAt(0).toUpperCase()+e.slice(1);
package/package.json ADDED
@@ -0,0 +1,337 @@
1
+ {
2
+ "name": "@stryke/string-format",
3
+ "version": "0.1.3",
4
+ "type": "module",
5
+ "description": "🌩️ A monorepo containing TypeScript utility packages with shared functionality common to many Storm Software applications.",
6
+ "repository": {
7
+ "type": "github",
8
+ "url": "https://github.com/storm-software/stryke.git",
9
+ "directory": "packages/string-format"
10
+ },
11
+ "private": false,
12
+ "publishConfig": { "access": "public" },
13
+ "dependencies": { "@stryke/helpers": ">=0.1.0", "@stryke/types": ">=0.1.1" },
14
+ "devDependencies": {},
15
+ "sideEffects": false,
16
+ "files": ["dist/**/*"],
17
+ "homepage": "https://stormsoftware.com",
18
+ "bugs": {
19
+ "url": "https://stormsoftware.com/support",
20
+ "email": "support@stormsoftware.com"
21
+ },
22
+ "license": "Apache-2.0",
23
+ "keywords": [
24
+ "stryke",
25
+ "typescript",
26
+ "utilities",
27
+ "storm-stack",
28
+ "storm-software",
29
+ "storm",
30
+ "storm-ops",
31
+ "cyclone-ui",
32
+ "sullivanpj",
33
+ "monorepo"
34
+ ],
35
+ "funding": {
36
+ "type": "github",
37
+ "url": "https://github.com/sponsors/storm-software"
38
+ },
39
+ "author": {
40
+ "name": "Storm Software",
41
+ "email": "contact@stormsoftware.com",
42
+ "url": "https://stormsoftware.com"
43
+ },
44
+ "maintainers": [
45
+ {
46
+ "name": "Storm Software",
47
+ "email": "contact@stormsoftware.com",
48
+ "url": "https://stormsoftware.com"
49
+ }
50
+ ],
51
+ "contributors": [
52
+ {
53
+ "name": "Storm Software",
54
+ "email": "contact@stormsoftware.com",
55
+ "url": "https://stormsoftware.com"
56
+ }
57
+ ],
58
+ "exports": {
59
+ "./upper-case-first": {
60
+ "import": {
61
+ "types": "./dist/upper-case-first.d.ts",
62
+ "default": "./dist/upper-case-first.mjs"
63
+ },
64
+ "require": {
65
+ "types": "./dist/upper-case-first.d.ts",
66
+ "default": "./dist/upper-case-first.cjs"
67
+ },
68
+ "default": {
69
+ "types": "./dist/upper-case-first.d.ts",
70
+ "default": "./dist/upper-case-first.mjs"
71
+ }
72
+ },
73
+ "./unescape": {
74
+ "import": {
75
+ "types": "./dist/unescape.d.ts",
76
+ "default": "./dist/unescape.mjs"
77
+ },
78
+ "require": {
79
+ "types": "./dist/unescape.d.ts",
80
+ "default": "./dist/unescape.cjs"
81
+ },
82
+ "default": {
83
+ "types": "./dist/unescape.d.ts",
84
+ "default": "./dist/unescape.mjs"
85
+ }
86
+ },
87
+ "./title-case": {
88
+ "import": {
89
+ "types": "./dist/title-case.d.ts",
90
+ "default": "./dist/title-case.mjs"
91
+ },
92
+ "require": {
93
+ "types": "./dist/title-case.d.ts",
94
+ "default": "./dist/title-case.cjs"
95
+ },
96
+ "default": {
97
+ "types": "./dist/title-case.d.ts",
98
+ "default": "./dist/title-case.mjs"
99
+ }
100
+ },
101
+ "./strip-indents": {
102
+ "import": {
103
+ "types": "./dist/strip-indents.d.ts",
104
+ "default": "./dist/strip-indents.mjs"
105
+ },
106
+ "require": {
107
+ "types": "./dist/strip-indents.d.ts",
108
+ "default": "./dist/strip-indents.cjs"
109
+ },
110
+ "default": {
111
+ "types": "./dist/strip-indents.d.ts",
112
+ "default": "./dist/strip-indents.mjs"
113
+ }
114
+ },
115
+ "./start-case": {
116
+ "import": {
117
+ "types": "./dist/start-case.d.ts",
118
+ "default": "./dist/start-case.mjs"
119
+ },
120
+ "require": {
121
+ "types": "./dist/start-case.d.ts",
122
+ "default": "./dist/start-case.cjs"
123
+ },
124
+ "default": {
125
+ "types": "./dist/start-case.d.ts",
126
+ "default": "./dist/start-case.mjs"
127
+ }
128
+ },
129
+ "./snake-case": {
130
+ "import": {
131
+ "types": "./dist/snake-case.d.ts",
132
+ "default": "./dist/snake-case.mjs"
133
+ },
134
+ "require": {
135
+ "types": "./dist/snake-case.d.ts",
136
+ "default": "./dist/snake-case.cjs"
137
+ },
138
+ "default": {
139
+ "types": "./dist/snake-case.d.ts",
140
+ "default": "./dist/snake-case.mjs"
141
+ }
142
+ },
143
+ "./pretty-bytes": {
144
+ "import": {
145
+ "types": "./dist/pretty-bytes.d.ts",
146
+ "default": "./dist/pretty-bytes.mjs"
147
+ },
148
+ "require": {
149
+ "types": "./dist/pretty-bytes.d.ts",
150
+ "default": "./dist/pretty-bytes.cjs"
151
+ },
152
+ "default": {
153
+ "types": "./dist/pretty-bytes.d.ts",
154
+ "default": "./dist/pretty-bytes.mjs"
155
+ }
156
+ },
157
+ "./period-split": {
158
+ "import": {
159
+ "types": "./dist/period-split.d.ts",
160
+ "default": "./dist/period-split.mjs"
161
+ },
162
+ "require": {
163
+ "types": "./dist/period-split.d.ts",
164
+ "default": "./dist/period-split.cjs"
165
+ },
166
+ "default": {
167
+ "types": "./dist/period-split.d.ts",
168
+ "default": "./dist/period-split.mjs"
169
+ }
170
+ },
171
+ "./pascal-case": {
172
+ "import": {
173
+ "types": "./dist/pascal-case.d.ts",
174
+ "default": "./dist/pascal-case.mjs"
175
+ },
176
+ "require": {
177
+ "types": "./dist/pascal-case.d.ts",
178
+ "default": "./dist/pascal-case.cjs"
179
+ },
180
+ "default": {
181
+ "types": "./dist/pascal-case.d.ts",
182
+ "default": "./dist/pascal-case.mjs"
183
+ }
184
+ },
185
+ "./pad": {
186
+ "import": { "types": "./dist/pad.d.ts", "default": "./dist/pad.mjs" },
187
+ "require": { "types": "./dist/pad.d.ts", "default": "./dist/pad.cjs" },
188
+ "default": { "types": "./dist/pad.d.ts", "default": "./dist/pad.mjs" }
189
+ },
190
+ "./normalize-email": {
191
+ "import": {
192
+ "types": "./dist/normalize-email.d.ts",
193
+ "default": "./dist/normalize-email.mjs"
194
+ },
195
+ "require": {
196
+ "types": "./dist/normalize-email.d.ts",
197
+ "default": "./dist/normalize-email.cjs"
198
+ },
199
+ "default": {
200
+ "types": "./dist/normalize-email.d.ts",
201
+ "default": "./dist/normalize-email.mjs"
202
+ }
203
+ },
204
+ "./lower-case-first": {
205
+ "import": {
206
+ "types": "./dist/lower-case-first.d.ts",
207
+ "default": "./dist/lower-case-first.mjs"
208
+ },
209
+ "require": {
210
+ "types": "./dist/lower-case-first.d.ts",
211
+ "default": "./dist/lower-case-first.cjs"
212
+ },
213
+ "default": {
214
+ "types": "./dist/lower-case-first.d.ts",
215
+ "default": "./dist/lower-case-first.mjs"
216
+ }
217
+ },
218
+ "./kebab-case": {
219
+ "import": {
220
+ "types": "./dist/kebab-case.d.ts",
221
+ "default": "./dist/kebab-case.mjs"
222
+ },
223
+ "require": {
224
+ "types": "./dist/kebab-case.d.ts",
225
+ "default": "./dist/kebab-case.cjs"
226
+ },
227
+ "default": {
228
+ "types": "./dist/kebab-case.d.ts",
229
+ "default": "./dist/kebab-case.mjs"
230
+ }
231
+ },
232
+ "./index": {
233
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.mjs" },
234
+ "require": {
235
+ "types": "./dist/index.d.ts",
236
+ "default": "./dist/index.cjs"
237
+ },
238
+ "default": { "types": "./dist/index.d.ts", "default": "./dist/index.mjs" }
239
+ },
240
+ "./get-words": {
241
+ "import": {
242
+ "types": "./dist/get-words.d.ts",
243
+ "default": "./dist/get-words.mjs"
244
+ },
245
+ "require": {
246
+ "types": "./dist/get-words.d.ts",
247
+ "default": "./dist/get-words.cjs"
248
+ },
249
+ "default": {
250
+ "types": "./dist/get-words.d.ts",
251
+ "default": "./dist/get-words.mjs"
252
+ }
253
+ },
254
+ "./escape": {
255
+ "import": {
256
+ "types": "./dist/escape.d.ts",
257
+ "default": "./dist/escape.mjs"
258
+ },
259
+ "require": {
260
+ "types": "./dist/escape.d.ts",
261
+ "default": "./dist/escape.cjs"
262
+ },
263
+ "default": {
264
+ "types": "./dist/escape.d.ts",
265
+ "default": "./dist/escape.mjs"
266
+ }
267
+ },
268
+ "./deburr": {
269
+ "import": {
270
+ "types": "./dist/deburr.d.ts",
271
+ "default": "./dist/deburr.mjs"
272
+ },
273
+ "require": {
274
+ "types": "./dist/deburr.d.ts",
275
+ "default": "./dist/deburr.cjs"
276
+ },
277
+ "default": {
278
+ "types": "./dist/deburr.d.ts",
279
+ "default": "./dist/deburr.mjs"
280
+ }
281
+ },
282
+ "./constant-case": {
283
+ "import": {
284
+ "types": "./dist/constant-case.d.ts",
285
+ "default": "./dist/constant-case.mjs"
286
+ },
287
+ "require": {
288
+ "types": "./dist/constant-case.d.ts",
289
+ "default": "./dist/constant-case.cjs"
290
+ },
291
+ "default": {
292
+ "types": "./dist/constant-case.d.ts",
293
+ "default": "./dist/constant-case.mjs"
294
+ }
295
+ },
296
+ "./camel-case": {
297
+ "import": {
298
+ "types": "./dist/camel-case.d.ts",
299
+ "default": "./dist/camel-case.mjs"
300
+ },
301
+ "require": {
302
+ "types": "./dist/camel-case.d.ts",
303
+ "default": "./dist/camel-case.cjs"
304
+ },
305
+ "default": {
306
+ "types": "./dist/camel-case.d.ts",
307
+ "default": "./dist/camel-case.mjs"
308
+ }
309
+ },
310
+ "./acronyms": {
311
+ "import": {
312
+ "types": "./dist/acronyms.d.ts",
313
+ "default": "./dist/acronyms.mjs"
314
+ },
315
+ "require": {
316
+ "types": "./dist/acronyms.d.ts",
317
+ "default": "./dist/acronyms.cjs"
318
+ },
319
+ "default": {
320
+ "types": "./dist/acronyms.d.ts",
321
+ "default": "./dist/acronyms.mjs"
322
+ }
323
+ },
324
+ ".": {
325
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.mjs" },
326
+ "require": {
327
+ "types": "./dist/index.d.ts",
328
+ "default": "./dist/index.cjs"
329
+ },
330
+ "default": { "types": "./dist/index.d.ts", "default": "./dist/index.mjs" }
331
+ },
332
+ "./package.json": "./package.json"
333
+ },
334
+ "main": "./dist/index.cjs",
335
+ "module": "./dist/index.mjs",
336
+ "types": "./dist/index.d.ts"
337
+ }