sugar-rails 1.2.5.1 → 1.3.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 (39) hide show
  1. data/README.md +110 -28
  2. data/lib/generators/sugar/build/build_generator.rb +107 -0
  3. data/lib/generators/sugar/install/install_generator.rb +2 -2
  4. data/lib/sugar/rails/version.rb +2 -2
  5. data/sugar-rails.gemspec +1 -1
  6. data/vendor/assets/javascripts/precompiled/development/array.js +1212 -0
  7. data/vendor/assets/javascripts/precompiled/development/core.js +329 -0
  8. data/vendor/assets/javascripts/precompiled/development/date.js +2179 -0
  9. data/vendor/assets/javascripts/precompiled/development/date_locales.js +952 -0
  10. data/vendor/assets/javascripts/precompiled/development/date_ranges.js +183 -0
  11. data/vendor/assets/javascripts/precompiled/development/es5.js +443 -0
  12. data/vendor/assets/javascripts/precompiled/development/function.js +222 -0
  13. data/vendor/assets/javascripts/{sugar-inflections.js → precompiled/development/inflections.js} +51 -162
  14. data/vendor/assets/javascripts/precompiled/development/language.js +383 -0
  15. data/vendor/assets/javascripts/precompiled/development/number.js +422 -0
  16. data/vendor/assets/javascripts/precompiled/development/object.js +348 -0
  17. data/vendor/assets/javascripts/precompiled/development/regexp.js +92 -0
  18. data/vendor/assets/javascripts/precompiled/development/string.js +871 -0
  19. data/vendor/assets/javascripts/precompiled/minified/array.js +16 -0
  20. data/vendor/assets/javascripts/precompiled/minified/core.js +8 -0
  21. data/vendor/assets/javascripts/precompiled/minified/date.js +40 -0
  22. data/vendor/assets/javascripts/precompiled/minified/date_locales.js +38 -0
  23. data/vendor/assets/javascripts/precompiled/minified/date_ranges.js +3 -0
  24. data/vendor/assets/javascripts/precompiled/minified/es5.js +7 -0
  25. data/vendor/assets/javascripts/precompiled/minified/function.js +4 -0
  26. data/vendor/assets/javascripts/precompiled/minified/inflections.js +11 -0
  27. data/vendor/assets/javascripts/precompiled/minified/language.js +19 -0
  28. data/vendor/assets/javascripts/precompiled/minified/number.js +5 -0
  29. data/vendor/assets/javascripts/precompiled/minified/object.js +6 -0
  30. data/vendor/assets/javascripts/precompiled/minified/regexp.js +2 -0
  31. data/vendor/assets/javascripts/precompiled/minified/string.js +12 -0
  32. data/vendor/assets/javascripts/precompiled/readme.txt +3 -0
  33. data/vendor/assets/javascripts/sugar-development.js +8054 -0
  34. data/vendor/assets/javascripts/sugar-full.js +179 -0
  35. data/vendor/assets/javascripts/sugar.js +111 -6211
  36. metadata +35 -9
  37. data/vendor/assets/javascripts/sugar-core.js +0 -4001
  38. data/vendor/assets/javascripts/sugar-dates-only.js +0 -3121
  39. data/vendor/assets/javascripts/sugar-dates.js +0 -2210
@@ -0,0 +1,222 @@
1
+
2
+ /***
3
+ * @package Function
4
+ * @dependency core
5
+ * @description Lazy, throttled, and memoized functions, delayed functions and handling of timers, argument currying.
6
+ *
7
+ ***/
8
+
9
+ function setDelay(fn, ms, after, scope, args) {
10
+ if(!fn.timers) fn.timers = [];
11
+ if(!isNumber(ms)) ms = 0;
12
+ fn.timers.push(setTimeout(function(){
13
+ fn.timers.splice(index, 1);
14
+ after.apply(scope, args || []);
15
+ }, ms));
16
+ var index = fn.timers.length;
17
+ }
18
+
19
+ extend(Function, true, false, {
20
+
21
+ /***
22
+ * @method lazy([ms] = 1, [limit] = Infinity)
23
+ * @returns Function
24
+ * @short Creates a lazy function that, when called repeatedly, will queue execution and wait [ms] milliseconds to execute again.
25
+ * @extra Lazy functions will always execute as many times as they are called up to [limit], after which point subsequent calls will be ignored (if it is set to a finite number). Compare this to %throttle%, which will execute only once per [ms] milliseconds. %lazy% is useful when you need to be sure that every call to a function is executed, but in a non-blocking manner. Calling %cancel% on a lazy function will clear the entire queue. Note that [ms] can also be a fraction.
26
+ * @example
27
+ *
28
+ * (function() {
29
+ * // Executes immediately.
30
+ * }).lazy()();
31
+ * (3).times(function() {
32
+ * // Executes 3 times, with each execution 20ms later than the last.
33
+ * }.lazy(20));
34
+ * (100).times(function() {
35
+ * // Executes 50 times, with each execution 20ms later than the last.
36
+ * }.lazy(20, 50));
37
+ *
38
+ ***/
39
+ 'lazy': function(ms, limit) {
40
+ var fn = this, queue = [], lock = false, execute, rounded, perExecution;
41
+ ms = ms || 1;
42
+ limit = limit || Infinity;
43
+ rounded = ceil(ms);
44
+ perExecution = round(rounded / ms);
45
+ execute = function() {
46
+ if(lock || queue.length == 0) return;
47
+ var max = math.max(queue.length - perExecution, 0);
48
+ while(queue.length > max) {
49
+ // Getting uber-meta here...
50
+ Function.prototype.apply.apply(fn, queue.shift());
51
+ }
52
+ setDelay(lazy, rounded, function() {
53
+ lock = false;
54
+ execute();
55
+ });
56
+ lock = true;
57
+ }
58
+ function lazy() {
59
+ // The first call is immediate, so having 1 in the queue
60
+ // implies two calls have already taken place.
61
+ if(lock && queue.length > limit - 2) return;
62
+ queue.push([this, arguments]);
63
+ execute();
64
+ }
65
+ return lazy;
66
+ },
67
+
68
+ /***
69
+ * @method delay([ms] = 0, [arg1], ...)
70
+ * @returns Function
71
+ * @short Executes the function after <ms> milliseconds.
72
+ * @extra Returns a reference to itself. %delay% is also a way to execute non-blocking operations that will wait until the CPU is free. Delayed functions can be canceled using the %cancel% method. Can also curry arguments passed in after <ms>.
73
+ * @example
74
+ *
75
+ * (function(arg1) {
76
+ * // called 1s later
77
+ * }).delay(1000, 'arg1');
78
+ *
79
+ ***/
80
+ 'delay': function(ms) {
81
+ var fn = this;
82
+ var args = multiArgs(arguments).slice(1);
83
+ setDelay(fn, ms, fn, fn, args);
84
+ return fn;
85
+ },
86
+
87
+ /***
88
+ * @method throttle(<ms>)
89
+ * @returns Function
90
+ * @short Creates a "throttled" version of the function that will only be executed once per <ms> milliseconds.
91
+ * @extra This is functionally equivalent to calling %lazy% with a [limit] of %1%. %throttle% is appropriate when you want to make sure a function is only executed at most once for a given duration. Compare this to %lazy%, which will queue rapid calls and execute them later.
92
+ * @example
93
+ *
94
+ * (3).times(function() {
95
+ * // called only once. will wait 50ms until it responds again
96
+ * }.throttle(50));
97
+ *
98
+ ***/
99
+ 'throttle': function(ms) {
100
+ return this.lazy(ms, 1);
101
+ },
102
+
103
+ /***
104
+ * @method debounce(<ms>)
105
+ * @returns Function
106
+ * @short Creates a "debounced" function that postpones its execution until after <ms> milliseconds have passed.
107
+ * @extra This method is useful to execute a function after things have "settled down". A good example of this is when a user tabs quickly through form fields, execution of a heavy operation should happen after a few milliseconds when they have "settled" on a field.
108
+ * @example
109
+ *
110
+ * var fn = (function(arg1) {
111
+ * // called once 50ms later
112
+ * }).debounce(50); fn() fn() fn();
113
+ *
114
+ ***/
115
+ 'debounce': function(ms) {
116
+ var fn = this;
117
+ return function() {
118
+ fn.cancel();
119
+ setDelay(fn, ms, fn, this, arguments);
120
+ }
121
+ },
122
+
123
+ /***
124
+ * @method cancel()
125
+ * @returns Function
126
+ * @short Cancels a delayed function scheduled to be run.
127
+ * @extra %delay%, %lazy%, %throttle%, and %debounce% can all set delays.
128
+ * @example
129
+ *
130
+ * (function() {
131
+ * alert('hay'); // Never called
132
+ * }).delay(500).cancel();
133
+ *
134
+ ***/
135
+ 'cancel': function() {
136
+ if(isArray(this.timers)) {
137
+ while(this.timers.length > 0) {
138
+ clearTimeout(this.timers.shift());
139
+ }
140
+ }
141
+ return this;
142
+ },
143
+
144
+ /***
145
+ * @method after([num] = 1)
146
+ * @returns Function
147
+ * @short Creates a function that will execute after [num] calls.
148
+ * @extra %after% is useful for running a final callback after a series of asynchronous operations, when the order in which the operations will complete is unknown.
149
+ * @example
150
+ *
151
+ * var fn = (function() {
152
+ * // Will be executed once only
153
+ * }).after(3); fn(); fn(); fn();
154
+ *
155
+ ***/
156
+ 'after': function(num) {
157
+ var fn = this, counter = 0, storedArguments = [];
158
+ if(!isNumber(num)) {
159
+ num = 1;
160
+ } else if(num === 0) {
161
+ fn.call();
162
+ return fn;
163
+ }
164
+ return function() {
165
+ var ret;
166
+ storedArguments.push(multiArgs(arguments));
167
+ counter++;
168
+ if(counter == num) {
169
+ ret = fn.call(this, storedArguments);
170
+ counter = 0;
171
+ storedArguments = [];
172
+ return ret;
173
+ }
174
+ }
175
+ },
176
+
177
+ /***
178
+ * @method once()
179
+ * @returns Function
180
+ * @short Creates a function that will execute only once and store the result.
181
+ * @extra %once% is useful for creating functions that will cache the result of an expensive operation and use it on subsequent calls. Also it can be useful for creating initialization functions that only need to be run once.
182
+ * @example
183
+ *
184
+ * var fn = (function() {
185
+ * // Will be executed once only
186
+ * }).once(); fn(); fn(); fn();
187
+ *
188
+ ***/
189
+ 'once': function() {
190
+ var fn = this;
191
+ return function() {
192
+ return hasOwnProperty(fn, 'memo') ? fn['memo'] : fn['memo'] = fn.apply(this, arguments);
193
+ }
194
+ },
195
+
196
+ /***
197
+ * @method fill(<arg1>, <arg2>, ...)
198
+ * @returns Function
199
+ * @short Returns a new version of the function which when called will have some of its arguments pre-emptively filled in, also known as "currying".
200
+ * @extra Arguments passed to a "filled" function are generally appended to the curried arguments. However, if %undefined% is passed as any of the arguments to %fill%, it will be replaced, when the "filled" function is executed. This allows currying of arguments even when they occur toward the end of an argument list (the example demonstrates this much more clearly).
201
+ * @example
202
+ *
203
+ * var delayOneSecond = setTimeout.fill(undefined, 1000);
204
+ * delayOneSecond(function() {
205
+ * // Will be executed 1s later
206
+ * });
207
+ *
208
+ ***/
209
+ 'fill': function() {
210
+ var fn = this, curried = multiArgs(arguments);
211
+ return function() {
212
+ var args = multiArgs(arguments);
213
+ curried.forEach(function(arg, index) {
214
+ if(arg != null || index >= args.length) args.splice(index, 0, arg);
215
+ });
216
+ return fn.apply(this, args);
217
+ }
218
+ }
219
+
220
+
221
+ });
222
+
@@ -1,4 +1,11 @@
1
- (function(context) {
1
+
2
+ /***
3
+ *
4
+ * @package Inflections
5
+ * @dependency string
6
+ * @description Pluralization similar to ActiveSupport including uncountable words and acronyms. Humanized and URL-friendly strings.
7
+ *
8
+ ***/
2
9
 
3
10
  /***
4
11
  * String module
@@ -6,23 +13,26 @@
6
13
  ***/
7
14
 
8
15
 
9
- var globalContext,
10
- plurals = [],
16
+ var plurals = [],
11
17
  singulars = [],
12
18
  uncountables = [],
13
19
  humans = [],
14
20
  acronyms = {},
15
21
  Downcased,
16
- Normalize,
17
22
  Inflector;
18
23
 
19
- globalContext = typeof global !== 'undefined' ? global : context;
24
+ function removeFromArray(arr, find) {
25
+ var index = arr.indexOf(find);
26
+ if(index > -1) {
27
+ arr.splice(index, 1);
28
+ }
29
+ }
20
30
 
21
31
  function removeFromUncountablesAndAddTo(arr, rule, replacement) {
22
- if(Object.isString(rule)) {
23
- uncountables.remove(rule);
32
+ if(isString(rule)) {
33
+ removeFromArray(uncountables, rule);
24
34
  }
25
- uncountables.remove(replacement)
35
+ removeFromArray(uncountables, replacement);
26
36
  arr.unshift({ rule: rule, replacement: replacement })
27
37
  }
28
38
 
@@ -31,13 +41,13 @@
31
41
  }
32
42
 
33
43
  function isUncountable(word) {
34
- return uncountables.any(function(uncountable) {
35
- return new RegExp('\\b' + uncountable + '$', 'i').test(word);
44
+ return uncountables.some(function(uncountable) {
45
+ return new regexp('\\b' + uncountable + '$', 'i').test(word);
36
46
  });
37
47
  }
38
48
 
39
49
  function inflect(word, pluralize) {
40
- word = Object.isString(word) ? word.toString() : '';
50
+ word = isString(word) ? word.toString() : '';
41
51
  if(word.isBlank() || isUncountable(word)) {
42
52
  return word;
43
53
  } else {
@@ -46,7 +56,7 @@
46
56
  }
47
57
 
48
58
  function runReplacements(word, table) {
49
- table.each(function(inflection) {
59
+ iterateOverObject(table, function(i, inflection) {
50
60
  if(word.match(inflection.rule)) {
51
61
  word = word.replace(inflection.rule, inflection.replacement);
52
62
  return false;
@@ -113,7 +123,10 @@
113
123
  */
114
124
  'acronym': function(word) {
115
125
  acronyms[word.toLowerCase()] = word;
116
- Inflector.acronymRegExp = new RegExp(Object.values(acronyms).join('|'), 'g');
126
+ var all = object.keys(acronyms).map(function(key) {
127
+ return acronyms[key];
128
+ });
129
+ Inflector.acronymRegExp = regexp(all.join('|'), 'g');
117
130
  },
118
131
 
119
132
  /*
@@ -149,19 +162,19 @@
149
162
  pluralFirstLower = pluralFirst.toLowerCase(),
150
163
  singularFirstUpper = singularFirst.toUpperCase(),
151
164
  singularFirstLower = singularFirst.toLowerCase();
152
- uncountables.remove(singular)
153
- uncountables.remove(plural)
165
+ removeFromArray(uncountables, singular);
166
+ removeFromArray(uncountables, plural);
154
167
  if(singularFirstUpper == pluralFirstUpper) {
155
- Inflector.plural(new RegExp('({1}){2}$'.assign(singularFirst, singularRest), 'i'), '$1' + pluralRest);
156
- Inflector.plural(new RegExp('({1}){2}$'.assign(pluralFirst, pluralRest), 'i'), '$1' + pluralRest);
157
- Inflector.singular(new RegExp('({1}){2}$'.assign(pluralFirst, pluralRest), 'i'), '$1' + singularRest);
168
+ Inflector.plural(new regexp('({1}){2}$'.assign(singularFirst, singularRest), 'i'), '$1' + pluralRest);
169
+ Inflector.plural(new regexp('({1}){2}$'.assign(pluralFirst, pluralRest), 'i'), '$1' + pluralRest);
170
+ Inflector.singular(new regexp('({1}){2}$'.assign(pluralFirst, pluralRest), 'i'), '$1' + singularRest);
158
171
  } else {
159
- Inflector.plural(new RegExp('{1}{2}$'.assign(singularFirstUpper, singularRest)), pluralFirstUpper + pluralRest);
160
- Inflector.plural(new RegExp('{1}{2}$'.assign(singularFirstLower, singularRest)), pluralFirstLower + pluralRest);
161
- Inflector.plural(new RegExp('{1}{2}$'.assign(pluralFirstUpper, pluralRest)), pluralFirstUpper + pluralRest);
162
- Inflector.plural(new RegExp('{1}{2}$'.assign(pluralFirstLower, pluralRest)), pluralFirstLower + pluralRest);
163
- Inflector.singular(new RegExp('{1}{2}$'.assign(pluralFirstUpper, pluralRest)), singularFirstUpper + singularRest);
164
- Inflector.singular(new RegExp('{1}{2}$'.assign(pluralFirstLower, pluralRest)), singularFirstLower + singularRest);
172
+ Inflector.plural(new regexp('{1}{2}$'.assign(singularFirstUpper, singularRest)), pluralFirstUpper + pluralRest);
173
+ Inflector.plural(new regexp('{1}{2}$'.assign(singularFirstLower, singularRest)), pluralFirstLower + pluralRest);
174
+ Inflector.plural(new regexp('{1}{2}$'.assign(pluralFirstUpper, pluralRest)), pluralFirstUpper + pluralRest);
175
+ Inflector.plural(new regexp('{1}{2}$'.assign(pluralFirstLower, pluralRest)), pluralFirstLower + pluralRest);
176
+ Inflector.singular(new regexp('{1}{2}$'.assign(pluralFirstUpper, pluralRest)), singularFirstUpper + singularRest);
177
+ Inflector.singular(new regexp('{1}{2}$'.assign(pluralFirstLower, pluralRest)), singularFirstLower + singularRest);
165
178
  }
166
179
  },
167
180
 
@@ -173,8 +186,9 @@
173
186
  * String.Inflector.uncountable('money', 'information')
174
187
  * String.Inflector.uncountable(['money', 'information', 'rice'])
175
188
  */
176
- 'uncountable': function() {
177
- uncountables.add(Array.create(arguments).flatten());
189
+ 'uncountable': function(first) {
190
+ var add = array.isArray(first) ? first : multiArgs(arguments);
191
+ uncountables = uncountables.concat(add);
178
192
  },
179
193
 
180
194
  /*
@@ -215,95 +229,6 @@
215
229
  'with', 'for'
216
230
  ];
217
231
 
218
- Normalize = {
219
- 'A': /[AⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ]/g,
220
- 'B': /[BⒷBḂḄḆɃƂƁ]/g,
221
- 'C': /[CⒸCĆĈĊČÇḈƇȻꜾ]/g,
222
- 'D': /[DⒹDḊĎḌḐḒḎĐƋƊƉꝹ]/g,
223
- 'E': /[EⒺEÈÉÊỀẾỄỂẼĒḔḖĔĖËẺĚȄȆẸỆȨḜĘḘḚƐƎ]/g,
224
- 'F': /[FⒻFḞƑꝻ]/g,
225
- 'G': /[GⒼGǴĜḠĞĠǦĢǤƓꞠꝽꝾ]/g,
226
- 'H': /[HⒽHĤḢḦȞḤḨḪĦⱧⱵꞍ]/g,
227
- 'I': /[IⒾIÌÍÎĨĪĬİÏḮỈǏȈȊỊĮḬƗ]/g,
228
- 'J': /[JⒿJĴɈ]/g,
229
- 'K': /[KⓀKḰǨḲĶḴƘⱩꝀꝂꝄꞢ]/g,
230
- 'L': /[LⓁLĿĹĽḶḸĻḼḺŁȽⱢⱠꝈꝆꞀ]/g,
231
- 'M': /[MⓂMḾṀṂⱮƜ]/g,
232
- 'N': /[NⓃNǸŃÑṄŇṆŅṊṈȠƝꞐꞤ]/g,
233
- 'O': /[OⓄOÒÓÔỒỐỖỔÕṌȬṎŌṐṒŎȮȰÖȪỎŐǑȌȎƠỜỚỠỞỢỌỘǪǬØǾƆƟꝊꝌ]/g,
234
- 'P': /[PⓅPṔṖƤⱣꝐꝒꝔ]/g,
235
- 'Q': /[QⓆQꝖꝘɊ]/g,
236
- 'R': /[RⓇRŔṘŘȐȒṚṜŖṞɌⱤꝚꞦꞂ]/g,
237
- 'S': /[SⓈSẞŚṤŜṠŠṦṢṨȘŞⱾꞨꞄ]/g,
238
- 'T': /[TⓉTṪŤṬȚŢṰṮŦƬƮȾꞆ]/g,
239
- 'U': /[UⓊUÙÚÛŨṸŪṺŬÜǛǗǕǙỦŮŰǓȔȖƯỪỨỮỬỰỤṲŲṶṴɄ]/g,
240
- 'V': /[VⓋVṼṾƲꝞɅ]/g,
241
- 'W': /[WⓌWẀẂŴẆẄẈⱲ]/g,
242
- 'X': /[XⓍXẊẌ]/g,
243
- 'Y': /[YⓎYỲÝŶỸȲẎŸỶỴƳɎỾ]/g,
244
- 'Z': /[ZⓏZŹẐŻŽẒẔƵȤⱿⱫꝢ]/g,
245
- 'a': /[aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐ]/g,
246
- 'b': /[bⓑbḃḅḇƀƃɓ]/g,
247
- 'c': /[cⓒcćĉċčçḉƈȼꜿↄ]/g,
248
- 'd': /[dⓓdḋďḍḑḓḏđƌɖɗꝺ]/g,
249
- 'e': /[eⓔeèéêềếễểẽēḕḗĕėëẻěȅȇẹệȩḝęḙḛɇɛǝ]/g,
250
- 'f': /[fⓕfḟƒꝼ]/g,
251
- 'g': /[gⓖgǵĝḡğġǧģǥɠꞡᵹꝿ]/g,
252
- 'h': /[hⓗhĥḣḧȟḥḩḫẖħⱨⱶɥ]/g,
253
- 'i': /[iⓘiìíîĩīĭïḯỉǐȉȋịįḭɨı]/g,
254
- 'j': /[jⓙjĵǰɉ]/g,
255
- 'k': /[kⓚkḱǩḳķḵƙⱪꝁꝃꝅꞣ]/g,
256
- 'l': /[lⓛlŀĺľḷḹļḽḻſłƚɫⱡꝉꞁꝇ]/g,
257
- 'm': /[mⓜmḿṁṃɱɯ]/g,
258
- 'n': /[nⓝnǹńñṅňṇņṋṉƞɲʼnꞑꞥ]/g,
259
- 'o': /[oⓞoòóôồốỗổõṍȭṏōṑṓŏȯȱöȫỏőǒȍȏơờớỡởợọộǫǭøǿɔꝋꝍɵ]/g,
260
- 'p': /[pⓟpṕṗƥᵽꝑꝓꝕ]/g,
261
- 'q': /[qⓠqɋꝗꝙ]/g,
262
- 'r': /[rⓡrŕṙřȑȓṛṝŗṟɍɽꝛꞧꞃ]/g,
263
- 's': /[sⓢsśṥŝṡšṧṣṩșşȿꞩꞅẛ]/g,
264
- 't': /[tⓣtṫẗťṭțţṱṯŧƭʈⱦꞇ]/g,
265
- 'u': /[uⓤuùúûũṹūṻŭüǜǘǖǚủůűǔȕȗưừứữửựụṳųṷṵʉ]/g,
266
- 'v': /[vⓥvṽṿʋꝟʌ]/g,
267
- 'w': /[wⓦwẁẃŵẇẅẘẉⱳ]/g,
268
- 'x': /[xⓧxẋẍ]/g,
269
- 'y': /[yⓨyỳýŷỹȳẏÿỷẙỵƴɏỿ]/g,
270
- 'z': /[zⓩzźẑżžẓẕƶȥɀⱬꝣ]/g,
271
- 'AA': /[Ꜳ]/g,
272
- 'AE': /[ÆǼǢ]/g,
273
- 'AO': /[Ꜵ]/g,
274
- 'AU': /[Ꜷ]/g,
275
- 'AV': /[ꜸꜺ]/g,
276
- 'AY': /[Ꜽ]/g,
277
- 'DZ': /[DZDŽ]/g,
278
- 'Dz': /[DzDž]/g,
279
- 'LJ': /[LJ]/g,
280
- 'Lj': /[Lj]/g,
281
- 'NJ': /[NJ]/g,
282
- 'Nj': /[Nj]/g,
283
- 'OI': /[Ƣ]/g,
284
- 'OO': /[Ꝏ]/g,
285
- 'OU': /[Ȣ]/g,
286
- 'TZ': /[Ꜩ]/g,
287
- 'VY': /[Ꝡ]/g,
288
- 'aa': /[ꜳ]/g,
289
- 'ae': /[æǽǣ]/g,
290
- 'ao': /[ꜵ]/g,
291
- 'au': /[ꜷ]/g,
292
- 'av': /[ꜹꜻ]/g,
293
- 'ay': /[ꜽ]/g,
294
- 'dz': /[dzdž]/g,
295
- 'hv': /[ƕ]/g,
296
- 'lj': /[lj]/g,
297
- 'nj': /[nj]/g,
298
- 'oi': /[ƣ]/g,
299
- 'ou': /[ȣ]/g,
300
- 'oo': /[ꝏ]/g,
301
- 'ss': /[ß]/g,
302
- 'tz': /[ꜩ]/g,
303
- 'vy': /[ꝡ]/
304
- };
305
-
306
-
307
232
  Inflector.plural(/$/, 's');
308
233
  Inflector.plural(/s$/gi, 's');
309
234
  Inflector.plural(/(ax|test)is$/gi, '$1es');
@@ -328,7 +253,7 @@
328
253
  Inflector.plural(/(quiz)$/gi, '$1zes');
329
254
  Inflector.plural(/(phot|cant|hom|zer|pian|portic|pr|quart|kimon)o$/gi, '$1os');
330
255
  Inflector.plural(/(craft)$/gi, '$1');
331
- Inflector.plural(/[eo]{2}(th?)$/gi, 'ee$1');
256
+ Inflector.plural(/([ft])[eo]{2}(th?)$/gi, '$1ee$2');
332
257
 
333
258
  Inflector.singular(/s$/gi, '');
334
259
  Inflector.singular(/([pst][aiu]s)$/gi, '$1');
@@ -372,7 +297,7 @@
372
297
  Inflector.uncountable('equipment,information,rice,money,species,series,fish,sheep,jeans'.split(','));
373
298
 
374
299
 
375
- String.extend({
300
+ extend(string, true, false, {
376
301
 
377
302
  /***
378
303
  * @method pluralize()
@@ -447,7 +372,7 @@
447
372
  hasPunctuation = fullStopPunctuation.test(word);
448
373
  isFirstOrLast = index == 0 || index == words.length - 1 || hasPunctuation || lastHadPunctuation;
449
374
  lastHadPunctuation = hasPunctuation;
450
- if(isFirstOrLast || !Downcased.any(word)) {
375
+ if(isFirstOrLast || Downcased.indexOf(word) === -1) {
451
376
  return capitalize(word);
452
377
  } else {
453
378
  return word;
@@ -455,24 +380,6 @@
455
380
  }).join(' ');
456
381
  },
457
382
 
458
- /***
459
- * @method namespace()
460
- * @returns Mixed
461
- * @short Tries to find the namespace or property with the name specified in the string.
462
- * @extra Namespacing begins at the global level and operates on every "." in the string. If any level returns %undefined% the result will be %undefined%.
463
- * @example
464
- *
465
- * 'Path.To.Namespace'.namespace() -> Path.To.Namespace
466
- *
467
- ***/
468
- 'namespace': function() {
469
- var spaces = this.split('.'), scope = globalContext;
470
- spaces.each(function(s) {
471
- return !!(scope = scope[s]);
472
- });
473
- return scope;
474
- },
475
-
476
383
  /***
477
384
  * @method parameterize()
478
385
  * @returns String
@@ -483,38 +390,20 @@
483
390
  *
484
391
  ***/
485
392
  'parameterize': function(separator) {
393
+ var str = this;
486
394
  if(separator === undefined) separator = '-';
487
- var str = this.normalize();
395
+ if(str.normalize) {
396
+ str = str.normalize();
397
+ }
488
398
  str = str.replace(/[^a-z0-9\-_]+/gi, separator)
489
399
  if(separator) {
490
- str = str.replace(new RegExp('^{sep}+|{sep}+$|({sep}){sep}+'.assign({ 'sep': RegExp.escape(separator) }), 'g'), '$1');
400
+ str = str.replace(new regexp('^{sep}+|{sep}+$|({sep}){sep}+'.assign({ 'sep': escapeRegExp(separator) }), 'g'), '$1');
491
401
  }
492
- return str.toLowerCase();
493
- },
494
-
495
- /***
496
- * @method normalize()
497
- * @returns String
498
- * @short Returns the string with accented and non-standard Latin-based characters converted into ASCII approximate equivalents.
499
- * @example
500
- *
501
- * 'á'.normalize() -> 'a'
502
- * 'Ménage à trois'.normalize() -> 'Menage a trois'
503
- * 'Volkswagen'.normalize() -> 'Volkswagen'
504
- * 'FULLWIDTH'.normalize() -> 'FULLWIDTH'
505
- *
506
- ***/
507
- 'normalize': function() {
508
- var str = this.toString();
509
- Object.each(Normalize, function(base, reg) {
510
- str = str.replace(reg, base);
511
- });
512
- return str;
402
+ return encodeURI(str.toLowerCase());
513
403
  }
514
404
 
515
405
  });
516
406
 
517
- String.Inflector = Inflector;
518
- String.Inflector.acronyms = acronyms;
407
+ string.Inflector = Inflector;
408
+ string.Inflector.acronyms = acronyms;
519
409
 
520
- })(this);