pageflow 17.0.1 → 17.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ const _ = require('underscore');
2
+
3
+ // Cocktail.js 0.3.0
4
+ // (c) 2012 Onsi Fakhouri
5
+ // Cocktail.js may be freely distributed under the MIT license.
6
+ // http://github.com/onsi/cocktail
7
+ var Cocktail = {};
8
+
9
+ Cocktail.mixins = {};
10
+
11
+ Cocktail.mixin = function mixin(klass) {
12
+ var mixins = _.chain(arguments).toArray().rest().flatten().value();
13
+
14
+ var collisions = {};
15
+
16
+ _(mixins).each(function(mixin) {
17
+ if (_.isString(mixin)) {
18
+ mixin = Cocktail.mixins[mixin];
19
+ }
20
+ _(mixin).each(function(value, key) {
21
+ if (_.isFunction(value)) {
22
+ if (klass.prototype[key]) {
23
+ collisions[key] = collisions[key] || [klass.prototype[key]];
24
+ collisions[key].push(value);
25
+ }
26
+ klass.prototype[key] = value;
27
+ } else if (_.isObject(value)) {
28
+ klass.prototype[key] = _.extend({}, value, klass.prototype[key] || {});
29
+ }
30
+ });
31
+ });
32
+
33
+ _(collisions).each(function(propertyValues, propertyName) {
34
+ klass.prototype[propertyName] = function() {
35
+ var that = this,
36
+ args = arguments,
37
+ returnValue = undefined;
38
+
39
+ _(propertyValues).each(function(value) {
40
+ var returnedValue = _.isFunction(value) ? value.apply(that, args) : value;
41
+ returnValue = (returnedValue === undefined ? returnValue : returnedValue);
42
+ });
43
+
44
+ return returnValue;
45
+ };
46
+ });
47
+ };
48
+
49
+ var originalExtend;
50
+
51
+ Cocktail.patch = function patch(Backbone) {
52
+ originalExtend = Backbone.Model.extend;
53
+
54
+ var extend = function(protoProps, classProps) {
55
+ var klass = originalExtend.call(this, protoProps, classProps);
56
+
57
+ var mixins = klass.prototype.mixins;
58
+ if (mixins && klass.prototype.hasOwnProperty('mixins')) {
59
+ Cocktail.mixin(klass, mixins);
60
+ }
61
+
62
+ return klass;
63
+ };
64
+
65
+ _([Backbone.Model, Backbone.Collection, Backbone.Router, Backbone.View]).each(function(klass) {
66
+ klass.mixin = function mixin() {
67
+ Cocktail.mixin(this, _.toArray(arguments));
68
+ };
69
+
70
+ klass.extend = extend;
71
+ });
72
+ };
73
+
74
+ Cocktail.unpatch = function unpatch(Backbone) {
75
+ _([Backbone.Model, Backbone.Collection, Backbone.Router, Backbone.View]).each(function(klass) {
76
+ klass.mixin = undefined;
77
+ klass.extend = originalExtend;
78
+ });
79
+ };
80
+
81
+ module.exports = Cocktail;
@@ -0,0 +1,453 @@
1
+ // Instantiate the object
2
+ var I18n = I18n || {};
3
+
4
+ // Set default locale to english
5
+ I18n.defaultLocale = "en";
6
+
7
+ // Set default handling of translation fallbacks to false
8
+ I18n.fallbacks = false;
9
+
10
+ // Set default separator
11
+ I18n.defaultSeparator = ".";
12
+
13
+ // Set current locale to null
14
+ I18n.locale = null;
15
+
16
+ // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
17
+ I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm;
18
+
19
+ I18n.isValidNode = function(obj, node, undefined) {
20
+ return obj[node] !== null && obj[node] !== undefined;
21
+ }
22
+
23
+ I18n.lookup = function(scope, options) {
24
+ var options = options || {}
25
+ , lookupInitialScope = scope
26
+ , translations = this.prepareOptions(I18n.translations)
27
+ , messages = translations[options.locale || I18n.currentLocale()]
28
+ , options = this.prepareOptions(options)
29
+ , currentScope
30
+ ;
31
+
32
+ if (!messages){
33
+ return;
34
+ }
35
+
36
+ if (typeof(scope) == "object") {
37
+ scope = scope.join(this.defaultSeparator);
38
+ }
39
+
40
+ if (options.scope) {
41
+ scope = options.scope.toString() + this.defaultSeparator + scope;
42
+ }
43
+
44
+ scope = scope.split(this.defaultSeparator);
45
+
46
+ while (scope.length > 0) {
47
+ currentScope = scope.shift();
48
+ messages = messages[currentScope];
49
+
50
+ if (!messages) {
51
+ if (I18n.fallbacks && !options.fallback) {
52
+ messages = I18n.lookup(lookupInitialScope, this.prepareOptions({ locale: I18n.defaultLocale, fallback: true }, options));
53
+ }
54
+ break;
55
+ }
56
+ }
57
+
58
+ if (!messages && this.isValidNode(options, "defaultValue")) {
59
+ messages = options.defaultValue;
60
+ }
61
+
62
+ return messages;
63
+ };
64
+
65
+ // Merge serveral hash options, checking if value is set before
66
+ // overwriting any value. The precedence is from left to right.
67
+ //
68
+ // I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"});
69
+ // #=> {name: "John Doe", role: "user"}
70
+ //
71
+ I18n.prepareOptions = function() {
72
+ var options = {}
73
+ , opts
74
+ , count = arguments.length
75
+ ;
76
+
77
+ for (var i = 0; i < count; i++) {
78
+ opts = arguments[i];
79
+
80
+ if (!opts) {
81
+ continue;
82
+ }
83
+
84
+ for (var key in opts) {
85
+ if (!this.isValidNode(options, key)) {
86
+ options[key] = opts[key];
87
+ }
88
+ }
89
+ }
90
+
91
+ return options;
92
+ };
93
+
94
+ I18n.interpolate = function(message, options) {
95
+ options = this.prepareOptions(options);
96
+ var matches = message.match(this.PLACEHOLDER)
97
+ , placeholder
98
+ , value
99
+ , name
100
+ , regex
101
+ ;
102
+
103
+ if (!matches) {
104
+ return message;
105
+ }
106
+
107
+ for (var i = 0; placeholder = matches[i]; i++) {
108
+ name = placeholder.replace(this.PLACEHOLDER, "$1");
109
+
110
+ value = options[name];
111
+
112
+ if (!this.isValidNode(options, name)) {
113
+ value = "[missing " + placeholder + " value]";
114
+ }
115
+
116
+ regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}"));
117
+ message = message.replace(regex, value);
118
+ }
119
+
120
+ return message;
121
+ };
122
+
123
+ I18n.translate = function(scope, options) {
124
+ options = this.prepareOptions(options);
125
+ var translation = this.lookup(scope, options);
126
+
127
+ try {
128
+ if (typeof(translation) == "object") {
129
+ if (typeof(options.count) == "number") {
130
+ return this.pluralize(options.count, scope, options);
131
+ } else {
132
+ return translation;
133
+ }
134
+ } else {
135
+ return this.interpolate(translation, options);
136
+ }
137
+ } catch(err) {
138
+ return this.missingTranslation(scope);
139
+ }
140
+ };
141
+
142
+ I18n.localize = function(scope, value) {
143
+ switch (scope) {
144
+ case "currency":
145
+ return this.toCurrency(value);
146
+ case "number":
147
+ scope = this.lookup("number.format");
148
+ return this.toNumber(value, scope);
149
+ case "percentage":
150
+ return this.toPercentage(value);
151
+ default:
152
+ if (scope.match(/^(date|time)/)) {
153
+ return this.toTime(scope, value);
154
+ } else {
155
+ return value.toString();
156
+ }
157
+ }
158
+ };
159
+
160
+ I18n.parseDate = function(date) {
161
+ var matches, convertedDate;
162
+
163
+ // we have a date, so just return it.
164
+ if (typeof(date) == "object") {
165
+ return date;
166
+ };
167
+
168
+ // it matches the following formats:
169
+ // yyyy-mm-dd
170
+ // yyyy-mm-dd[ T]hh:mm::ss
171
+ // yyyy-mm-dd[ T]hh:mm::ss
172
+ // yyyy-mm-dd[ T]hh:mm::ssZ
173
+ // yyyy-mm-dd[ T]hh:mm::ss+0000
174
+ //
175
+ matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2}))?(Z|\+0000)?/);
176
+
177
+ if (matches) {
178
+ for (var i = 1; i <= 6; i++) {
179
+ matches[i] = parseInt(matches[i], 10) || 0;
180
+ }
181
+
182
+ // month starts on 0
183
+ matches[2] -= 1;
184
+
185
+ if (matches[7]) {
186
+ convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]));
187
+ } else {
188
+ convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]);
189
+ }
190
+ } else if (typeof(date) == "number") {
191
+ // UNIX timestamp
192
+ convertedDate = new Date();
193
+ convertedDate.setTime(date);
194
+ } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) {
195
+ // a valid javascript format with timezone info
196
+ convertedDate = new Date();
197
+ convertedDate.setTime(Date.parse(date))
198
+ } else {
199
+ // an arbitrary javascript string
200
+ convertedDate = new Date();
201
+ convertedDate.setTime(Date.parse(date));
202
+ }
203
+
204
+ return convertedDate;
205
+ };
206
+
207
+ I18n.toTime = function(scope, d) {
208
+ var date = this.parseDate(d)
209
+ , format = this.lookup(scope)
210
+ ;
211
+
212
+ if (date.toString().match(/invalid/i)) {
213
+ return date.toString();
214
+ }
215
+
216
+ if (!format) {
217
+ return date.toString();
218
+ }
219
+
220
+ return this.strftime(date, format);
221
+ };
222
+
223
+ I18n.strftime = function(date, format) {
224
+ var options = this.lookup("date");
225
+
226
+ if (!options) {
227
+ return date.toString();
228
+ }
229
+
230
+ options.meridian = options.meridian || ["AM", "PM"];
231
+
232
+ var weekDay = date.getDay()
233
+ , day = date.getDate()
234
+ , year = date.getFullYear()
235
+ , month = date.getMonth() + 1
236
+ , hour = date.getHours()
237
+ , hour12 = hour
238
+ , meridian = hour > 11 ? 1 : 0
239
+ , secs = date.getSeconds()
240
+ , mins = date.getMinutes()
241
+ , offset = date.getTimezoneOffset()
242
+ , absOffsetHours = Math.floor(Math.abs(offset / 60))
243
+ , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60)
244
+ , timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes)
245
+ ;
246
+
247
+ if (hour12 > 12) {
248
+ hour12 = hour12 - 12;
249
+ } else if (hour12 === 0) {
250
+ hour12 = 12;
251
+ }
252
+
253
+ var padding = function(n) {
254
+ var s = "0" + n.toString();
255
+ return s.substr(s.length - 2);
256
+ };
257
+
258
+ var f = format;
259
+ f = f.replace("%a", options.abbr_day_names[weekDay]);
260
+ f = f.replace("%A", options.day_names[weekDay]);
261
+ f = f.replace("%b", options.abbr_month_names[month]);
262
+ f = f.replace("%B", options.month_names[month]);
263
+ f = f.replace("%d", padding(day));
264
+ f = f.replace("%e", day);
265
+ f = f.replace("%-d", day);
266
+ f = f.replace("%H", padding(hour));
267
+ f = f.replace("%-H", hour);
268
+ f = f.replace("%I", padding(hour12));
269
+ f = f.replace("%-I", hour12);
270
+ f = f.replace("%m", padding(month));
271
+ f = f.replace("%-m", month);
272
+ f = f.replace("%M", padding(mins));
273
+ f = f.replace("%-M", mins);
274
+ f = f.replace("%p", options.meridian[meridian]);
275
+ f = f.replace("%S", padding(secs));
276
+ f = f.replace("%-S", secs);
277
+ f = f.replace("%w", weekDay);
278
+ f = f.replace("%y", padding(year));
279
+ f = f.replace("%-y", padding(year).replace(/^0+/, ""));
280
+ f = f.replace("%Y", year);
281
+ f = f.replace("%z", timezoneoffset);
282
+
283
+ return f;
284
+ };
285
+
286
+ I18n.toNumber = function(number, options) {
287
+ options = this.prepareOptions(
288
+ options,
289
+ this.lookup("number.format"),
290
+ {precision: 3, separator: ".", delimiter: ",", strip_insignificant_zeros: false}
291
+ );
292
+
293
+ var negative = number < 0
294
+ , string = Math.abs(number).toFixed(options.precision).toString()
295
+ , parts = string.split(".")
296
+ , precision
297
+ , buffer = []
298
+ , formattedNumber
299
+ ;
300
+
301
+ number = parts[0];
302
+ precision = parts[1];
303
+
304
+ while (number.length > 0) {
305
+ buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));
306
+ number = number.substr(0, number.length -3);
307
+ }
308
+
309
+ formattedNumber = buffer.join(options.delimiter);
310
+
311
+ if (options.precision > 0) {
312
+ formattedNumber += options.separator + parts[1];
313
+ }
314
+
315
+ if (negative) {
316
+ formattedNumber = "-" + formattedNumber;
317
+ }
318
+
319
+ if (options.strip_insignificant_zeros) {
320
+ var regex = {
321
+ separator: new RegExp(options.separator.replace(/\./, "\\.") + "$")
322
+ , zeros: /0+$/
323
+ };
324
+
325
+ formattedNumber = formattedNumber
326
+ .replace(regex.zeros, "")
327
+ .replace(regex.separator, "")
328
+ ;
329
+ }
330
+
331
+ return formattedNumber;
332
+ };
333
+
334
+ I18n.toCurrency = function(number, options) {
335
+ options = this.prepareOptions(
336
+ options,
337
+ this.lookup("number.currency.format"),
338
+ this.lookup("number.format"),
339
+ {unit: "$", precision: 2, format: "%u%n", delimiter: ",", separator: "."}
340
+ );
341
+
342
+ number = this.toNumber(number, options);
343
+ number = options.format
344
+ .replace("%u", options.unit)
345
+ .replace("%n", number)
346
+ ;
347
+
348
+ return number;
349
+ };
350
+
351
+ I18n.toHumanSize = function(number, options) {
352
+ var kb = 1024
353
+ , size = number
354
+ , iterations = 0
355
+ , unit
356
+ , precision
357
+ ;
358
+
359
+ while (size >= kb && iterations < 4) {
360
+ size = size / kb;
361
+ iterations += 1;
362
+ }
363
+
364
+ if (iterations === 0) {
365
+ unit = this.t("number.human.storage_units.units.byte", {count: size});
366
+ precision = 0;
367
+ } else {
368
+ unit = this.t("number.human.storage_units.units." + [null, "kb", "mb", "gb", "tb"][iterations]);
369
+ precision = (size - Math.floor(size) === 0) ? 0 : 1;
370
+ }
371
+
372
+ options = this.prepareOptions(
373
+ options,
374
+ {precision: precision, format: "%n%u", delimiter: ""}
375
+ );
376
+
377
+ number = this.toNumber(size, options);
378
+ number = options.format
379
+ .replace("%u", unit)
380
+ .replace("%n", number)
381
+ ;
382
+
383
+ return number;
384
+ };
385
+
386
+ I18n.toPercentage = function(number, options) {
387
+ options = this.prepareOptions(
388
+ options,
389
+ this.lookup("number.percentage.format"),
390
+ this.lookup("number.format"),
391
+ {precision: 3, separator: ".", delimiter: ""}
392
+ );
393
+
394
+ number = this.toNumber(number, options);
395
+ return number + "%";
396
+ };
397
+
398
+ I18n.pluralize = function(count, scope, options) {
399
+ var translation;
400
+
401
+ try {
402
+ translation = this.lookup(scope, options);
403
+ } catch (error) {}
404
+
405
+ if (!translation) {
406
+ return this.missingTranslation(scope);
407
+ }
408
+
409
+ var message;
410
+ options = this.prepareOptions(options);
411
+ options.count = count.toString();
412
+
413
+ switch(Math.abs(count)) {
414
+ case 0:
415
+ message = this.isValidNode(translation, "zero") ? translation.zero :
416
+ this.isValidNode(translation, "none") ? translation.none :
417
+ this.isValidNode(translation, "other") ? translation.other :
418
+ this.missingTranslation(scope, "zero");
419
+ break;
420
+ case 1:
421
+ message = this.isValidNode(translation, "one") ? translation.one : this.missingTranslation(scope, "one");
422
+ break;
423
+ default:
424
+ message = this.isValidNode(translation, "other") ? translation.other : this.missingTranslation(scope, "other");
425
+ }
426
+
427
+ return this.interpolate(message, options);
428
+ };
429
+
430
+ I18n.missingTranslation = function() {
431
+ var message = '[missing "' + this.currentLocale()
432
+ , count = arguments.length
433
+ ;
434
+
435
+ for (var i = 0; i < count; i++) {
436
+ message += "." + arguments[i];
437
+ }
438
+
439
+ message += '" translation]';
440
+
441
+ return message;
442
+ };
443
+
444
+ I18n.currentLocale = function() {
445
+ return (I18n.locale || I18n.defaultLocale);
446
+ };
447
+
448
+ // shortcuts
449
+ I18n.t = I18n.translate;
450
+ I18n.l = I18n.localize;
451
+ I18n.p = I18n.pluralize;
452
+
453
+ module.exports = I18n;