├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── elm.json
├── package-lock.json
├── package.json
├── src
└── String
│ └── Extra.elm
└── tests
├── .gitignore
├── CamelizeTest.elm
├── ClassifyTest.elm
├── DasherizeTest.elm
├── HumanizeTest.elm
├── NonEmptyTest.elm
├── RemoveAccentsTest.elm
├── ReplaceSliceTest.elm
├── TestData.elm
├── Tests.elm
├── UnderscoredTest.elm
├── UnicodeTests.elm
├── UnindentTest.elm
└── elm-package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # elm-package generated files
2 | elm-stuff/
3 | # elm-repl generated files
4 | repl-temp-*
5 | node_modules
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: node
3 |
4 |
5 | cache:
6 | directories:
7 | - elm-stuff/build-artifacts
8 | - elm-stuff/packages
9 | - test/elm-stuff/build-artifacts
10 | - test/elm-stuff/packages
11 | - sysconfcpus
12 |
13 | before_install:
14 | - if [ ${TRAVIS_OS_NAME} == "osx" ];
15 | then brew update; brew install nvm; mkdir ~/.nvm; export NVM_DIR=~/.nvm; source $(brew --prefix nvm)/nvm.sh;
16 | fi
17 |
18 | install:
19 | - npm install
20 |
21 | script:
22 | - npm run test
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, Elm Community
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of string-extra nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | string-extra
2 | ============
3 |
4 | String helper functions for Elm, inspired by [underscore.string](http://epeli.github.io/underscore.string/).
5 |
6 | [](https://travis-ci.org/elm-community/string-extra)
7 |
8 | Contributing
9 | ------------
10 |
11 | Pull requests are welcome. If you want to talk to us, join us on the
12 | `#elm-community` or `#string-extra` channels on the [Elm Slack](https://elmlang.slack.com).
13 |
14 | Testing
15 | -------
16 |
17 | ```
18 | npm i
19 | npm run test
20 | ```
21 |
22 | Maintainers
23 | -----------
24 |
25 | This package is maintained by
26 |
27 | - [José Lorenzo Rodríguez](https://github.com/lorenzo)
28 | - [Jaap Broekhuizen](https://github.com/jaapz)
29 |
30 | Thanks
31 | ------
32 |
33 | This package is an effort to consolidate [lorenzo/elm-string-addons](https://github.com/lorenzo/elm-string-addons),
34 | [NoRedInk/elm-string-extra](https://github.com/NoRedInk/elm-string-extra), and
35 | add utility functions inspired by [underscore.string](http://epeli.github.io/underscore.string/).
36 |
37 | So thanks to the authors of those libraries for making `string-extra` possible.
38 |
39 | License
40 | -------
41 |
42 | The source code for this package is released under the terms of the BSD3
43 | license. See the `LICENSE` file.
44 |
--------------------------------------------------------------------------------
/elm.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "package",
3 | "name": "elm-community/string-extra",
4 | "summary": "String helper functions for Elm",
5 | "license": "BSD-3-Clause",
6 | "version": "4.0.0",
7 | "exposed-modules": [
8 | "String.Extra"
9 | ],
10 | "elm-version": "0.19.0 <= v < 0.20.0",
11 | "dependencies": {
12 | "elm/core": "1.0.0 <= v < 2.0.0",
13 | "elm/regex": "1.0.0 <= v < 2.0.0"
14 | },
15 | "test-dependencies": {
16 | "elm-explorations/test": "1.2.1 <= v < 2.0.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "string-extra",
3 | "version": "1.4.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "ajv": {
8 | "version": "6.10.0",
9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
10 | "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
11 | "requires": {
12 | "fast-deep-equal": "^2.0.1",
13 | "fast-json-stable-stringify": "^2.0.0",
14 | "json-schema-traverse": "^0.4.1",
15 | "uri-js": "^4.2.2"
16 | }
17 | },
18 | "ansi-styles": {
19 | "version": "3.2.1",
20 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
21 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
22 | "requires": {
23 | "color-convert": "^1.9.0"
24 | }
25 | },
26 | "anymatch": {
27 | "version": "1.3.2",
28 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
29 | "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
30 | "requires": {
31 | "micromatch": "^2.1.5",
32 | "normalize-path": "^2.0.0"
33 | }
34 | },
35 | "arr-diff": {
36 | "version": "2.0.0",
37 | "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
38 | "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
39 | "requires": {
40 | "arr-flatten": "^1.0.1"
41 | }
42 | },
43 | "arr-flatten": {
44 | "version": "1.1.0",
45 | "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
46 | "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
47 | },
48 | "arr-union": {
49 | "version": "3.1.0",
50 | "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
51 | "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
52 | },
53 | "array-unique": {
54 | "version": "0.2.1",
55 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
56 | "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
57 | },
58 | "asn1": {
59 | "version": "0.2.4",
60 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
61 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
62 | "requires": {
63 | "safer-buffer": "~2.1.0"
64 | }
65 | },
66 | "assert-plus": {
67 | "version": "1.0.0",
68 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
69 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
70 | },
71 | "assign-symbols": {
72 | "version": "1.0.0",
73 | "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
74 | "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
75 | },
76 | "async-each": {
77 | "version": "1.0.1",
78 | "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
79 | "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
80 | },
81 | "asynckit": {
82 | "version": "0.4.0",
83 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
84 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
85 | },
86 | "atob": {
87 | "version": "2.1.2",
88 | "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
89 | "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
90 | },
91 | "aws-sign2": {
92 | "version": "0.7.0",
93 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
94 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
95 | },
96 | "aws4": {
97 | "version": "1.8.0",
98 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
99 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
100 | },
101 | "balanced-match": {
102 | "version": "1.0.0",
103 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
104 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
105 | },
106 | "base": {
107 | "version": "0.11.2",
108 | "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
109 | "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
110 | "requires": {
111 | "cache-base": "^1.0.1",
112 | "class-utils": "^0.3.5",
113 | "component-emitter": "^1.2.1",
114 | "define-property": "^1.0.0",
115 | "isobject": "^3.0.1",
116 | "mixin-deep": "^1.2.0",
117 | "pascalcase": "^0.1.1"
118 | },
119 | "dependencies": {
120 | "define-property": {
121 | "version": "1.0.0",
122 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
123 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
124 | "requires": {
125 | "is-descriptor": "^1.0.0"
126 | }
127 | },
128 | "is-accessor-descriptor": {
129 | "version": "1.0.0",
130 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
131 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
132 | "requires": {
133 | "kind-of": "^6.0.0"
134 | }
135 | },
136 | "is-data-descriptor": {
137 | "version": "1.0.0",
138 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
139 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
140 | "requires": {
141 | "kind-of": "^6.0.0"
142 | }
143 | },
144 | "is-descriptor": {
145 | "version": "1.0.2",
146 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
147 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
148 | "requires": {
149 | "is-accessor-descriptor": "^1.0.0",
150 | "is-data-descriptor": "^1.0.0",
151 | "kind-of": "^6.0.2"
152 | }
153 | },
154 | "isobject": {
155 | "version": "3.0.1",
156 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
157 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
158 | },
159 | "kind-of": {
160 | "version": "6.0.2",
161 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
162 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
163 | }
164 | }
165 | },
166 | "bcrypt-pbkdf": {
167 | "version": "1.0.2",
168 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
169 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
170 | "requires": {
171 | "tweetnacl": "^0.14.3"
172 | }
173 | },
174 | "binary": {
175 | "version": "0.3.0",
176 | "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
177 | "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
178 | "requires": {
179 | "buffers": "~0.1.1",
180 | "chainsaw": "~0.1.0"
181 | }
182 | },
183 | "binary-extensions": {
184 | "version": "1.13.0",
185 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz",
186 | "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw=="
187 | },
188 | "binwrap": {
189 | "version": "0.2.0",
190 | "resolved": "https://registry.npmjs.org/binwrap/-/binwrap-0.2.0.tgz",
191 | "integrity": "sha512-HUspivC8zPE37KJQ0S4zsNHUpymzQBinmpdMoa+JwmB6Mi+p30ywVZJcillYpbQmiX2wLykaaDJxXmwZkbaZGA==",
192 | "requires": {
193 | "mustache": "^2.3.0",
194 | "request": "^2.87.0",
195 | "request-promise": "^4.2.0",
196 | "tar": "^2.2.1",
197 | "unzip-stream": "^0.3.0"
198 | }
199 | },
200 | "block-stream": {
201 | "version": "0.0.9",
202 | "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
203 | "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
204 | "requires": {
205 | "inherits": "~2.0.0"
206 | }
207 | },
208 | "bluebird": {
209 | "version": "3.5.3",
210 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
211 | "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
212 | },
213 | "brace-expansion": {
214 | "version": "1.1.11",
215 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
216 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
217 | "requires": {
218 | "balanced-match": "^1.0.0",
219 | "concat-map": "0.0.1"
220 | }
221 | },
222 | "braces": {
223 | "version": "1.8.5",
224 | "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
225 | "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
226 | "requires": {
227 | "expand-range": "^1.8.1",
228 | "preserve": "^0.2.0",
229 | "repeat-element": "^1.1.2"
230 | }
231 | },
232 | "buffers": {
233 | "version": "0.1.1",
234 | "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
235 | "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
236 | },
237 | "cache-base": {
238 | "version": "1.0.1",
239 | "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
240 | "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
241 | "requires": {
242 | "collection-visit": "^1.0.0",
243 | "component-emitter": "^1.2.1",
244 | "get-value": "^2.0.6",
245 | "has-value": "^1.0.0",
246 | "isobject": "^3.0.1",
247 | "set-value": "^2.0.0",
248 | "to-object-path": "^0.3.0",
249 | "union-value": "^1.0.0",
250 | "unset-value": "^1.0.0"
251 | },
252 | "dependencies": {
253 | "isobject": {
254 | "version": "3.0.1",
255 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
256 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
257 | }
258 | }
259 | },
260 | "caseless": {
261 | "version": "0.12.0",
262 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
263 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
264 | },
265 | "chainsaw": {
266 | "version": "0.1.0",
267 | "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
268 | "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
269 | "requires": {
270 | "traverse": ">=0.3.0 <0.4"
271 | }
272 | },
273 | "chalk": {
274 | "version": "2.1.0",
275 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
276 | "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
277 | "requires": {
278 | "ansi-styles": "^3.1.0",
279 | "escape-string-regexp": "^1.0.5",
280 | "supports-color": "^4.0.0"
281 | }
282 | },
283 | "chokidar": {
284 | "version": "1.7.0",
285 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
286 | "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
287 | "requires": {
288 | "anymatch": "^1.3.0",
289 | "async-each": "^1.0.0",
290 | "fsevents": "^1.0.0",
291 | "glob-parent": "^2.0.0",
292 | "inherits": "^2.0.1",
293 | "is-binary-path": "^1.0.0",
294 | "is-glob": "^2.0.0",
295 | "path-is-absolute": "^1.0.0",
296 | "readdirp": "^2.0.0"
297 | }
298 | },
299 | "class-utils": {
300 | "version": "0.3.6",
301 | "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
302 | "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
303 | "requires": {
304 | "arr-union": "^3.1.0",
305 | "define-property": "^0.2.5",
306 | "isobject": "^3.0.0",
307 | "static-extend": "^0.1.1"
308 | },
309 | "dependencies": {
310 | "define-property": {
311 | "version": "0.2.5",
312 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
313 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
314 | "requires": {
315 | "is-descriptor": "^0.1.0"
316 | }
317 | },
318 | "isobject": {
319 | "version": "3.0.1",
320 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
321 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
322 | }
323 | }
324 | },
325 | "collection-visit": {
326 | "version": "1.0.0",
327 | "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
328 | "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
329 | "requires": {
330 | "map-visit": "^1.0.0",
331 | "object-visit": "^1.0.0"
332 | }
333 | },
334 | "color-convert": {
335 | "version": "1.9.3",
336 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
337 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
338 | "requires": {
339 | "color-name": "1.1.3"
340 | }
341 | },
342 | "color-name": {
343 | "version": "1.1.3",
344 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
345 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
346 | },
347 | "combined-stream": {
348 | "version": "1.0.7",
349 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
350 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
351 | "requires": {
352 | "delayed-stream": "~1.0.0"
353 | }
354 | },
355 | "component-emitter": {
356 | "version": "1.2.1",
357 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
358 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
359 | },
360 | "concat-map": {
361 | "version": "0.0.1",
362 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
363 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
364 | },
365 | "copy-descriptor": {
366 | "version": "0.1.1",
367 | "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
368 | "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
369 | },
370 | "core-util-is": {
371 | "version": "1.0.2",
372 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
373 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
374 | },
375 | "cross-spawn": {
376 | "version": "4.0.0",
377 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.0.tgz",
378 | "integrity": "sha1-glR3SrR4a4xbPPTfumbOVjkywlI=",
379 | "requires": {
380 | "lru-cache": "^4.0.1",
381 | "which": "^1.2.9"
382 | }
383 | },
384 | "dashdash": {
385 | "version": "1.14.1",
386 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
387 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
388 | "requires": {
389 | "assert-plus": "^1.0.0"
390 | }
391 | },
392 | "debug": {
393 | "version": "2.6.9",
394 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
395 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
396 | "requires": {
397 | "ms": "2.0.0"
398 | }
399 | },
400 | "decode-uri-component": {
401 | "version": "0.2.0",
402 | "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
403 | "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
404 | },
405 | "define-property": {
406 | "version": "2.0.2",
407 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
408 | "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
409 | "requires": {
410 | "is-descriptor": "^1.0.2",
411 | "isobject": "^3.0.1"
412 | },
413 | "dependencies": {
414 | "is-accessor-descriptor": {
415 | "version": "1.0.0",
416 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
417 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
418 | "requires": {
419 | "kind-of": "^6.0.0"
420 | }
421 | },
422 | "is-data-descriptor": {
423 | "version": "1.0.0",
424 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
425 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
426 | "requires": {
427 | "kind-of": "^6.0.0"
428 | }
429 | },
430 | "is-descriptor": {
431 | "version": "1.0.2",
432 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
433 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
434 | "requires": {
435 | "is-accessor-descriptor": "^1.0.0",
436 | "is-data-descriptor": "^1.0.0",
437 | "kind-of": "^6.0.2"
438 | }
439 | },
440 | "isobject": {
441 | "version": "3.0.1",
442 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
443 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
444 | },
445 | "kind-of": {
446 | "version": "6.0.2",
447 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
448 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
449 | }
450 | }
451 | },
452 | "delayed-stream": {
453 | "version": "1.0.0",
454 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
455 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
456 | },
457 | "ecc-jsbn": {
458 | "version": "0.1.2",
459 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
460 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
461 | "requires": {
462 | "jsbn": "~0.1.0",
463 | "safer-buffer": "^2.1.0"
464 | }
465 | },
466 | "elm": {
467 | "version": "0.19.0-bugfix6",
468 | "resolved": "https://registry.npmjs.org/elm/-/elm-0.19.0-bugfix6.tgz",
469 | "integrity": "sha512-nD/oK/nG26ULh94GREsILA9aQa3Gon+KKBmS0Z0MstywLWwrhuWKba8gfiIWLdnpQWHFIf+UsThk6Z71UWi6TQ==",
470 | "requires": {
471 | "binwrap": "0.2.0"
472 | }
473 | },
474 | "elm-test": {
475 | "version": "0.19.0-rev5",
476 | "resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.0-rev5.tgz",
477 | "integrity": "sha512-D/LS6Db9VIuaM3UffbBkrHmR6oLpm68EYVSru9CeHkVqUQwedVuLmZX6d0jvnU0C8I/dLSEdXlGueaPgTGhNnA==",
478 | "requires": {
479 | "chalk": "2.1.0",
480 | "chokidar": "1.7.0",
481 | "cross-spawn": "4.0.0",
482 | "elmi-to-json": "0.19.1",
483 | "find-parent-dir": "^0.3.0",
484 | "firstline": "1.2.1",
485 | "fs-extra": "0.30.0",
486 | "fsevents": "1.2.4",
487 | "glob": "7.1.1",
488 | "lodash": "4.17.11",
489 | "minimist": "^1.2.0",
490 | "murmur-hash-js": "1.0.0",
491 | "node-elm-compiler": "5.0.1",
492 | "split": "1.0.1",
493 | "supports-color": "4.2.0",
494 | "temp": "0.8.3",
495 | "which": "1.3.1",
496 | "xmlbuilder": "^8.2.2"
497 | },
498 | "dependencies": {
499 | "glob": {
500 | "version": "7.1.1",
501 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
502 | "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
503 | "requires": {
504 | "fs.realpath": "^1.0.0",
505 | "inflight": "^1.0.4",
506 | "inherits": "2",
507 | "minimatch": "^3.0.2",
508 | "once": "^1.3.0",
509 | "path-is-absolute": "^1.0.0"
510 | }
511 | },
512 | "minimist": {
513 | "version": "1.2.0",
514 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
515 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
516 | }
517 | }
518 | },
519 | "elmi-to-json": {
520 | "version": "0.19.1",
521 | "resolved": "https://registry.npmjs.org/elmi-to-json/-/elmi-to-json-0.19.1.tgz",
522 | "integrity": "sha512-O0Z3YsYU9OTb1hTDGORWxi69QjQFEIPfZVq/oc1D5lhL3swduHKY8vdKGuo+WlKVdTas99oNIsgL7yojWdYcsQ==",
523 | "requires": {
524 | "binwrap": "^0.2.0-rc2"
525 | }
526 | },
527 | "escape-string-regexp": {
528 | "version": "1.0.5",
529 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
530 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
531 | },
532 | "expand-brackets": {
533 | "version": "0.1.5",
534 | "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
535 | "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
536 | "requires": {
537 | "is-posix-bracket": "^0.1.0"
538 | }
539 | },
540 | "expand-range": {
541 | "version": "1.8.2",
542 | "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
543 | "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
544 | "requires": {
545 | "fill-range": "^2.1.0"
546 | }
547 | },
548 | "extend": {
549 | "version": "3.0.2",
550 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
551 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
552 | },
553 | "extend-shallow": {
554 | "version": "3.0.2",
555 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
556 | "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
557 | "requires": {
558 | "assign-symbols": "^1.0.0",
559 | "is-extendable": "^1.0.1"
560 | },
561 | "dependencies": {
562 | "is-extendable": {
563 | "version": "1.0.1",
564 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
565 | "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
566 | "requires": {
567 | "is-plain-object": "^2.0.4"
568 | }
569 | }
570 | }
571 | },
572 | "extglob": {
573 | "version": "0.3.2",
574 | "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
575 | "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
576 | "requires": {
577 | "is-extglob": "^1.0.0"
578 | }
579 | },
580 | "extsprintf": {
581 | "version": "1.3.0",
582 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
583 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
584 | },
585 | "fast-deep-equal": {
586 | "version": "2.0.1",
587 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
588 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
589 | },
590 | "fast-json-stable-stringify": {
591 | "version": "2.0.0",
592 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
593 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
594 | },
595 | "filename-regex": {
596 | "version": "2.0.1",
597 | "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
598 | "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
599 | },
600 | "fill-range": {
601 | "version": "2.2.4",
602 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
603 | "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
604 | "requires": {
605 | "is-number": "^2.1.0",
606 | "isobject": "^2.0.0",
607 | "randomatic": "^3.0.0",
608 | "repeat-element": "^1.1.2",
609 | "repeat-string": "^1.5.2"
610 | }
611 | },
612 | "find-elm-dependencies": {
613 | "version": "2.0.0",
614 | "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.0.tgz",
615 | "integrity": "sha512-lnLilxwdS3U/CSPoMnfUL1u21MBNolv6NF54y4Yds7WxdRMrTBXrmugrcvIGvakWQ2anYuinmBSUR+jUQy+vpA==",
616 | "requires": {
617 | "firstline": "1.2.0",
618 | "lodash": "4.17.10"
619 | },
620 | "dependencies": {
621 | "firstline": {
622 | "version": "1.2.0",
623 | "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.0.tgz",
624 | "integrity": "sha1-yfSIbn9/vwr8EtcZQdzgaxkq6gU="
625 | },
626 | "lodash": {
627 | "version": "4.17.10",
628 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
629 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
630 | }
631 | }
632 | },
633 | "find-parent-dir": {
634 | "version": "0.3.0",
635 | "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
636 | "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ="
637 | },
638 | "firstline": {
639 | "version": "1.2.1",
640 | "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.1.tgz",
641 | "integrity": "sha1-uIZzxCAJ+IIfrCkm6ZcgrO6ST64="
642 | },
643 | "for-in": {
644 | "version": "1.0.2",
645 | "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
646 | "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
647 | },
648 | "for-own": {
649 | "version": "0.1.5",
650 | "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
651 | "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
652 | "requires": {
653 | "for-in": "^1.0.1"
654 | }
655 | },
656 | "forever-agent": {
657 | "version": "0.6.1",
658 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
659 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
660 | },
661 | "form-data": {
662 | "version": "2.3.3",
663 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
664 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
665 | "requires": {
666 | "asynckit": "^0.4.0",
667 | "combined-stream": "^1.0.6",
668 | "mime-types": "^2.1.12"
669 | }
670 | },
671 | "fragment-cache": {
672 | "version": "0.2.1",
673 | "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
674 | "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
675 | "requires": {
676 | "map-cache": "^0.2.2"
677 | }
678 | },
679 | "fs-extra": {
680 | "version": "0.30.0",
681 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
682 | "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
683 | "requires": {
684 | "graceful-fs": "^4.1.2",
685 | "jsonfile": "^2.1.0",
686 | "klaw": "^1.0.0",
687 | "path-is-absolute": "^1.0.0",
688 | "rimraf": "^2.2.8"
689 | }
690 | },
691 | "fs.realpath": {
692 | "version": "1.0.0",
693 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
694 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
695 | },
696 | "fsevents": {
697 | "version": "1.2.4",
698 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
699 | "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
700 | "optional": true,
701 | "requires": {
702 | "nan": "^2.9.2",
703 | "node-pre-gyp": "^0.10.0"
704 | },
705 | "dependencies": {
706 | "abbrev": {
707 | "version": "1.1.1",
708 | "bundled": true,
709 | "optional": true
710 | },
711 | "ansi-regex": {
712 | "version": "2.1.1",
713 | "bundled": true,
714 | "optional": true
715 | },
716 | "aproba": {
717 | "version": "1.2.0",
718 | "bundled": true,
719 | "optional": true
720 | },
721 | "are-we-there-yet": {
722 | "version": "1.1.4",
723 | "bundled": true,
724 | "optional": true,
725 | "requires": {
726 | "delegates": "^1.0.0",
727 | "readable-stream": "^2.0.6"
728 | }
729 | },
730 | "balanced-match": {
731 | "version": "1.0.0",
732 | "bundled": true,
733 | "optional": true
734 | },
735 | "brace-expansion": {
736 | "version": "1.1.11",
737 | "bundled": true,
738 | "optional": true,
739 | "requires": {
740 | "balanced-match": "^1.0.0",
741 | "concat-map": "0.0.1"
742 | }
743 | },
744 | "chownr": {
745 | "version": "1.0.1",
746 | "bundled": true,
747 | "optional": true
748 | },
749 | "code-point-at": {
750 | "version": "1.1.0",
751 | "bundled": true,
752 | "optional": true
753 | },
754 | "concat-map": {
755 | "version": "0.0.1",
756 | "bundled": true,
757 | "optional": true
758 | },
759 | "console-control-strings": {
760 | "version": "1.1.0",
761 | "bundled": true,
762 | "optional": true
763 | },
764 | "core-util-is": {
765 | "version": "1.0.2",
766 | "bundled": true,
767 | "optional": true
768 | },
769 | "debug": {
770 | "version": "2.6.9",
771 | "bundled": true,
772 | "optional": true,
773 | "requires": {
774 | "ms": "2.0.0"
775 | }
776 | },
777 | "deep-extend": {
778 | "version": "0.5.1",
779 | "bundled": true,
780 | "optional": true
781 | },
782 | "delegates": {
783 | "version": "1.0.0",
784 | "bundled": true,
785 | "optional": true
786 | },
787 | "detect-libc": {
788 | "version": "1.0.3",
789 | "bundled": true,
790 | "optional": true
791 | },
792 | "fs-minipass": {
793 | "version": "1.2.5",
794 | "bundled": true,
795 | "optional": true,
796 | "requires": {
797 | "minipass": "^2.2.1"
798 | }
799 | },
800 | "fs.realpath": {
801 | "version": "1.0.0",
802 | "bundled": true,
803 | "optional": true
804 | },
805 | "gauge": {
806 | "version": "2.7.4",
807 | "bundled": true,
808 | "optional": true,
809 | "requires": {
810 | "aproba": "^1.0.3",
811 | "console-control-strings": "^1.0.0",
812 | "has-unicode": "^2.0.0",
813 | "object-assign": "^4.1.0",
814 | "signal-exit": "^3.0.0",
815 | "string-width": "^1.0.1",
816 | "strip-ansi": "^3.0.1",
817 | "wide-align": "^1.1.0"
818 | }
819 | },
820 | "glob": {
821 | "version": "7.1.2",
822 | "bundled": true,
823 | "optional": true,
824 | "requires": {
825 | "fs.realpath": "^1.0.0",
826 | "inflight": "^1.0.4",
827 | "inherits": "2",
828 | "minimatch": "^3.0.4",
829 | "once": "^1.3.0",
830 | "path-is-absolute": "^1.0.0"
831 | }
832 | },
833 | "has-unicode": {
834 | "version": "2.0.1",
835 | "bundled": true,
836 | "optional": true
837 | },
838 | "iconv-lite": {
839 | "version": "0.4.21",
840 | "bundled": true,
841 | "optional": true,
842 | "requires": {
843 | "safer-buffer": "^2.1.0"
844 | }
845 | },
846 | "ignore-walk": {
847 | "version": "3.0.1",
848 | "bundled": true,
849 | "optional": true,
850 | "requires": {
851 | "minimatch": "^3.0.4"
852 | }
853 | },
854 | "inflight": {
855 | "version": "1.0.6",
856 | "bundled": true,
857 | "optional": true,
858 | "requires": {
859 | "once": "^1.3.0",
860 | "wrappy": "1"
861 | }
862 | },
863 | "inherits": {
864 | "version": "2.0.3",
865 | "bundled": true,
866 | "optional": true
867 | },
868 | "ini": {
869 | "version": "1.3.5",
870 | "bundled": true,
871 | "optional": true
872 | },
873 | "is-fullwidth-code-point": {
874 | "version": "1.0.0",
875 | "bundled": true,
876 | "optional": true,
877 | "requires": {
878 | "number-is-nan": "^1.0.0"
879 | }
880 | },
881 | "isarray": {
882 | "version": "1.0.0",
883 | "bundled": true,
884 | "optional": true
885 | },
886 | "minimatch": {
887 | "version": "3.0.4",
888 | "bundled": true,
889 | "optional": true,
890 | "requires": {
891 | "brace-expansion": "^1.1.7"
892 | }
893 | },
894 | "minimist": {
895 | "version": "0.0.8",
896 | "bundled": true,
897 | "optional": true
898 | },
899 | "minipass": {
900 | "version": "2.2.4",
901 | "bundled": true,
902 | "optional": true,
903 | "requires": {
904 | "safe-buffer": "^5.1.1",
905 | "yallist": "^3.0.0"
906 | }
907 | },
908 | "minizlib": {
909 | "version": "1.1.0",
910 | "bundled": true,
911 | "optional": true,
912 | "requires": {
913 | "minipass": "^2.2.1"
914 | }
915 | },
916 | "mkdirp": {
917 | "version": "0.5.1",
918 | "bundled": true,
919 | "optional": true,
920 | "requires": {
921 | "minimist": "0.0.8"
922 | }
923 | },
924 | "ms": {
925 | "version": "2.0.0",
926 | "bundled": true,
927 | "optional": true
928 | },
929 | "needle": {
930 | "version": "2.2.0",
931 | "bundled": true,
932 | "optional": true,
933 | "requires": {
934 | "debug": "^2.1.2",
935 | "iconv-lite": "^0.4.4",
936 | "sax": "^1.2.4"
937 | }
938 | },
939 | "node-pre-gyp": {
940 | "version": "0.10.0",
941 | "bundled": true,
942 | "optional": true,
943 | "requires": {
944 | "detect-libc": "^1.0.2",
945 | "mkdirp": "^0.5.1",
946 | "needle": "^2.2.0",
947 | "nopt": "^4.0.1",
948 | "npm-packlist": "^1.1.6",
949 | "npmlog": "^4.0.2",
950 | "rc": "^1.1.7",
951 | "rimraf": "^2.6.1",
952 | "semver": "^5.3.0",
953 | "tar": "^4"
954 | }
955 | },
956 | "nopt": {
957 | "version": "4.0.1",
958 | "bundled": true,
959 | "optional": true,
960 | "requires": {
961 | "abbrev": "1",
962 | "osenv": "^0.1.4"
963 | }
964 | },
965 | "npm-bundled": {
966 | "version": "1.0.3",
967 | "bundled": true,
968 | "optional": true
969 | },
970 | "npm-packlist": {
971 | "version": "1.1.10",
972 | "bundled": true,
973 | "optional": true,
974 | "requires": {
975 | "ignore-walk": "^3.0.1",
976 | "npm-bundled": "^1.0.1"
977 | }
978 | },
979 | "npmlog": {
980 | "version": "4.1.2",
981 | "bundled": true,
982 | "optional": true,
983 | "requires": {
984 | "are-we-there-yet": "~1.1.2",
985 | "console-control-strings": "~1.1.0",
986 | "gauge": "~2.7.3",
987 | "set-blocking": "~2.0.0"
988 | }
989 | },
990 | "number-is-nan": {
991 | "version": "1.0.1",
992 | "bundled": true,
993 | "optional": true
994 | },
995 | "object-assign": {
996 | "version": "4.1.1",
997 | "bundled": true,
998 | "optional": true
999 | },
1000 | "once": {
1001 | "version": "1.4.0",
1002 | "bundled": true,
1003 | "optional": true,
1004 | "requires": {
1005 | "wrappy": "1"
1006 | }
1007 | },
1008 | "os-homedir": {
1009 | "version": "1.0.2",
1010 | "bundled": true,
1011 | "optional": true
1012 | },
1013 | "os-tmpdir": {
1014 | "version": "1.0.2",
1015 | "bundled": true,
1016 | "optional": true
1017 | },
1018 | "osenv": {
1019 | "version": "0.1.5",
1020 | "bundled": true,
1021 | "optional": true,
1022 | "requires": {
1023 | "os-homedir": "^1.0.0",
1024 | "os-tmpdir": "^1.0.0"
1025 | }
1026 | },
1027 | "path-is-absolute": {
1028 | "version": "1.0.1",
1029 | "bundled": true,
1030 | "optional": true
1031 | },
1032 | "process-nextick-args": {
1033 | "version": "2.0.0",
1034 | "bundled": true,
1035 | "optional": true
1036 | },
1037 | "rc": {
1038 | "version": "1.2.7",
1039 | "bundled": true,
1040 | "optional": true,
1041 | "requires": {
1042 | "deep-extend": "^0.5.1",
1043 | "ini": "~1.3.0",
1044 | "minimist": "^1.2.0",
1045 | "strip-json-comments": "~2.0.1"
1046 | },
1047 | "dependencies": {
1048 | "minimist": {
1049 | "version": "1.2.0",
1050 | "bundled": true,
1051 | "optional": true
1052 | }
1053 | }
1054 | },
1055 | "readable-stream": {
1056 | "version": "2.3.6",
1057 | "bundled": true,
1058 | "optional": true,
1059 | "requires": {
1060 | "core-util-is": "~1.0.0",
1061 | "inherits": "~2.0.3",
1062 | "isarray": "~1.0.0",
1063 | "process-nextick-args": "~2.0.0",
1064 | "safe-buffer": "~5.1.1",
1065 | "string_decoder": "~1.1.1",
1066 | "util-deprecate": "~1.0.1"
1067 | }
1068 | },
1069 | "rimraf": {
1070 | "version": "2.6.2",
1071 | "bundled": true,
1072 | "optional": true,
1073 | "requires": {
1074 | "glob": "^7.0.5"
1075 | }
1076 | },
1077 | "safe-buffer": {
1078 | "version": "5.1.1",
1079 | "bundled": true,
1080 | "optional": true
1081 | },
1082 | "safer-buffer": {
1083 | "version": "2.1.2",
1084 | "bundled": true,
1085 | "optional": true
1086 | },
1087 | "sax": {
1088 | "version": "1.2.4",
1089 | "bundled": true,
1090 | "optional": true
1091 | },
1092 | "semver": {
1093 | "version": "5.5.0",
1094 | "bundled": true,
1095 | "optional": true
1096 | },
1097 | "set-blocking": {
1098 | "version": "2.0.0",
1099 | "bundled": true,
1100 | "optional": true
1101 | },
1102 | "signal-exit": {
1103 | "version": "3.0.2",
1104 | "bundled": true,
1105 | "optional": true
1106 | },
1107 | "string-width": {
1108 | "version": "1.0.2",
1109 | "bundled": true,
1110 | "optional": true,
1111 | "requires": {
1112 | "code-point-at": "^1.0.0",
1113 | "is-fullwidth-code-point": "^1.0.0",
1114 | "strip-ansi": "^3.0.0"
1115 | }
1116 | },
1117 | "string_decoder": {
1118 | "version": "1.1.1",
1119 | "bundled": true,
1120 | "optional": true,
1121 | "requires": {
1122 | "safe-buffer": "~5.1.0"
1123 | }
1124 | },
1125 | "strip-ansi": {
1126 | "version": "3.0.1",
1127 | "bundled": true,
1128 | "optional": true,
1129 | "requires": {
1130 | "ansi-regex": "^2.0.0"
1131 | }
1132 | },
1133 | "strip-json-comments": {
1134 | "version": "2.0.1",
1135 | "bundled": true,
1136 | "optional": true
1137 | },
1138 | "tar": {
1139 | "version": "4.4.1",
1140 | "bundled": true,
1141 | "optional": true,
1142 | "requires": {
1143 | "chownr": "^1.0.1",
1144 | "fs-minipass": "^1.2.5",
1145 | "minipass": "^2.2.4",
1146 | "minizlib": "^1.1.0",
1147 | "mkdirp": "^0.5.0",
1148 | "safe-buffer": "^5.1.1",
1149 | "yallist": "^3.0.2"
1150 | }
1151 | },
1152 | "util-deprecate": {
1153 | "version": "1.0.2",
1154 | "bundled": true,
1155 | "optional": true
1156 | },
1157 | "wide-align": {
1158 | "version": "1.1.2",
1159 | "bundled": true,
1160 | "optional": true,
1161 | "requires": {
1162 | "string-width": "^1.0.2"
1163 | }
1164 | },
1165 | "wrappy": {
1166 | "version": "1.0.2",
1167 | "bundled": true,
1168 | "optional": true
1169 | },
1170 | "yallist": {
1171 | "version": "3.0.2",
1172 | "bundled": true,
1173 | "optional": true
1174 | }
1175 | }
1176 | },
1177 | "fstream": {
1178 | "version": "1.0.11",
1179 | "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
1180 | "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
1181 | "requires": {
1182 | "graceful-fs": "^4.1.2",
1183 | "inherits": "~2.0.0",
1184 | "mkdirp": ">=0.5 0",
1185 | "rimraf": "2"
1186 | }
1187 | },
1188 | "get-value": {
1189 | "version": "2.0.6",
1190 | "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
1191 | "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
1192 | },
1193 | "getpass": {
1194 | "version": "0.1.7",
1195 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
1196 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
1197 | "requires": {
1198 | "assert-plus": "^1.0.0"
1199 | }
1200 | },
1201 | "glob": {
1202 | "version": "7.1.3",
1203 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
1204 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
1205 | "requires": {
1206 | "fs.realpath": "^1.0.0",
1207 | "inflight": "^1.0.4",
1208 | "inherits": "2",
1209 | "minimatch": "^3.0.4",
1210 | "once": "^1.3.0",
1211 | "path-is-absolute": "^1.0.0"
1212 | }
1213 | },
1214 | "glob-base": {
1215 | "version": "0.3.0",
1216 | "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
1217 | "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
1218 | "requires": {
1219 | "glob-parent": "^2.0.0",
1220 | "is-glob": "^2.0.0"
1221 | }
1222 | },
1223 | "glob-parent": {
1224 | "version": "2.0.0",
1225 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
1226 | "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
1227 | "requires": {
1228 | "is-glob": "^2.0.0"
1229 | }
1230 | },
1231 | "graceful-fs": {
1232 | "version": "4.1.15",
1233 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
1234 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
1235 | },
1236 | "har-schema": {
1237 | "version": "2.0.0",
1238 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
1239 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
1240 | },
1241 | "har-validator": {
1242 | "version": "5.1.3",
1243 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
1244 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
1245 | "requires": {
1246 | "ajv": "^6.5.5",
1247 | "har-schema": "^2.0.0"
1248 | }
1249 | },
1250 | "has-flag": {
1251 | "version": "2.0.0",
1252 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
1253 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
1254 | },
1255 | "has-value": {
1256 | "version": "1.0.0",
1257 | "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
1258 | "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
1259 | "requires": {
1260 | "get-value": "^2.0.6",
1261 | "has-values": "^1.0.0",
1262 | "isobject": "^3.0.0"
1263 | },
1264 | "dependencies": {
1265 | "isobject": {
1266 | "version": "3.0.1",
1267 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1268 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
1269 | }
1270 | }
1271 | },
1272 | "has-values": {
1273 | "version": "1.0.0",
1274 | "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
1275 | "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
1276 | "requires": {
1277 | "is-number": "^3.0.0",
1278 | "kind-of": "^4.0.0"
1279 | },
1280 | "dependencies": {
1281 | "is-number": {
1282 | "version": "3.0.0",
1283 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
1284 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
1285 | "requires": {
1286 | "kind-of": "^3.0.2"
1287 | },
1288 | "dependencies": {
1289 | "kind-of": {
1290 | "version": "3.2.2",
1291 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1292 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1293 | "requires": {
1294 | "is-buffer": "^1.1.5"
1295 | }
1296 | }
1297 | }
1298 | },
1299 | "kind-of": {
1300 | "version": "4.0.0",
1301 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
1302 | "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
1303 | "requires": {
1304 | "is-buffer": "^1.1.5"
1305 | }
1306 | }
1307 | }
1308 | },
1309 | "http-signature": {
1310 | "version": "1.2.0",
1311 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
1312 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
1313 | "requires": {
1314 | "assert-plus": "^1.0.0",
1315 | "jsprim": "^1.2.2",
1316 | "sshpk": "^1.7.0"
1317 | }
1318 | },
1319 | "inflight": {
1320 | "version": "1.0.6",
1321 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1322 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1323 | "requires": {
1324 | "once": "^1.3.0",
1325 | "wrappy": "1"
1326 | }
1327 | },
1328 | "inherits": {
1329 | "version": "2.0.3",
1330 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
1331 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
1332 | },
1333 | "is-accessor-descriptor": {
1334 | "version": "0.1.6",
1335 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
1336 | "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
1337 | "requires": {
1338 | "kind-of": "^3.0.2"
1339 | }
1340 | },
1341 | "is-binary-path": {
1342 | "version": "1.0.1",
1343 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
1344 | "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
1345 | "requires": {
1346 | "binary-extensions": "^1.0.0"
1347 | }
1348 | },
1349 | "is-buffer": {
1350 | "version": "1.1.6",
1351 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
1352 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
1353 | },
1354 | "is-data-descriptor": {
1355 | "version": "0.1.4",
1356 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
1357 | "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
1358 | "requires": {
1359 | "kind-of": "^3.0.2"
1360 | }
1361 | },
1362 | "is-descriptor": {
1363 | "version": "0.1.6",
1364 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
1365 | "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
1366 | "requires": {
1367 | "is-accessor-descriptor": "^0.1.6",
1368 | "is-data-descriptor": "^0.1.4",
1369 | "kind-of": "^5.0.0"
1370 | },
1371 | "dependencies": {
1372 | "kind-of": {
1373 | "version": "5.1.0",
1374 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
1375 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
1376 | }
1377 | }
1378 | },
1379 | "is-dotfile": {
1380 | "version": "1.0.3",
1381 | "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
1382 | "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
1383 | },
1384 | "is-equal-shallow": {
1385 | "version": "0.1.3",
1386 | "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
1387 | "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
1388 | "requires": {
1389 | "is-primitive": "^2.0.0"
1390 | }
1391 | },
1392 | "is-extendable": {
1393 | "version": "0.1.1",
1394 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
1395 | "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
1396 | },
1397 | "is-extglob": {
1398 | "version": "1.0.0",
1399 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
1400 | "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
1401 | },
1402 | "is-glob": {
1403 | "version": "2.0.1",
1404 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
1405 | "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
1406 | "requires": {
1407 | "is-extglob": "^1.0.0"
1408 | }
1409 | },
1410 | "is-number": {
1411 | "version": "2.1.0",
1412 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
1413 | "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
1414 | "requires": {
1415 | "kind-of": "^3.0.2"
1416 | }
1417 | },
1418 | "is-plain-object": {
1419 | "version": "2.0.4",
1420 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
1421 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
1422 | "requires": {
1423 | "isobject": "^3.0.1"
1424 | },
1425 | "dependencies": {
1426 | "isobject": {
1427 | "version": "3.0.1",
1428 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1429 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
1430 | }
1431 | }
1432 | },
1433 | "is-posix-bracket": {
1434 | "version": "0.1.1",
1435 | "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
1436 | "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
1437 | },
1438 | "is-primitive": {
1439 | "version": "2.0.0",
1440 | "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
1441 | "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
1442 | },
1443 | "is-typedarray": {
1444 | "version": "1.0.0",
1445 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
1446 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
1447 | },
1448 | "is-windows": {
1449 | "version": "1.0.2",
1450 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
1451 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
1452 | },
1453 | "isarray": {
1454 | "version": "1.0.0",
1455 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1456 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1457 | },
1458 | "isexe": {
1459 | "version": "2.0.0",
1460 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1461 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
1462 | },
1463 | "isobject": {
1464 | "version": "2.1.0",
1465 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
1466 | "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
1467 | "requires": {
1468 | "isarray": "1.0.0"
1469 | }
1470 | },
1471 | "isstream": {
1472 | "version": "0.1.2",
1473 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
1474 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
1475 | },
1476 | "jsbn": {
1477 | "version": "0.1.1",
1478 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
1479 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
1480 | },
1481 | "json-schema": {
1482 | "version": "0.2.3",
1483 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
1484 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
1485 | },
1486 | "json-schema-traverse": {
1487 | "version": "0.4.1",
1488 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1489 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
1490 | },
1491 | "json-stringify-safe": {
1492 | "version": "5.0.1",
1493 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
1494 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
1495 | },
1496 | "jsonfile": {
1497 | "version": "2.4.0",
1498 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
1499 | "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
1500 | "requires": {
1501 | "graceful-fs": "^4.1.6"
1502 | }
1503 | },
1504 | "jsprim": {
1505 | "version": "1.4.1",
1506 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
1507 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
1508 | "requires": {
1509 | "assert-plus": "1.0.0",
1510 | "extsprintf": "1.3.0",
1511 | "json-schema": "0.2.3",
1512 | "verror": "1.10.0"
1513 | }
1514 | },
1515 | "kind-of": {
1516 | "version": "3.2.2",
1517 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1518 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1519 | "requires": {
1520 | "is-buffer": "^1.1.5"
1521 | }
1522 | },
1523 | "klaw": {
1524 | "version": "1.3.1",
1525 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
1526 | "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
1527 | "requires": {
1528 | "graceful-fs": "^4.1.9"
1529 | }
1530 | },
1531 | "lodash": {
1532 | "version": "4.17.11",
1533 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
1534 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
1535 | },
1536 | "lru-cache": {
1537 | "version": "4.1.5",
1538 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
1539 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
1540 | "requires": {
1541 | "pseudomap": "^1.0.2",
1542 | "yallist": "^2.1.2"
1543 | }
1544 | },
1545 | "map-cache": {
1546 | "version": "0.2.2",
1547 | "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
1548 | "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
1549 | },
1550 | "map-visit": {
1551 | "version": "1.0.0",
1552 | "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
1553 | "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
1554 | "requires": {
1555 | "object-visit": "^1.0.0"
1556 | }
1557 | },
1558 | "math-random": {
1559 | "version": "1.0.4",
1560 | "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
1561 | "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A=="
1562 | },
1563 | "micromatch": {
1564 | "version": "2.3.11",
1565 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
1566 | "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
1567 | "requires": {
1568 | "arr-diff": "^2.0.0",
1569 | "array-unique": "^0.2.1",
1570 | "braces": "^1.8.2",
1571 | "expand-brackets": "^0.1.4",
1572 | "extglob": "^0.3.1",
1573 | "filename-regex": "^2.0.0",
1574 | "is-extglob": "^1.0.0",
1575 | "is-glob": "^2.0.1",
1576 | "kind-of": "^3.0.2",
1577 | "normalize-path": "^2.0.1",
1578 | "object.omit": "^2.0.0",
1579 | "parse-glob": "^3.0.4",
1580 | "regex-cache": "^0.4.2"
1581 | }
1582 | },
1583 | "mime-db": {
1584 | "version": "1.38.0",
1585 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
1586 | "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
1587 | },
1588 | "mime-types": {
1589 | "version": "2.1.22",
1590 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
1591 | "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
1592 | "requires": {
1593 | "mime-db": "~1.38.0"
1594 | }
1595 | },
1596 | "minimatch": {
1597 | "version": "3.0.4",
1598 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1599 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1600 | "requires": {
1601 | "brace-expansion": "^1.1.7"
1602 | }
1603 | },
1604 | "minimist": {
1605 | "version": "0.0.8",
1606 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
1607 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
1608 | },
1609 | "mixin-deep": {
1610 | "version": "1.3.1",
1611 | "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
1612 | "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
1613 | "requires": {
1614 | "for-in": "^1.0.2",
1615 | "is-extendable": "^1.0.1"
1616 | },
1617 | "dependencies": {
1618 | "is-extendable": {
1619 | "version": "1.0.1",
1620 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
1621 | "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
1622 | "requires": {
1623 | "is-plain-object": "^2.0.4"
1624 | }
1625 | }
1626 | }
1627 | },
1628 | "mkdirp": {
1629 | "version": "0.5.1",
1630 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
1631 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
1632 | "requires": {
1633 | "minimist": "0.0.8"
1634 | }
1635 | },
1636 | "ms": {
1637 | "version": "2.0.0",
1638 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1639 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1640 | },
1641 | "murmur-hash-js": {
1642 | "version": "1.0.0",
1643 | "resolved": "https://registry.npmjs.org/murmur-hash-js/-/murmur-hash-js-1.0.0.tgz",
1644 | "integrity": "sha1-UEEEkmnJZjPIZjhpYLL0KJ515bA="
1645 | },
1646 | "mustache": {
1647 | "version": "2.3.2",
1648 | "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz",
1649 | "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ=="
1650 | },
1651 | "nan": {
1652 | "version": "2.12.1",
1653 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
1654 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==",
1655 | "optional": true
1656 | },
1657 | "nanomatch": {
1658 | "version": "1.2.13",
1659 | "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
1660 | "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
1661 | "requires": {
1662 | "arr-diff": "^4.0.0",
1663 | "array-unique": "^0.3.2",
1664 | "define-property": "^2.0.2",
1665 | "extend-shallow": "^3.0.2",
1666 | "fragment-cache": "^0.2.1",
1667 | "is-windows": "^1.0.2",
1668 | "kind-of": "^6.0.2",
1669 | "object.pick": "^1.3.0",
1670 | "regex-not": "^1.0.0",
1671 | "snapdragon": "^0.8.1",
1672 | "to-regex": "^3.0.1"
1673 | },
1674 | "dependencies": {
1675 | "arr-diff": {
1676 | "version": "4.0.0",
1677 | "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
1678 | "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
1679 | },
1680 | "array-unique": {
1681 | "version": "0.3.2",
1682 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
1683 | "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
1684 | },
1685 | "kind-of": {
1686 | "version": "6.0.2",
1687 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
1688 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
1689 | }
1690 | }
1691 | },
1692 | "node-elm-compiler": {
1693 | "version": "5.0.1",
1694 | "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.1.tgz",
1695 | "integrity": "sha512-Li9NfZTL83/URoUEWly+iHJeOcZRBYUaeIL4MImnB4r21oe/xpkR6JRHjdNjLf1rMtO0tgPyOvuGW4Beytaaow==",
1696 | "requires": {
1697 | "cross-spawn": "4.0.0",
1698 | "find-elm-dependencies": "2.0.0",
1699 | "lodash": "4.17.10",
1700 | "temp": "^0.8.3"
1701 | },
1702 | "dependencies": {
1703 | "lodash": {
1704 | "version": "4.17.10",
1705 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
1706 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
1707 | }
1708 | }
1709 | },
1710 | "normalize-path": {
1711 | "version": "2.1.1",
1712 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
1713 | "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
1714 | "requires": {
1715 | "remove-trailing-separator": "^1.0.1"
1716 | }
1717 | },
1718 | "oauth-sign": {
1719 | "version": "0.9.0",
1720 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
1721 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
1722 | },
1723 | "object-copy": {
1724 | "version": "0.1.0",
1725 | "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
1726 | "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
1727 | "requires": {
1728 | "copy-descriptor": "^0.1.0",
1729 | "define-property": "^0.2.5",
1730 | "kind-of": "^3.0.3"
1731 | },
1732 | "dependencies": {
1733 | "define-property": {
1734 | "version": "0.2.5",
1735 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
1736 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
1737 | "requires": {
1738 | "is-descriptor": "^0.1.0"
1739 | }
1740 | }
1741 | }
1742 | },
1743 | "object-visit": {
1744 | "version": "1.0.1",
1745 | "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
1746 | "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
1747 | "requires": {
1748 | "isobject": "^3.0.0"
1749 | },
1750 | "dependencies": {
1751 | "isobject": {
1752 | "version": "3.0.1",
1753 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1754 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
1755 | }
1756 | }
1757 | },
1758 | "object.omit": {
1759 | "version": "2.0.1",
1760 | "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
1761 | "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
1762 | "requires": {
1763 | "for-own": "^0.1.4",
1764 | "is-extendable": "^0.1.1"
1765 | }
1766 | },
1767 | "object.pick": {
1768 | "version": "1.3.0",
1769 | "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
1770 | "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
1771 | "requires": {
1772 | "isobject": "^3.0.1"
1773 | },
1774 | "dependencies": {
1775 | "isobject": {
1776 | "version": "3.0.1",
1777 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1778 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
1779 | }
1780 | }
1781 | },
1782 | "once": {
1783 | "version": "1.4.0",
1784 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1785 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1786 | "requires": {
1787 | "wrappy": "1"
1788 | }
1789 | },
1790 | "os-tmpdir": {
1791 | "version": "1.0.2",
1792 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1793 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
1794 | },
1795 | "parse-glob": {
1796 | "version": "3.0.4",
1797 | "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
1798 | "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
1799 | "requires": {
1800 | "glob-base": "^0.3.0",
1801 | "is-dotfile": "^1.0.0",
1802 | "is-extglob": "^1.0.0",
1803 | "is-glob": "^2.0.0"
1804 | }
1805 | },
1806 | "pascalcase": {
1807 | "version": "0.1.1",
1808 | "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
1809 | "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
1810 | },
1811 | "path-is-absolute": {
1812 | "version": "1.0.1",
1813 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1814 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
1815 | },
1816 | "performance-now": {
1817 | "version": "2.1.0",
1818 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
1819 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
1820 | },
1821 | "posix-character-classes": {
1822 | "version": "0.1.1",
1823 | "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
1824 | "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
1825 | },
1826 | "preserve": {
1827 | "version": "0.2.0",
1828 | "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
1829 | "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
1830 | },
1831 | "process-nextick-args": {
1832 | "version": "2.0.0",
1833 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
1834 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
1835 | },
1836 | "pseudomap": {
1837 | "version": "1.0.2",
1838 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
1839 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
1840 | },
1841 | "psl": {
1842 | "version": "1.1.31",
1843 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
1844 | "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
1845 | },
1846 | "punycode": {
1847 | "version": "2.1.1",
1848 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1849 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
1850 | },
1851 | "qs": {
1852 | "version": "6.5.2",
1853 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
1854 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
1855 | },
1856 | "randomatic": {
1857 | "version": "3.1.1",
1858 | "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
1859 | "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==",
1860 | "requires": {
1861 | "is-number": "^4.0.0",
1862 | "kind-of": "^6.0.0",
1863 | "math-random": "^1.0.1"
1864 | },
1865 | "dependencies": {
1866 | "is-number": {
1867 | "version": "4.0.0",
1868 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
1869 | "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
1870 | },
1871 | "kind-of": {
1872 | "version": "6.0.2",
1873 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
1874 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
1875 | }
1876 | }
1877 | },
1878 | "readable-stream": {
1879 | "version": "2.3.6",
1880 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
1881 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
1882 | "requires": {
1883 | "core-util-is": "~1.0.0",
1884 | "inherits": "~2.0.3",
1885 | "isarray": "~1.0.0",
1886 | "process-nextick-args": "~2.0.0",
1887 | "safe-buffer": "~5.1.1",
1888 | "string_decoder": "~1.1.1",
1889 | "util-deprecate": "~1.0.1"
1890 | }
1891 | },
1892 | "readdirp": {
1893 | "version": "2.2.1",
1894 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
1895 | "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
1896 | "requires": {
1897 | "graceful-fs": "^4.1.11",
1898 | "micromatch": "^3.1.10",
1899 | "readable-stream": "^2.0.2"
1900 | },
1901 | "dependencies": {
1902 | "arr-diff": {
1903 | "version": "4.0.0",
1904 | "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
1905 | "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
1906 | },
1907 | "array-unique": {
1908 | "version": "0.3.2",
1909 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
1910 | "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
1911 | },
1912 | "braces": {
1913 | "version": "2.3.2",
1914 | "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
1915 | "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
1916 | "requires": {
1917 | "arr-flatten": "^1.1.0",
1918 | "array-unique": "^0.3.2",
1919 | "extend-shallow": "^2.0.1",
1920 | "fill-range": "^4.0.0",
1921 | "isobject": "^3.0.1",
1922 | "repeat-element": "^1.1.2",
1923 | "snapdragon": "^0.8.1",
1924 | "snapdragon-node": "^2.0.1",
1925 | "split-string": "^3.0.2",
1926 | "to-regex": "^3.0.1"
1927 | },
1928 | "dependencies": {
1929 | "extend-shallow": {
1930 | "version": "2.0.1",
1931 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
1932 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
1933 | "requires": {
1934 | "is-extendable": "^0.1.0"
1935 | }
1936 | }
1937 | }
1938 | },
1939 | "expand-brackets": {
1940 | "version": "2.1.4",
1941 | "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
1942 | "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
1943 | "requires": {
1944 | "debug": "^2.3.3",
1945 | "define-property": "^0.2.5",
1946 | "extend-shallow": "^2.0.1",
1947 | "posix-character-classes": "^0.1.0",
1948 | "regex-not": "^1.0.0",
1949 | "snapdragon": "^0.8.1",
1950 | "to-regex": "^3.0.1"
1951 | },
1952 | "dependencies": {
1953 | "define-property": {
1954 | "version": "0.2.5",
1955 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
1956 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
1957 | "requires": {
1958 | "is-descriptor": "^0.1.0"
1959 | }
1960 | },
1961 | "extend-shallow": {
1962 | "version": "2.0.1",
1963 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
1964 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
1965 | "requires": {
1966 | "is-extendable": "^0.1.0"
1967 | }
1968 | },
1969 | "is-accessor-descriptor": {
1970 | "version": "0.1.6",
1971 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
1972 | "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
1973 | "requires": {
1974 | "kind-of": "^3.0.2"
1975 | },
1976 | "dependencies": {
1977 | "kind-of": {
1978 | "version": "3.2.2",
1979 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1980 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1981 | "requires": {
1982 | "is-buffer": "^1.1.5"
1983 | }
1984 | }
1985 | }
1986 | },
1987 | "is-data-descriptor": {
1988 | "version": "0.1.4",
1989 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
1990 | "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
1991 | "requires": {
1992 | "kind-of": "^3.0.2"
1993 | },
1994 | "dependencies": {
1995 | "kind-of": {
1996 | "version": "3.2.2",
1997 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1998 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1999 | "requires": {
2000 | "is-buffer": "^1.1.5"
2001 | }
2002 | }
2003 | }
2004 | },
2005 | "is-descriptor": {
2006 | "version": "0.1.6",
2007 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
2008 | "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
2009 | "requires": {
2010 | "is-accessor-descriptor": "^0.1.6",
2011 | "is-data-descriptor": "^0.1.4",
2012 | "kind-of": "^5.0.0"
2013 | }
2014 | },
2015 | "kind-of": {
2016 | "version": "5.1.0",
2017 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
2018 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
2019 | }
2020 | }
2021 | },
2022 | "extglob": {
2023 | "version": "2.0.4",
2024 | "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
2025 | "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
2026 | "requires": {
2027 | "array-unique": "^0.3.2",
2028 | "define-property": "^1.0.0",
2029 | "expand-brackets": "^2.1.4",
2030 | "extend-shallow": "^2.0.1",
2031 | "fragment-cache": "^0.2.1",
2032 | "regex-not": "^1.0.0",
2033 | "snapdragon": "^0.8.1",
2034 | "to-regex": "^3.0.1"
2035 | },
2036 | "dependencies": {
2037 | "define-property": {
2038 | "version": "1.0.0",
2039 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
2040 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
2041 | "requires": {
2042 | "is-descriptor": "^1.0.0"
2043 | }
2044 | },
2045 | "extend-shallow": {
2046 | "version": "2.0.1",
2047 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
2048 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
2049 | "requires": {
2050 | "is-extendable": "^0.1.0"
2051 | }
2052 | }
2053 | }
2054 | },
2055 | "fill-range": {
2056 | "version": "4.0.0",
2057 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
2058 | "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
2059 | "requires": {
2060 | "extend-shallow": "^2.0.1",
2061 | "is-number": "^3.0.0",
2062 | "repeat-string": "^1.6.1",
2063 | "to-regex-range": "^2.1.0"
2064 | },
2065 | "dependencies": {
2066 | "extend-shallow": {
2067 | "version": "2.0.1",
2068 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
2069 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
2070 | "requires": {
2071 | "is-extendable": "^0.1.0"
2072 | }
2073 | }
2074 | }
2075 | },
2076 | "is-accessor-descriptor": {
2077 | "version": "1.0.0",
2078 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
2079 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
2080 | "requires": {
2081 | "kind-of": "^6.0.0"
2082 | }
2083 | },
2084 | "is-data-descriptor": {
2085 | "version": "1.0.0",
2086 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
2087 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
2088 | "requires": {
2089 | "kind-of": "^6.0.0"
2090 | }
2091 | },
2092 | "is-descriptor": {
2093 | "version": "1.0.2",
2094 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
2095 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
2096 | "requires": {
2097 | "is-accessor-descriptor": "^1.0.0",
2098 | "is-data-descriptor": "^1.0.0",
2099 | "kind-of": "^6.0.2"
2100 | }
2101 | },
2102 | "is-number": {
2103 | "version": "3.0.0",
2104 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
2105 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
2106 | "requires": {
2107 | "kind-of": "^3.0.2"
2108 | },
2109 | "dependencies": {
2110 | "kind-of": {
2111 | "version": "3.2.2",
2112 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
2113 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
2114 | "requires": {
2115 | "is-buffer": "^1.1.5"
2116 | }
2117 | }
2118 | }
2119 | },
2120 | "isobject": {
2121 | "version": "3.0.1",
2122 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
2123 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
2124 | },
2125 | "kind-of": {
2126 | "version": "6.0.2",
2127 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
2128 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
2129 | },
2130 | "micromatch": {
2131 | "version": "3.1.10",
2132 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
2133 | "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
2134 | "requires": {
2135 | "arr-diff": "^4.0.0",
2136 | "array-unique": "^0.3.2",
2137 | "braces": "^2.3.1",
2138 | "define-property": "^2.0.2",
2139 | "extend-shallow": "^3.0.2",
2140 | "extglob": "^2.0.4",
2141 | "fragment-cache": "^0.2.1",
2142 | "kind-of": "^6.0.2",
2143 | "nanomatch": "^1.2.9",
2144 | "object.pick": "^1.3.0",
2145 | "regex-not": "^1.0.0",
2146 | "snapdragon": "^0.8.1",
2147 | "to-regex": "^3.0.2"
2148 | }
2149 | }
2150 | }
2151 | },
2152 | "regex-cache": {
2153 | "version": "0.4.4",
2154 | "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
2155 | "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
2156 | "requires": {
2157 | "is-equal-shallow": "^0.1.3"
2158 | }
2159 | },
2160 | "regex-not": {
2161 | "version": "1.0.2",
2162 | "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
2163 | "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
2164 | "requires": {
2165 | "extend-shallow": "^3.0.2",
2166 | "safe-regex": "^1.1.0"
2167 | }
2168 | },
2169 | "remove-trailing-separator": {
2170 | "version": "1.1.0",
2171 | "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
2172 | "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
2173 | },
2174 | "repeat-element": {
2175 | "version": "1.1.3",
2176 | "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
2177 | "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
2178 | },
2179 | "repeat-string": {
2180 | "version": "1.6.1",
2181 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
2182 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
2183 | },
2184 | "request": {
2185 | "version": "2.88.0",
2186 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
2187 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
2188 | "requires": {
2189 | "aws-sign2": "~0.7.0",
2190 | "aws4": "^1.8.0",
2191 | "caseless": "~0.12.0",
2192 | "combined-stream": "~1.0.6",
2193 | "extend": "~3.0.2",
2194 | "forever-agent": "~0.6.1",
2195 | "form-data": "~2.3.2",
2196 | "har-validator": "~5.1.0",
2197 | "http-signature": "~1.2.0",
2198 | "is-typedarray": "~1.0.0",
2199 | "isstream": "~0.1.2",
2200 | "json-stringify-safe": "~5.0.1",
2201 | "mime-types": "~2.1.19",
2202 | "oauth-sign": "~0.9.0",
2203 | "performance-now": "^2.1.0",
2204 | "qs": "~6.5.2",
2205 | "safe-buffer": "^5.1.2",
2206 | "tough-cookie": "~2.4.3",
2207 | "tunnel-agent": "^0.6.0",
2208 | "uuid": "^3.3.2"
2209 | }
2210 | },
2211 | "request-promise": {
2212 | "version": "4.2.4",
2213 | "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz",
2214 | "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==",
2215 | "requires": {
2216 | "bluebird": "^3.5.0",
2217 | "request-promise-core": "1.1.2",
2218 | "stealthy-require": "^1.1.1",
2219 | "tough-cookie": "^2.3.3"
2220 | }
2221 | },
2222 | "request-promise-core": {
2223 | "version": "1.1.2",
2224 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
2225 | "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
2226 | "requires": {
2227 | "lodash": "^4.17.11"
2228 | }
2229 | },
2230 | "resolve-url": {
2231 | "version": "0.2.1",
2232 | "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
2233 | "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
2234 | },
2235 | "ret": {
2236 | "version": "0.1.15",
2237 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
2238 | "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
2239 | },
2240 | "rimraf": {
2241 | "version": "2.6.3",
2242 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
2243 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
2244 | "requires": {
2245 | "glob": "^7.1.3"
2246 | }
2247 | },
2248 | "safe-buffer": {
2249 | "version": "5.1.2",
2250 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2251 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
2252 | },
2253 | "safe-regex": {
2254 | "version": "1.1.0",
2255 | "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
2256 | "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
2257 | "requires": {
2258 | "ret": "~0.1.10"
2259 | }
2260 | },
2261 | "safer-buffer": {
2262 | "version": "2.1.2",
2263 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2264 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
2265 | },
2266 | "set-value": {
2267 | "version": "2.0.0",
2268 | "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
2269 | "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
2270 | "requires": {
2271 | "extend-shallow": "^2.0.1",
2272 | "is-extendable": "^0.1.1",
2273 | "is-plain-object": "^2.0.3",
2274 | "split-string": "^3.0.1"
2275 | },
2276 | "dependencies": {
2277 | "extend-shallow": {
2278 | "version": "2.0.1",
2279 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
2280 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
2281 | "requires": {
2282 | "is-extendable": "^0.1.0"
2283 | }
2284 | }
2285 | }
2286 | },
2287 | "snapdragon": {
2288 | "version": "0.8.2",
2289 | "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
2290 | "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
2291 | "requires": {
2292 | "base": "^0.11.1",
2293 | "debug": "^2.2.0",
2294 | "define-property": "^0.2.5",
2295 | "extend-shallow": "^2.0.1",
2296 | "map-cache": "^0.2.2",
2297 | "source-map": "^0.5.6",
2298 | "source-map-resolve": "^0.5.0",
2299 | "use": "^3.1.0"
2300 | },
2301 | "dependencies": {
2302 | "define-property": {
2303 | "version": "0.2.5",
2304 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
2305 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
2306 | "requires": {
2307 | "is-descriptor": "^0.1.0"
2308 | }
2309 | },
2310 | "extend-shallow": {
2311 | "version": "2.0.1",
2312 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
2313 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
2314 | "requires": {
2315 | "is-extendable": "^0.1.0"
2316 | }
2317 | }
2318 | }
2319 | },
2320 | "snapdragon-node": {
2321 | "version": "2.1.1",
2322 | "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
2323 | "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
2324 | "requires": {
2325 | "define-property": "^1.0.0",
2326 | "isobject": "^3.0.0",
2327 | "snapdragon-util": "^3.0.1"
2328 | },
2329 | "dependencies": {
2330 | "define-property": {
2331 | "version": "1.0.0",
2332 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
2333 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
2334 | "requires": {
2335 | "is-descriptor": "^1.0.0"
2336 | }
2337 | },
2338 | "is-accessor-descriptor": {
2339 | "version": "1.0.0",
2340 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
2341 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
2342 | "requires": {
2343 | "kind-of": "^6.0.0"
2344 | }
2345 | },
2346 | "is-data-descriptor": {
2347 | "version": "1.0.0",
2348 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
2349 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
2350 | "requires": {
2351 | "kind-of": "^6.0.0"
2352 | }
2353 | },
2354 | "is-descriptor": {
2355 | "version": "1.0.2",
2356 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
2357 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
2358 | "requires": {
2359 | "is-accessor-descriptor": "^1.0.0",
2360 | "is-data-descriptor": "^1.0.0",
2361 | "kind-of": "^6.0.2"
2362 | }
2363 | },
2364 | "isobject": {
2365 | "version": "3.0.1",
2366 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
2367 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
2368 | },
2369 | "kind-of": {
2370 | "version": "6.0.2",
2371 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
2372 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
2373 | }
2374 | }
2375 | },
2376 | "snapdragon-util": {
2377 | "version": "3.0.1",
2378 | "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
2379 | "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
2380 | "requires": {
2381 | "kind-of": "^3.2.0"
2382 | }
2383 | },
2384 | "source-map": {
2385 | "version": "0.5.7",
2386 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2387 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
2388 | },
2389 | "source-map-resolve": {
2390 | "version": "0.5.2",
2391 | "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
2392 | "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
2393 | "requires": {
2394 | "atob": "^2.1.1",
2395 | "decode-uri-component": "^0.2.0",
2396 | "resolve-url": "^0.2.1",
2397 | "source-map-url": "^0.4.0",
2398 | "urix": "^0.1.0"
2399 | }
2400 | },
2401 | "source-map-url": {
2402 | "version": "0.4.0",
2403 | "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
2404 | "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
2405 | },
2406 | "split": {
2407 | "version": "1.0.1",
2408 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
2409 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
2410 | "requires": {
2411 | "through": "2"
2412 | }
2413 | },
2414 | "split-string": {
2415 | "version": "3.1.0",
2416 | "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
2417 | "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
2418 | "requires": {
2419 | "extend-shallow": "^3.0.0"
2420 | }
2421 | },
2422 | "sshpk": {
2423 | "version": "1.16.1",
2424 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
2425 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
2426 | "requires": {
2427 | "asn1": "~0.2.3",
2428 | "assert-plus": "^1.0.0",
2429 | "bcrypt-pbkdf": "^1.0.0",
2430 | "dashdash": "^1.12.0",
2431 | "ecc-jsbn": "~0.1.1",
2432 | "getpass": "^0.1.1",
2433 | "jsbn": "~0.1.0",
2434 | "safer-buffer": "^2.0.2",
2435 | "tweetnacl": "~0.14.0"
2436 | }
2437 | },
2438 | "static-extend": {
2439 | "version": "0.1.2",
2440 | "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
2441 | "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
2442 | "requires": {
2443 | "define-property": "^0.2.5",
2444 | "object-copy": "^0.1.0"
2445 | },
2446 | "dependencies": {
2447 | "define-property": {
2448 | "version": "0.2.5",
2449 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
2450 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
2451 | "requires": {
2452 | "is-descriptor": "^0.1.0"
2453 | }
2454 | }
2455 | }
2456 | },
2457 | "stealthy-require": {
2458 | "version": "1.1.1",
2459 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
2460 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
2461 | },
2462 | "string_decoder": {
2463 | "version": "1.1.1",
2464 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
2465 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2466 | "requires": {
2467 | "safe-buffer": "~5.1.0"
2468 | }
2469 | },
2470 | "supports-color": {
2471 | "version": "4.2.0",
2472 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.0.tgz",
2473 | "integrity": "sha512-Ts0Mu/A1S1aZxEJNG88I4Oc9rcZSBFNac5e27yh4j2mqbhZSSzR1Ah79EYwSn9Zuh7lrlGD2cVGzw1RKGzyLSg==",
2474 | "requires": {
2475 | "has-flag": "^2.0.0"
2476 | }
2477 | },
2478 | "tar": {
2479 | "version": "2.2.1",
2480 | "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
2481 | "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
2482 | "requires": {
2483 | "block-stream": "*",
2484 | "fstream": "^1.0.2",
2485 | "inherits": "2"
2486 | }
2487 | },
2488 | "temp": {
2489 | "version": "0.8.3",
2490 | "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
2491 | "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
2492 | "requires": {
2493 | "os-tmpdir": "^1.0.0",
2494 | "rimraf": "~2.2.6"
2495 | },
2496 | "dependencies": {
2497 | "rimraf": {
2498 | "version": "2.2.8",
2499 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
2500 | "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
2501 | }
2502 | }
2503 | },
2504 | "through": {
2505 | "version": "2.3.8",
2506 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
2507 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
2508 | },
2509 | "to-object-path": {
2510 | "version": "0.3.0",
2511 | "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
2512 | "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
2513 | "requires": {
2514 | "kind-of": "^3.0.2"
2515 | }
2516 | },
2517 | "to-regex": {
2518 | "version": "3.0.2",
2519 | "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
2520 | "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
2521 | "requires": {
2522 | "define-property": "^2.0.2",
2523 | "extend-shallow": "^3.0.2",
2524 | "regex-not": "^1.0.2",
2525 | "safe-regex": "^1.1.0"
2526 | }
2527 | },
2528 | "to-regex-range": {
2529 | "version": "2.1.1",
2530 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
2531 | "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
2532 | "requires": {
2533 | "is-number": "^3.0.0",
2534 | "repeat-string": "^1.6.1"
2535 | },
2536 | "dependencies": {
2537 | "is-number": {
2538 | "version": "3.0.0",
2539 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
2540 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
2541 | "requires": {
2542 | "kind-of": "^3.0.2"
2543 | }
2544 | }
2545 | }
2546 | },
2547 | "tough-cookie": {
2548 | "version": "2.4.3",
2549 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
2550 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
2551 | "requires": {
2552 | "psl": "^1.1.24",
2553 | "punycode": "^1.4.1"
2554 | },
2555 | "dependencies": {
2556 | "punycode": {
2557 | "version": "1.4.1",
2558 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
2559 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
2560 | }
2561 | }
2562 | },
2563 | "traverse": {
2564 | "version": "0.3.9",
2565 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
2566 | "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
2567 | },
2568 | "tunnel-agent": {
2569 | "version": "0.6.0",
2570 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
2571 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
2572 | "requires": {
2573 | "safe-buffer": "^5.0.1"
2574 | }
2575 | },
2576 | "tweetnacl": {
2577 | "version": "0.14.5",
2578 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
2579 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
2580 | },
2581 | "union-value": {
2582 | "version": "1.0.0",
2583 | "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
2584 | "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
2585 | "requires": {
2586 | "arr-union": "^3.1.0",
2587 | "get-value": "^2.0.6",
2588 | "is-extendable": "^0.1.1",
2589 | "set-value": "^0.4.3"
2590 | },
2591 | "dependencies": {
2592 | "extend-shallow": {
2593 | "version": "2.0.1",
2594 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
2595 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
2596 | "requires": {
2597 | "is-extendable": "^0.1.0"
2598 | }
2599 | },
2600 | "set-value": {
2601 | "version": "0.4.3",
2602 | "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
2603 | "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
2604 | "requires": {
2605 | "extend-shallow": "^2.0.1",
2606 | "is-extendable": "^0.1.1",
2607 | "is-plain-object": "^2.0.1",
2608 | "to-object-path": "^0.3.0"
2609 | }
2610 | }
2611 | }
2612 | },
2613 | "unset-value": {
2614 | "version": "1.0.0",
2615 | "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
2616 | "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
2617 | "requires": {
2618 | "has-value": "^0.3.1",
2619 | "isobject": "^3.0.0"
2620 | },
2621 | "dependencies": {
2622 | "has-value": {
2623 | "version": "0.3.1",
2624 | "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
2625 | "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
2626 | "requires": {
2627 | "get-value": "^2.0.3",
2628 | "has-values": "^0.1.4",
2629 | "isobject": "^2.0.0"
2630 | },
2631 | "dependencies": {
2632 | "isobject": {
2633 | "version": "2.1.0",
2634 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
2635 | "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
2636 | "requires": {
2637 | "isarray": "1.0.0"
2638 | }
2639 | }
2640 | }
2641 | },
2642 | "has-values": {
2643 | "version": "0.1.4",
2644 | "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
2645 | "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
2646 | },
2647 | "isobject": {
2648 | "version": "3.0.1",
2649 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
2650 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
2651 | }
2652 | }
2653 | },
2654 | "unzip-stream": {
2655 | "version": "0.3.0",
2656 | "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.0.tgz",
2657 | "integrity": "sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==",
2658 | "requires": {
2659 | "binary": "^0.3.0",
2660 | "mkdirp": "^0.5.1"
2661 | }
2662 | },
2663 | "uri-js": {
2664 | "version": "4.2.2",
2665 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
2666 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
2667 | "requires": {
2668 | "punycode": "^2.1.0"
2669 | }
2670 | },
2671 | "urix": {
2672 | "version": "0.1.0",
2673 | "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
2674 | "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
2675 | },
2676 | "use": {
2677 | "version": "3.1.1",
2678 | "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
2679 | "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
2680 | },
2681 | "util-deprecate": {
2682 | "version": "1.0.2",
2683 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2684 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
2685 | },
2686 | "uuid": {
2687 | "version": "3.3.2",
2688 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
2689 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
2690 | },
2691 | "verror": {
2692 | "version": "1.10.0",
2693 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
2694 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
2695 | "requires": {
2696 | "assert-plus": "^1.0.0",
2697 | "core-util-is": "1.0.2",
2698 | "extsprintf": "^1.2.0"
2699 | }
2700 | },
2701 | "which": {
2702 | "version": "1.3.1",
2703 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2704 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2705 | "requires": {
2706 | "isexe": "^2.0.0"
2707 | }
2708 | },
2709 | "wrappy": {
2710 | "version": "1.0.2",
2711 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2712 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
2713 | },
2714 | "xmlbuilder": {
2715 | "version": "8.2.2",
2716 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
2717 | "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M="
2718 | },
2719 | "yallist": {
2720 | "version": "2.1.2",
2721 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
2722 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
2723 | }
2724 | }
2725 | }
2726 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "string-extra",
3 | "version": "1.4.0",
4 | "description": "String helper functions for Elm",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "tests"
8 | },
9 | "scripts": {
10 | "test": "elm-test"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/elm-community/string-extra.git"
15 | },
16 | "author": "",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/elm-community/string-extra/issues"
20 | },
21 | "homepage": "https://github.com/elm-community/string-extra#readme",
22 | "dependencies": {
23 | "elm": "0.19.0-bugfix6",
24 | "elm-test": "0.19.0-rev5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/String/Extra.elm:
--------------------------------------------------------------------------------
1 | module String.Extra exposing
2 | ( toSentenceCase, toTitleCase, decapitalize
3 | , camelize, classify, underscored, dasherize, humanize
4 | , replaceSlice, insertAt, nonEmpty, nonBlank, removeAccents
5 | , break, softBreak
6 | , wrap, wrapWith, softWrap, softWrapWith, quote, surround
7 | , isBlank, countOccurrences
8 | , clean, unquote, unsurround, unindent, ellipsis, softEllipsis, ellipsisWith, stripTags, pluralize
9 | , toSentence, toSentenceOxford
10 | , rightOf, leftOf, rightOfBack, leftOfBack
11 | , toCodePoints, fromCodePoints
12 | )
13 |
14 | {-| Additional functions for working with Strings
15 |
16 |
17 | ## Change words casing
18 |
19 | @docs toSentenceCase, toTitleCase, decapitalize
20 |
21 |
22 | ## Inflector functions
23 |
24 | Functions borrowed from the Rails Inflector class
25 |
26 | @docs camelize, classify, underscored, dasherize, humanize
27 |
28 |
29 | ## Replace and Splice
30 |
31 | @docs replaceSlice, insertAt, nonEmpty, nonBlank, removeAccents
32 |
33 |
34 | ## Splitting
35 |
36 | @docs break, softBreak
37 |
38 |
39 | ## Wrapping
40 |
41 | @docs wrap, wrapWith, softWrap, softWrapWith, quote, surround
42 |
43 |
44 | ## Checks
45 |
46 | @docs isBlank, countOccurrences
47 |
48 |
49 | ## Formatting
50 |
51 | @docs clean, unquote, unsurround, unindent, ellipsis, softEllipsis, ellipsisWith, stripTags, pluralize
52 |
53 |
54 | ## Converting Lists
55 |
56 | @docs toSentence, toSentenceOxford
57 |
58 |
59 | ## Finding
60 |
61 | @docs rightOf, leftOf, rightOfBack, leftOfBack
62 |
63 |
64 | ## Converting UTF-32
65 |
66 | @docs toCodePoints, fromCodePoints
67 |
68 | -}
69 |
70 | import Char exposing (toLower, toUpper)
71 | import List
72 | import Maybe exposing (Maybe(..))
73 | import Regex exposing (Regex)
74 | import String exposing (cons, join, uncons)
75 | import Tuple
76 |
77 |
78 | {-| Change the case of the first letter of a string to either uppercase or
79 | lowercase, depending of the value of `wantedCase`. This is an internal
80 | function for use in `toSentenceCase` and `decapitalize`.
81 | -}
82 | changeCase : (Char -> Char) -> String -> String
83 | changeCase mutator word =
84 | uncons word
85 | |> Maybe.map (\( head, tail ) -> cons (mutator head) tail)
86 | |> Maybe.withDefault ""
87 |
88 |
89 | {-| Capitalize the first letter of a string.
90 |
91 | toSentenceCase "this is a phrase" == "This is a phrase"
92 |
93 | toSentenceCase "hello, world" == "Hello, world"
94 |
95 | -}
96 | toSentenceCase : String -> String
97 | toSentenceCase word =
98 | changeCase toUpper word
99 |
100 |
101 | {-| Decapitalize the first letter of a string.
102 |
103 | decapitalize "This is a phrase" == "this is a phrase"
104 |
105 | decapitalize "Hello, World" == "hello, World"
106 |
107 | -}
108 | decapitalize : String -> String
109 | decapitalize word =
110 | changeCase toLower word
111 |
112 |
113 | {-| Capitalize the first character of each word in a string.
114 |
115 | toTitleCase "this is a phrase" == "This Is A Phrase"
116 |
117 | toTitleCase "hello, world" == "Hello, World"
118 |
119 | -}
120 | toTitleCase : String -> String
121 | toTitleCase ws =
122 | let
123 | uppercaseMatch =
124 | Regex.replace (regexFromString "\\w+") (.match >> toSentenceCase)
125 | in
126 | ws
127 | |> Regex.replace
128 | (regexFromString "^([a-z])|\\s+([a-z])")
129 | (.match >> uppercaseMatch)
130 |
131 |
132 | {-| Replace text within a portion of a string given a substitution
133 | string, a start index and an end index. The substitution includes the character
134 | at the start index but not the one at the end index.
135 |
136 | replaceSlice "Sue" 4 7 "Hi, Bob" == "Hi, Sue"
137 |
138 | replaceSlice "elephants" 0 6 "snakes on a plane!" == "elephants on a plane!"
139 |
140 | replaceSlice "under" 7 9 "snakes on a plane!" == "snakes under a plane!"
141 |
142 | -}
143 | replaceSlice : String -> Int -> Int -> String -> String
144 | replaceSlice substitution start end string =
145 | String.slice 0 start string ++ substitution ++ String.slice end (String.length string) string
146 |
147 |
148 | {-| Insert a substring at the specified index.
149 |
150 | insertAt "world" 6 "Hello " == "Hello world"
151 |
152 | -}
153 | insertAt : String -> Int -> String -> String
154 | insertAt insert pos string =
155 | replaceSlice insert pos pos string
156 |
157 |
158 | {-| Break a string into a list of strings of a specified maximum length.
159 |
160 | break 10 "The quick brown fox" == [ "The quick ", "brown fox" ]
161 |
162 | break 2 "" == [ "" ]
163 |
164 | -}
165 | break : Int -> String -> List String
166 | break width string =
167 | if width == 0 || string == "" then
168 | [ string ]
169 |
170 | else
171 | breaker width string []
172 |
173 |
174 | breaker : Int -> String -> List String -> List String
175 | breaker width string acc =
176 | case string of
177 | "" ->
178 | List.reverse acc
179 |
180 | _ ->
181 | breaker width
182 | (String.dropLeft width string)
183 | (String.slice 0 width string :: acc)
184 |
185 |
186 | {-| Break a string into a list of strings of a specified maximum length,
187 | without truncating words.
188 |
189 | softBreak 6 "The quick brown fox" == [ "The quick", " brown", " fox" ]
190 |
191 | -}
192 | softBreak : Int -> String -> List String
193 | softBreak width string =
194 | if width <= 0 then
195 | []
196 |
197 | else
198 | string
199 | |> Regex.find (softBreakRegexp width)
200 | |> List.map .match
201 |
202 |
203 | softBreakRegexp : Int -> Regex.Regex
204 | softBreakRegexp width =
205 | regexFromString <| ".{1," ++ String.fromInt width ++ "}(\\s+|$)|\\S+?(\\s+|$)"
206 |
207 |
208 | {-| Trim the whitespace of both sides of the string and compress
209 | repeated whitespace internally to a single whitespace char.
210 |
211 | clean " The quick brown fox " == "The quick brown fox"
212 |
213 | -}
214 | clean : String -> String
215 | clean string =
216 | string
217 | |> Regex.replace (regexFromString "\\s\\s+") (always " ")
218 | |> String.trim
219 |
220 |
221 | {-| Test if a string is empty or only contains whitespace.
222 |
223 | isBlank "" == True
224 |
225 | isBlank "\n" == True
226 |
227 | isBlank " " == True
228 |
229 | isBlank " a" == False
230 |
231 | -}
232 | isBlank : String -> Bool
233 | isBlank string =
234 | Regex.contains (regexFromString "^\\s*$") string
235 |
236 |
237 | {-| Convert an underscored or dasherized string to a camelized one.
238 |
239 | camelize "-moz-transform" == "MozTransform"
240 |
241 | -}
242 | camelize : String -> String
243 | camelize string =
244 | Regex.replace
245 | (regexFromString "[-_\\s]+(.)?")
246 | (\{ submatches } ->
247 | case submatches of
248 | (Just match) :: _ ->
249 | String.toUpper match
250 |
251 | _ ->
252 | ""
253 | )
254 | (String.trim string)
255 |
256 |
257 | {-| Convert a string to a camelized string starting with an uppercase letter.
258 | All non-word characters will be stripped out of the original string.
259 |
260 | classify "some_class_name" == "SomeClassName"
261 |
262 | classify "myLittleCamel.class.name" == "MyLittleCamelClassName"
263 |
264 | -}
265 | classify : String -> String
266 | classify string =
267 | string
268 | |> Regex.replace (regexFromString "[\\W_]") (always " ")
269 | |> camelize
270 | |> String.replace " " ""
271 | |> toSentenceCase
272 |
273 |
274 | {-| Surround a string with another string.
275 |
276 | surround "bar" "foo" == "barfoobar"
277 |
278 | -}
279 | surround : String -> String -> String
280 | surround wrapper string =
281 | wrapper ++ string ++ wrapper
282 |
283 |
284 | {-| Remove surrounding strings from another string.
285 |
286 | unsurround "foo" "foobarfoo" == "bar"
287 |
288 | -}
289 | unsurround : String -> String -> String
290 | unsurround wrapper string =
291 | if String.startsWith wrapper string && String.endsWith wrapper string then
292 | let
293 | length =
294 | String.length wrapper
295 | in
296 | string
297 | |> String.dropLeft length
298 | |> String.dropRight length
299 |
300 | else
301 | string
302 |
303 |
304 | {-| Add quotes to a string.
305 |
306 | quote "foo" == "\"foo\""
307 |
308 | -}
309 | quote : String -> String
310 | quote string =
311 | surround "\"" string
312 |
313 |
314 | {-| Remove quotes that surround a string.
315 |
316 | unquote "\"foo\"" == "foo"
317 |
318 | unquote "\"foo\"bar\""
319 |
320 | -}
321 | unquote : String -> String
322 | unquote string =
323 | unsurround "\"" string
324 |
325 |
326 | {-| Return a string joined by underscores after separating it by its uppercase characters.
327 | Any sequence of spaces or dashes will also be converted to a single underscore.
328 | The final string will be lowercased.
329 |
330 | underscored "SomeClassName" == "some_class_name"
331 | underscored "some-class-name" == "some_class_name"
332 | underscored "SomeClass name" == "some_class_name
333 |
334 | -}
335 | underscored : String -> String
336 | underscored string =
337 | string
338 | |> String.trim
339 | |> Regex.replace (regexFromString "([a-z\\d])([A-Z]+)") (.submatches >> List.filterMap identity >> String.join "_")
340 | |> Regex.replace (regexFromString "[_-\\s]+") (always "_")
341 | |> String.toLower
342 |
343 |
344 | {-| Return a string joined by dashes after separating it by its uppercase characters.
345 | Any sequence of spaces or underscores will also be converted to a single dash.
346 | The final string will be lowercased.
347 |
348 | dasherize "SomeClassName" == "-some-class-name"
349 | dasherize "some_class_name" = "some-class-name"
350 | dasherize "someClass name" = "some-class-name"
351 |
352 | -}
353 | dasherize : String -> String
354 | dasherize string =
355 | string
356 | |> String.trim
357 | |> Regex.replace (regexFromString "([A-Z])") (.match >> String.append "-")
358 | |> Regex.replace (regexFromString "[_-\\s]+") (always "-")
359 | |> String.toLower
360 |
361 |
362 | {-| Separate a string into parts of a given width, using a given separator.
363 |
364 | Look at `wrap` if you just want to wrap using newlines.
365 |
366 | wrapWith 7 "\n" "My very long text" === "My very\nlong text"
367 |
368 | wrapWith 100 "\n" "Too short" === "Too short"
369 |
370 | -}
371 | wrapWith : Int -> String -> String -> String
372 | wrapWith width separator string =
373 | string
374 | |> break width
375 | |> String.join separator
376 |
377 |
378 | {-| Chop a given string into parts of a given width, separating them with a
379 | new line.
380 |
381 | wrap 7 "My very long text" === "My very\nlong te\nxt"
382 |
383 | wrap 100 "Too short" === "Too short"
384 |
385 | -}
386 | wrap : Int -> String -> String
387 | wrap width string =
388 | wrapWith width "\n" string
389 |
390 |
391 | {-| Chop a given string into parts of a given width without breaking words apart,
392 | and then separate them using a new line.
393 |
394 | softWrap 7 "My very long text" === "My very\nlong text"
395 |
396 | softWrap 3 "Hello World" === "Hello \nWorld"
397 |
398 | softWrap 100 "Too short" === "Too short"
399 |
400 | -}
401 | softWrap : Int -> String -> String
402 | softWrap width string =
403 | softWrapWith width "\n" string
404 |
405 |
406 | {-| Chop a given string into parts of a given width without breaking words apart,
407 | and then separate them using the given separator.
408 |
409 | softWrapWith 7 "..." "My very long text" === "My very...long text"
410 |
411 | softWrapWith 3 "\n" "Hello World" === "Hello \nWorld"
412 |
413 | softWrapWith 100 "\t" "Too short" === "Too short"
414 |
415 | -}
416 | softWrapWith : Int -> String -> String -> String
417 | softWrapWith width separator string =
418 | string
419 | |> softBreak width
420 | |> String.join separator
421 |
422 |
423 | {-| Convert an underscored, camelized, or dasherized string into one that can be
424 | read by humans. Also remove beginning and ending whitespace, and removes the
425 | postfix '\_id'. The first character will be capitalized.
426 |
427 | humanize "this_is_great" == "This is great"
428 | humanize "ThisIsGreat" = "This is great"
429 | humanize "this-is-great" = "This is great"
430 | humanize "author_id" = "Author"
431 |
432 | -}
433 | humanize : String -> String
434 | humanize string =
435 | string
436 | |> Regex.replace (regexFromString "[A-Z]+") (.match >> String.append "-")
437 | |> Regex.replace (regexFromString "_id$|[-_\\s]+") (always " ")
438 | |> String.trim
439 | |> String.toLower
440 | |> toSentenceCase
441 |
442 |
443 | {-| Remove the shortest sequence of leading spaces or tabs on each line
444 | of the string, so that at least one of the lines will not have any
445 | leading spaces nor tabs and the rest of the lines will have the same
446 | amount of indentation removed.
447 |
448 | unindent " Hello\n World " == "Hello\n World"
449 |
450 | unindent "\t\tHello\n\t\t\t\tWorld" == "Hello\n\t\tWorld"
451 |
452 | -}
453 | unindent : String -> String
454 | unindent multilineSting =
455 | let
456 | lines =
457 | String.lines multilineSting
458 |
459 | countLeadingWhitespace count line =
460 | case String.uncons line of
461 | Nothing ->
462 | count
463 |
464 | Just ( char, rest ) ->
465 | case char of
466 | ' ' ->
467 | countLeadingWhitespace (count + 1) rest
468 |
469 | '\t' ->
470 | countLeadingWhitespace (count + 1) rest
471 |
472 | _ ->
473 | count
474 |
475 | isNotWhitespace char =
476 | char /= ' ' && char /= '\t'
477 |
478 | minLead =
479 | lines
480 | |> List.filter (String.any isNotWhitespace)
481 | |> List.map (countLeadingWhitespace 0)
482 | |> List.minimum
483 | |> Maybe.withDefault 0
484 | in
485 | lines
486 | |> List.map (String.dropLeft minLead)
487 | |> String.join "\n"
488 |
489 |
490 | {-| Return the number of occurrences of a substring in another string.
491 |
492 | countOccurrences "Hello" "Hello World" == 1
493 |
494 | countOccurrences "o" "Hello World" == 2
495 |
496 | -}
497 | countOccurrences : String -> String -> Int
498 | countOccurrences needle haystack =
499 | if String.length needle == 0 || String.length haystack == 0 then
500 | 0
501 |
502 | else
503 | haystack
504 | |> String.indexes needle
505 | |> List.length
506 |
507 |
508 | {-| Truncate the second string at the specified length if the string is
509 | longer than the specified length, and replace the end of the truncated
510 | string with the first string, such that the resulting string is of the
511 | specified length.
512 |
513 | The resulting string will have at most the specified length.
514 |
515 | ellipsisWith 5 " .." "Hello World" == "He .."
516 |
517 | ellipsisWith 10 " .." "Hello World" == "Hello W .."
518 |
519 | ellipsisWith 10 " .." "Hello" == "Hello"
520 |
521 | ellipsisWith 8 " .." "Hello World" == "Hello .."
522 |
523 | -}
524 | ellipsisWith : Int -> String -> String -> String
525 | ellipsisWith howLong append string =
526 | if String.length string <= howLong then
527 | string
528 |
529 | else
530 | String.left (howLong - String.length append) string ++ append
531 |
532 |
533 | {-| Truncate the string at the specified length if the string is
534 | longer than the specified length, and replace the end of the truncated
535 | string with `"..."`, such that the resulting string is of the
536 | specified length.
537 |
538 | The resulting string will have at most the specified length.
539 |
540 | ellipsis 5 "Hello World" == "He..."
541 |
542 | ellipsis 10 "Hello World" == "Hello W..."
543 |
544 | ellipsis 10 "Hello" == "Hello"
545 |
546 | ellipsis 8 "Hello World" == "Hello..."
547 |
548 | -}
549 | ellipsis : Int -> String -> String
550 | ellipsis howLong string =
551 | ellipsisWith howLong "..." string
552 |
553 |
554 | {-| Truncate the string at the last complete word less than or equal to
555 | the specified length and append `"..."`. When the specified length is
556 | less than the length of the first word, the ellipsis is appended to the
557 | first word. When the specified length is greater than or equal to the
558 | length of the string, an identical string is returned.
559 |
560 | In contrast to `ellipsis`, this function will not produce incomplete
561 | words, and the resulting string can exceed the specified length. In
562 | addition, it removes trailing whitespace and punctuation characters at
563 | the end of the truncated string.
564 |
565 | softEllipsis 1 "Hello, World" == "Hello..."
566 |
567 | softEllipsis 5 "Hello, World" == "Hello..."
568 |
569 | softEllipsis 6 "Hello, World" == "Hello..."
570 |
571 | softEllipsis 15 "Hello, cruel world" == "Hello, cruel..."
572 |
573 | softEllipsis 10 "Hello" == "Hello"
574 |
575 | -}
576 | softEllipsis : Int -> String -> String
577 | softEllipsis howLong string =
578 | if String.length string <= howLong then
579 | string
580 |
581 | else
582 | string
583 | |> Regex.findAtMost 1 (softBreakRegexp howLong)
584 | |> List.map .match
585 | |> String.join ""
586 | |> Regex.replace (regexFromString "([\\.,;:\\s])+$") (always "")
587 | |> (\a -> String.append a "...")
588 |
589 |
590 | {-| Convert a list of strings into a human-readable list.
591 |
592 | toSentence [] == ""
593 |
594 | toSentence [ "lions" ] == "lions"
595 |
596 | toSentence [ "lions", "tigers" ] == "lions and tigers"
597 |
598 | toSentence [ "lions", "tigers", "bears" ] == "lions, tigers and bears"
599 |
600 | -}
601 | toSentence : List String -> String
602 | toSentence list =
603 | case list of
604 | x :: y :: z :: more ->
605 | toSentenceHelper " and " (x ++ ", " ++ y) (z :: more)
606 |
607 | _ ->
608 | toSentenceBaseCase list
609 |
610 |
611 | {-| Convert a list of strings into a human-readable list using an oxford comma.
612 |
613 | toSentenceOxford [] == ""
614 |
615 | toSentenceOxford [ "lions" ] == "lions"
616 |
617 | toSentenceOxford [ "lions", "tigers" ] == "lions and tigers"
618 |
619 | toSentenceOxford [ "lions", "tigers", "bears" ] == "lions, tigers, and bears"
620 |
621 | -}
622 | toSentenceOxford : List String -> String
623 | toSentenceOxford list =
624 | case list of
625 | x :: y :: z :: more ->
626 | toSentenceHelper ", and " (x ++ ", " ++ y) (z :: more)
627 |
628 | _ ->
629 | toSentenceBaseCase list
630 |
631 |
632 | toSentenceBaseCase : List String -> String
633 | toSentenceBaseCase list =
634 | case list of
635 | x :: [] ->
636 | x
637 |
638 | x :: y :: [] ->
639 | x ++ " and " ++ y
640 |
641 | _ ->
642 | ""
643 |
644 |
645 | toSentenceHelper : String -> String -> List String -> String
646 | toSentenceHelper lastPart sentence list =
647 | case list of
648 | [] ->
649 | sentence
650 |
651 | x :: [] ->
652 | sentence ++ lastPart ++ x
653 |
654 | x :: xs ->
655 | toSentenceHelper lastPart (sentence ++ ", " ++ x) xs
656 |
657 |
658 | {-| Remove all HTML tags from the string, preserving the text inside them.
659 |
660 | stripTags "a link" == "a link"
661 | stripTags " == "alert('hello world!')"
662 |
663 | -}
664 | stripTags : String -> String
665 | stripTags string =
666 | string
667 | |> Regex.replace (regexFromString "<\\/?[^>]+>") (always "")
668 |
669 |
670 | {-| Given a number, a singular string, and a plural string, return the number
671 | followed by a space, followed by either the singular string if the number was 1,
672 | or the plural string otherwise.
673 |
674 | pluralize "elf" "elves" 2 == "2 elves"
675 |
676 | pluralize "elf" "elves" 1 == "1 elf"
677 |
678 | pluralize "elf" "elves" 0 == "0 elves"
679 |
680 | -}
681 | pluralize : String -> String -> Int -> String
682 | pluralize singular plural count =
683 | if count == 1 then
684 | "1 " ++ singular
685 |
686 | else
687 | String.fromInt count ++ " " ++ plural
688 |
689 |
690 | {-| Search a string from left to right for a pattern and return a substring
691 | consisting of the characters in the string that are to the right of the pattern.
692 |
693 | rightOf "_" "This_is_a_test_string" == "is_a_test_string"
694 |
695 | -}
696 | rightOf : String -> String -> String
697 | rightOf pattern string =
698 | string
699 | |> Regex.findAtMost 1 (regexFromString <| regexEscape pattern ++ "(.*)$")
700 | |> List.map (.submatches >> firstResult)
701 | |> String.join ""
702 |
703 |
704 | {-| Search a string from left to right for a pattern and return a substring
705 | consisting of the characters in the string that are to the left of the pattern.
706 |
707 | leftOf "_" "This_is_a_test_string" == "This"
708 |
709 | -}
710 | leftOf : String -> String -> String
711 | leftOf pattern string =
712 | string
713 | |> Regex.findAtMost 1 (regexFromString <| "^(.*?)" ++ regexEscape pattern)
714 | |> List.map (.submatches >> firstResult)
715 | |> String.join ""
716 |
717 |
718 | firstResult : List (Maybe String) -> String
719 | firstResult list =
720 | firstResultHelp "" list
721 |
722 |
723 | firstResultHelp : String -> List (Maybe String) -> String
724 | firstResultHelp default list =
725 | case list of
726 | [] ->
727 | default
728 |
729 | (Just a) :: _ ->
730 | a
731 |
732 | Nothing :: rest ->
733 | firstResultHelp default rest
734 |
735 |
736 | {-| Search a string from right to left for a pattern and return a substring
737 | consisting of the characters in the string that are to the right of the pattern.
738 |
739 | rightOfBack "_" "This_is_a_test_string" == "string"
740 |
741 | -}
742 | rightOfBack : String -> String -> String
743 | rightOfBack pattern string =
744 | string
745 | |> String.indexes pattern
746 | |> List.reverse
747 | |> List.head
748 | |> Maybe.map ((+) (String.length pattern) >> (\a -> String.dropLeft a string))
749 | |> Maybe.withDefault ""
750 |
751 |
752 | {-| Search a string from right to left for a pattern and return a substring
753 | consisting of the characters in the string that are to the left of the pattern.
754 |
755 | leftOfBack "_" "This_is_a_test_string" == "This_is_a_test"
756 |
757 | -}
758 | leftOfBack : String -> String -> String
759 | leftOfBack pattern string =
760 | string
761 | |> String.indexes pattern
762 | |> List.reverse
763 | |> List.head
764 | |> Maybe.map (\a -> String.left a string)
765 | |> Maybe.withDefault ""
766 |
767 |
768 | {-| Convert a string into a list of UTF-32 code points.
769 |
770 | toCodePoints "abc" == [ 97, 98, 99 ]
771 |
772 | toCodePoints "©§π" == [ 169, 167, 960 ]
773 |
774 | toCodePoints "💩!" == [ 128169, 33 ]
775 |
776 | Note that code points do not necessarily correspond to logical/visual
777 | characters, since it is possible for things like accented characters to be
778 | represented as two separate UTF-32 code points (a base character and a
779 | combining accent).
780 |
781 | `toCodePoints string` is equivalent to:
782 |
783 | List.map Char.toCode (String.toList string)
784 |
785 | -}
786 | toCodePoints : String -> List Int
787 | toCodePoints string =
788 | List.map Char.toCode (String.toList string)
789 |
790 |
791 | {-| Convert a list of UTF-32 code points into a string. Inverse of
792 | `toCodePoints`.
793 |
794 | fromCodePoints [ 97, 98, 99 ] == "abc"
795 |
796 | fromCodePoints [ 169, 167, 960 ] == "©§π"
797 |
798 | fromCodePoints [ 128169, 33 ] == "💩!"
799 |
800 | `fromCodePoints codePoints` is equivalent to:
801 |
802 | String.fromList (List.map Char.fromCode codePoints)
803 |
804 | -}
805 | fromCodePoints : List Int -> String
806 | fromCodePoints codePoints =
807 | String.fromList (List.map Char.fromCode codePoints)
808 |
809 |
810 | {-| Convert a string to a Nothing when empty.
811 |
812 | nonEmpty "" == Nothing
813 |
814 | nonEmpty "Hello world" == Just "Hello world"
815 |
816 | -}
817 | nonEmpty : String -> Maybe String
818 | nonEmpty string =
819 | if String.isEmpty string then
820 | Nothing
821 |
822 | else
823 | Just string
824 |
825 |
826 | {-| Convert a string to a Nothing when blank.
827 |
828 | nonBlank "" == Nothing
829 |
830 | nonBlank " " == Nothing
831 |
832 | nonBlank "Hello world" == Just "Hello world"
833 |
834 | -}
835 | nonBlank : String -> Maybe String
836 | nonBlank string =
837 | if isBlank string then
838 | Nothing
839 |
840 | else
841 | Just string
842 |
843 |
844 | {-| Remove accents from string.
845 |
846 | removeAccents "andré" == "andre"
847 |
848 | removeAccents "Atenção" == "Atencao"
849 |
850 | -}
851 | removeAccents : String -> String
852 | removeAccents string =
853 | if String.isEmpty string then
854 | string
855 |
856 | else
857 | let
858 | do_regex_to_remove_acents ( regex, replace_character ) =
859 | Regex.replace regex (\_ -> replace_character)
860 | in
861 | List.foldl do_regex_to_remove_acents string accentRegex
862 |
863 |
864 | {-| Create list with regex and char to replace.
865 | -}
866 | accentRegex : List ( Regex.Regex, String )
867 | accentRegex =
868 | let
869 | matches =
870 | [ ( "[à-æ]", "a" )
871 | , ( "[À-Æ]", "A" )
872 | , ( "ç", "c" )
873 | , ( "Ç", "C" )
874 | , ( "[è-ë]", "e" )
875 | , ( "[È-Ë]", "E" )
876 | , ( "[ì-ï]", "i" )
877 | , ( "[Ì-Ï]", "I" )
878 | , ( "ñ", "n" )
879 | , ( "Ñ", "N" )
880 | , ( "[ò-ö]", "o" )
881 | , ( "[Ò-Ö]", "O" )
882 | , ( "[ù-ü]", "u" )
883 | , ( "[Ù-Ü]", "U" )
884 | , ( "ý", "y" )
885 | , ( "ÿ", "y" )
886 | , ( "Ý", "Y" )
887 | ]
888 | in
889 | List.map (Tuple.mapFirst regexFromString) matches
890 |
891 |
892 | regexEscape : String -> String
893 | regexEscape =
894 | Regex.replace (regexFromString "[-/\\^$*+?.()|[\\]{}]") (\{ match } -> "\\" ++ match)
895 |
896 |
897 | regexFromString : String -> Regex
898 | regexFromString =
899 | Regex.fromString >> Maybe.withDefault Regex.never
900 |
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | elm-stuff
2 | elm.js
3 | test.js
4 |
--------------------------------------------------------------------------------
/tests/CamelizeTest.elm:
--------------------------------------------------------------------------------
1 | module CamelizeTest exposing (camelizeTest)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import Regex
7 | import String exposing (replace, uncons)
8 | import String.Extra exposing (..)
9 | import Test exposing (..)
10 | import TestData
11 |
12 |
13 | camelizeTest : Test
14 | camelizeTest =
15 | describe "camelize"
16 | [ fuzz string "It does not contain dashes" <|
17 | \s ->
18 | camelize s
19 | |> String.contains "-"
20 | |> Expect.false "Camelize should remove dashes"
21 | , fuzz string "It does not contain underscores" <|
22 | \s ->
23 | camelize s
24 | |> String.contains "-"
25 | |> Expect.false "Camelize should remove underscores"
26 | , fuzz string "It is the same lowercased string after removing the dashes and spaces" <|
27 | \s ->
28 | let
29 | expected =
30 | replace "-" ""
31 | >> replace "_" ""
32 | >> Regex.replace (Regex.fromString "\\s+" |> Maybe.withDefault Regex.never) (\_ -> "")
33 | >> String.toLower
34 | in
35 | camelize s
36 | |> String.toLower
37 | |> Expect.equal (expected s)
38 | , fuzz (validWords '-') "The first letter after each dash is capitalized" <|
39 | \s ->
40 | camelize s
41 | |> Expect.equal (runCamelize "-" s)
42 | , fuzz (validWords ' ') "The first letter after each space is capitalized" <|
43 | \s ->
44 | camelize s
45 | |> Expect.equal (runCamelize " " s)
46 | ]
47 |
48 |
49 | runCamelize : String -> String -> String
50 | runCamelize separator string =
51 | string
52 | |> String.trim
53 | |> replace (separator ++ separator) separator
54 | |> String.split separator
55 | |> List.indexedMap capitalizeOdds
56 | |> String.join ""
57 |
58 |
59 | capitalizeOdds : Int -> String -> String
60 | capitalizeOdds pos str =
61 | if pos > 0 then
62 | toSentenceCase str
63 |
64 | else
65 | str
66 |
67 |
68 | validWords : Char -> Fuzzer String
69 | validWords ch =
70 | TestData.randomStringsWithChars [ ch ]
71 |
--------------------------------------------------------------------------------
/tests/ClassifyTest.elm:
--------------------------------------------------------------------------------
1 | module ClassifyTest exposing (classifyTest)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import Random
7 | import Regex
8 | import String exposing (replace, uncons)
9 | import String.Extra exposing (..)
10 | import Test exposing (..)
11 | import TestData
12 | import Tuple exposing (first, second)
13 |
14 |
15 | classifyTest : Test
16 | classifyTest =
17 | describe "classify"
18 | [ fuzz string "It does not contain non-word characters" <|
19 | \string ->
20 | classify string
21 | |> Regex.contains (Regex.fromString "[\\W]" |> Maybe.withDefault Regex.never)
22 | |> Expect.false "Non word characters detected"
23 | , fuzz TestData.randomStrings "It starts with an uppercase letter" <|
24 | \string ->
25 | string
26 | |> classify
27 | |> uncons
28 | |> Maybe.map first
29 | |> Expect.equal (string |> String.trim |> String.toUpper |> uncons |> Maybe.map first)
30 | , fuzz validWords "It is camelized once replaced non word charactes with a compatible string" <|
31 | \string ->
32 | string
33 | |> classify
34 | |> uncons
35 | |> Maybe.map second
36 | |> Expect.equal (string |> replace "." "-" |> camelize |> uncons |> Maybe.map second)
37 | ]
38 |
39 |
40 | validWords : Fuzzer String
41 | validWords =
42 | TestData.randomStringsWithCharGenerators
43 | [ Random.map Char.fromCode (Random.int 45 46)
44 | , Random.constant (Char.fromCode 95)
45 | ]
46 |
--------------------------------------------------------------------------------
/tests/DasherizeTest.elm:
--------------------------------------------------------------------------------
1 | module DasherizeTest exposing (dasherizeTest)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import String exposing (replace, uncons)
7 | import String.Extra exposing (..)
8 | import Test exposing (..)
9 | import TestData
10 |
11 |
12 | dasherizeTest : Test
13 | dasherizeTest =
14 | describe "dasherize"
15 | [ fuzz string "It is a lowercased string" <|
16 | \s ->
17 | dasherize s
18 | |> String.toLower
19 | |> Expect.equal (dasherize s)
20 | , fuzz string "It replaces spaces and underscores with a dash" <|
21 | \s ->
22 | let
23 | expected =
24 | String.toLower
25 | >> String.trim
26 | >> replace " " " "
27 | >> replace " " "-"
28 | >> replace "_" "-"
29 | >> replace "--" "-"
30 | >> replace "--" "-"
31 | in
32 | dasherize (String.toLower s)
33 | |> String.toLower
34 | |> Expect.equal (expected s)
35 | , fuzz TestData.randomStrings "It puts dash before every single uppercase character" <|
36 | \s ->
37 | dasherize s
38 | |> Expect.equal (replaceUppercase s |> String.toLower)
39 | ]
40 |
41 |
42 | replaceUppercase : String -> String
43 | replaceUppercase string =
44 | string
45 | |> String.toList
46 | |> List.map
47 | (\c ->
48 | if Char.isUpper c then
49 | "-" ++ String.fromChar c
50 |
51 | else
52 | String.fromChar c
53 | )
54 | |> String.join ""
55 |
--------------------------------------------------------------------------------
/tests/HumanizeTest.elm:
--------------------------------------------------------------------------------
1 | module HumanizeTest exposing (humanizeTest)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import Regex
7 | import String
8 | import String.Extra exposing (..)
9 | import Test exposing (..)
10 | import TestData
11 | import Tuple exposing (first, second)
12 |
13 |
14 | humanizeTest : Test
15 | humanizeTest =
16 | describe "humanize"
17 | [ test "All uppercase" <|
18 | \_ ->
19 | humanize "ALL_UPPERCASE IS FINE"
20 | |> Expect.equal "All uppercase is fine"
21 | , test "Some uppercase" <|
22 | \_ ->
23 | humanize "I like HTML"
24 | |> Expect.equal "I like html"
25 | , test "Snake case" <|
26 | \_ ->
27 | humanize "this_is_great"
28 | |> Expect.equal "This is great"
29 | , test "Capitalized" <|
30 | \_ ->
31 | humanize "ThisIsGreat"
32 | |> Expect.equal "This is great"
33 | , test "Kebab case" <|
34 | \_ ->
35 | humanize "this-is-great"
36 | |> Expect.equal "This is great"
37 | , test "Id suffix" <|
38 | \_ ->
39 | humanize "author_id"
40 | |> Expect.equal "Author"
41 | , fuzz (validWords []) "It starts with an uppercase letter after trimming" <|
42 | \s ->
43 | let
44 | expected =
45 | String.trim
46 | >> toSentenceCase
47 | >> String.uncons
48 | >> Maybe.map (first >> String.fromChar)
49 | >> Maybe.withDefault ""
50 | in
51 | humanize s
52 | |> String.uncons
53 | |> Maybe.map (first >> String.fromChar)
54 | |> Maybe.withDefault ""
55 | |> Expect.equal (expected s)
56 | , fuzz (validWords []) "The tail of the string is lowercased" <|
57 | \s ->
58 | humanize s
59 | |> String.uncons
60 | |> Maybe.map second
61 | |> Maybe.withDefault "a"
62 | |> String.filter ((/=) ' ')
63 | |> String.all Char.isLower
64 | |> Expect.true "Not all characters in the string are lowercased"
65 | , fuzz (validWords [ '_', '-' ]) "It removes a trailing `_id` & replaces underscores and dashes with a single whitespace" <|
66 | \s ->
67 | let
68 | expected =
69 | String.toLower
70 | >> Regex.replaceAtMost 1 (regex "_id$") (\_ -> "")
71 | >> String.replace "-" " "
72 | >> String.replace "_" " "
73 | >> Regex.replace (regex "\\s+") (\_ -> " ")
74 | >> String.trim
75 | in
76 | humanize (String.toLower s)
77 | |> String.toLower
78 | |> Expect.equal (expected s)
79 | , fuzz string "It yields the same string after removing underscores, dashes and spaces" <|
80 | \s ->
81 | let
82 | expected =
83 | String.replace "-" ""
84 | >> String.replace "_" ""
85 | >> Regex.replace (regex "\\s+") (\_ -> "")
86 | >> String.toLower
87 | in
88 | humanize s
89 | |> String.replace " " ""
90 | |> String.toLower
91 | |> Expect.equal (expected s)
92 | , fuzz (validWords []) "It adds a space before each group of uppercase letter" <|
93 | \s ->
94 | let
95 | expected =
96 | Regex.replace (regex "[A-Z]+") (\{ match } -> " " ++ match)
97 | >> String.toLower
98 | >> String.trim
99 | in
100 | humanize s
101 | |> String.toLower
102 | |> Expect.equal (expected s)
103 | , fuzz string "It does not leave double spaces around" <|
104 | \s ->
105 | let
106 | expected =
107 | replaceUppercase >> String.toLower >> String.trim
108 | in
109 | humanize s
110 | |> String.contains " "
111 | |> Expect.false "The string contains double spaces"
112 | , fuzz idString "It strips the _id at the end" <|
113 | \s ->
114 | humanize s
115 | |> String.endsWith "id"
116 | |> Expect.false "The string should not end with id"
117 | ]
118 |
119 |
120 | idString : Fuzzer String
121 | idString =
122 | validWords [ '-', '_' ]
123 | |> map (\s -> s ++ "s_id")
124 |
125 |
126 | validWords : List Char -> Fuzzer String
127 | validWords ch =
128 | TestData.randomStringsWithChars ch
129 |
130 |
131 | replaceUppercase : String -> String
132 | replaceUppercase string =
133 | string
134 | |> String.toList
135 | |> List.map
136 | (\c ->
137 | if Char.isUpper c then
138 | " " ++ String.fromChar c
139 |
140 | else
141 | String.fromChar c
142 | )
143 | |> String.join ""
144 |
145 |
146 | regex str =
147 | Maybe.withDefault Regex.never <|
148 | Regex.fromString str
149 |
--------------------------------------------------------------------------------
/tests/NonEmptyTest.elm:
--------------------------------------------------------------------------------
1 | module NonEmptyTest exposing (nonEmptyTest)
2 |
3 | import Expect
4 | import String.Extra exposing (nonEmpty)
5 | import Test exposing (..)
6 |
7 |
8 | nonEmptyTest : Test
9 | nonEmptyTest =
10 | describe "nonEmpty"
11 | [ test "Should result in a just when string has greater length than 0" <|
12 | \() ->
13 | nonEmpty "Hello world"
14 | |> Expect.equal (Just "Hello world")
15 | , test "Should result in Nothing when an empty string is passed in" <|
16 | \() ->
17 | nonEmpty ""
18 | |> Expect.equal Nothing
19 | ]
20 |
--------------------------------------------------------------------------------
/tests/RemoveAccentsTest.elm:
--------------------------------------------------------------------------------
1 | module RemoveAccentsTest exposing (removeAccentsTest)
2 |
3 | import Expect
4 | import String.Extra exposing (removeAccents)
5 | import Test exposing (..)
6 |
7 |
8 | removeAccentsTest : Test
9 | removeAccentsTest =
10 | describe "removeAccents"
11 | [ test "Should result string without accents" <|
12 | \() ->
13 | removeAccents "áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ"
14 | |> Expect.equal "aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC"
15 | , test "Should result in phrase without accents" <|
16 | \() ->
17 | removeAccents "andré JOÂO"
18 | |> Expect.equal "andre JOAO"
19 | ]
20 |
--------------------------------------------------------------------------------
/tests/ReplaceSliceTest.elm:
--------------------------------------------------------------------------------
1 | module ReplaceSliceTest exposing (replaceSliceTest)
2 |
3 | import Expect
4 | import Fuzz exposing (..)
5 | import Random
6 | import Shrink
7 | import String
8 | import String.Extra exposing (..)
9 | import Test exposing (..)
10 | import TestData
11 |
12 |
13 | replaceSliceTest : Test
14 | replaceSliceTest =
15 | describe "replaceSlice"
16 | [ fuzz replaceSliceProducer "Result contains the substitution string" <|
17 | \( ( string, sub ), ( start, end ) ) ->
18 | case string of
19 | "" ->
20 | replaceSlice sub start end string
21 | |> Expect.equal sub
22 |
23 | _ ->
24 | replaceSlice sub start end string
25 | |> String.contains sub
26 | |> Expect.true "The slice was not subtituted"
27 | , fuzz replaceSliceProducer "Result string has the length of the substitution + string after removing the slice" <|
28 | \( ( string, sub ), ( start, end ) ) ->
29 | case string of
30 | "" ->
31 | replaceSlice sub start end string
32 | |> String.length
33 | |> Expect.equal (String.length sub)
34 |
35 | _ ->
36 | replaceSlice sub start end string
37 | |> String.length
38 | |> Expect.equal ((String.length string - (end - start)) + String.length sub)
39 | , fuzz replaceSliceProducer "Start of the original string remains the same" <|
40 | \( ( string, sub ), ( start, end ) ) ->
41 | case string of
42 | "" ->
43 | replaceSlice sub start end string
44 | |> Expect.equal sub
45 |
46 | _ ->
47 | replaceSlice sub start end string
48 | |> String.slice 0 start
49 | |> Expect.equal (String.slice 0 start string)
50 | , fuzz replaceSliceProducer "End of the original string remains the same" <|
51 | \( ( string, sub ), ( start, end ) ) ->
52 | let
53 | replaced =
54 | replaceSlice sub start end string
55 | in
56 | case string of
57 | "" ->
58 | replaced
59 | |> Expect.equal sub
60 |
61 | _ ->
62 | replaced
63 | |> String.slice (start + String.length sub) (String.length replaced)
64 | |> Expect.equal (String.slice end (String.length string) string)
65 | ]
66 |
67 |
68 | replaceSliceProducer : Fuzzer ( ( String, String ), ( Int, Int ) )
69 | replaceSliceProducer =
70 | let
71 | producer =
72 | Random.map2 Tuple.pair TestData.randomString TestData.randomString
73 | |> Random.andThen (\( str, sub ) -> Random.pair (Random.constant ( str, sub )) (Random.int 0 <| String.length str))
74 | |> Random.andThen (\( ( str, sub ), start ) -> Random.pair (Random.constant ( str, sub )) (Random.pair (Random.constant start) (Random.int start <| String.length str)))
75 | in
76 | Fuzz.custom producer Shrink.noShrink
77 |
--------------------------------------------------------------------------------
/tests/TestData.elm:
--------------------------------------------------------------------------------
1 | module TestData exposing
2 | ( randomString
3 | , randomStrings
4 | , randomStringsWithCharGenerators
5 | , randomStringsWithChars
6 | )
7 |
8 | import Fuzz exposing (Fuzzer)
9 | import Random
10 | import Shrink
11 |
12 |
13 | withChar : List Char -> Random.Generator Char
14 | withChar ch =
15 | withCharGenerators <| List.map Random.constant ch
16 |
17 |
18 | withCharGenerators : List (Random.Generator Char) -> Random.Generator Char
19 | withCharGenerators charGenerators =
20 | Random.andThen identity <|
21 | Random.uniform (Random.map Char.fromCode (Random.int 97 122)) <|
22 | Random.map Char.fromCode (Random.int 65 90)
23 | :: charGenerators
24 |
25 |
26 | randomString : Random.Generator String
27 | randomString =
28 | randomStringWithCharGenerators [ withChar [] ]
29 |
30 |
31 | randomStringWithCharGenerators : List (Random.Generator Char) -> Random.Generator String
32 | randomStringWithCharGenerators charGenerators =
33 | Random.int 1 10
34 | |> Random.andThen (\i -> Random.map String.fromList <| Random.list i (withCharGenerators charGenerators))
35 |
36 |
37 | randomStrings : Fuzzer String
38 | randomStrings =
39 | randomStringsWithChars []
40 |
41 |
42 | randomStringsWithChars : List Char -> Fuzzer String
43 | randomStringsWithChars chars =
44 | randomStringsWithCharGenerators [ withChar chars ]
45 |
46 |
47 | randomStringsWithCharGenerators : List (Random.Generator Char) -> Fuzzer String
48 | randomStringsWithCharGenerators charGenerators =
49 | Fuzz.custom (randomStringWithCharGenerators charGenerators) Shrink.string
50 |
--------------------------------------------------------------------------------
/tests/Tests.elm:
--------------------------------------------------------------------------------
1 | module Tests exposing (breakTest, cleanTest, countOccurrencesTest, decapitalizeTest, ellipsisTest, insertAtProducer, insertAtTest, isBlankTest, nonBlankTest, pluralizeTest, softBreakTest, surroundTest, tail, toSentenceCaseTest, toTitleCaseTest, unquoteTest, wrapTest)
2 |
3 | import Expect
4 | import Fuzz exposing (..)
5 | import Json.Encode exposing (Value)
6 | import String exposing (fromChar, replace, toLower, toUpper, uncons)
7 | import String.Extra exposing (..)
8 | import Test exposing (..)
9 | import Tuple exposing (first, second)
10 |
11 |
12 | tail : String -> String
13 | tail =
14 | uncons >> Maybe.map second >> Maybe.withDefault ""
15 |
16 |
17 | toSentenceCaseTest : Test
18 | toSentenceCaseTest =
19 | describe "toSentenceCase"
20 | [ fuzz string "It converts the first char of the string to uppercase" <|
21 | \string ->
22 | let
23 | result =
24 | string
25 | |> toSentenceCase
26 | |> uncons
27 | |> Maybe.map (first >> fromChar)
28 | |> Maybe.withDefault ""
29 |
30 | expected =
31 | string
32 | |> uncons
33 | |> Maybe.map (first >> fromChar >> toUpper)
34 | |> Maybe.withDefault ""
35 | in
36 | Expect.equal expected result
37 | , fuzz string "The tail of the string remains untouched" <|
38 | \string ->
39 | let
40 | result =
41 | (toSentenceCase >> tail) string
42 |
43 | expected =
44 | tail string
45 | in
46 | Expect.equal expected result
47 | ]
48 |
49 |
50 | decapitalizeTest : Test
51 | decapitalizeTest =
52 | describe "decapitalize"
53 | [ fuzz string "It only converst the first char in the string to lowercase" <|
54 | \string ->
55 | let
56 | result =
57 | string
58 | |> decapitalize
59 | |> uncons
60 | |> Maybe.map (first >> fromChar)
61 | |> Maybe.withDefault ""
62 |
63 | expected =
64 | string
65 | |> uncons
66 | |> Maybe.map (first >> fromChar >> toLower)
67 | |> Maybe.withDefault ""
68 | in
69 | Expect.equal expected result
70 | , fuzz string "It does not change the tail of the string" <|
71 | \string ->
72 | let
73 | result =
74 | (decapitalize >> tail) string
75 |
76 | expected =
77 | tail string
78 | in
79 | Expect.equal expected result
80 | ]
81 |
82 |
83 | toTitleCaseTest : Test
84 | toTitleCaseTest =
85 | describe "toTitleCase"
86 | [ fuzz (list string) "It converts the first letter of each word to uppercase" <|
87 | \strings ->
88 | let
89 | result =
90 | strings
91 | |> String.join " "
92 | |> toTitleCase
93 | |> String.words
94 |
95 | expected =
96 | strings
97 | |> String.join " "
98 | |> String.words
99 | |> List.map toSentenceCase
100 | in
101 | Expect.equal expected result
102 | , fuzz (list string) "It does not change the length of the string" <|
103 | \strings ->
104 | let
105 | result =
106 | strings
107 | |> String.join " "
108 | |> toTitleCase
109 | |> String.length
110 |
111 | expected =
112 | strings
113 | |> String.join " "
114 | |> String.length
115 | in
116 | Expect.equal expected result
117 | ]
118 |
119 |
120 | breakTest : Test
121 | breakTest =
122 | describe "break"
123 | [ fuzz2 string (intRange 0 100) "The list should have as many elements as the ceil division of the length" <|
124 | \string width ->
125 | case ( string, width ) of
126 | ( "", _ ) ->
127 | break width string
128 | |> List.length
129 | |> Expect.equal 1
130 |
131 | ( _, 0 ) ->
132 | break width string
133 | |> List.length
134 | |> Expect.equal 1
135 |
136 | _ ->
137 | break width string
138 | |> List.length
139 | |> Expect.equal (ceiling <| (toFloat << String.length) string / toFloat width)
140 | , fuzz2 string (intRange 1 10) "Concatenating the result yields the original string" <|
141 | \string width ->
142 | break width string
143 | |> String.concat
144 | |> Expect.equal string
145 | , fuzz2 string (intRange 1 10) "No element in the list should have more than `width` chars" <|
146 | \string width ->
147 | break width string
148 | |> List.map String.length
149 | |> List.filter ((<) width)
150 | |> List.isEmpty
151 | |> Expect.true "The list has some long elements"
152 | ]
153 |
154 |
155 | softBreakTest : Test
156 | softBreakTest =
157 | describe "softBreak"
158 | [ fuzz2 string (intRange 1 10) "Concatenating the result yields the original string" <|
159 | \string width ->
160 | softBreak width (String.trim string)
161 | |> String.concat
162 | |> Expect.equal (String.trim string)
163 | , fuzz2 string (intRange 1 10) "The list should not have more elements than words" <|
164 | \string width ->
165 | softBreak width string
166 | |> List.length
167 | |> Expect.atMost (String.words string |> List.length)
168 | ]
169 |
170 |
171 | cleanTest : Test
172 | cleanTest =
173 | describe "clean"
174 | [ fuzz string "The String.split result is the same as String.words" <|
175 | \string ->
176 | let
177 | result =
178 | string
179 | |> clean
180 | |> String.split " "
181 |
182 | expected =
183 | String.words string
184 | in
185 | Expect.equal expected result
186 | , fuzz string "It trims the string on the left side" <|
187 | \string ->
188 | string
189 | |> clean
190 | |> String.startsWith " "
191 | |> Expect.false "Did not trim the start of the string"
192 | , fuzz string "It trims the string on the right side" <|
193 | \string ->
194 | string
195 | |> clean
196 | |> String.endsWith " "
197 | |> Expect.false "Did not trim the end of the string"
198 | ]
199 |
200 |
201 | insertAtTest : Test
202 | insertAtTest =
203 | describe "insertAt"
204 | [ fuzz insertAtProducer "Result contains the substitution string" <|
205 | \( sub, at, string ) ->
206 | string
207 | |> insertAt sub at
208 | |> String.contains sub
209 | |> Expect.true "Could not find substitution string in result"
210 | , fuzz insertAtProducer "Resulting string has length as the sum of both arguments" <|
211 | \( sub, at, string ) ->
212 | insertAt sub at string
213 | |> String.length
214 | |> Expect.equal (String.length sub + String.length string)
215 | , fuzz insertAtProducer "Start of the string remains the same" <|
216 | \( sub, at, string ) ->
217 | insertAt sub at string
218 | |> String.slice 0 at
219 | |> Expect.equal (String.slice 0 at string)
220 | , fuzz insertAtProducer "End of the string remains the same" <|
221 | \( sub, at, string ) ->
222 | insertAt sub at string
223 | |> String.slice (at + String.length sub) (String.length string + String.length sub)
224 | |> Expect.equal (String.slice at (String.length string) string)
225 | ]
226 |
227 |
228 | insertAtProducer : Fuzzer ( String, Int, String )
229 | insertAtProducer =
230 | tuple3 ( intRange 0 10, intRange 1 10, string )
231 | |> map (\( a, b, s ) -> ( "b" ++ s, b, String.repeat (a + b) "a" ))
232 |
233 |
234 | isBlankTest : Test
235 | isBlankTest =
236 | describe "isBlank"
237 | [ test "Returns true if the given string is blank" <|
238 | \_ ->
239 | isBlank ""
240 | |> Expect.true "Did not return true"
241 | , test "Returns false if the given string is not blank" <|
242 | \_ ->
243 | isBlank " Slartibartfast"
244 | |> Expect.false "Did not return false"
245 | ]
246 |
247 |
248 | nonBlankTest : Test
249 | nonBlankTest =
250 | describe "nonBlank"
251 | [ test "Returns Nothing if the given string is blank" <|
252 | \_ ->
253 | nonBlank ""
254 | |> Expect.equal Nothing
255 | , test "Returns just the string if the given string is not blank" <|
256 | \_ ->
257 | nonBlank " Slartibartfast"
258 | |> Expect.equal (Just " Slartibartfast")
259 | ]
260 |
261 |
262 | surroundTest : Test
263 | surroundTest =
264 | describe "surround"
265 | [ fuzz2 string string "It starts with the wrapping string" <|
266 | \string wrap ->
267 | string
268 | |> surround wrap
269 | |> String.startsWith wrap
270 | |> Expect.true "Did not start with the wrapping string"
271 | , fuzz2 string string "It ends with the wrapping string" <|
272 | \string wrap ->
273 | string
274 | |> surround wrap
275 | |> String.endsWith wrap
276 | |> Expect.true "Did not end with the wrapping string"
277 | , fuzz2 string string "It contains the original string" <|
278 | \string wrap ->
279 | string
280 | |> surround wrap
281 | |> String.contains string
282 | |> Expect.true "Did not contain the string"
283 | , fuzz2 string string "It does not have anything else inside" <|
284 | \string wrap ->
285 | let
286 | result =
287 | String.length (surround wrap string)
288 |
289 | expected =
290 | String.length string + (2 * String.length wrap)
291 | in
292 | Expect.equal expected result
293 | ]
294 |
295 |
296 |
297 | -- TODO: ensure this test only gets strings that contain the needle in the
298 | -- haystack?
299 |
300 |
301 | countOccurrencesTest : Test
302 | countOccurrencesTest =
303 | describe "countOccurrences"
304 | [ fuzz2 string string "Removing the occurences should yield the right length" <|
305 | \needle haystack ->
306 | let
307 | times =
308 | countOccurrences needle haystack
309 |
310 | result =
311 | String.length haystack - (times * String.length needle)
312 |
313 | expected =
314 | String.length (replace needle "" haystack)
315 | in
316 | Expect.equal expected result
317 | ]
318 |
319 |
320 | ellipsisTest : Test
321 | ellipsisTest =
322 | describe "ellipsis"
323 | [ fuzz2 (intRange 3 20) string "The resulting string length does not exceed the specified length" <|
324 | \howLong string ->
325 | ellipsis howLong string
326 | |> String.length
327 | |> (>=) howLong
328 | |> Expect.true "Resulting string exceeds specified length"
329 | , fuzz2 (intRange 3 20) string "The resulting string contains three dots at the end if necessary" <|
330 | \howLong string ->
331 | let
332 | result =
333 | ellipsis howLong string
334 | in
335 | result
336 | |> String.endsWith "..."
337 | |> (if String.length string > howLong then
338 | Expect.true "Should add ellipsis to this string"
339 |
340 | else
341 | Expect.false "Should not add ellipsis"
342 | )
343 | , fuzz2 (intRange 3 20) string "It starts with the left of the original string" <|
344 | \howLong string ->
345 | let
346 | result =
347 | ellipsis howLong string
348 |
349 | resultLeft =
350 | String.dropRight 3 result
351 | in
352 | string
353 | |> String.startsWith resultLeft
354 | |> Expect.true "Should start with the original left"
355 | ]
356 |
357 |
358 | unquoteTest : Test
359 | unquoteTest =
360 | describe "unquote"
361 | [ test "Removes quotes from the start of the string" <|
362 | \_ ->
363 | unquote "\"Magrathea\""
364 | |> Expect.equal "Magrathea"
365 | ]
366 |
367 |
368 | wrapTest : Test
369 | wrapTest =
370 | describe "wrap"
371 | [ fuzz2 (intRange 1 20) string "Wraps given string at the requested length" <|
372 | \howLong string ->
373 | wrap howLong string
374 | |> String.split "\n"
375 | |> List.map (\str -> String.length str <= howLong)
376 | |> List.all ((==) True)
377 | |> Expect.true "Given string was not wrapped at requested length"
378 | , test "Does not wrap string shorter than the requested length" <|
379 | \_ ->
380 | wrap 50 "Heart of Gold"
381 | |> String.contains "\n"
382 | |> Expect.false "Short string was wrapped"
383 | ]
384 |
385 |
386 | pluralizeTest : Test
387 | pluralizeTest =
388 | describe "pluralize"
389 | [ test "It uses the singular version when the count is one" <|
390 | \() ->
391 | pluralize "elf" "elves" 1
392 | |> Expect.equal "1 elf"
393 | , test "It uses the plural version for > 1 count" <|
394 | \() ->
395 | pluralize "elf" "elves" 4
396 | |> Expect.equal "4 elves"
397 | , test "It uses the plural version for 0 count" <|
398 | \() ->
399 | pluralize "elf" "elves" 0
400 | |> Expect.equal "0 elves"
401 | ]
402 |
--------------------------------------------------------------------------------
/tests/UnderscoredTest.elm:
--------------------------------------------------------------------------------
1 | module UnderscoredTest exposing (underscoredTest)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import String exposing (replace, uncons)
7 | import String.Extra exposing (..)
8 | import Test exposing (..)
9 | import TestData
10 |
11 |
12 | underscoredTest : Test
13 | underscoredTest =
14 | describe "underscored"
15 | [ fuzz string "It is a lowercased string" <|
16 | \s ->
17 | underscored s
18 | |> String.toLower
19 | |> Expect.equal (underscored s |> String.toLower)
20 | , fuzz string "It replaces spaces and dashes with an underscore" <|
21 | \s ->
22 | let
23 | expected =
24 | String.toLower
25 | >> String.trim
26 | >> replace " " " "
27 | >> replace " " "-"
28 | >> replace "-" "_"
29 | >> replace "__" "_"
30 | >> replace "__" "_"
31 | in
32 | underscored (String.toLower s)
33 | |> Expect.equal (expected s)
34 | , fuzz TestData.randomStrings "It puts an underscore before each uppercase characters group unless it starts with uppercase" <|
35 | \s ->
36 | underscored s
37 | |> Expect.equal (replaceUppercase s |> String.toLower)
38 | ]
39 |
40 |
41 | replaceUppercase : String -> String
42 | replaceUppercase string =
43 | string
44 | |> String.toList
45 | |> List.indexedMap Tuple.pair
46 | |> List.foldr recordUpperCasePositions []
47 | |> List.foldl reduceList []
48 | |> List.foldl replacePositions string
49 |
50 |
51 | recordUpperCasePositions : ( Int, Char ) -> List ( Int, Char ) -> List ( Int, Char )
52 | recordUpperCasePositions ( index, char ) acc =
53 | if Char.isUpper char then
54 | ( index, char ) :: acc
55 |
56 | else
57 | acc
58 |
59 |
60 | reduceList : ( Int, Char ) -> List ( Int, Int, Char ) -> List ( Int, Int, Char )
61 | reduceList ( index, char ) acc =
62 | case acc of
63 | ( start, end, c ) :: rest ->
64 | if index == end + 1 then
65 | ( start, index, c ) :: rest
66 |
67 | else
68 | ( index, index, char ) :: acc
69 |
70 | [] ->
71 | ( index, index, char ) :: acc
72 |
73 |
74 | replacePositions : ( Int, Int, Char ) -> String -> String
75 | replacePositions ( start, _, c ) string =
76 | if start == 0 then
77 | string
78 |
79 | else
80 | replaceSlice ("_" ++ String.fromChar c) start (start + 1) string
81 |
--------------------------------------------------------------------------------
/tests/UnicodeTests.elm:
--------------------------------------------------------------------------------
1 | module UnicodeTests exposing (unicodeTests)
2 |
3 | import Char
4 | import Expect
5 | import Fuzz exposing (..)
6 | import String
7 | import String.Extra exposing (..)
8 | import Test exposing (..)
9 |
10 |
11 | bmpCodePointFuzzer : Fuzzer Int
12 | bmpCodePointFuzzer =
13 | frequency
14 | [ ( 1, intRange 0 0xD7FF )
15 | , ( 1, intRange 0xE000 0xFFFF )
16 | ]
17 |
18 |
19 | unicodeStringFuzzer : Fuzzer String
20 | unicodeStringFuzzer =
21 | let
22 | singletonFuzzer =
23 | bmpCodePointFuzzer |> map (\codePoint -> [ codePoint ])
24 |
25 | leadingSurrogateFuzzer =
26 | intRange 0xD800 0xDBFF
27 |
28 | trailingSurrogateFuzzer =
29 | intRange 0xDC00 0xDFFF
30 |
31 | surrogatePairFuzzer =
32 | tuple ( leadingSurrogateFuzzer, trailingSurrogateFuzzer )
33 | |> map (\( leading, trailing ) -> [ leading, trailing ])
34 |
35 | sublistFuzzer =
36 | frequency
37 | [ ( 1, singletonFuzzer )
38 | , ( 1, surrogatePairFuzzer )
39 | ]
40 | in
41 | list sublistFuzzer
42 | |> map List.concat
43 | |> map (List.map Char.fromCode)
44 | |> map String.fromList
45 |
46 |
47 | codePointFuzzer : Fuzzer Int
48 | codePointFuzzer =
49 | let
50 | astralCodePointFuzzer =
51 | intRange 0x00010000 0x0010FFFF
52 | in
53 | frequency
54 | [ ( 1, bmpCodePointFuzzer )
55 | , ( 1, astralCodePointFuzzer )
56 | ]
57 |
58 |
59 | expectedStringLength : List Int -> Int
60 | expectedStringLength codePoints =
61 | let
62 | numCodeUnits codePoint =
63 | if codePoint <= 0xFFFF then
64 | 1
65 |
66 | else
67 | 2
68 | in
69 | codePoints |> List.map numCodeUnits |> List.sum
70 |
71 |
72 | hardCodedTestCases : List ( String, List Int )
73 | hardCodedTestCases =
74 | [ ( "", [] )
75 | , ( "©§π", [ 169, 167, 960 ] )
76 | , ( "💩!", [ 128169, 33 ] )
77 | , ( "abc", [ 97, 98, 99 ] )
78 | ]
79 |
80 |
81 | unicodeTests : Test
82 | unicodeTests =
83 | describe "unicode"
84 | [ fuzz unicodeStringFuzzer "fromCodePoints is inverse of toCodePoints" <|
85 | \string ->
86 | fromCodePoints (toCodePoints string)
87 | |> Expect.equal string
88 | , fuzz (list codePointFuzzer) "toCodePoints is inverse of fromCodePoints" <|
89 | \codePoints ->
90 | toCodePoints (fromCodePoints codePoints)
91 | |> Expect.equal codePoints
92 | , fuzz (list codePointFuzzer) "string length is greater than or equal to number of code points" <|
93 | \codePoints ->
94 | String.length (fromCodePoints codePoints)
95 | |> Expect.atLeast (List.length codePoints)
96 | , fuzz unicodeStringFuzzer "number of code points is less than or equal to string length" <|
97 | \string ->
98 | List.length (toCodePoints string)
99 | |> Expect.atMost (String.length string)
100 | , fuzz (list codePointFuzzer) "encoded string length is as expected" <|
101 | \codePoints ->
102 | String.length (fromCodePoints codePoints)
103 | |> Expect.equal (expectedStringLength codePoints)
104 | , describe "toCodePoints works as expected on hard-coded test cases"
105 | (hardCodedTestCases
106 | |> List.indexedMap
107 | (\index ( string, codePoints ) ->
108 | test ("toCodePoints works properly - test case " ++ Debug.toString index)
109 | (\() -> toCodePoints string |> Expect.equal codePoints)
110 | )
111 | )
112 | , describe "fromCodePoints works as expected on hard-coded test cases"
113 | (hardCodedTestCases
114 | |> List.indexedMap
115 | (\index ( string, codePoints ) ->
116 | test ("fromCodePoints works properly - test case " ++ Debug.toString index)
117 | (\() -> fromCodePoints codePoints |> Expect.equal string)
118 | )
119 | )
120 | ]
121 |
--------------------------------------------------------------------------------
/tests/UnindentTest.elm:
--------------------------------------------------------------------------------
1 | module UnindentTest exposing (unindentTest)
2 |
3 | import Expect
4 | import Fuzz exposing (..)
5 | import String exposing (uncons)
6 | import String.Extra exposing (..)
7 | import Test exposing (..)
8 | import Tuple exposing (first)
9 |
10 |
11 | unindentTest : Test
12 | unindentTest =
13 | describe "unindent"
14 | [ fuzz multilineProducerString "It produces the same trimmed string" <|
15 | \s ->
16 | let
17 | expected =
18 | String.lines >> List.map String.trimLeft
19 | in
20 | unindent s
21 | |> String.lines
22 | |> List.map String.trimLeft
23 | |> Expect.equal (expected s)
24 | , fuzz multilineProducerString "It produces at least one line with no leading whitespace" <|
25 | \s ->
26 | unindent s
27 | |> String.lines
28 | |> List.map (not << String.startsWith " ")
29 | |> List.any ((==) True)
30 | |> Expect.true "No lines with leading whitespace detected"
31 | , fuzz multilineProducer "All lines' length have been reduced by exactly the minimum indentation" <|
32 | \( s, spaces ) ->
33 | let
34 | expected =
35 | String.lines s
36 | |> List.map String.length
37 | |> List.map (\i -> i - spaces)
38 | in
39 | unindent s
40 | |> String.lines
41 | |> List.map String.length
42 | |> Expect.equal expected
43 | ]
44 |
45 |
46 | multilineProducerString : Fuzzer String
47 | multilineProducerString =
48 | map (convertToMultiline >> first)
49 | (tuple3 ( intRange 0 10, intRange 0 10, intRange 0 10 ))
50 |
51 |
52 | multilineProducer : Fuzzer ( String, Int )
53 | multilineProducer =
54 | map convertToMultiline
55 | (tuple3 ( intRange 0 10, intRange 0 10, intRange 0 10 ))
56 |
57 |
58 | convertToMultiline : ( Int, Int, Int ) -> ( String, Int )
59 | convertToMultiline ( a, b, c ) =
60 | ( [ String.repeat a " " ++ "aaaa aaa "
61 | , String.repeat b " " ++ "aaaa aaa"
62 | , String.repeat c " " ++ "ccc "
63 | ]
64 | |> String.join "\n"
65 | , min (min a b) c
66 | )
67 |
--------------------------------------------------------------------------------
/tests/elm-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "summary": "String Addons library tests",
4 | "repository": "https://github.com/user/project.git",
5 | "license": "BSD3",
6 | "source-directories": [
7 | ".",
8 | "../src"
9 | ],
10 | "exposed-modules": [],
11 | "dependencies": {
12 | "elm-community/elm-test": "4.0.0 <= v < 5.0.0",
13 | "elm-community/shrink": "2.0.0 <= v < 3.0.0",
14 | "elm-lang/core": "5.0.0 <= v < 6.0.0",
15 | "mgold/elm-random-pcg": "4.0.2 <= v < 5.0.0"
16 | },
17 | "elm-version": "0.18.0 <= v < 0.19.0"
18 | }
19 |
--------------------------------------------------------------------------------