36b6acc2d92d835eaecaf12fc45eb16648db124a
[yaffs-website] / node_modules / underscore.string / dist / underscore.string.js
1 /* underscore.string 3.2.2 | MIT licensed | http://epeli.github.com/underscore.string/ */
2
3 !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.s=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
4 var trim = _dereq_('./trim');
5 var decap = _dereq_('./decapitalize');
6
7 module.exports = function camelize(str, decapitalize) {
8   str = trim(str).replace(/[-_\s]+(.)?/g, function(match, c) {
9     return c ? c.toUpperCase() : "";
10   });
11
12   if (decapitalize === true) {
13     return decap(str);
14   } else {
15     return str;
16   }
17 };
18
19 },{"./decapitalize":10,"./trim":63}],2:[function(_dereq_,module,exports){
20 var makeString = _dereq_('./helper/makeString');
21
22 module.exports = function capitalize(str, lowercaseRest) {
23   str = makeString(str);
24   var remainingChars = !lowercaseRest ? str.slice(1) : str.slice(1).toLowerCase();
25
26   return str.charAt(0).toUpperCase() + remainingChars;
27 };
28
29 },{"./helper/makeString":21}],3:[function(_dereq_,module,exports){
30 var makeString = _dereq_('./helper/makeString');
31
32 module.exports = function chars(str) {
33   return makeString(str).split('');
34 };
35
36 },{"./helper/makeString":21}],4:[function(_dereq_,module,exports){
37 module.exports = function chop(str, step) {
38   if (str == null) return [];
39   str = String(str);
40   step = ~~step;
41   return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
42 };
43
44 },{}],5:[function(_dereq_,module,exports){
45 var capitalize = _dereq_('./capitalize');
46 var camelize = _dereq_('./camelize');
47 var makeString = _dereq_('./helper/makeString');
48
49 module.exports = function classify(str) {
50   str = makeString(str);
51   return capitalize(camelize(str.replace(/[\W_]/g, ' ')).replace(/\s/g, ''));
52 };
53
54 },{"./camelize":1,"./capitalize":2,"./helper/makeString":21}],6:[function(_dereq_,module,exports){
55 var trim = _dereq_('./trim');
56
57 module.exports = function clean(str) {
58   return trim(str).replace(/\s\s+/g, ' ');
59 };
60
61 },{"./trim":63}],7:[function(_dereq_,module,exports){
62
63 var makeString = _dereq_('./helper/makeString');
64
65 var from  = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșşšŝťțţŭùúüűûñÿýçżźž",
66     to    = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssstttuuuuuunyyczzz";
67
68 from += from.toUpperCase();
69 to += to.toUpperCase();
70
71 to = to.split("");
72
73 // for tokens requireing multitoken output
74 from += "ß";
75 to.push('ss');
76
77
78 module.exports = function cleanDiacritics(str) {
79     return makeString(str).replace(/.{1}/g, function(c){
80       var index = from.indexOf(c);
81       return index === -1 ? c : to[index];
82   });
83 };
84
85 },{"./helper/makeString":21}],8:[function(_dereq_,module,exports){
86 var makeString = _dereq_('./helper/makeString');
87
88 module.exports = function(str, substr) {
89   str = makeString(str);
90   substr = makeString(substr);
91
92   if (str.length === 0 || substr.length === 0) return 0;
93   
94   return str.split(substr).length - 1;
95 };
96
97 },{"./helper/makeString":21}],9:[function(_dereq_,module,exports){
98 var trim = _dereq_('./trim');
99
100 module.exports = function dasherize(str) {
101   return trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
102 };
103
104 },{"./trim":63}],10:[function(_dereq_,module,exports){
105 var makeString = _dereq_('./helper/makeString');
106
107 module.exports = function decapitalize(str) {
108   str = makeString(str);
109   return str.charAt(0).toLowerCase() + str.slice(1);
110 };
111
112 },{"./helper/makeString":21}],11:[function(_dereq_,module,exports){
113 var makeString = _dereq_('./helper/makeString');
114
115 function getIndent(str) {
116   var matches = str.match(/^[\s\\t]*/gm);
117   var indent = matches[0].length;
118   
119   for (var i = 1; i < matches.length; i++) {
120     indent = Math.min(matches[i].length, indent);
121   }
122
123   return indent;
124 }
125
126 module.exports = function dedent(str, pattern) {
127   str = makeString(str);
128   var indent = getIndent(str);
129   var reg;
130
131   if (indent === 0) return str;
132
133   if (typeof pattern === 'string') {
134     reg = new RegExp('^' + pattern, 'gm');
135   } else {
136     reg = new RegExp('^[ \\t]{' + indent + '}', 'gm');
137   }
138
139   return str.replace(reg, '');
140 };
141
142 },{"./helper/makeString":21}],12:[function(_dereq_,module,exports){
143 var makeString = _dereq_('./helper/makeString');
144 var toPositive = _dereq_('./helper/toPositive');
145
146 module.exports = function endsWith(str, ends, position) {
147   str = makeString(str);
148   ends = '' + ends;
149   if (typeof position == 'undefined') {
150     position = str.length - ends.length;
151   } else {
152     position = Math.min(toPositive(position), str.length) - ends.length;
153   }
154   return position >= 0 && str.indexOf(ends, position) === position;
155 };
156
157 },{"./helper/makeString":21,"./helper/toPositive":23}],13:[function(_dereq_,module,exports){
158 var makeString = _dereq_('./helper/makeString');
159 var escapeChars = _dereq_('./helper/escapeChars');
160
161 var regexString = "[";
162 for(var key in escapeChars) {
163   regexString += key;
164 }
165 regexString += "]";
166
167 var regex = new RegExp( regexString, 'g');
168
169 module.exports = function escapeHTML(str) {
170
171   return makeString(str).replace(regex, function(m) {
172     return '&' + escapeChars[m] + ';';
173   });
174 };
175
176 },{"./helper/escapeChars":18,"./helper/makeString":21}],14:[function(_dereq_,module,exports){
177 module.exports = function() {
178   var result = {};
179
180   for (var prop in this) {
181     if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse|join|map)$/)) continue;
182     result[prop] = this[prop];
183   }
184
185   return result;
186 };
187
188 },{}],15:[function(_dereq_,module,exports){
189 //  Underscore.string
190 //  (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
191 //  Underscore.string is freely distributable under the terms of the MIT license.
192 //  Documentation: https://github.com/epeli/underscore.string
193 //  Some code is borrowed from MooTools and Alexandru Marasteanu.
194 //  Version '3.2.2'
195
196 'use strict';
197
198 function s(value) {
199   /* jshint validthis: true */
200   if (!(this instanceof s)) return new s(value);
201   this._wrapped = value;
202 }
203
204 s.VERSION = '3.2.2';
205
206 s.isBlank          = _dereq_('./isBlank');
207 s.stripTags        = _dereq_('./stripTags');
208 s.capitalize       = _dereq_('./capitalize');
209 s.decapitalize     = _dereq_('./decapitalize');
210 s.chop             = _dereq_('./chop');
211 s.trim             = _dereq_('./trim');
212 s.clean            = _dereq_('./clean');
213 s.cleanDiacritics  = _dereq_('./cleanDiacritics');
214 s.count            = _dereq_('./count');
215 s.chars            = _dereq_('./chars');
216 s.swapCase         = _dereq_('./swapCase');
217 s.escapeHTML       = _dereq_('./escapeHTML');
218 s.unescapeHTML     = _dereq_('./unescapeHTML');
219 s.splice           = _dereq_('./splice');
220 s.insert           = _dereq_('./insert');
221 s.replaceAll       = _dereq_('./replaceAll');
222 s.include          = _dereq_('./include');
223 s.join             = _dereq_('./join');
224 s.lines            = _dereq_('./lines');
225 s.dedent           = _dereq_('./dedent');
226 s.reverse          = _dereq_('./reverse');
227 s.startsWith       = _dereq_('./startsWith');
228 s.endsWith         = _dereq_('./endsWith');
229 s.pred             = _dereq_('./pred');
230 s.succ             = _dereq_('./succ');
231 s.titleize         = _dereq_('./titleize');
232 s.camelize         = _dereq_('./camelize');
233 s.underscored      = _dereq_('./underscored');
234 s.dasherize        = _dereq_('./dasherize');
235 s.classify         = _dereq_('./classify');
236 s.humanize         = _dereq_('./humanize');
237 s.ltrim            = _dereq_('./ltrim');
238 s.rtrim            = _dereq_('./rtrim');
239 s.truncate         = _dereq_('./truncate');
240 s.prune            = _dereq_('./prune');
241 s.words            = _dereq_('./words');
242 s.pad              = _dereq_('./pad');
243 s.lpad             = _dereq_('./lpad');
244 s.rpad             = _dereq_('./rpad');
245 s.lrpad            = _dereq_('./lrpad');
246 s.sprintf          = _dereq_('./sprintf');
247 s.vsprintf         = _dereq_('./vsprintf');
248 s.toNumber         = _dereq_('./toNumber');
249 s.numberFormat     = _dereq_('./numberFormat');
250 s.strRight         = _dereq_('./strRight');
251 s.strRightBack     = _dereq_('./strRightBack');
252 s.strLeft          = _dereq_('./strLeft');
253 s.strLeftBack      = _dereq_('./strLeftBack');
254 s.toSentence       = _dereq_('./toSentence');
255 s.toSentenceSerial = _dereq_('./toSentenceSerial');
256 s.slugify          = _dereq_('./slugify');
257 s.surround         = _dereq_('./surround');
258 s.quote            = _dereq_('./quote');
259 s.unquote          = _dereq_('./unquote');
260 s.repeat           = _dereq_('./repeat');
261 s.naturalCmp       = _dereq_('./naturalCmp');
262 s.levenshtein      = _dereq_('./levenshtein');
263 s.toBoolean        = _dereq_('./toBoolean');
264 s.exports          = _dereq_('./exports');
265 s.escapeRegExp     = _dereq_('./helper/escapeRegExp');
266 s.wrap             = _dereq_('./wrap');
267 s.map              = _dereq_('./map');
268
269 // Aliases
270 s.strip     = s.trim;
271 s.lstrip    = s.ltrim;
272 s.rstrip    = s.rtrim;
273 s.center    = s.lrpad;
274 s.rjust     = s.lpad;
275 s.ljust     = s.rpad;
276 s.contains  = s.include;
277 s.q         = s.quote;
278 s.toBool    = s.toBoolean;
279 s.camelcase = s.camelize;
280 s.mapChars  = s.map;
281
282
283 // Implement chaining
284 s.prototype = {
285   value: function value() {
286     return this._wrapped;
287   }
288 };
289
290 function fn2method(key, fn) {
291   if (typeof fn !== "function") return;
292   s.prototype[key] = function() {
293     var args = [this._wrapped].concat(Array.prototype.slice.call(arguments));
294     var res = fn.apply(null, args);
295     // if the result is non-string stop the chain and return the value
296     return typeof res === 'string' ? new s(res) : res;
297   };
298 }
299
300 // Copy functions to instance methods for chaining
301 for (var key in s) fn2method(key, s[key]);
302
303 fn2method("tap", function tap(string, fn) {
304   return fn(string);
305 });
306
307 function prototype2method(methodName) {
308   fn2method(methodName, function(context) {
309     var args = Array.prototype.slice.call(arguments, 1);
310     return String.prototype[methodName].apply(context, args);
311   });
312 }
313
314 var prototypeMethods = [
315     "toUpperCase",
316     "toLowerCase",
317     "split",
318     "replace",
319     "slice",
320     "substring",
321     "substr",
322     "concat"
323 ];
324
325 for (var method in prototypeMethods) prototype2method(prototypeMethods[method]);
326
327
328 module.exports = s;
329
330 },{"./camelize":1,"./capitalize":2,"./chars":3,"./chop":4,"./classify":5,"./clean":6,"./cleanDiacritics":7,"./count":8,"./dasherize":9,"./decapitalize":10,"./dedent":11,"./endsWith":12,"./escapeHTML":13,"./exports":14,"./helper/escapeRegExp":19,"./humanize":24,"./include":25,"./insert":26,"./isBlank":27,"./join":28,"./levenshtein":29,"./lines":30,"./lpad":31,"./lrpad":32,"./ltrim":33,"./map":34,"./naturalCmp":35,"./numberFormat":36,"./pad":37,"./pred":38,"./prune":39,"./quote":40,"./repeat":41,"./replaceAll":42,"./reverse":43,"./rpad":44,"./rtrim":45,"./slugify":46,"./splice":47,"./sprintf":48,"./startsWith":49,"./strLeft":50,"./strLeftBack":51,"./strRight":52,"./strRightBack":53,"./stripTags":54,"./succ":55,"./surround":56,"./swapCase":57,"./titleize":58,"./toBoolean":59,"./toNumber":60,"./toSentence":61,"./toSentenceSerial":62,"./trim":63,"./truncate":64,"./underscored":65,"./unescapeHTML":66,"./unquote":67,"./vsprintf":68,"./words":69,"./wrap":70}],16:[function(_dereq_,module,exports){
331 var makeString = _dereq_('./makeString');
332
333 module.exports = function adjacent(str, direction) {
334   str = makeString(str);
335   if (str.length === 0) {
336     return '';
337   }
338   return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length - 1) + direction);
339 };
340
341 },{"./makeString":21}],17:[function(_dereq_,module,exports){
342 var escapeRegExp = _dereq_('./escapeRegExp');
343
344 module.exports = function defaultToWhiteSpace(characters) {
345   if (characters == null)
346     return '\\s';
347   else if (characters.source)
348     return characters.source;
349   else
350     return '[' + escapeRegExp(characters) + ']';
351 };
352
353 },{"./escapeRegExp":19}],18:[function(_dereq_,module,exports){
354 /* We're explicitly defining the list of entities we want to escape.
355 nbsp is an HTML entity, but we don't want to escape all space characters in a string, hence its omission in this map.
356
357 */
358 var escapeChars = {
359     '¢' : 'cent',
360     '£' : 'pound',
361     '¥' : 'yen',
362     '€': 'euro',
363     '©' :'copy',
364     '®' : 'reg',
365     '<' : 'lt',
366     '>' : 'gt',
367     '"' : 'quot',
368     '&' : 'amp',
369     "'" : '#39'
370 };
371
372 module.exports = escapeChars;
373
374 },{}],19:[function(_dereq_,module,exports){
375 var makeString = _dereq_('./makeString');
376
377 module.exports = function escapeRegExp(str) {
378   return makeString(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
379 };
380
381 },{"./makeString":21}],20:[function(_dereq_,module,exports){
382 /*
383 We're explicitly defining the list of entities that might see in escape HTML strings
384 */
385 var htmlEntities = {
386   nbsp: ' ',
387   cent: '¢',
388   pound: '£',
389   yen: '¥',
390   euro: '€',
391   copy: '©',
392   reg: '®',
393   lt: '<',
394   gt: '>',
395   quot: '"',
396   amp: '&',
397   apos: "'"
398 };
399
400 module.exports = htmlEntities;
401
402 },{}],21:[function(_dereq_,module,exports){
403 /**
404  * Ensure some object is a coerced to a string
405  **/
406 module.exports = function makeString(object) {
407   if (object == null) return '';
408   return '' + object;
409 };
410
411 },{}],22:[function(_dereq_,module,exports){
412 module.exports = function strRepeat(str, qty){
413   if (qty < 1) return '';
414   var result = '';
415   while (qty > 0) {
416     if (qty & 1) result += str;
417     qty >>= 1, str += str;
418   }
419   return result;
420 };
421
422 },{}],23:[function(_dereq_,module,exports){
423 module.exports = function toPositive(number) {
424   return number < 0 ? 0 : (+number || 0);
425 };
426
427 },{}],24:[function(_dereq_,module,exports){
428 var capitalize = _dereq_('./capitalize');
429 var underscored = _dereq_('./underscored');
430 var trim = _dereq_('./trim');
431
432 module.exports = function humanize(str) {
433   return capitalize(trim(underscored(str).replace(/_id$/, '').replace(/_/g, ' ')));
434 };
435
436 },{"./capitalize":2,"./trim":63,"./underscored":65}],25:[function(_dereq_,module,exports){
437 var makeString = _dereq_('./helper/makeString');
438
439 module.exports = function include(str, needle) {
440   if (needle === '') return true;
441   return makeString(str).indexOf(needle) !== -1;
442 };
443
444 },{"./helper/makeString":21}],26:[function(_dereq_,module,exports){
445 var splice = _dereq_('./splice');
446
447 module.exports = function insert(str, i, substr) {
448   return splice(str, i, 0, substr);
449 };
450
451 },{"./splice":47}],27:[function(_dereq_,module,exports){
452 var makeString = _dereq_('./helper/makeString');
453
454 module.exports = function isBlank(str) {
455   return (/^\s*$/).test(makeString(str));
456 };
457
458 },{"./helper/makeString":21}],28:[function(_dereq_,module,exports){
459 var makeString = _dereq_('./helper/makeString');
460 var slice = [].slice;
461
462 module.exports = function join() {
463   var args = slice.call(arguments),
464     separator = args.shift();
465
466   return args.join(makeString(separator));
467 };
468
469 },{"./helper/makeString":21}],29:[function(_dereq_,module,exports){
470 var makeString = _dereq_('./helper/makeString');
471
472 /**
473  * Based on the implementation here: https://github.com/hiddentao/fast-levenshtein
474  */
475 module.exports = function levenshtein(str1, str2) {
476   'use strict';
477   str1 = makeString(str1);
478   str2 = makeString(str2);
479
480   // Short cut cases  
481   if (str1 === str2) return 0;
482   if (!str1 || !str2) return Math.max(str1.length, str2.length);
483
484   // two rows
485   var prevRow = new Array(str2.length + 1);
486
487   // initialise previous row
488   for (var i = 0; i < prevRow.length; ++i) {
489     prevRow[i] = i;
490   }
491
492   // calculate current row distance from previous row
493   for (i = 0; i < str1.length; ++i) {
494     var nextCol = i + 1;
495
496     for (var j = 0; j < str2.length; ++j) {
497       var curCol = nextCol;
498
499       // substution
500       nextCol = prevRow[j] + ( (str1.charAt(i) === str2.charAt(j)) ? 0 : 1 );
501       // insertion
502       var tmp = curCol + 1;
503       if (nextCol > tmp) {
504         nextCol = tmp;
505       }
506       // deletion
507       tmp = prevRow[j + 1] + 1;
508       if (nextCol > tmp) {
509         nextCol = tmp;
510       }
511
512       // copy current col value into previous (in preparation for next iteration)
513       prevRow[j] = curCol;
514     }
515
516     // copy last col value into previous (in preparation for next iteration)
517     prevRow[j] = nextCol;
518   }
519
520   return nextCol;
521 };
522
523 },{"./helper/makeString":21}],30:[function(_dereq_,module,exports){
524 module.exports = function lines(str) {
525   if (str == null) return [];
526   return String(str).split(/\r\n?|\n/);
527 };
528
529 },{}],31:[function(_dereq_,module,exports){
530 var pad = _dereq_('./pad');
531
532 module.exports = function lpad(str, length, padStr) {
533   return pad(str, length, padStr);
534 };
535
536 },{"./pad":37}],32:[function(_dereq_,module,exports){
537 var pad = _dereq_('./pad');
538
539 module.exports = function lrpad(str, length, padStr) {
540   return pad(str, length, padStr, 'both');
541 };
542
543 },{"./pad":37}],33:[function(_dereq_,module,exports){
544 var makeString = _dereq_('./helper/makeString');
545 var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
546 var nativeTrimLeft = String.prototype.trimLeft;
547
548 module.exports = function ltrim(str, characters) {
549   str = makeString(str);
550   if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
551   characters = defaultToWhiteSpace(characters);
552   return str.replace(new RegExp('^' + characters + '+'), '');
553 };
554
555 },{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],34:[function(_dereq_,module,exports){
556 var makeString = _dereq_('./helper/makeString');
557
558 module.exports = function(str, callback) {
559   str = makeString(str);
560
561   if (str.length === 0 || typeof callback !== 'function') return str;
562
563   return str.replace(/./g, callback);
564 };
565
566 },{"./helper/makeString":21}],35:[function(_dereq_,module,exports){
567 module.exports = function naturalCmp(str1, str2) {
568   if (str1 == str2) return 0;
569   if (!str1) return -1;
570   if (!str2) return 1;
571
572   var cmpRegex = /(\.\d+|\d+|\D+)/g,
573     tokens1 = String(str1).match(cmpRegex),
574     tokens2 = String(str2).match(cmpRegex),
575     count = Math.min(tokens1.length, tokens2.length);
576
577   for (var i = 0; i < count; i++) {
578     var a = tokens1[i],
579       b = tokens2[i];
580
581     if (a !== b) {
582       var num1 = +a;
583       var num2 = +b;
584       if (num1 === num1 && num2 === num2) {
585         return num1 > num2 ? 1 : -1;
586       }
587       return a < b ? -1 : 1;
588     }
589   }
590
591   if (tokens1.length != tokens2.length)
592     return tokens1.length - tokens2.length;
593
594   return str1 < str2 ? -1 : 1;
595 };
596
597 },{}],36:[function(_dereq_,module,exports){
598 module.exports = function numberFormat(number, dec, dsep, tsep) {
599   if (isNaN(number) || number == null) return '';
600
601   number = number.toFixed(~~dec);
602   tsep = typeof tsep == 'string' ? tsep : ',';
603
604   var parts = number.split('.'),
605     fnums = parts[0],
606     decimals = parts[1] ? (dsep || '.') + parts[1] : '';
607
608   return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
609 };
610
611 },{}],37:[function(_dereq_,module,exports){
612 var makeString = _dereq_('./helper/makeString');
613 var strRepeat = _dereq_('./helper/strRepeat');
614
615 module.exports = function pad(str, length, padStr, type) {
616   str = makeString(str);
617   length = ~~length;
618
619   var padlen = 0;
620
621   if (!padStr)
622     padStr = ' ';
623   else if (padStr.length > 1)
624     padStr = padStr.charAt(0);
625
626   switch (type) {
627     case 'right':
628       padlen = length - str.length;
629       return str + strRepeat(padStr, padlen);
630     case 'both':
631       padlen = length - str.length;
632       return strRepeat(padStr, Math.ceil(padlen / 2)) + str + strRepeat(padStr, Math.floor(padlen / 2));
633     default: // 'left'
634       padlen = length - str.length;
635       return strRepeat(padStr, padlen) + str;
636   }
637 };
638
639 },{"./helper/makeString":21,"./helper/strRepeat":22}],38:[function(_dereq_,module,exports){
640 var adjacent = _dereq_('./helper/adjacent');
641
642 module.exports = function succ(str) {
643   return adjacent(str, -1);
644 };
645
646 },{"./helper/adjacent":16}],39:[function(_dereq_,module,exports){
647 /**
648  * _s.prune: a more elegant version of truncate
649  * prune extra chars, never leaving a half-chopped word.
650  * @author github.com/rwz
651  */
652 var makeString = _dereq_('./helper/makeString');
653 var rtrim = _dereq_('./rtrim');
654
655 module.exports = function prune(str, length, pruneStr) {
656   str = makeString(str);
657   length = ~~length;
658   pruneStr = pruneStr != null ? String(pruneStr) : '...';
659
660   if (str.length <= length) return str;
661
662   var tmpl = function(c) {
663     return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' ';
664   },
665     template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
666
667   if (template.slice(template.length - 2).match(/\w\w/))
668     template = template.replace(/\s*\S+$/, '');
669   else
670     template = rtrim(template.slice(0, template.length - 1));
671
672   return (template + pruneStr).length > str.length ? str : str.slice(0, template.length) + pruneStr;
673 };
674
675 },{"./helper/makeString":21,"./rtrim":45}],40:[function(_dereq_,module,exports){
676 var surround = _dereq_('./surround');
677
678 module.exports = function quote(str, quoteChar) {
679   return surround(str, quoteChar || '"');
680 };
681
682 },{"./surround":56}],41:[function(_dereq_,module,exports){
683 var makeString = _dereq_('./helper/makeString');
684 var strRepeat = _dereq_('./helper/strRepeat');
685
686 module.exports = function repeat(str, qty, separator) {
687   str = makeString(str);
688
689   qty = ~~qty;
690
691   // using faster implementation if separator is not needed;
692   if (separator == null) return strRepeat(str, qty);
693
694   // this one is about 300x slower in Google Chrome
695   /*eslint no-empty: 0*/
696   for (var repeat = []; qty > 0; repeat[--qty] = str) {}
697   return repeat.join(separator);
698 };
699
700 },{"./helper/makeString":21,"./helper/strRepeat":22}],42:[function(_dereq_,module,exports){
701 var makeString = _dereq_('./helper/makeString');
702
703 module.exports = function replaceAll(str, find, replace, ignorecase) {
704   var flags = (ignorecase === true)?'gi':'g';
705   var reg = new RegExp(find, flags);
706
707   return makeString(str).replace(reg, replace);
708 };
709
710 },{"./helper/makeString":21}],43:[function(_dereq_,module,exports){
711 var chars = _dereq_('./chars');
712
713 module.exports = function reverse(str) {
714   return chars(str).reverse().join('');
715 };
716
717 },{"./chars":3}],44:[function(_dereq_,module,exports){
718 var pad = _dereq_('./pad');
719
720 module.exports = function rpad(str, length, padStr) {
721   return pad(str, length, padStr, 'right');
722 };
723
724 },{"./pad":37}],45:[function(_dereq_,module,exports){
725 var makeString = _dereq_('./helper/makeString');
726 var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
727 var nativeTrimRight = String.prototype.trimRight;
728
729 module.exports = function rtrim(str, characters) {
730   str = makeString(str);
731   if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
732   characters = defaultToWhiteSpace(characters);
733   return str.replace(new RegExp(characters + '+$'), '');
734 };
735
736 },{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],46:[function(_dereq_,module,exports){
737 var trim = _dereq_('./trim');
738 var dasherize = _dereq_('./dasherize');
739 var cleanDiacritics = _dereq_("./cleanDiacritics");
740
741 module.exports = function slugify(str) {
742   return trim(dasherize(cleanDiacritics(str).replace(/[^\w\s-]/g, '-').toLowerCase()), '-');
743 };
744
745 },{"./cleanDiacritics":7,"./dasherize":9,"./trim":63}],47:[function(_dereq_,module,exports){
746 var chars = _dereq_('./chars');
747
748 module.exports = function splice(str, i, howmany, substr) {
749   var arr = chars(str);
750   arr.splice(~~i, ~~howmany, substr);
751   return arr.join('');
752 };
753
754 },{"./chars":3}],48:[function(_dereq_,module,exports){
755 // sprintf() for JavaScript 0.7-beta1
756 // http://www.diveintojavascript.com/projects/javascript-sprintf
757 //
758 // Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
759 // All rights reserved.
760 var strRepeat = _dereq_('./helper/strRepeat');
761 var toString = Object.prototype.toString;
762 var sprintf = (function() {
763   function get_type(variable) {
764     return toString.call(variable).slice(8, -1).toLowerCase();
765   }
766
767   var str_repeat = strRepeat;
768
769   var str_format = function() {
770     if (!str_format.cache.hasOwnProperty(arguments[0])) {
771       str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
772     }
773     return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
774   };
775
776   str_format.format = function(parse_tree, argv) {
777     var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
778     for (i = 0; i < tree_length; i++) {
779       node_type = get_type(parse_tree[i]);
780       if (node_type === 'string') {
781         output.push(parse_tree[i]);
782       }
783       else if (node_type === 'array') {
784         match = parse_tree[i]; // convenience purposes only
785         if (match[2]) { // keyword argument
786           arg = argv[cursor];
787           for (k = 0; k < match[2].length; k++) {
788             if (!arg.hasOwnProperty(match[2][k])) {
789               throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
790             }
791             arg = arg[match[2][k]];
792           }
793         } else if (match[1]) { // positional argument (explicit)
794           arg = argv[match[1]];
795         }
796         else { // positional argument (implicit)
797           arg = argv[cursor++];
798         }
799
800         if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
801           throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
802         }
803         switch (match[8]) {
804           case 'b': arg = arg.toString(2); break;
805           case 'c': arg = String.fromCharCode(arg); break;
806           case 'd': arg = parseInt(arg, 10); break;
807           case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
808           case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
809           case 'o': arg = arg.toString(8); break;
810           case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
811           case 'u': arg = Math.abs(arg); break;
812           case 'x': arg = arg.toString(16); break;
813           case 'X': arg = arg.toString(16).toUpperCase(); break;
814         }
815         arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
816         pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
817         pad_length = match[6] - String(arg).length;
818         pad = match[6] ? str_repeat(pad_character, pad_length) : '';
819         output.push(match[5] ? arg + pad : pad + arg);
820       }
821     }
822     return output.join('');
823   };
824
825   str_format.cache = {};
826
827   str_format.parse = function(fmt) {
828     var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
829     while (_fmt) {
830       if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
831         parse_tree.push(match[0]);
832       }
833       else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
834         parse_tree.push('%');
835       }
836       else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
837         if (match[2]) {
838           arg_names |= 1;
839           var field_list = [], replacement_field = match[2], field_match = [];
840           if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
841             field_list.push(field_match[1]);
842             while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
843               if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
844                 field_list.push(field_match[1]);
845               }
846               else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
847                 field_list.push(field_match[1]);
848               }
849               else {
850                 throw new Error('[_.sprintf] huh?');
851               }
852             }
853           }
854           else {
855             throw new Error('[_.sprintf] huh?');
856           }
857           match[2] = field_list;
858         }
859         else {
860           arg_names |= 2;
861         }
862         if (arg_names === 3) {
863           throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
864         }
865         parse_tree.push(match);
866       }
867       else {
868         throw new Error('[_.sprintf] huh?');
869       }
870       _fmt = _fmt.substring(match[0].length);
871     }
872     return parse_tree;
873   };
874
875   return str_format;
876 })();
877
878 module.exports = sprintf;
879
880 },{"./helper/strRepeat":22}],49:[function(_dereq_,module,exports){
881 var makeString = _dereq_('./helper/makeString');
882 var toPositive = _dereq_('./helper/toPositive');
883
884 module.exports = function startsWith(str, starts, position) {
885   str = makeString(str);
886   starts = '' + starts;
887   position = position == null ? 0 : Math.min(toPositive(position), str.length);
888   return str.lastIndexOf(starts, position) === position;
889 };
890
891 },{"./helper/makeString":21,"./helper/toPositive":23}],50:[function(_dereq_,module,exports){
892 var makeString = _dereq_('./helper/makeString');
893
894 module.exports = function strLeft(str, sep) {
895   str = makeString(str);
896   sep = makeString(sep);
897   var pos = !sep ? -1 : str.indexOf(sep);
898   return~ pos ? str.slice(0, pos) : str;
899 };
900
901 },{"./helper/makeString":21}],51:[function(_dereq_,module,exports){
902 var makeString = _dereq_('./helper/makeString');
903
904 module.exports = function strLeftBack(str, sep) {
905   str = makeString(str);
906   sep = makeString(sep);
907   var pos = str.lastIndexOf(sep);
908   return~ pos ? str.slice(0, pos) : str;
909 };
910
911 },{"./helper/makeString":21}],52:[function(_dereq_,module,exports){
912 var makeString = _dereq_('./helper/makeString');
913
914 module.exports = function strRight(str, sep) {
915   str = makeString(str);
916   sep = makeString(sep);
917   var pos = !sep ? -1 : str.indexOf(sep);
918   return~ pos ? str.slice(pos + sep.length, str.length) : str;
919 };
920
921 },{"./helper/makeString":21}],53:[function(_dereq_,module,exports){
922 var makeString = _dereq_('./helper/makeString');
923
924 module.exports = function strRightBack(str, sep) {
925   str = makeString(str);
926   sep = makeString(sep);
927   var pos = !sep ? -1 : str.lastIndexOf(sep);
928   return~ pos ? str.slice(pos + sep.length, str.length) : str;
929 };
930
931 },{"./helper/makeString":21}],54:[function(_dereq_,module,exports){
932 var makeString = _dereq_('./helper/makeString');
933
934 module.exports = function stripTags(str) {
935   return makeString(str).replace(/<\/?[^>]+>/g, '');
936 };
937
938 },{"./helper/makeString":21}],55:[function(_dereq_,module,exports){
939 var adjacent = _dereq_('./helper/adjacent');
940
941 module.exports = function succ(str) {
942   return adjacent(str, 1);
943 };
944
945 },{"./helper/adjacent":16}],56:[function(_dereq_,module,exports){
946 module.exports = function surround(str, wrapper) {
947   return [wrapper, str, wrapper].join('');
948 };
949
950 },{}],57:[function(_dereq_,module,exports){
951 var makeString = _dereq_('./helper/makeString');
952
953 module.exports = function swapCase(str) {
954   return makeString(str).replace(/\S/g, function(c) {
955     return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
956   });
957 };
958
959 },{"./helper/makeString":21}],58:[function(_dereq_,module,exports){
960 var makeString = _dereq_('./helper/makeString');
961
962 module.exports = function titleize(str) {
963   return makeString(str).toLowerCase().replace(/(?:^|\s|-)\S/g, function(c) {
964     return c.toUpperCase();
965   });
966 };
967
968 },{"./helper/makeString":21}],59:[function(_dereq_,module,exports){
969 var trim = _dereq_('./trim');
970
971 function boolMatch(s, matchers) {
972   var i, matcher, down = s.toLowerCase();
973   matchers = [].concat(matchers);
974   for (i = 0; i < matchers.length; i += 1) {
975     matcher = matchers[i];
976     if (!matcher) continue;
977     if (matcher.test && matcher.test(s)) return true;
978     if (matcher.toLowerCase() === down) return true;
979   }
980 }
981
982 module.exports = function toBoolean(str, trueValues, falseValues) {
983   if (typeof str === "number") str = "" + str;
984   if (typeof str !== "string") return !!str;
985   str = trim(str);
986   if (boolMatch(str, trueValues || ["true", "1"])) return true;
987   if (boolMatch(str, falseValues || ["false", "0"])) return false;
988 };
989
990 },{"./trim":63}],60:[function(_dereq_,module,exports){
991 module.exports = function toNumber(num, precision) {
992   if (num == null) return 0;
993   var factor = Math.pow(10, isFinite(precision) ? precision : 0);
994   return Math.round(num * factor) / factor;
995 };
996
997 },{}],61:[function(_dereq_,module,exports){
998 var rtrim = _dereq_('./rtrim');
999
1000 module.exports = function toSentence(array, separator, lastSeparator, serial) {
1001   separator = separator || ', ';
1002   lastSeparator = lastSeparator || ' and ';
1003   var a = array.slice(),
1004     lastMember = a.pop();
1005
1006   if (array.length > 2 && serial) lastSeparator = rtrim(separator) + lastSeparator;
1007
1008   return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
1009 };
1010
1011 },{"./rtrim":45}],62:[function(_dereq_,module,exports){
1012 var toSentence = _dereq_('./toSentence');
1013
1014 module.exports = function toSentenceSerial(array, sep, lastSep) {
1015   return toSentence(array, sep, lastSep, true);
1016 };
1017
1018 },{"./toSentence":61}],63:[function(_dereq_,module,exports){
1019 var makeString = _dereq_('./helper/makeString');
1020 var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
1021 var nativeTrim = String.prototype.trim;
1022
1023 module.exports = function trim(str, characters) {
1024   str = makeString(str);
1025   if (!characters && nativeTrim) return nativeTrim.call(str);
1026   characters = defaultToWhiteSpace(characters);
1027   return str.replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), '');
1028 };
1029
1030 },{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],64:[function(_dereq_,module,exports){
1031 var makeString = _dereq_('./helper/makeString');
1032
1033 module.exports = function truncate(str, length, truncateStr) {
1034   str = makeString(str);
1035   truncateStr = truncateStr || '...';
1036   length = ~~length;
1037   return str.length > length ? str.slice(0, length) + truncateStr : str;
1038 };
1039
1040 },{"./helper/makeString":21}],65:[function(_dereq_,module,exports){
1041 var trim = _dereq_('./trim');
1042
1043 module.exports = function underscored(str) {
1044   return trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
1045 };
1046
1047 },{"./trim":63}],66:[function(_dereq_,module,exports){
1048 var makeString = _dereq_('./helper/makeString');
1049 var htmlEntities = _dereq_('./helper/htmlEntities');
1050
1051 module.exports = function unescapeHTML(str) {
1052   return makeString(str).replace(/\&([^;]+);/g, function(entity, entityCode) {
1053     var match;
1054
1055     if (entityCode in htmlEntities) {
1056       return htmlEntities[entityCode];
1057     /*eslint no-cond-assign: 0*/
1058     } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
1059       return String.fromCharCode(parseInt(match[1], 16));
1060     /*eslint no-cond-assign: 0*/
1061     } else if (match = entityCode.match(/^#(\d+)$/)) {
1062       return String.fromCharCode(~~match[1]);
1063     } else {
1064       return entity;
1065     }
1066   });
1067 };
1068
1069 },{"./helper/htmlEntities":20,"./helper/makeString":21}],67:[function(_dereq_,module,exports){
1070 module.exports = function unquote(str, quoteChar) {
1071   quoteChar = quoteChar || '"';
1072   if (str[0] === quoteChar && str[str.length - 1] === quoteChar)
1073     return str.slice(1, str.length - 1);
1074   else return str;
1075 };
1076
1077 },{}],68:[function(_dereq_,module,exports){
1078 var sprintf = _dereq_('./sprintf');
1079
1080 module.exports = function vsprintf(fmt, argv) {
1081   argv.unshift(fmt);
1082   return sprintf.apply(null, argv);
1083 };
1084
1085 },{"./sprintf":48}],69:[function(_dereq_,module,exports){
1086 var isBlank = _dereq_('./isBlank');
1087 var trim = _dereq_('./trim');
1088
1089 module.exports = function words(str, delimiter) {
1090   if (isBlank(str)) return [];
1091   return trim(str, delimiter).split(delimiter || /\s+/);
1092 };
1093
1094 },{"./isBlank":27,"./trim":63}],70:[function(_dereq_,module,exports){
1095 // Wrap
1096 // wraps a string by a certain width
1097
1098 var makeString = _dereq_('./helper/makeString');
1099
1100 module.exports = function wrap(str, options){
1101         str = makeString(str);
1102
1103         options = options || {};
1104
1105         var width = options.width || 75;
1106         var seperator = options.seperator || '\n';
1107         var cut = options.cut || false;
1108         var preserveSpaces = options.preserveSpaces || false;
1109         var trailingSpaces = options.trailingSpaces || false;
1110
1111   var result;
1112
1113         if(width <= 0){
1114                 return str;
1115         }
1116
1117         else if(!cut){
1118
1119                 var words = str.split(" ");
1120                 var current_column = 0;
1121                 result = "";
1122
1123                 while(words.length > 0){
1124                         
1125                         // if adding a space and the next word would cause this line to be longer than width...
1126                         if(1 + words[0].length + current_column > width){
1127                                 //start a new line if this line is not already empty
1128                                 if(current_column > 0){
1129                                         // add a space at the end of the line is preserveSpaces is true
1130                                         if (preserveSpaces){
1131                                                 result += ' ';
1132                                                 current_column++;
1133                                         }
1134                                         // fill the rest of the line with spaces if trailingSpaces option is true
1135                                         else if(trailingSpaces){
1136                                                 while(current_column < width){
1137                                                         result += ' ';
1138                                                         current_column++;
1139                                                 }                                               
1140                                         }
1141                                         //start new line
1142                                         result += seperator;
1143                                         current_column = 0;
1144                                 }
1145                         }
1146
1147                         // if not at the begining of the line, add a space in front of the word
1148                         if(current_column > 0){
1149                                 result += " ";
1150                                 current_column++;
1151                         }
1152
1153                         // tack on the next word, update current column, a pop words array
1154                         result += words[0];
1155                         current_column += words[0].length;
1156                         words.shift();
1157
1158                 }
1159
1160                 // fill the rest of the line with spaces if trailingSpaces option is true
1161                 if(trailingSpaces){
1162                         while(current_column < width){
1163                                 result += ' ';
1164                                 current_column++;
1165                         }                                               
1166                 }
1167
1168                 return result;
1169
1170         }
1171
1172         else {
1173
1174                 var index = 0;
1175                 result = "";
1176
1177                 // walk through each character and add seperators where appropriate
1178                 while(index < str.length){
1179                         if(index % width == 0 && index > 0){
1180                                 result += seperator;
1181                         }
1182                         result += str.charAt(index);
1183                         index++;
1184                 }
1185
1186                 // fill the rest of the line with spaces if trailingSpaces option is true
1187                 if(trailingSpaces){
1188                         while(index % width > 0){
1189                                 result += ' ';
1190                                 index++;
1191                         }                                               
1192                 }
1193                 
1194                 return result;
1195         }
1196 };
1197
1198 },{"./helper/makeString":21}]},{},[15])
1199 (15)
1200 });