precedent 1.0.6 → 1.0.7

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 (73) hide show
  1. package/.config/code-server/config.yaml +4 -0
  2. package/.config/configstore/update-notifier-npm-check-updates.json +4 -0
  3. package/.config/configstore/update-notifier-npm.json +4 -0
  4. package/.config/luxury-extras/.vscode/launch.json +46 -0
  5. package/.config/luxury-extras/Dockerfile +32 -0
  6. package/.config/luxury-extras/Dockerfile_LUXURYCode +45 -0
  7. package/.config/luxury-extras/MySQL/Dockerfile +51 -0
  8. package/.config/luxury-extras/MySQL/Dockerfile_LUXURYCODE +65 -0
  9. package/.config/luxury-extras/MySQL/MySQL-Laden-Entry.sh +17 -0
  10. package/.config/luxury-extras/MySQL/MySQL-Security.sql +5 -0
  11. package/.config/luxury-extras/model/ddl/BookStore.ddl +66 -0
  12. package/.config/luxury-extras/model/documentation/Dictionary.md +18 -0
  13. package/.config/luxury-extras/model/documentation/Model-Author.md +20 -0
  14. package/.config/luxury-extras/model/documentation/Model-Book.md +26 -0
  15. package/.config/luxury-extras/model/documentation/Model-BookAuthorJoin.md +14 -0
  16. package/.config/luxury-extras/model/documentation/Model-BookPrice.md +25 -0
  17. package/.config/luxury-extras/model/documentation/Model-Review.md +22 -0
  18. package/.config/luxury-extras/model/documentation/ModelChangeTracking.md +17 -0
  19. package/.config/luxury-extras/model/documentation/README.md +1 -0
  20. package/.config/luxury-extras/model/documentation/diagram/README.md +1 -0
  21. package/.config/luxury-extras/model/documentation/diagram/Stricture_Output.dot +13 -0
  22. package/.config/luxury-extras/model/documentation/diagram/Stricture_Output.png +0 -0
  23. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Author.json +220 -0
  24. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Book.json +268 -0
  25. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-BookAuthorJoin.json +172 -0
  26. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-BookPrice.json +260 -0
  27. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Review.json +236 -0
  28. package/.config/luxury-extras/model/json_schema_entities/README.md +1 -0
  29. package/.config/luxury-extras/model/json_schema_model/BookStore-Extended.json +915 -0
  30. package/.config/luxury-extras/model/json_schema_model/BookStore-PICT.json +1 -0
  31. package/.config/luxury-extras/model/json_schema_model/BookStore.json +280 -0
  32. package/.config/luxury-extras/model/json_schema_model/README.md +1 -0
  33. package/.config/luxury-extras/model/mysql_create/BookStore-CreateDatabase.mysql.sql +116 -0
  34. package/.config/luxury-extras/model/mysql_create/README.md +1 -0
  35. package/.vscode/launch.json +46 -0
  36. package/DockerfileLUXURYCode +45 -0
  37. package/{harness/Debug.js → debug/Harness.js} +0 -0
  38. package/dist/precedent.js +322 -0
  39. package/dist/precedent.min.js +37 -0
  40. package/dist/precedent.min.js.map +1 -0
  41. package/gulpfile.js +56 -62
  42. package/package.json +19 -14
  43. package/source/Precedent-Browser-Shim.js +8 -2
  44. package/.c9/.nakignore +0 -17
  45. package/.c9/metadata/tab0 +0 -1
  46. package/.c9/metadata/tab3 +0 -1
  47. package/.c9/metadata/workspace/.travis.yml +0 -1
  48. package/.c9/metadata/workspace/Ideas.md +0 -1
  49. package/.c9/metadata/workspace/Precedent-Command.js +0 -1
  50. package/.c9/metadata/workspace/Precident-Command.js +0 -1
  51. package/.c9/metadata/workspace/README.md +0 -1
  52. package/.c9/metadata/workspace/bin/Precedent +0 -1
  53. package/.c9/metadata/workspace/bin/Precident +0 -1
  54. package/.c9/metadata/workspace/bower.json +0 -1
  55. package/.c9/metadata/workspace/dist/precedent.latest.min.js +0 -1
  56. package/.c9/metadata/workspace/fs.js +0 -1
  57. package/.c9/metadata/workspace/gulpfile.js +0 -1
  58. package/.c9/metadata/workspace/harness/Debug.js +0 -1
  59. package/.c9/metadata/workspace/internal/module.js +0 -1
  60. package/.c9/metadata/workspace/module.js +0 -1
  61. package/.c9/metadata/workspace/package.json +0 -1
  62. package/.c9/metadata/workspace/source/Precedent-Browser-Shim.js +0 -1
  63. package/.c9/metadata/workspace/source/Precedent-Options.js +0 -1
  64. package/.c9/metadata/workspace/source/Precedent.js +0 -1
  65. package/.c9/metadata/workspace/source/StringParser.js +0 -1
  66. package/.c9/metadata/workspace/source/WordTree.js +0 -1
  67. package/.c9/metadata/workspace/test/Precedent_tests.js +0 -1
  68. package/.c9/project.settings +0 -91
  69. package/.npmignore +0 -37
  70. package/dist/precedent.1.0.5.js +0 -339
  71. package/dist/precedent.1.0.5.min.js +0 -2
  72. package/dist/precedent.1.0.5.min.js.map +0 -1
  73. package/dist/precedent.latest.min.js +0 -2
@@ -0,0 +1,322 @@
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Precedent = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
+ /**
3
+ * @license MIT
4
+ * @author <steven@velozo.com>
5
+ */
6
+
7
+ /**
8
+ * Precedent browser shim loader
9
+ */
10
+
11
+ // Load the precedent module into the browser global automatically.
12
+ var libPrecedent = require('./Precedent.js');
13
+
14
+ if ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))
15
+ {
16
+ window.Precedent = libPrecedent;
17
+ }
18
+
19
+ module.exports = libPrecedent;
20
+ },{"./Precedent.js":2}],2:[function(require,module,exports){
21
+ /**
22
+ * Precedent Meta-Templating
23
+ *
24
+ * @license MIT
25
+ *
26
+ * @author Steven Velozo <steven@velozo.com>
27
+ *
28
+ * @description Process text streams, parsing out meta-template expressions.
29
+ */
30
+ var libWordTree = require(`./WordTree.js`);
31
+ var libStringParser = require(`./StringParser.js`);
32
+
33
+ class Precedent
34
+ {
35
+ /**
36
+ * Precedent Constructor
37
+ */
38
+ constructor()
39
+ {
40
+ this.WordTree = new libWordTree();
41
+
42
+ this.StringParser = new libStringParser();
43
+
44
+ this.ParseTree = this.WordTree.ParseTree;
45
+ }
46
+
47
+ /**
48
+ * Add a Pattern to the Parse Tree
49
+ * @method addPattern
50
+ * @param {Object} pTree - A node on the parse tree to push the characters into
51
+ * @param {string} pPattern - The string to add to the tree
52
+ * @param {number} pIndex - callback function
53
+ * @return {bool} True if adding the pattern was successful
54
+ */
55
+ addPattern(pPatternStart, pPatternEnd, pParser)
56
+ {
57
+ return this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);
58
+ }
59
+
60
+ /**
61
+ * Parse a string with the existing parse tree
62
+ * @method parseString
63
+ * @param {string} pString - The string to parse
64
+ * @return {string} The result from the parser
65
+ */
66
+ parseString(pString)
67
+ {
68
+ return this.StringParser.parseString(pString, this.ParseTree);
69
+ }
70
+ }
71
+
72
+ module.exports = Precedent;
73
+
74
+ },{"./StringParser.js":3,"./WordTree.js":4}],3:[function(require,module,exports){
75
+ /**
76
+ * String Parser
77
+ *
78
+ * @license MIT
79
+ *
80
+ * @author Steven Velozo <steven@velozo.com>
81
+ *
82
+ * @description Parse a string, properly processing each matched token in the word tree.
83
+ */
84
+
85
+ class StringParser
86
+ {
87
+ /**
88
+ * StringParser Constructor
89
+ */
90
+ constructor()
91
+ {
92
+ }
93
+
94
+ /**
95
+ * Create a fresh parsing state object to work with.
96
+ * @method newParserState
97
+ * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)
98
+ * @return {Object} A new parser state object for running a character parser on
99
+ * @private
100
+ */
101
+ newParserState (pParseTree)
102
+ {
103
+ return (
104
+ {
105
+ ParseTree: pParseTree,
106
+
107
+ Output: '',
108
+ OutputBuffer: '',
109
+
110
+ Pattern: false,
111
+
112
+ PatternMatch: false,
113
+ PatternMatchOutputBuffer: ''
114
+ });
115
+ }
116
+
117
+ /**
118
+ * Assign a node of the parser tree to be the next potential match.
119
+ * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).
120
+ * @method assignNode
121
+ * @param {Object} pNode - A node on the parse tree to assign
122
+ * @param {Object} pParserState - The state object for the current parsing task
123
+ * @private
124
+ */
125
+ assignNode (pNode, pParserState)
126
+ {
127
+ pParserState.PatternMatch = pNode;
128
+
129
+ // If the pattern has a END we can assume it has a parse function...
130
+ if (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))
131
+ {
132
+ // ... this is the legitimate start of a pattern.
133
+ pParserState.Pattern = pParserState.PatternMatch;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Append a character to the output buffer in the parser state.
139
+ * This output buffer is used when a potential match is being explored, or a match is being explored.
140
+ * @method appendOutputBuffer
141
+ * @param {string} pCharacter - The character to append
142
+ * @param {Object} pParserState - The state object for the current parsing task
143
+ * @private
144
+ */
145
+ appendOutputBuffer (pCharacter, pParserState)
146
+ {
147
+ pParserState.OutputBuffer += pCharacter;
148
+ }
149
+
150
+ /**
151
+ * Flush the output buffer to the output and clear it.
152
+ * @method flushOutputBuffer
153
+ * @param {Object} pParserState - The state object for the current parsing task
154
+ * @private
155
+ */
156
+ flushOutputBuffer (pParserState)
157
+ {
158
+ pParserState.Output += pParserState.OutputBuffer;
159
+ pParserState.OutputBuffer = '';
160
+ }
161
+
162
+
163
+ /**
164
+ * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.
165
+ * @method checkPatternEnd
166
+ * @param {Object} pParserState - The state object for the current parsing task
167
+ * @private
168
+ */
169
+ checkPatternEnd (pParserState)
170
+ {
171
+ if ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) &&
172
+ (pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))
173
+ {
174
+ // ... this is the end of a pattern, cut off the end tag and parse it.
175
+ // Trim the start and end tags off the output buffer now
176
+ pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));
177
+ // Flush the output buffer.
178
+ this.flushOutputBuffer(pParserState);
179
+ // End pattern mode
180
+ pParserState.Pattern = false;
181
+ pParserState.PatternMatch = false;
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Parse a character in the buffer.
187
+ * @method parseCharacter
188
+ * @param {string} pCharacter - The character to append
189
+ * @param {Object} pParserState - The state object for the current parsing task
190
+ * @private
191
+ */
192
+ parseCharacter (pCharacter, pParserState)
193
+ {
194
+ // (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....
195
+ if (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))
196
+ {
197
+ // ... assign the node as the matched node.
198
+ this.assignNode(pParserState.ParseTree[pCharacter], pParserState);
199
+ this.appendOutputBuffer(pCharacter, pParserState);
200
+ }
201
+ // (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)
202
+ else if (pParserState.PatternMatch)
203
+ {
204
+ // If the pattern has a subpattern with this key
205
+ if (pParserState.PatternMatch.hasOwnProperty(pCharacter))
206
+ {
207
+ // Continue matching patterns.
208
+ this.assignNode(pParserState.PatternMatch[pCharacter], pParserState);
209
+ }
210
+ this.appendOutputBuffer(pCharacter, pParserState);
211
+ if (pParserState.Pattern)
212
+ {
213
+ // ... Check if this is the end of the pattern (if we are matching a valid pattern)...
214
+ this.checkPatternEnd(pParserState);
215
+ }
216
+ }
217
+ // (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
218
+ else
219
+ {
220
+ pParserState.Output += pCharacter;
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Parse a string for matches, and process any template segments that occur.
226
+ * @method parseString
227
+ * @param {string} pString - The string to parse.
228
+ * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)
229
+ */
230
+ parseString (pString, pParseTree)
231
+ {
232
+ let tmpParserState = this.newParserState(pParseTree);
233
+
234
+ for (var i = 0; i < pString.length; i++)
235
+ {
236
+ // TODO: This is not fast.
237
+ this.parseCharacter(pString[i], tmpParserState);
238
+ }
239
+
240
+ this.flushOutputBuffer(tmpParserState);
241
+
242
+ return tmpParserState.Output;
243
+ }
244
+ }
245
+
246
+ module.exports = StringParser;
247
+
248
+ },{}],4:[function(require,module,exports){
249
+ /**
250
+ * Word Tree
251
+ *
252
+ * @license MIT
253
+ *
254
+ * @author Steven Velozo <steven@velozo.com>
255
+ *
256
+ * @description Create a tree (directed graph) of Javascript objects, one character per object.
257
+ */
258
+
259
+ class WordTree
260
+ {
261
+ /**
262
+ * WordTree Constructor
263
+ */
264
+ constructor()
265
+ {
266
+ this.ParseTree = {};
267
+ }
268
+
269
+ /**
270
+ * Add a child character to a Parse Tree node
271
+ * @method addChild
272
+ * @param {Object} pTree - A parse tree to push the characters into
273
+ * @param {string} pPattern - The string to add to the tree
274
+ * @param {number} pIndex - callback function
275
+ * @returns {Object} The resulting leaf node that was added (or found)
276
+ * @private
277
+ */
278
+ addChild (pTree, pPattern, pIndex)
279
+ {
280
+ if (pIndex > pPattern.length)
281
+ return pTree;
282
+
283
+ if (!pTree.hasOwnProperty(pPattern[pIndex]))
284
+ pTree[pPattern[pIndex]] = {};
285
+
286
+ return pTree[pPattern[pIndex]];
287
+ }
288
+
289
+ /** Add a Pattern to the Parse Tree
290
+ * @method addPattern
291
+ * @param {Object} pTree - A node on the parse tree to push the characters into
292
+ * @param {string} pPattern - The string to add to the tree
293
+ * @param {number} pIndex - callback function
294
+ * @return {bool} True if adding the pattern was successful
295
+ */
296
+ addPattern (pPatternStart, pPatternEnd, pParser)
297
+ {
298
+ if (pPatternStart.length < 1)
299
+ return false;
300
+
301
+ let tmpLeaf = this.ParseTree;
302
+
303
+ // Add the tree of leaves iteratively
304
+ for (var i = 0; i < pPatternStart.length; i++)
305
+ tmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);
306
+
307
+ tmpLeaf.PatternStart = pPatternStart;
308
+ tmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;
309
+ tmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser :
310
+ (typeof(pParser) === 'string') ? () => { return pParser; } :
311
+ (pData) => { return pData; };
312
+
313
+ return true;
314
+ }
315
+ }
316
+
317
+ module.exports = WordTree;
318
+
319
+ },{}]},{},[1])(1)
320
+ });
321
+
322
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzb3VyY2UvUHJlY2VkZW50LUJyb3dzZXItU2hpbS5qcyIsInNvdXJjZS9QcmVjZWRlbnQuanMiLCJzb3VyY2UvU3RyaW5nUGFyc2VyLmpzIiwic291cmNlL1dvcmRUcmVlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qKlxuKiBAbGljZW5zZSBNSVRcbiogQGF1dGhvciA8c3RldmVuQHZlbG96by5jb20+XG4qL1xuXG4vKipcbiogUHJlY2VkZW50IGJyb3dzZXIgc2hpbSBsb2FkZXJcbiovXG5cbi8vIExvYWQgdGhlIHByZWNlZGVudCBtb2R1bGUgaW50byB0aGUgYnJvd3NlciBnbG9iYWwgYXV0b21hdGljYWxseS5cbnZhciBsaWJQcmVjZWRlbnQgPSByZXF1aXJlKCcuL1ByZWNlZGVudC5qcycpO1xuXG5pZiAoKHR5cGVvZih3aW5kb3cpID09ICdvYmplY3QnKSAmJiAoIXdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnUHJlY2VkZW50JykpKVxue1xuXHR3aW5kb3cuUHJlY2VkZW50ID0gbGliUHJlY2VkZW50O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpYlByZWNlZGVudDsiLCIvKipcbiogUHJlY2VkZW50IE1ldGEtVGVtcGxhdGluZ1xuKlxuKiBAbGljZW5zZSAgICAgTUlUXG4qXG4qIEBhdXRob3IgICAgICBTdGV2ZW4gVmVsb3pvIDxzdGV2ZW5AdmVsb3pvLmNvbT5cbipcbiogQGRlc2NyaXB0aW9uIFByb2Nlc3MgdGV4dCBzdHJlYW1zLCBwYXJzaW5nIG91dCBtZXRhLXRlbXBsYXRlIGV4cHJlc3Npb25zLlxuKi9cbnZhciBsaWJXb3JkVHJlZSA9IHJlcXVpcmUoYC4vV29yZFRyZWUuanNgKTtcbnZhciBsaWJTdHJpbmdQYXJzZXIgPSByZXF1aXJlKGAuL1N0cmluZ1BhcnNlci5qc2ApO1xuXG5jbGFzcyBQcmVjZWRlbnRcbntcblx0LyoqXG5cdCAqIFByZWNlZGVudCBDb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0dGhpcy5Xb3JkVHJlZSA9IG5ldyBsaWJXb3JkVHJlZSgpO1xuXHRcdFxuXHRcdHRoaXMuU3RyaW5nUGFyc2VyID0gbmV3IGxpYlN0cmluZ1BhcnNlcigpO1xuXG5cdFx0dGhpcy5QYXJzZVRyZWUgPSB0aGlzLldvcmRUcmVlLlBhcnNlVHJlZTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIEFkZCBhIFBhdHRlcm4gdG8gdGhlIFBhcnNlIFRyZWVcblx0ICogQG1ldGhvZCBhZGRQYXR0ZXJuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwVHJlZSAtIEEgbm9kZSBvbiB0aGUgcGFyc2UgdHJlZSB0byBwdXNoIHRoZSBjaGFyYWN0ZXJzIGludG9cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBQYXR0ZXJuIC0gVGhlIHN0cmluZyB0byBhZGQgdG8gdGhlIHRyZWVcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBJbmRleCAtIGNhbGxiYWNrIGZ1bmN0aW9uXG5cdCAqIEByZXR1cm4ge2Jvb2x9IFRydWUgaWYgYWRkaW5nIHRoZSBwYXR0ZXJuIHdhcyBzdWNjZXNzZnVsXG5cdCAqL1xuXHRhZGRQYXR0ZXJuKHBQYXR0ZXJuU3RhcnQsIHBQYXR0ZXJuRW5kLCBwUGFyc2VyKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuV29yZFRyZWUuYWRkUGF0dGVybihwUGF0dGVyblN0YXJ0LCBwUGF0dGVybkVuZCwgcFBhcnNlcik7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBQYXJzZSBhIHN0cmluZyB3aXRoIHRoZSBleGlzdGluZyBwYXJzZSB0cmVlXG5cdCAqIEBtZXRob2QgcGFyc2VTdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd9IHBTdHJpbmcgLSBUaGUgc3RyaW5nIHRvIHBhcnNlXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHJlc3VsdCBmcm9tIHRoZSBwYXJzZXJcblx0ICovXG5cdHBhcnNlU3RyaW5nKHBTdHJpbmcpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5TdHJpbmdQYXJzZXIucGFyc2VTdHJpbmcocFN0cmluZywgdGhpcy5QYXJzZVRyZWUpO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUHJlY2VkZW50O1xuIiwiLyoqXG4qIFN0cmluZyBQYXJzZXJcbipcbiogQGxpY2Vuc2UgICAgIE1JVFxuKlxuKiBAYXV0aG9yICAgICAgU3RldmVuIFZlbG96byA8c3RldmVuQHZlbG96by5jb20+XG4qXG4qIEBkZXNjcmlwdGlvbiBQYXJzZSBhIHN0cmluZywgcHJvcGVybHkgcHJvY2Vzc2luZyBlYWNoIG1hdGNoZWQgdG9rZW4gaW4gdGhlIHdvcmQgdHJlZS5cbiovXG5cbmNsYXNzIFN0cmluZ1BhcnNlclxue1xuXHQvKipcblx0ICogU3RyaW5nUGFyc2VyIENvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0fVxuXHRcblx0LyoqXG5cdCAqIENyZWF0ZSBhIGZyZXNoIHBhcnNpbmcgc3RhdGUgb2JqZWN0IHRvIHdvcmsgd2l0aC5cblx0ICogQG1ldGhvZCBuZXdQYXJzZXJTdGF0ZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFBhcnNlVHJlZSAtIEEgbm9kZSBvbiB0aGUgcGFyc2UgdHJlZSB0byBiZWdpbiBwYXJzaW5nIGZyb20gKHVzdWFsbHkgcm9vdClcblx0ICogQHJldHVybiB7T2JqZWN0fSBBIG5ldyBwYXJzZXIgc3RhdGUgb2JqZWN0IGZvciBydW5uaW5nIGEgY2hhcmFjdGVyIHBhcnNlciBvblxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0bmV3UGFyc2VyU3RhdGUgKHBQYXJzZVRyZWUpXG5cdHtcblx0XHRyZXR1cm4gKFxuXHRcdHtcblx0XHQgICAgUGFyc2VUcmVlOiBwUGFyc2VUcmVlLFxuXG5cdFx0XHRPdXRwdXQ6ICcnLFxuXHRcdFx0T3V0cHV0QnVmZmVyOiAnJyxcblxuXHRcdFx0UGF0dGVybjogZmFsc2UsXG5cblx0XHRcdFBhdHRlcm5NYXRjaDogZmFsc2UsXG5cdFx0XHRQYXR0ZXJuTWF0Y2hPdXRwdXRCdWZmZXI6ICcnXG5cdFx0fSk7XG5cdH1cblx0XHRcblx0LyoqXG5cdCAqIEFzc2lnbiBhIG5vZGUgb2YgdGhlIHBhcnNlciB0cmVlIHRvIGJlIHRoZSBuZXh0IHBvdGVudGlhbCBtYXRjaC5cblx0ICogSWYgdGhlIG5vZGUgaGFzIGEgUGF0dGVybkVuZCBwcm9wZXJ0eSwgaXQgaXMgYSB2YWxpZCBtYXRjaCBhbmQgc3VwZXJjZWRlcyB0aGUgbGFzdCB2YWxpZCBtYXRjaCAob3IgYmVjb21lcyB0aGUgaW5pdGlhbCBtYXRjaCkuXG5cdCAqIEBtZXRob2QgYXNzaWduTm9kZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcE5vZGUgLSBBIG5vZGUgb24gdGhlIHBhcnNlIHRyZWUgdG8gYXNzaWduXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwUGFyc2VyU3RhdGUgLSBUaGUgc3RhdGUgb2JqZWN0IGZvciB0aGUgY3VycmVudCBwYXJzaW5nIHRhc2tcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGFzc2lnbk5vZGUgKHBOb2RlLCBwUGFyc2VyU3RhdGUpXG5cdHtcblx0XHRwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoID0gcE5vZGU7XG5cblx0XHQvLyBJZiB0aGUgcGF0dGVybiBoYXMgYSBFTkQgd2UgY2FuIGFzc3VtZSBpdCBoYXMgYSBwYXJzZSBmdW5jdGlvbi4uLlxuXHRcdGlmIChwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoLmhhc093blByb3BlcnR5KCdQYXR0ZXJuRW5kJykpXG5cdFx0e1xuXHRcdFx0Ly8gLi4uIHRoaXMgaXMgdGhlIGxlZ2l0aW1hdGUgc3RhcnQgb2YgYSBwYXR0ZXJuLlxuXHRcdFx0cFBhcnNlclN0YXRlLlBhdHRlcm4gPSBwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoO1xuXHRcdH1cblx0fVxuXHRcblx0LyoqXG5cdCAqIEFwcGVuZCBhIGNoYXJhY3RlciB0byB0aGUgb3V0cHV0IGJ1ZmZlciBpbiB0aGUgcGFyc2VyIHN0YXRlLlxuXHQgKiBUaGlzIG91dHB1dCBidWZmZXIgaXMgdXNlZCB3aGVuIGEgcG90ZW50aWFsIG1hdGNoIGlzIGJlaW5nIGV4cGxvcmVkLCBvciBhIG1hdGNoIGlzIGJlaW5nIGV4cGxvcmVkLlxuXHQgKiBAbWV0aG9kIGFwcGVuZE91dHB1dEJ1ZmZlclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcENoYXJhY3RlciAtIFRoZSBjaGFyYWN0ZXIgdG8gYXBwZW5kXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwUGFyc2VyU3RhdGUgLSBUaGUgc3RhdGUgb2JqZWN0IGZvciB0aGUgY3VycmVudCBwYXJzaW5nIHRhc2tcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGFwcGVuZE91dHB1dEJ1ZmZlciAocENoYXJhY3RlciwgcFBhcnNlclN0YXRlKVxuXHR7XG5cdFx0cFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlciArPSBwQ2hhcmFjdGVyO1xuXHR9XG5cdFxuXHQvKipcblx0ICogRmx1c2ggdGhlIG91dHB1dCBidWZmZXIgdG8gdGhlIG91dHB1dCBhbmQgY2xlYXIgaXQuXG5cdCAqIEBtZXRob2QgZmx1c2hPdXRwdXRCdWZmZXJcblx0ICogQHBhcmFtIHtPYmplY3R9IHBQYXJzZXJTdGF0ZSAtIFRoZSBzdGF0ZSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IHBhcnNpbmcgdGFza1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0Zmx1c2hPdXRwdXRCdWZmZXIgKHBQYXJzZXJTdGF0ZSlcblx0e1xuXHRcdHBQYXJzZXJTdGF0ZS5PdXRwdXQgKz0gcFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlcjtcblx0XHRwUGFyc2VyU3RhdGUuT3V0cHV0QnVmZmVyID0gJyc7XG5cdH1cblxuXHRcblx0LyoqXG5cdCAqIENoZWNrIGlmIHRoZSBwYXR0ZXJuIGhhcyBlbmRlZC4gIElmIGl0IGhhcywgcHJvcGVybHkgZmx1c2ggdGhlIGJ1ZmZlciBhbmQgc3RhcnQgbG9va2luZyBmb3IgbmV3IHBhdHRlcm5zLlxuXHQgKiBAbWV0aG9kIGNoZWNrUGF0dGVybkVuZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFBhcnNlclN0YXRlIC0gVGhlIHN0YXRlIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgcGFyc2luZyB0YXNrXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRjaGVja1BhdHRlcm5FbmQgKHBQYXJzZXJTdGF0ZSlcblx0e1xuXHRcdGlmICgocFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlci5sZW5ndGggPj0gcFBhcnNlclN0YXRlLlBhdHRlcm4uUGF0dGVybkVuZC5sZW5ndGgrcFBhcnNlclN0YXRlLlBhdHRlcm4uUGF0dGVyblN0YXJ0Lmxlbmd0aCkgJiYgXG5cdFx0XHQocFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlci5zdWJzdHIoLXBQYXJzZXJTdGF0ZS5QYXR0ZXJuLlBhdHRlcm5FbmQubGVuZ3RoKSA9PT0gcFBhcnNlclN0YXRlLlBhdHRlcm4uUGF0dGVybkVuZCkpXG5cdFx0e1xuXHRcdFx0Ly8gLi4uIHRoaXMgaXMgdGhlIGVuZCBvZiBhIHBhdHRlcm4sIGN1dCBvZmYgdGhlIGVuZCB0YWcgYW5kIHBhcnNlIGl0LlxuXHRcdFx0Ly8gVHJpbSB0aGUgc3RhcnQgYW5kIGVuZCB0YWdzIG9mZiB0aGUgb3V0cHV0IGJ1ZmZlciBub3dcblx0XHRcdHBQYXJzZXJTdGF0ZS5PdXRwdXRCdWZmZXIgPSBwUGFyc2VyU3RhdGUuUGF0dGVybi5QYXJzZShwUGFyc2VyU3RhdGUuT3V0cHV0QnVmZmVyLnN1YnN0cihwUGFyc2VyU3RhdGUuUGF0dGVybi5QYXR0ZXJuU3RhcnQubGVuZ3RoLCBwUGFyc2VyU3RhdGUuT3V0cHV0QnVmZmVyLmxlbmd0aCAtIChwUGFyc2VyU3RhdGUuUGF0dGVybi5QYXR0ZXJuU3RhcnQubGVuZ3RoK3BQYXJzZXJTdGF0ZS5QYXR0ZXJuLlBhdHRlcm5FbmQubGVuZ3RoKSkpO1xuXHRcdFx0Ly8gRmx1c2ggdGhlIG91dHB1dCBidWZmZXIuXG5cdFx0XHR0aGlzLmZsdXNoT3V0cHV0QnVmZmVyKHBQYXJzZXJTdGF0ZSk7XG5cdFx0XHQvLyBFbmQgcGF0dGVybiBtb2RlXG5cdFx0XHRwUGFyc2VyU3RhdGUuUGF0dGVybiA9IGZhbHNlO1xuXHRcdFx0cFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaCA9IGZhbHNlO1xuXHRcdH1cblx0fVxuXHRcblx0LyoqXG5cdCAqIFBhcnNlIGEgY2hhcmFjdGVyIGluIHRoZSBidWZmZXIuXG5cdCAqIEBtZXRob2QgcGFyc2VDaGFyYWN0ZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHBDaGFyYWN0ZXIgLSBUaGUgY2hhcmFjdGVyIHRvIGFwcGVuZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFBhcnNlclN0YXRlIC0gVGhlIHN0YXRlIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgcGFyc2luZyB0YXNrXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRwYXJzZUNoYXJhY3RlciAocENoYXJhY3RlciwgcFBhcnNlclN0YXRlKVxuXHR7XG5cdFx0Ly8gKDEpIElmIHdlIGFyZW4ndCBpbiBhIHBhdHRlcm4gbWF0Y2gsIGFuZCB3ZSBhcmVuJ3QgcG90ZW50aWFsbHkgbWF0Y2hpbmcsIGFuZCB0aGlzIG1heSBiZSB0aGUgc3RhcnQgb2YgYSBuZXcgcGF0dGVybi4uLi5cblx0XHRpZiAoIXBQYXJzZXJTdGF0ZS5QYXR0ZXJuTWF0Y2ggJiYgcFBhcnNlclN0YXRlLlBhcnNlVHJlZS5oYXNPd25Qcm9wZXJ0eShwQ2hhcmFjdGVyKSlcblx0XHR7XG5cdFx0XHQvLyAuLi4gYXNzaWduIHRoZSBub2RlIGFzIHRoZSBtYXRjaGVkIG5vZGUuXG5cdFx0XHR0aGlzLmFzc2lnbk5vZGUocFBhcnNlclN0YXRlLlBhcnNlVHJlZVtwQ2hhcmFjdGVyXSwgcFBhcnNlclN0YXRlKTtcblx0XHRcdHRoaXMuYXBwZW5kT3V0cHV0QnVmZmVyKHBDaGFyYWN0ZXIsIHBQYXJzZXJTdGF0ZSk7XG5cdFx0fVxuXHRcdC8vICgyKSBJZiB3ZSBhcmUgaW4gYSBwYXR0ZXJuIG1hdGNoIChhY3RpdmVseSBzZWVpbmcgaWYgdGhpcyBpcyBwYXJ0IG9mIGEgbmV3IHBhdHRlcm4gdG9rZW4pXG5cdFx0ZWxzZSBpZiAocFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaClcblx0XHR7XG5cdFx0XHQvLyBJZiB0aGUgcGF0dGVybiBoYXMgYSBzdWJwYXR0ZXJuIHdpdGggdGhpcyBrZXlcblx0XHRcdGlmIChwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoLmhhc093blByb3BlcnR5KHBDaGFyYWN0ZXIpKVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBDb250aW51ZSBtYXRjaGluZyBwYXR0ZXJucy5cblx0XHRcdFx0dGhpcy5hc3NpZ25Ob2RlKHBQYXJzZXJTdGF0ZS5QYXR0ZXJuTWF0Y2hbcENoYXJhY3Rlcl0sIHBQYXJzZXJTdGF0ZSk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmFwcGVuZE91dHB1dEJ1ZmZlcihwQ2hhcmFjdGVyLCBwUGFyc2VyU3RhdGUpO1xuXHRcdFx0aWYgKHBQYXJzZXJTdGF0ZS5QYXR0ZXJuKVxuXHRcdFx0e1xuXHRcdFx0XHQvLyAuLi4gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgZW5kIG9mIHRoZSBwYXR0ZXJuIChpZiB3ZSBhcmUgbWF0Y2hpbmcgYSB2YWxpZCBwYXR0ZXJuKS4uLlxuXHRcdFx0XHR0aGlzLmNoZWNrUGF0dGVybkVuZChwUGFyc2VyU3RhdGUpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHQvLyAoMykgSWYgd2UgYXJlbid0IGluIGEgcGF0dGVybiBtYXRjaCBvciBwYXR0ZXJuLCBhbmQgdGhpcyBpc24ndCB0aGUgc3RhcnQgb2YgYSBuZXcgcGF0dGVybiAoUkFXIG1vZGUpLi4uLlxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHRwUGFyc2VyU3RhdGUuT3V0cHV0ICs9IHBDaGFyYWN0ZXI7XG5cdFx0fVxuXHR9XG5cdFxuXHQvKipcblx0ICogUGFyc2UgYSBzdHJpbmcgZm9yIG1hdGNoZXMsIGFuZCBwcm9jZXNzIGFueSB0ZW1wbGF0ZSBzZWdtZW50cyB0aGF0IG9jY3VyLlxuXHQgKiBAbWV0aG9kIHBhcnNlU3RyaW5nXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwU3RyaW5nIC0gVGhlIHN0cmluZyB0byBwYXJzZS5cblx0ICogQHBhcmFtIHtPYmplY3R9IHBQYXJzZVRyZWUgLSBUaGUgcGFyc2UgdHJlZSB0byBiZWdpbiBwYXJzaW5nIGZyb20gKHVzdWFsbHkgcm9vdClcblx0ICovXG5cdHBhcnNlU3RyaW5nIChwU3RyaW5nLCBwUGFyc2VUcmVlKVxuXHR7XG5cdFx0bGV0IHRtcFBhcnNlclN0YXRlID0gdGhpcy5uZXdQYXJzZXJTdGF0ZShwUGFyc2VUcmVlKTtcblxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgcFN0cmluZy5sZW5ndGg7IGkrKylcblx0XHR7XG5cdFx0XHQvLyBUT0RPOiBUaGlzIGlzIG5vdCBmYXN0LlxuXHRcdFx0dGhpcy5wYXJzZUNoYXJhY3RlcihwU3RyaW5nW2ldLCB0bXBQYXJzZXJTdGF0ZSk7XG5cdFx0fVxuXHRcdFxuXHRcdHRoaXMuZmx1c2hPdXRwdXRCdWZmZXIodG1wUGFyc2VyU3RhdGUpO1xuXHRcdFxuXHRcdHJldHVybiB0bXBQYXJzZXJTdGF0ZS5PdXRwdXQ7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJpbmdQYXJzZXI7XG4iLCIvKipcbiogV29yZCBUcmVlXG4qXG4qIEBsaWNlbnNlICAgICBNSVRcbipcbiogQGF1dGhvciAgICAgIFN0ZXZlbiBWZWxvem8gPHN0ZXZlbkB2ZWxvem8uY29tPlxuKlxuKiBAZGVzY3JpcHRpb24gQ3JlYXRlIGEgdHJlZSAoZGlyZWN0ZWQgZ3JhcGgpIG9mIEphdmFzY3JpcHQgb2JqZWN0cywgb25lIGNoYXJhY3RlciBwZXIgb2JqZWN0LlxuKi9cblxuY2xhc3MgV29yZFRyZWVcbntcblx0LyoqXG5cdCAqIFdvcmRUcmVlIENvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0XHR0aGlzLlBhcnNlVHJlZSA9IHt9O1xuXHR9XG5cdFxuXHQvKiogXG5cdCAqIEFkZCBhIGNoaWxkIGNoYXJhY3RlciB0byBhIFBhcnNlIFRyZWUgbm9kZVxuXHQgKiBAbWV0aG9kIGFkZENoaWxkXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwVHJlZSAtIEEgcGFyc2UgdHJlZSB0byBwdXNoIHRoZSBjaGFyYWN0ZXJzIGludG9cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBQYXR0ZXJuIC0gVGhlIHN0cmluZyB0byBhZGQgdG8gdGhlIHRyZWVcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBJbmRleCAtIGNhbGxiYWNrIGZ1bmN0aW9uXG5cdCAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSByZXN1bHRpbmcgbGVhZiBub2RlIHRoYXQgd2FzIGFkZGVkIChvciBmb3VuZClcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGFkZENoaWxkIChwVHJlZSwgcFBhdHRlcm4sIHBJbmRleClcblx0e1xuXHRcdGlmIChwSW5kZXggPiBwUGF0dGVybi5sZW5ndGgpXG5cdFx0XHRyZXR1cm4gcFRyZWU7XG5cdFx0XG5cdFx0aWYgKCFwVHJlZS5oYXNPd25Qcm9wZXJ0eShwUGF0dGVybltwSW5kZXhdKSlcblx0XHRcdHBUcmVlW3BQYXR0ZXJuW3BJbmRleF1dID0ge307XG5cdFx0XG5cdFx0cmV0dXJuIHBUcmVlW3BQYXR0ZXJuW3BJbmRleF1dO1xuXHR9XG5cdFxuXHQvKiogQWRkIGEgUGF0dGVybiB0byB0aGUgUGFyc2UgVHJlZVxuXHQgKiBAbWV0aG9kIGFkZFBhdHRlcm5cblx0ICogQHBhcmFtIHtPYmplY3R9IHBUcmVlIC0gQSBub2RlIG9uIHRoZSBwYXJzZSB0cmVlIHRvIHB1c2ggdGhlIGNoYXJhY3RlcnMgaW50b1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gcFBhdHRlcm4gLSBUaGUgc3RyaW5nIHRvIGFkZCB0byB0aGUgdHJlZVxuXHQgKiBAcGFyYW0ge251bWJlcn0gcEluZGV4IC0gY2FsbGJhY2sgZnVuY3Rpb25cblx0ICogQHJldHVybiB7Ym9vbH0gVHJ1ZSBpZiBhZGRpbmcgdGhlIHBhdHRlcm4gd2FzIHN1Y2Nlc3NmdWxcblx0ICovXG5cdGFkZFBhdHRlcm4gKHBQYXR0ZXJuU3RhcnQsIHBQYXR0ZXJuRW5kLCBwUGFyc2VyKVxuXHR7XG5cdFx0aWYgKHBQYXR0ZXJuU3RhcnQubGVuZ3RoIDwgMSlcblx0XHRcdHJldHVybiBmYWxzZTtcblxuXHRcdGxldCB0bXBMZWFmID0gdGhpcy5QYXJzZVRyZWU7XG5cblx0XHQvLyBBZGQgdGhlIHRyZWUgb2YgbGVhdmVzIGl0ZXJhdGl2ZWx5XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBwUGF0dGVyblN0YXJ0Lmxlbmd0aDsgaSsrKVxuXHRcdFx0dG1wTGVhZiA9IHRoaXMuYWRkQ2hpbGQodG1wTGVhZiwgcFBhdHRlcm5TdGFydCwgaSk7XG5cblx0XHR0bXBMZWFmLlBhdHRlcm5TdGFydCA9IHBQYXR0ZXJuU3RhcnQ7XG5cdFx0dG1wTGVhZi5QYXR0ZXJuRW5kID0gKCh0eXBlb2YocFBhdHRlcm5FbmQpID09PSAnc3RyaW5nJykgJiYgKHBQYXR0ZXJuRW5kLmxlbmd0aCA+IDApKSA/IHBQYXR0ZXJuRW5kIDogcFBhdHRlcm5TdGFydDtcblx0XHR0bXBMZWFmLlBhcnNlID0gKHR5cGVvZihwUGFyc2VyKSA9PT0gJ2Z1bmN0aW9uJykgPyBwUGFyc2VyIDogXG5cdFx0XHRcdFx0XHQodHlwZW9mKHBQYXJzZXIpID09PSAnc3RyaW5nJykgPyAoKSA9PiB7IHJldHVybiBwUGFyc2VyOyB9IDpcblx0XHRcdFx0XHRcdChwRGF0YSkgPT4geyByZXR1cm4gcERhdGE7IH07XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdvcmRUcmVlO1xuIl19
@@ -0,0 +1,37 @@
1
+ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Precedent=t()}}((function(){return function t(e,r,n){function a(s,f){if(!r[s]){if(!e[s]){var o="function"==typeof require&&require;if(!f&&o)return o(s,!0);if(u)return u(s,!0);var i=new Error("Cannot find module '"+s+"'");throw i.code="MODULE_NOT_FOUND",i}var P=r[s]={exports:{}};e[s][0].call(P.exports,(function(t){return a(e[s][1][t]||t)}),P,P.exports,t,e,r,n)}return r[s].exports}for(var u="function"==typeof require&&require,s=0;s<n.length;s++)a(n[s]);return a}({1:[function(t,e,r){
2
+ /**
3
+ * @license MIT
4
+ * @author <steven@velozo.com>
5
+ */
6
+ var n=t("./Precedent.js");"object"!=typeof window||window.hasOwnProperty("Precedent")||(window.Precedent=n),e.exports=n},{"./Precedent.js":2}],2:[function(t,e,r){
7
+ /**
8
+ * Precedent Meta-Templating
9
+ *
10
+ * @license MIT
11
+ *
12
+ * @author Steven Velozo <steven@velozo.com>
13
+ *
14
+ * @description Process text streams, parsing out meta-template expressions.
15
+ */
16
+ var n=t("./WordTree.js"),a=t("./StringParser.js");e.exports=class{constructor(){this.WordTree=new n,this.StringParser=new a,this.ParseTree=this.WordTree.ParseTree}addPattern(t,e,r){return this.WordTree.addPattern(t,e,r)}parseString(t){return this.StringParser.parseString(t,this.ParseTree)}}},{"./StringParser.js":3,"./WordTree.js":4}],3:[function(t,e,r){e.exports=
17
+ /**
18
+ * String Parser
19
+ *
20
+ * @license MIT
21
+ *
22
+ * @author Steven Velozo <steven@velozo.com>
23
+ *
24
+ * @description Parse a string, properly processing each matched token in the word tree.
25
+ */
26
+ class{constructor(){}newParserState(t){return{ParseTree:t,Output:"",OutputBuffer:"",Pattern:!1,PatternMatch:!1,PatternMatchOutputBuffer:""}}assignNode(t,e){e.PatternMatch=t,e.PatternMatch.hasOwnProperty("PatternEnd")&&(e.Pattern=e.PatternMatch)}appendOutputBuffer(t,e){e.OutputBuffer+=t}flushOutputBuffer(t){t.Output+=t.OutputBuffer,t.OutputBuffer=""}checkPatternEnd(t){t.OutputBuffer.length>=t.Pattern.PatternEnd.length+t.Pattern.PatternStart.length&&t.OutputBuffer.substr(-t.Pattern.PatternEnd.length)===t.Pattern.PatternEnd&&(t.OutputBuffer=t.Pattern.Parse(t.OutputBuffer.substr(t.Pattern.PatternStart.length,t.OutputBuffer.length-(t.Pattern.PatternStart.length+t.Pattern.PatternEnd.length))),this.flushOutputBuffer(t),t.Pattern=!1,t.PatternMatch=!1)}parseCharacter(t,e){!e.PatternMatch&&e.ParseTree.hasOwnProperty(t)?(this.assignNode(e.ParseTree[t],e),this.appendOutputBuffer(t,e)):e.PatternMatch?(e.PatternMatch.hasOwnProperty(t)&&this.assignNode(e.PatternMatch[t],e),this.appendOutputBuffer(t,e),e.Pattern&&this.checkPatternEnd(e)):e.Output+=t}parseString(t,e){let r=this.newParserState(e);for(var n=0;n<t.length;n++)this.parseCharacter(t[n],r);return this.flushOutputBuffer(r),r.Output}}},{}],4:[function(t,e,r){e.exports=
27
+ /**
28
+ * Word Tree
29
+ *
30
+ * @license MIT
31
+ *
32
+ * @author Steven Velozo <steven@velozo.com>
33
+ *
34
+ * @description Create a tree (directed graph) of Javascript objects, one character per object.
35
+ */
36
+ class{constructor(){this.ParseTree={}}addChild(t,e,r){return r>e.length?t:(t.hasOwnProperty(e[r])||(t[e[r]]={}),t[e[r]])}addPattern(t,e,r){if(t.length<1)return!1;let n=this.ParseTree;for(var a=0;a<t.length;a++)n=this.addChild(n,t,a);return n.PatternStart=t,n.PatternEnd="string"==typeof e&&e.length>0?e:t,n.Parse="function"==typeof r?r:"string"==typeof r?()=>r:t=>t,!0}}},{}]},{},[1])(1)}));
37
+ //# sourceMappingURL=precedent.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["node_modules/browser-pack/_prelude.js","source/Precedent-Browser-Shim.js","precedent.min.js","source/Precedent.js","source/StringParser.js","source/WordTree.js"],"names":["f","exports","module","define","amd","window","global","self","this","Precedent","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","libPrecedent","hasOwnProperty","libWordTree","libStringParser","constructor","WordTree","StringParser","ParseTree","addPattern","pPatternStart","pPatternEnd","pParser","parseString","pString","newParserState","pParseTree","Output","OutputBuffer","Pattern","PatternMatch","PatternMatchOutputBuffer","assignNode","pNode","pParserState","appendOutputBuffer","pCharacter","flushOutputBuffer","checkPatternEnd","PatternEnd","PatternStart","substr","Parse","parseCharacter","tmpParserState","addChild","pTree","pPattern","pIndex","tmpLeaf","pData"],"mappings":"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","file":"precedent.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()","/**\n* @license MIT\n* @author <steven@velozo.com>\n*/\n\n/**\n* Precedent browser shim loader\n*/\n\n// Load the precedent module into the browser global automatically.\nvar libPrecedent = require('./Precedent.js');\n\nif ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))\n{\n\twindow.Precedent = libPrecedent;\n}\n\nmodule.exports = libPrecedent;",null,"/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n","/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t ParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n","/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (pIndex > pPattern.length)\n\t\t\treturn pTree;\n\t\t\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n"]}
package/gulpfile.js CHANGED
@@ -1,68 +1,62 @@
1
- /**
2
- * Precedent Meta-templating Web Build Package
3
- *
4
- * @license MIT
5
- *
6
- * @author Steven Velozo <steven@velozo.com>
7
- */
8
- var _Version = require('./package.json').version;
9
-
10
- var libGulp = require('gulp');
11
-
12
- var libBrowserify = require('browserify');
13
- var libBabelify = require('babelify');
14
- var libVinylSource = require('vinyl-source-stream');
15
- var libVinylBuffer = require('vinyl-buffer');
16
- var libUglify = require('gulp-uglify');
17
- var libRename = require('gulp-rename');
18
- var libSourceMaps = require('gulp-sourcemaps');
19
- var libRunSequence = require('run-sequence');
20
-
21
- libGulp.task('copy-latest-release', ['build-release'],
22
- ()=>
1
+ 'use strict';
2
+
3
+ const libBrowserify = require('browserify');
4
+ const libGulp = require('gulp');
5
+
6
+ const libVinylSourceStream = require('vinyl-source-stream');
7
+ const libVinylBuffer = require('vinyl-buffer');
8
+
9
+ const libTerser = require('gulp-terser');
10
+ const libBuble = require('gulp-buble');
11
+ const libSourcemaps = require('gulp-sourcemaps');
12
+ const libGulpUtil = require('gulp-util');
13
+
14
+ // Build the module for the browser
15
+ // This gulp task is taken from the gulp recipe repository:
16
+ // https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md
17
+ libGulp.task('minified',
18
+ () => {
19
+ // set up the custom browserify instance for this task
20
+ var tmpBrowserify = libBrowserify(
23
21
  {
24
- libGulp.src('./dist/precedent.'+_Version+'.min.js')
25
- .pipe(libRename('precedent.latest.min.js'))
26
- .pipe(libGulp.dest('./dist'));
22
+ entries: './source/Precedent-Browser-Shim.js',
23
+ standalone: 'Precedent',
24
+ debug: true
27
25
  });
28
26
 
29
- libGulp.task('build-release',
30
- ()=>
31
- {
32
- // app.js is your main JS file with all your module inclusions
33
- return libBrowserify({entries: './source/Precedent', debug: false})
34
- .transform("babelify", { presets: ["es2015"] })
35
- .bundle()
36
- .pipe(libVinylSource('precedent.'+_Version+'.min.js'))
27
+ return tmpBrowserify.bundle()
28
+ .pipe(libVinylSourceStream('precedent.min.js'))
29
+ .pipe(libVinylBuffer())
30
+ .pipe(libSourcemaps.init({loadMaps: true}))
31
+ // Add transformation tasks to the pipeline here.
32
+ .pipe(libTerser())
33
+ .on('error', libGulpUtil.log)
34
+ .pipe(libSourcemaps.write('./'))
35
+ .pipe(libGulp.dest('./dist/'));
36
+ });
37
+
38
+ // Build the module for the browser
39
+ // This gulp task is taken from the gulp recipe repository:
40
+ // https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md
41
+ libGulp.task('debug',
42
+ () => {
43
+ // set up the custom browserify instance for this task
44
+ var tmpBrowserify = libBrowserify(
45
+ {
46
+ entries: './source/Precedent-Browser-Shim.js',
47
+ standalone: 'Precedent',
48
+ debug: true
49
+ });
50
+
51
+ return tmpBrowserify.bundle()
52
+ .pipe(libVinylSourceStream('precedent.js'))
37
53
  .pipe(libVinylBuffer())
38
- .pipe(libSourceMaps.init())
39
- .pipe(libUglify())
40
- .pipe(libSourceMaps.write('./'))
41
- .pipe(libGulp.dest('./dist'));
42
- }
43
- );
44
-
45
- libGulp.task('build-debug',
46
- ()=>
47
- {
48
- return libBrowserify({entries: './source/Precedent', debug: true})
49
- .transform("babelify", { presets: ["es2015"] })
50
- .bundle()
51
- .pipe(libVinylSource('precedent.'+_Version+'.js'))
52
- .pipe(libVinylBuffer())
53
- .pipe(libGulp.dest('./dist'));
54
- }
55
- );
56
-
57
- libGulp.task('build', ['build-release','build-debug','copy-latest-release']);
54
+ .on('error', libGulpUtil.log)
55
+ .pipe(libGulp.dest('./dist/'));
56
+ });
58
57
 
59
- libGulp.task('build',
60
- (fCallback) =>
61
- {
62
- libRunSequence(['build-debug', 'build-release'],
63
- 'copy-latest-release',
64
- fCallback);
65
- }
58
+ libGulp.task
59
+ (
60
+ 'build',
61
+ libGulp.series('debug', 'minified')
66
62
  );
67
-
68
- libGulp.task('default', ['build']);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "precedent",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Precedent Meta-Templating",
5
5
  "main": "source/Precedent.js",
6
6
  "bin": {
@@ -24,19 +24,24 @@
24
24
  "url": "https://github.com/stevenvelozo/precedent/issues"
25
25
  },
26
26
  "devDependencies": {
27
- "babel-preset-es2015": "^6.24.1",
28
- "babelify": "^7.3.0",
29
- "browserify": "^14.4.0",
30
- "chai": "3.5.0",
31
- "gulp": "^3.9.1",
32
- "gulp-rename": "^1.2.2",
33
- "gulp-sourcemaps": "^2.6.0",
34
- "gulp-uglify": "^3.0.0",
35
- "istanbul": "0.4.5",
36
- "mocha": "3.3.0",
37
- "run-sequence": "^1.2.2",
38
- "vinyl-buffer": "^1.0.0",
39
- "vinyl-source-stream": "^1.1.0"
27
+ "@babel/core": "^7.17.9",
28
+ "@babel/preset-env": "^7.16.11",
29
+ "@testing-library/dom": "^8.13.0",
30
+ "async": "^3.2.3",
31
+ "browserify": "^17.0.0",
32
+ "chai": "4.3.6",
33
+ "gulp": "^4.0.2",
34
+ "gulp-babel": "^8.0.0",
35
+ "gulp-buble": "^0.9.0",
36
+ "gulp-sourcemaps": "^3.0.0",
37
+ "gulp-terser": "^2.1.0",
38
+ "gulp-util": "^3.0.8",
39
+ "jsdom": "^19.0.0",
40
+ "mocha": "9.2.2",
41
+ "npm-check-updates": "^12.5.9",
42
+ "nyc": "^15.1.0",
43
+ "vinyl-buffer": "^1.0.1",
44
+ "vinyl-source-stream": "^2.0.0"
40
45
  },
41
46
  "dependencies": {}
42
47
  }
@@ -8,5 +8,11 @@
8
8
  */
9
9
 
10
10
  // Load the precedent module into the browser global automatically.
11
- var Precedent = require('./Precedent.js');
12
- module.exports = Precedent;
11
+ var libPrecedent = require('./Precedent.js');
12
+
13
+ if ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))
14
+ {
15
+ window.Precedent = libPrecedent;
16
+ }
17
+
18
+ module.exports = libPrecedent;
package/.c9/.nakignore DELETED
@@ -1,17 +0,0 @@
1
- *~backup-*
2
- .c9revisions
3
- .c9
4
- .git
5
- .svn
6
- .DS_Store
7
- .bzr
8
- .cdv
9
- ~.dep
10
- ~.dot
11
- ~.nib
12
- ~.plst
13
- .hg
14
- .pc
15
- *.min.js
16
- .nakignore
17
- /dev
package/.c9/metadata/tab0 DELETED
@@ -1 +0,0 @@
1
- {"filter":false,"title":"git - \"stevenvelozo-precedent-4804145\" ","tooltip":"git - \"stevenvelozo-precedent-4804145\" ","undoManager":{"mark":-1,"position":-1,"stack":[]},"terminal":{"id":"clone","cwd":"","width":1648,"height":405,"scrollTop":14346},"hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709"}
package/.c9/metadata/tab3 DELETED
@@ -1 +0,0 @@
1
- {"filter":false,"title":"Debug Harness - Running","tooltip":"Debug Harness - Running","undoManager":{"mark":-1,"position":-1,"stack":[]},"output":{"id":"output-defaultDebug-wHarness","width":1648,"height":405,"scrollTop":608,"config":{"command":"harness/Debug.js","debug":true,"default":true,"name":"Debug Harness","runner":"Node.js (default)","toolbar":true},"running":{"pid":19860,"name":"output-defaultDebug-wHarness","running":2,"runner":[{"cmd":["bash","--login","-c","nvm use default > /dev/null; node ${debug?--nocrankshaft --nolazy --nodead_code_elimination --debug-brk=15454} '$file' $args"],"debugger":"v8","debugport":15454,"selector":"source.js","info":"Your code is running at \\033[01;34m$url\\033[00m.\n\\033[01;31mImportant:\\033[00m use \\033[01;32mprocess.env.PORT\\033[00m as the port and \\033[01;32mprocess.env.IP\\033[00m as the host in your scripts!\n","caption":"Node.js (default)","$builtin":true}],"debug":true}},"timestamp":1494786977632,"hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709"}
@@ -1 +0,0 @@
1
- {"filter":false,"title":".travis.yml","tooltip":"/.travis.yml","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":15},"end":{"row":4,"column":15},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":42,"mode":"ace/mode/yaml"}},"timestamp":1493836451758,"hash":"f9a1f0c930abdc50772e6d5cba85997a7067b28c"}