imerss-bioinfo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/README.md +156 -0
  2. package/build.js +196 -0
  3. package/docs/css/imerss-viz-all.css +1227 -0
  4. package/docs/css/imerss-viz-wp-overrides.css +70 -0
  5. package/docs/css/pepiowelh.css +76 -0
  6. package/docs/css/xetthecum-external.css +47 -0
  7. package/docs/css/xetthecum-shared.css +80 -0
  8. package/docs/css/xetthecum.css +526 -0
  9. package/docs/js/imerss-viz-all.js +58 -0
  10. package/docs/js/imerss-viz-all.js.map +1 -0
  11. package/docs/js/jquery.js +10881 -0
  12. package/index.html +81 -0
  13. package/index.js +7 -0
  14. package/indexWithJustMap.html +92 -0
  15. package/indexWithMap.html +79 -0
  16. package/indexWithMapHoweSound.html +91 -0
  17. package/indexWithMapPepiowelh.html +119 -0
  18. package/indexWithMapValdes.html +90 -0
  19. package/indexWithMapXetthecum.html +90 -0
  20. package/package.json +50 -0
  21. package/src/WoRMS/taxonAPI.js +13 -0
  22. package/src/arphify.js +662 -0
  23. package/src/assignNames.js +103 -0
  24. package/src/auxBuild/restoreJQuery.js +1 -0
  25. package/src/buildSource/Comprehensive Lists.html +42 -0
  26. package/src/buildSource/Data Paper Part I Visualisation.html +50 -0
  27. package/src/buildSource/Galiano Life List.html +43 -0
  28. package/src/buildSource/Metchosin/index.html +22 -0
  29. package/src/buildSource/Pe'pi'ow'elh.html +72 -0
  30. package/src/buildSource/Squamish Life List.html +48 -0
  31. package/src/buildSource/Valdes Island Biodiversity.html +64 -0
  32. package/src/buildSource/Xetthecum.html +40 -0
  33. package/src/buildSource/dataPaperSunburstAndMap.html +30 -0
  34. package/src/buildSource/index.html +224 -0
  35. package/src/client/css/imerss-viz-wp-overrides.css +70 -0
  36. package/src/client/css/imerss-viz.css +531 -0
  37. package/src/client/css/pepiowelh.css +76 -0
  38. package/src/client/css/xetthecum-external.css +47 -0
  39. package/src/client/css/xetthecum-shared.css +80 -0
  40. package/src/client/css/xetthecum.css +526 -0
  41. package/src/client/html/imerss-viz-map-only.html +75 -0
  42. package/src/client/html/imerss-viz-map-pepi.html +77 -0
  43. package/src/client/html/imerss-viz-map-xetthecum.html +90 -0
  44. package/src/client/html/imerss-viz-map.html +75 -0
  45. package/src/client/html/imerss-viz.html +58 -0
  46. package/src/client/html/importing Xetthecum patterns.txt +10 -0
  47. package/src/client/html/xetthecum-patterns.html +27 -0
  48. package/src/client/img/Animalia_2.svg +1 -0
  49. package/src/client/img/Animalia_Annelida.svg +655 -0
  50. package/src/client/img/Animalia_Chaetognatha.svg +72 -0
  51. package/src/client/img/Animalia_Cnidaria.svg +173 -0
  52. package/src/client/img/Animalia_Ctenophora.svg +298 -0
  53. package/src/client/img/Animalia_Nemertea.svg +54 -0
  54. package/src/client/img/Animalia_Phoronida.svg +271 -0
  55. package/src/client/img/Animalia_Platyhelminthes.svg +58 -0
  56. package/src/client/img/Animalia_Porifera.svg +220 -0
  57. package/src/client/img/Animalia_Sipuncula.svg +155 -0
  58. package/src/client/img/Arachnoidiscus_schmidtii_web_1-2-scaled.webp +0 -0
  59. package/src/client/img/Arrow-down.svg +11 -0
  60. package/src/client/img/Arrow-up.svg +6 -0
  61. package/src/client/img/Chromista.svg +1 -0
  62. package/src/client/img/Pepiowelh/BlackNoWe2-wb-bb.png +0 -0
  63. package/src/client/img/Pepiowelh/BlackNoWe2-wb.png +0 -0
  64. package/src/client/img/Pepiowelh/BlackNoWe2.png +0 -0
  65. package/src/client/img/Pepiowelh/Ecocultural Mapping Banner.svg +1 -0
  66. package/src/client/img/Plankton.jpg +0 -0
  67. package/src/client/img/Plantae.svg +1 -0
  68. package/src/client/img/Plantae_2.svg +1 -0
  69. package/src/client/img/Protista.svg +1 -0
  70. package/src/client/img/Valdes/Valdes Island Conservancy.jpg +0 -0
  71. package/src/client/img/Xetthecum/Agricultural.jpg +0 -0
  72. package/src/client/img/Xetthecum/Anthropogenic_banner.jpg +0 -0
  73. package/src/client/img/Xetthecum/Broad_Leaf.jpg +0 -0
  74. package/src/client/img/Xetthecum/Caves.jpg +0 -0
  75. package/src/client/img/Xetthecum/Coastal_Bluffs.jpg +0 -0
  76. package/src/client/img/Xetthecum/Conifer_Pole_Sapling.jpg +0 -0
  77. package/src/client/img/Xetthecum/Developed.jpg +0 -0
  78. package/src/client/img/Xetthecum/Dock.jpg +0 -0
  79. package/src/client/img/Xetthecum/Eelgrass.jpg +0 -0
  80. package/src/client/img/Xetthecum/Forests_banner.jpg +0 -0
  81. package/src/client/img/Xetthecum/Freshwater_banner.jpg +0 -0
  82. package/src/client/img/Xetthecum/Greig_Creek.jpg +0 -0
  83. package/src/client/img/Xetthecum/Intertidal.jpg +0 -0
  84. package/src/client/img/Xetthecum/Laughlin_Lake.jpg +0 -0
  85. package/src/client/img/Xetthecum/Marine_banner.jpg +0 -0
  86. package/src/client/img/Xetthecum/Mature_Conifer_Forest.jpg +0 -0
  87. package/src/client/img/Xetthecum/Porlier_Pass_Road.jpg +0 -0
  88. package/src/client/img/Xetthecum/Riparian.jpg +0 -0
  89. package/src/client/img/Xetthecum/Rural.jpg +0 -0
  90. package/src/client/img/Xetthecum/Subtidal.jpg +0 -0
  91. package/src/client/img/Xetthecum/Wetland.jpg +0 -0
  92. package/src/client/img/Xetthecum/Woodland.jpg +0 -0
  93. package/src/client/img/Xetthecum/Woodland_banner.jpg +0 -0
  94. package/src/client/img/Xetthecum/Xetthecum.jpg +0 -0
  95. package/src/client/img/Xetthecum/Young_Conifer_Forest.jpg +0 -0
  96. package/src/client/img/Xetthecum/Young_Mixed_Forest.jpg +0 -0
  97. package/src/client/img/Xetthecum/food.svg +38 -0
  98. package/src/client/img/Xetthecum/indicator.svg +52 -0
  99. package/src/client/img/Xetthecum/material.svg +186 -0
  100. package/src/client/img/Xetthecum/medicinal.svg +62 -0
  101. package/src/client/img/Xetthecum/missing-value.svg +3 -0
  102. package/src/client/img/Xetthecum/spiritual.svg +13 -0
  103. package/src/client/img/Xetthecum/trade.svg +74 -0
  104. package/src/client/img/audio.svg +5 -0
  105. package/src/client/img/external-link.svg +3 -0
  106. package/src/client/img/selected-eye.svg +4 -0
  107. package/src/client/img/selected-tick.svg +3 -0
  108. package/src/client/img/thumbs/BCLeps.jpg +0 -0
  109. package/src/client/img/thumbs/Checklist.jpg +0 -0
  110. package/src/client/img/thumbs/Data-Paper-Figma.jpg +0 -0
  111. package/src/client/img/thumbs/Galiano-Data-Paper.jpg +0 -0
  112. package/src/client/img/thumbs/Galiano.jpg +0 -0
  113. package/src/client/img/thumbs/Maxwell.jpg +0 -0
  114. package/src/client/img/thumbs/Squamish.jpg +0 -0
  115. package/src/client/img/thumbs/Valdes.jpg +0 -0
  116. package/src/client/img/thumbs/Xetthecum.jpg +0 -0
  117. package/src/client/img/up-arrow.svg +4 -0
  118. package/src/client/js/autocomplete.js +53 -0
  119. package/src/client/js/checklist.js +179 -0
  120. package/src/client/js/colour.js +139 -0
  121. package/src/client/js/datasetControls.js +212 -0
  122. package/src/client/js/imerss-viz.js +1397 -0
  123. package/src/client/js/leafletMap.js +357 -0
  124. package/src/client/js/leafletMapWithGrid.js +337 -0
  125. package/src/client/js/leafletMapWithRegions.js +381 -0
  126. package/src/client/js/renderSVG.js +108 -0
  127. package/src/client/js/tabs.js +53 -0
  128. package/src/client/js/xetthecum.js +106 -0
  129. package/src/client/json/emptyPhyloMap.json +1 -0
  130. package/src/client/json/kingdomPhyloMap.json +17 -0
  131. package/src/client/json/phyloMap.json +58 -0
  132. package/src/compare.js +97 -0
  133. package/src/compilecsv.js +47 -0
  134. package/src/dataProcessing/LZ4.js +27 -0
  135. package/src/dataProcessing/coordinatePatch.js +151 -0
  136. package/src/dataProcessing/readCSV.js +107 -0
  137. package/src/dataProcessing/readCSVwithMap.js +90 -0
  138. package/src/dataProcessing/readCSVwithoutMap.js +25 -0
  139. package/src/dataProcessing/readJSON.js +23 -0
  140. package/src/dataProcessing/sqlite.js +174 -0
  141. package/src/dataProcessing/summarise.js +122 -0
  142. package/src/dataProcessing/taxonScrape.js +14 -0
  143. package/src/dataProcessing/worker.js +31 -0
  144. package/src/dataProcessing/writeCSV.js +34 -0
  145. package/src/dataProcessing/writeJSON.js +15 -0
  146. package/src/dbtaxa.js +96 -0
  147. package/src/deAuthorise.js +48 -0
  148. package/src/deqgis.js +148 -0
  149. package/src/expressions/expr.js +65 -0
  150. package/src/expressions/jsep.js +925 -0
  151. package/src/filterFirst.js +51 -0
  152. package/src/geom/geoJSON.js +121 -0
  153. package/src/iNaturalist/examples/api.inaturalist.org-v1-taxa!q=Acmispon americanus americanus.json +200 -0
  154. package/src/iNaturalist/examples/api.inaturalist.org-v1-taxa!q=Flabellina japonica.json +61 -0
  155. package/src/iNaturalist/examples/www.inaturalist.org-taxa-877359.json +132 -0
  156. package/src/iNaturalist/iNatUrls.js +17 -0
  157. package/src/iNaturalist/obsAPI.js +150 -0
  158. package/src/iNaturalist/taxonAPI.js +460 -0
  159. package/src/inatObs.js +120 -0
  160. package/src/inattify.js +123 -0
  161. package/src/intersect.js +80 -0
  162. package/src/intersectFilter.js +48 -0
  163. package/src/landlocked.js +137 -0
  164. package/src/lib/jquery.binarytransport.js +51 -0
  165. package/src/lib/lz4-commentary.txt +9 -0
  166. package/src/lib/lz4.js +73 -0
  167. package/src/lib/point-in-polygon.js +36 -0
  168. package/src/lz4.js +40 -0
  169. package/src/marmalise.js +333 -0
  170. package/src/materialise.js +68 -0
  171. package/src/reintegrate.js +71 -0
  172. package/src/taxonomise.js +615 -0
  173. package/src/unscrewGBIF.js +44 -0
  174. package/src/utils/dataSource.js +173 -0
  175. package/src/utils/settleStructure.js +62 -0
  176. package/src/utils/utils.js +92 -0
  177. package/src/viz/plethify.js +39 -0
  178. package/src/wormify.js +154 -0
  179. package/src/xetthecum/xetthecumFilters.js +126 -0
  180. package/test/testDataSource.js +182 -0
  181. package/test/testiNatObsSource.js +38 -0
  182. package/test/testiNatSource.js +50 -0
@@ -0,0 +1,925 @@
1
+ /* eslint-disable */
2
+
3
+ // This file was taken from revision 25fcb53 of https://github.com/EricSmekens/jsep/blob/master/src/jsep.js
4
+ // since we need the fix which axed "LogicalExpression" but need to defeat the insufferable ES6 modules crap
5
+ // which prevents it from loading. The "export" keyword was removed from the top of the file and a standard
6
+ // CJS export was put at the bottom. Probably when jsep 0.5.0 is released we can update to it
7
+
8
+ // JavaScript Expression Parser (JSEP) <%= version %>
9
+ // JSEP may be freely distributed under the MIT License
10
+ // https://ericsmekens.github.io/jsep/
11
+ class Jsep {
12
+ /**
13
+ * @returns {string}
14
+ */
15
+ static get version() {
16
+ // To be filled in by the template
17
+ return '<%= version %>';
18
+ }
19
+
20
+ /**
21
+ * @returns {string}
22
+ */
23
+ static toString() {
24
+ return 'JavaScript Expression Parser (JSEP) v' + Jsep.version;
25
+ };
26
+
27
+ // ==================== CONFIG ================================
28
+ /**
29
+ * @method addUnaryOp
30
+ * @param {string} op_name The name of the unary op to add
31
+ * @returns {Jsep}
32
+ */
33
+ static addUnaryOp(op_name) {
34
+ Jsep.max_unop_len = Math.max(op_name.length, Jsep.max_unop_len);
35
+ Jsep.unary_ops[op_name] = 1;
36
+ return Jsep;
37
+ }
38
+
39
+ /**
40
+ * @method jsep.addBinaryOp
41
+ * @param {string} op_name The name of the binary op to add
42
+ * @param {number} precedence The precedence of the binary op (can be a float)
43
+ * @returns {Jsep}
44
+ */
45
+ static addBinaryOp(op_name, precedence) {
46
+ Jsep.max_binop_len = Math.max(op_name.length, Jsep.max_binop_len);
47
+ Jsep.binary_ops[op_name] = precedence;
48
+ return Jsep;
49
+ }
50
+
51
+ /**
52
+ * @method addIdentifierChar
53
+ * @param {string} char The additional character to treat as a valid part of an identifier
54
+ * @returns {Jsep}
55
+ */
56
+ static addIdentifierChar(char) {
57
+ Jsep.additional_identifier_chars.add(char);
58
+ return Jsep;
59
+ }
60
+
61
+ /**
62
+ * @method addLiteral
63
+ * @param {string} literal_name The name of the literal to add
64
+ * @param {*} literal_value The value of the literal
65
+ * @returns {Jsep}
66
+ */
67
+ static addLiteral(literal_name, literal_value) {
68
+ Jsep.literals[literal_name] = literal_value;
69
+ return Jsep;
70
+ }
71
+
72
+ /**
73
+ * @method removeUnaryOp
74
+ * @param {string} op_name The name of the unary op to remove
75
+ * @returns {Jsep}
76
+ */
77
+ static removeUnaryOp(op_name) {
78
+ delete Jsep.unary_ops[op_name];
79
+ if (op_name.length === Jsep.max_unop_len) {
80
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
81
+ }
82
+ return Jsep;
83
+ }
84
+
85
+ /**
86
+ * @method removeAllUnaryOps
87
+ * @returns {Jsep}
88
+ */
89
+ static removeAllUnaryOps() {
90
+ Jsep.unary_ops = {};
91
+ Jsep.max_unop_len = 0;
92
+
93
+ return Jsep;
94
+ }
95
+
96
+ /**
97
+ * @method removeIdentifierChar
98
+ * @param {string} char The additional character to stop treating as a valid part of an identifier
99
+ * @returns {Jsep}
100
+ */
101
+ static removeIdentifierChar(char) {
102
+ Jsep.additional_identifier_chars.delete(char);
103
+ return Jsep;
104
+ }
105
+
106
+ /**
107
+ * @method removeBinaryOp
108
+ * @param {string} op_name The name of the binary op to remove
109
+ * @returns {Jsep}
110
+ */
111
+ static removeBinaryOp(op_name) {
112
+ delete Jsep.binary_ops[op_name];
113
+
114
+ if (op_name.length === Jsep.max_binop_len) {
115
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
116
+ }
117
+
118
+ return Jsep;
119
+ }
120
+
121
+ /**
122
+ * @method removeAllBinaryOps
123
+ * @returns {Jsep}
124
+ */
125
+ static removeAllBinaryOps() {
126
+ Jsep.binary_ops = {};
127
+ Jsep.max_binop_len = 0;
128
+
129
+ return Jsep;
130
+ }
131
+
132
+ /**
133
+ * @method removeLiteral
134
+ * @param {string} literal_name The name of the literal to remove
135
+ * @returns {Jsep}
136
+ */
137
+ static removeLiteral(literal_name) {
138
+ delete Jsep.literals[literal_name];
139
+ return Jsep;
140
+ }
141
+
142
+ /**
143
+ * @method removeAllLiterals
144
+ * @returns {Jsep}
145
+ */
146
+ static removeAllLiterals() {
147
+ Jsep.literals = {};
148
+
149
+ return Jsep;
150
+ }
151
+ // ==================== END CONFIG ============================
152
+
153
+
154
+ /**
155
+ * @returns {string}
156
+ */
157
+ get char() {
158
+ return this.expr.charAt(this.index);
159
+ }
160
+
161
+ /**
162
+ * @returns {number}
163
+ */
164
+ get code() {
165
+ return this.expr.charCodeAt(this.index);
166
+ };
167
+
168
+
169
+ /**
170
+ * @param {string} expr a string with the passed in express
171
+ * @returns Jsep
172
+ */
173
+ constructor(expr) {
174
+ // `index` stores the character number we are currently at
175
+ // All of the gobbles below will modify `index` as we move along
176
+ this.expr = expr;
177
+ this.index = 0;
178
+ }
179
+
180
+ /**
181
+ * static top-level parser
182
+ * @returns {jsep.Expression}
183
+ */
184
+ static parse(expr) {
185
+ return (new Jsep(expr)).parse();
186
+ }
187
+
188
+ /**
189
+ * Get the longest key length of any object
190
+ * @param {object} obj
191
+ * @returns {number}
192
+ */
193
+ static getMaxKeyLen(obj) {
194
+ return Math.max(0, ...Object.keys(obj).map(k => k.length));
195
+ }
196
+
197
+ /**
198
+ * `ch` is a character code in the next three functions
199
+ * @param {number} ch
200
+ * @returns {boolean}
201
+ */
202
+ static isDecimalDigit(ch) {
203
+ return (ch >= 48 && ch <= 57); // 0...9
204
+ }
205
+
206
+ /**
207
+ * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float.
208
+ * @param {string} op_val
209
+ * @returns {number}
210
+ */
211
+ static binaryPrecedence(op_val) {
212
+ return Jsep.binary_ops[op_val] || 0;
213
+ }
214
+
215
+ /**
216
+ * Looks for start of identifier
217
+ * @param {number} ch
218
+ * @returns {boolean}
219
+ */
220
+ static isIdentifierStart(ch) {
221
+ return (ch >= 65 && ch <= 90) || // A...Z
222
+ (ch >= 97 && ch <= 122) || // a...z
223
+ (ch >= 128 && !Jsep.binary_ops[String.fromCharCode(ch)]) || // any non-ASCII that is not an operator
224
+ (Jsep.additional_identifier_chars.has(String.fromCharCode(ch))); // additional characters
225
+ }
226
+
227
+ /**
228
+ * @param {number} ch
229
+ * @returns {boolean}
230
+ */
231
+ static isIdentifierPart(ch) {
232
+ return Jsep.isIdentifierStart(ch) || Jsep.isDecimalDigit(ch);
233
+ }
234
+
235
+ /**
236
+ * throw error at index of the expression
237
+ * @param {string} message
238
+ * @throws
239
+ */
240
+ throwError(message) {
241
+ const error = new Error(message + ' at character ' + this.index);
242
+ error.index = this.index;
243
+ error.description = message;
244
+ throw error;
245
+ }
246
+
247
+ /**
248
+ * Push `index` up to the next non-space character
249
+ */
250
+ gobbleSpaces() {
251
+ let ch = this.code;
252
+ // Whitespace
253
+ while (ch === Jsep.SPACE_CODE
254
+ || ch === Jsep.TAB_CODE
255
+ || ch === Jsep.LF_CODE
256
+ || ch === Jsep.CR_CODE) {
257
+ ch = this.expr.charCodeAt(++this.index);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Top-level method to parse all expressions and returns compound or single node
263
+ * @returns {jsep.Expression}
264
+ */
265
+ parse() {
266
+ const nodes = this.gobbleExpressions();
267
+
268
+ // If there's only one expression just try returning the expression
269
+ if (nodes.length === 1) {
270
+ return nodes[0];
271
+ }
272
+ else {
273
+ return {
274
+ type: Jsep.COMPOUND,
275
+ body: nodes
276
+ };
277
+ }
278
+ }
279
+
280
+ /**
281
+ * top-level parser (but can be reused within as well)
282
+ * @param {number} [untilICode]
283
+ * @returns {jsep.Expression[]}
284
+ */
285
+ gobbleExpressions(untilICode) {
286
+ let nodes = [], ch_i, node;
287
+
288
+ while (this.index < this.expr.length) {
289
+ ch_i = this.code;
290
+
291
+ // Expressions can be separated by semicolons, commas, or just inferred without any
292
+ // separators
293
+ if (ch_i === Jsep.SEMCOL_CODE || ch_i === Jsep.COMMA_CODE) {
294
+ this.index++; // ignore separators
295
+ }
296
+ else {
297
+ // Try to gobble each expression individually
298
+ if (node = this.gobbleExpression()) {
299
+ nodes.push(node);
300
+ // If we weren't able to find a binary expression and are out of room, then
301
+ // the expression passed in probably has too much
302
+ }
303
+ else if (this.index < this.expr.length) {
304
+ if (ch_i === untilICode) {
305
+ break;
306
+ }
307
+ this.throwError('Unexpected "' + this.char + '"');
308
+ }
309
+ }
310
+ }
311
+
312
+ return nodes;
313
+ }
314
+
315
+ //
316
+ /**
317
+ * The main parsing function. Much of this code is dedicated to ternary expressions
318
+ * @returns {?jsep.Expression}
319
+ */
320
+ gobbleExpression() {
321
+ const test = this.gobbleBinaryExpression();
322
+
323
+ this.gobbleSpaces();
324
+
325
+ if (this.code === Jsep.QUMARK_CODE) {
326
+ // Ternary expression: test ? consequent : alternate
327
+ this.index++;
328
+ const consequent = this.gobbleExpression();
329
+
330
+ if (!consequent) {
331
+ this.throwError('Expected expression');
332
+ }
333
+
334
+ this.gobbleSpaces();
335
+
336
+ if (this.code === Jsep.COLON_CODE) {
337
+ this.index++;
338
+ const alternate = this.gobbleExpression();
339
+
340
+ if (!alternate) {
341
+ this.throwError('Expected expression');
342
+ }
343
+ return {
344
+ type: Jsep.CONDITIONAL_EXP,
345
+ test,
346
+ consequent,
347
+ alternate
348
+ };
349
+ }
350
+ else {
351
+ this.throwError('Expected :');
352
+ }
353
+ }
354
+ else {
355
+ return test;
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Search for the operation portion of the string (e.g. `+`, `===`)
361
+ * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`)
362
+ * and move down from 3 to 2 to 1 character until a matching binary operation is found
363
+ * then, return that binary operation
364
+ * @returns {string|boolean}
365
+ */
366
+ gobbleBinaryOp() {
367
+ this.gobbleSpaces();
368
+ let to_check = this.expr.substr(this.index, Jsep.max_binop_len);
369
+ let tc_len = to_check.length;
370
+
371
+ while (tc_len > 0) {
372
+ // Don't accept a binary op when it is an identifier.
373
+ // Binary ops that start with a identifier-valid character must be followed
374
+ // by a non identifier-part valid character
375
+ if (Jsep.binary_ops.hasOwnProperty(to_check) && (
376
+ !Jsep.isIdentifierStart(this.code) ||
377
+ (this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))
378
+ )) {
379
+ this.index += tc_len;
380
+ return to_check;
381
+ }
382
+ to_check = to_check.substr(0, --tc_len);
383
+ }
384
+ return false;
385
+ }
386
+
387
+ /**
388
+ * This function is responsible for gobbling an individual expression,
389
+ * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)`
390
+ * @returns {?jsep.BinaryExpression}
391
+ */
392
+ gobbleBinaryExpression() {
393
+ let node, biop, prec, stack, biop_info, left, right, i, cur_biop;
394
+
395
+ // First, try to get the leftmost thing
396
+ // Then, check to see if there's a binary operator operating on that leftmost thing
397
+ left = this.gobbleToken();
398
+ biop = this.gobbleBinaryOp();
399
+
400
+ // If there wasn't a binary operator, just return the leftmost node
401
+ if (!biop) {
402
+ return left;
403
+ }
404
+
405
+ // Otherwise, we need to start a stack to properly place the binary operations in their
406
+ // precedence structure
407
+ biop_info = { value: biop, prec: Jsep.binaryPrecedence(biop)};
408
+
409
+ right = this.gobbleToken();
410
+
411
+ if (!right) {
412
+ this.throwError("Expected expression after " + biop);
413
+ }
414
+
415
+ stack = [left, biop_info, right];
416
+
417
+ // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm)
418
+ while ((biop = this.gobbleBinaryOp())) {
419
+ prec = Jsep.binaryPrecedence(biop);
420
+
421
+ if (prec === 0) {
422
+ this.index -= biop.length;
423
+ break;
424
+ }
425
+
426
+ biop_info = { value: biop, prec };
427
+
428
+ cur_biop = biop;
429
+
430
+ // Reduce: make a binary expression from the three topmost entries.
431
+ while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
432
+ right = stack.pop();
433
+ biop = stack.pop().value;
434
+ left = stack.pop();
435
+ node = {
436
+ type: Jsep.BINARY_EXP,
437
+ operator: biop,
438
+ left,
439
+ right
440
+ };
441
+ stack.push(node);
442
+ }
443
+
444
+ node = this.gobbleToken();
445
+
446
+ if (!node) {
447
+ this.throwError("Expected expression after " + cur_biop);
448
+ }
449
+
450
+ stack.push(biop_info, node);
451
+ }
452
+
453
+ i = stack.length - 1;
454
+ node = stack[i];
455
+
456
+ while (i > 1) {
457
+ node = {
458
+ type: Jsep.BINARY_EXP,
459
+ operator: stack[i - 1].value,
460
+ left: stack[i - 2],
461
+ right: node
462
+ };
463
+ i -= 2;
464
+ }
465
+
466
+ return node;
467
+ }
468
+
469
+ /**
470
+ * An individual part of a binary expression:
471
+ * e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis)
472
+ * @returns {boolean|jsep.Expression}
473
+ */
474
+ gobbleToken() {
475
+ let ch, to_check, tc_len, node;
476
+
477
+ this.gobbleSpaces();
478
+ ch = this.code;
479
+
480
+ if (Jsep.isDecimalDigit(ch) || ch === Jsep.PERIOD_CODE) {
481
+ // Char code 46 is a dot `.` which can start off a numeric literal
482
+ return this.gobbleNumericLiteral();
483
+ }
484
+
485
+ if (ch === Jsep.SQUOTE_CODE || ch === Jsep.DQUOTE_CODE) {
486
+ // Single or double quotes
487
+ node = this.gobbleStringLiteral();
488
+ }
489
+ else if (ch === Jsep.OBRACK_CODE) {
490
+ node = this.gobbleArray();
491
+ }
492
+ else {
493
+ to_check = this.expr.substr(this.index, Jsep.max_unop_len);
494
+ tc_len = to_check.length;
495
+
496
+ while (tc_len > 0) {
497
+ // Don't accept an unary op when it is an identifier.
498
+ // Unary ops that start with a identifier-valid character must be followed
499
+ // by a non identifier-part valid character
500
+ if (Jsep.unary_ops.hasOwnProperty(to_check) && (
501
+ !Jsep.isIdentifierStart(this.code) ||
502
+ (this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))
503
+ )) {
504
+ this.index += tc_len;
505
+ return {
506
+ type: Jsep.UNARY_EXP,
507
+ operator: to_check,
508
+ argument: this.gobbleToken(),
509
+ prefix: true
510
+ };
511
+ }
512
+
513
+ to_check = to_check.substr(0, --tc_len);
514
+ }
515
+
516
+ if (Jsep.isIdentifierStart(ch)) {
517
+ node = this.gobbleIdentifier();
518
+ }
519
+ else if (ch === Jsep.OPAREN_CODE) { // open parenthesis
520
+ node = this.gobbleGroup();
521
+ }
522
+ }
523
+
524
+ if (!node) {
525
+ return false;
526
+ }
527
+
528
+ this.gobbleSpaces();
529
+
530
+ ch = this.code;
531
+
532
+ // Gobble properties of of identifiers/strings/arrays/groups.
533
+ // e.g. `foo`, `bar.baz`, `foo['bar'].baz`
534
+ // It also gobbles function calls:
535
+ // e.g. `Math.acos(obj.angle)`
536
+
537
+ while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE) {
538
+ this.index++;
539
+
540
+ if (ch === Jsep.PERIOD_CODE) {
541
+ this.gobbleSpaces();
542
+ node = {
543
+ type: Jsep.MEMBER_EXP,
544
+ computed: false,
545
+ object: node,
546
+ property: this.gobbleIdentifier()
547
+ };
548
+ }
549
+ else if (ch === Jsep.OBRACK_CODE) {
550
+ node = {
551
+ type: Jsep.MEMBER_EXP,
552
+ computed: true,
553
+ object: node,
554
+ property: this.gobbleExpression()
555
+ };
556
+ this.gobbleSpaces();
557
+ ch = this.code;
558
+ if (ch !== Jsep.CBRACK_CODE) {
559
+ this.throwError('Unclosed [');
560
+ }
561
+ this.index++;
562
+ }
563
+ else if (ch === Jsep.OPAREN_CODE) {
564
+ // A function call is being made; gobble all the arguments
565
+ node = {
566
+ type: Jsep.CALL_EXP,
567
+ 'arguments': this.gobbleArguments(Jsep.CPAREN_CODE),
568
+ callee: node
569
+ };
570
+ }
571
+ this.gobbleSpaces();
572
+ ch = this.code;
573
+ }
574
+
575
+ return node;
576
+ }
577
+
578
+ /**
579
+ * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to
580
+ * keep track of everything in the numeric literal and then calling `parseFloat` on that string
581
+ * @returns {jsep.Literal}
582
+ */
583
+ gobbleNumericLiteral() {
584
+ let number = '', ch, chCode;
585
+
586
+ while (Jsep.isDecimalDigit(this.code)) {
587
+ number += this.expr.charAt(this.index++);
588
+ }
589
+
590
+ if (this.code === Jsep.PERIOD_CODE) { // can start with a decimal marker
591
+ number += this.expr.charAt(this.index++);
592
+
593
+ while (Jsep.isDecimalDigit(this.code)) {
594
+ number += this.expr.charAt(this.index++);
595
+ }
596
+ }
597
+
598
+ ch = this.char;
599
+
600
+ if (ch === 'e' || ch === 'E') { // exponent marker
601
+ number += this.expr.charAt(this.index++);
602
+ ch = this.char;
603
+
604
+ if (ch === '+' || ch === '-') { // exponent sign
605
+ number += this.expr.charAt(this.index++);
606
+ }
607
+
608
+ while (Jsep.isDecimalDigit(this.code)) { // exponent itself
609
+ number += this.expr.charAt(this.index++);
610
+ }
611
+
612
+ if (!Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1)) ) {
613
+ this.throwError('Expected exponent (' + number + this.char + ')');
614
+ }
615
+ }
616
+
617
+ chCode = this.code;
618
+
619
+ // Check to make sure this isn't a variable name that start with a number (123abc)
620
+ if (Jsep.isIdentifierStart(chCode)) {
621
+ this.throwError('Variable names cannot start with a number (' +
622
+ number + this.char + ')');
623
+ }
624
+ else if (chCode === Jsep.PERIOD_CODE) {
625
+ this.throwError('Unexpected period');
626
+ }
627
+
628
+ return {
629
+ type: Jsep.LITERAL,
630
+ value: parseFloat(number),
631
+ raw: number
632
+ };
633
+ }
634
+
635
+ /**
636
+ * Parses a string literal, staring with single or double quotes with basic support for escape codes
637
+ * e.g. `"hello world"`, `'this is\nJSEP'`
638
+ * @returns {jsep.Literal}
639
+ */
640
+ gobbleStringLiteral() {
641
+ let str = '';
642
+ let quote = this.expr.charAt(this.index++);
643
+ let closed = false;
644
+
645
+ while (this.index < this.expr.length) {
646
+ let ch = this.expr.charAt(this.index++);
647
+
648
+ if (ch === quote) {
649
+ closed = true;
650
+ break;
651
+ }
652
+ else if (ch === '\\') {
653
+ // Check for all of the common escape codes
654
+ ch = this.expr.charAt(this.index++);
655
+
656
+ switch (ch) {
657
+ case 'n': str += '\n'; break;
658
+ case 'r': str += '\r'; break;
659
+ case 't': str += '\t'; break;
660
+ case 'b': str += '\b'; break;
661
+ case 'f': str += '\f'; break;
662
+ case 'v': str += '\x0B'; break;
663
+ default : str += ch;
664
+ }
665
+ }
666
+ else {
667
+ str += ch;
668
+ }
669
+ }
670
+
671
+ if (!closed) {
672
+ this.throwError('Unclosed quote after "' + str + '"');
673
+ }
674
+
675
+ return {
676
+ type: Jsep.LITERAL,
677
+ value: str,
678
+ raw: quote + str + quote
679
+ };
680
+ }
681
+
682
+ /**
683
+ * Gobbles only identifiers
684
+ * e.g.: `foo`, `_value`, `$x1`
685
+ * Also, this function checks if that identifier is a literal:
686
+ * (e.g. `true`, `false`, `null`) or `this`
687
+ * @returns {jsep.Expression}
688
+ */
689
+ gobbleIdentifier() {
690
+ let ch = this.code, start = this.index, identifier;
691
+
692
+ if (Jsep.isIdentifierStart(ch)) {
693
+ this.index++;
694
+ }
695
+ else {
696
+ this.throwError('Unexpected ' + this.char);
697
+ }
698
+
699
+ while (this.index < this.expr.length) {
700
+ ch = this.code;
701
+
702
+ if (Jsep.isIdentifierPart(ch)) {
703
+ this.index++;
704
+ }
705
+ else {
706
+ break;
707
+ }
708
+ }
709
+ identifier = this.expr.slice(start, this.index);
710
+
711
+ if (Jsep.literals.hasOwnProperty(identifier)) {
712
+ return {
713
+ type: Jsep.LITERAL,
714
+ value: Jsep.literals[identifier],
715
+ raw: identifier
716
+ };
717
+ }
718
+ else if (identifier === Jsep.this_str) {
719
+ return { type: Jsep.THIS_EXP };
720
+ }
721
+ else {
722
+ return {
723
+ type: Jsep.IDENTIFIER,
724
+ name: identifier
725
+ };
726
+ }
727
+ }
728
+
729
+ /**
730
+ * Gobbles a list of arguments within the context of a function call
731
+ * or array literal. This function also assumes that the opening character
732
+ * `(` or `[` has already been gobbled, and gobbles expressions and commas
733
+ * until the terminator character `)` or `]` is encountered.
734
+ * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]`
735
+ * @param {string} termination
736
+ * @returns {jsep.Expression[]}
737
+ */
738
+ gobbleArguments(termination) {
739
+ const args = [];
740
+ let closed = false;
741
+ let separator_count = 0;
742
+
743
+ while (this.index < this.expr.length) {
744
+ this.gobbleSpaces();
745
+ let ch_i = this.code;
746
+
747
+ if (ch_i === termination) { // done parsing
748
+ closed = true;
749
+ this.index++;
750
+
751
+ if (termination === Jsep.CPAREN_CODE && separator_count && separator_count >= args.length){
752
+ this.throwError('Unexpected token ' + String.fromCharCode(termination));
753
+ }
754
+
755
+ break;
756
+ }
757
+ else if (ch_i === Jsep.COMMA_CODE) { // between expressions
758
+ this.index++;
759
+ separator_count++;
760
+
761
+ if (separator_count !== args.length) { // missing argument
762
+ if (termination === Jsep.CPAREN_CODE) {
763
+ this.throwError('Unexpected token ,');
764
+ }
765
+ else if (termination === Jsep.CBRACK_CODE) {
766
+ for (let arg = args.length; arg < separator_count; arg++) {
767
+ args.push(null);
768
+ }
769
+ }
770
+ }
771
+ }
772
+ else {
773
+ const node = this.gobbleExpression();
774
+
775
+ if (!node || node.type === Jsep.COMPOUND) {
776
+ this.throwError('Expected comma');
777
+ }
778
+
779
+ args.push(node);
780
+ }
781
+ }
782
+
783
+ if (!closed) {
784
+ this.throwError('Expected ' + String.fromCharCode(termination));
785
+ }
786
+
787
+ return args;
788
+ }
789
+
790
+ /**
791
+ * Responsible for parsing a group of things within parentheses `()`
792
+ * that have no identifier in front (so not a function call)
793
+ * This function assumes that it needs to gobble the opening parenthesis
794
+ * and then tries to gobble everything within that parenthesis, assuming
795
+ * that the next thing it should see is the close parenthesis. If not,
796
+ * then the expression probably doesn't have a `)`
797
+ * @returns {boolean|jsep.Expression}
798
+ */
799
+ gobbleGroup() {
800
+ this.index++;
801
+ let nodes = this.gobbleExpressions(Jsep.CPAREN_CODE);
802
+ if (this.code === Jsep.CPAREN_CODE) {
803
+ this.index++;
804
+ if (nodes.length === 1) {
805
+ return nodes[0];
806
+ }
807
+ else if (!nodes.length) {
808
+ return false;
809
+ }
810
+ else {
811
+ return {
812
+ type: Jsep.SEQUENCE_EXP,
813
+ expressions: nodes,
814
+ };
815
+ }
816
+ }
817
+ else {
818
+ this.throwError('Unclosed (');
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Responsible for parsing Array literals `[1, 2, 3]`
824
+ * This function assumes that it needs to gobble the opening bracket
825
+ * and then tries to gobble the expressions as arguments.
826
+ * @returns {jsep.ArrayExpression}
827
+ */
828
+ gobbleArray() {
829
+ this.index++;
830
+
831
+ return {
832
+ type: Jsep.ARRAY_EXP,
833
+ elements: this.gobbleArguments(Jsep.CBRACK_CODE)
834
+ };
835
+ }
836
+ }
837
+
838
+ // Backward Compatibility (before adding the static fields):
839
+ const jsep = expr => (new Jsep(expr)).parse();
840
+ const staticMethods = Object.getOwnPropertyNames(Jsep);
841
+ staticMethods
842
+ .slice(staticMethods.indexOf('version'), staticMethods.indexOf('removeAllLiterals') + 1)
843
+ .forEach((m) => {
844
+ jsep[m] = Jsep[m];
845
+ });
846
+ // export default jsep;
847
+
848
+
849
+ // Static fields:
850
+ Object.assign(Jsep, {
851
+ // Node Types
852
+ // ----------
853
+ // This is the full set of types that any JSEP node can be.
854
+ // Store them here to save space when minified
855
+ COMPOUND: 'Compound',
856
+ SEQUENCE_EXP: 'SequenceExpression',
857
+ IDENTIFIER: 'Identifier',
858
+ MEMBER_EXP: 'MemberExpression',
859
+ LITERAL: 'Literal',
860
+ THIS_EXP: 'ThisExpression',
861
+ CALL_EXP: 'CallExpression',
862
+ UNARY_EXP: 'UnaryExpression',
863
+ BINARY_EXP: 'BinaryExpression',
864
+ CONDITIONAL_EXP: 'ConditionalExpression',
865
+ ARRAY_EXP: 'ArrayExpression',
866
+
867
+ TAB_CODE: 9,
868
+ LF_CODE: 10,
869
+ CR_CODE: 13,
870
+ SPACE_CODE: 32,
871
+ PERIOD_CODE: 46, // '.'
872
+ COMMA_CODE: 44, // ','
873
+ SQUOTE_CODE: 39, // single quote
874
+ DQUOTE_CODE: 34, // double quotes
875
+ OPAREN_CODE: 40, // (
876
+ CPAREN_CODE: 41, // )
877
+ OBRACK_CODE: 91, // [
878
+ CBRACK_CODE: 93, // ]
879
+ QUMARK_CODE: 63, // ?
880
+ SEMCOL_CODE: 59, // ;
881
+ COLON_CODE: 58, // :
882
+
883
+
884
+ // Operations
885
+ // ----------
886
+ // Use a quickly-accessible map to store all of the unary operators
887
+ // Values are set to `1` (it really doesn't matter)
888
+ unary_ops: {
889
+ '-': 1,
890
+ '!': 1,
891
+ '~': 1,
892
+ '+': 1
893
+ },
894
+
895
+ // Also use a map for the binary operations but set their values to their
896
+ // binary precedence for quick reference:
897
+ // see [Order of operations](http://en.wikipedia.org/wiki/Order_of_operations#Programming_language)
898
+ binary_ops: {
899
+ '||': 1, '&&': 2, '|': 3, '^': 4, '&': 5,
900
+ '==': 6, '!=': 6, '===': 6, '!==': 6,
901
+ '<': 7, '>': 7, '<=': 7, '>=': 7,
902
+ '<<': 8, '>>': 8, '>>>': 8,
903
+ '+': 9, '-': 9,
904
+ '*': 10, '/': 10, '%': 10
905
+ },
906
+
907
+ // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char)
908
+ additional_identifier_chars: new Set(['$', '_']),
909
+
910
+ // Literals
911
+ // ----------
912
+ // Store the values to return for the various literals we may encounter
913
+ literals: {
914
+ 'true': true,
915
+ 'false': false,
916
+ 'null': null
917
+ },
918
+
919
+ // Except for `this`, which is special. This could be changed to something like `'self'` as well
920
+ this_str: 'this',
921
+ });
922
+ Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);
923
+ Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);
924
+
925
+ module.exports = Jsep;