ember-intl
Version:
Ember toolbox for internationalization.
1,562 lines (1,251 loc) • 164 kB
JavaScript
(function(){;
var define, requireModule, require, requirejs;
(function() {
var _isArray;
if (!Array.isArray) {
_isArray = function (x) {
return Object.prototype.toString.call(x) === "[object Array]";
};
} else {
_isArray = Array.isArray;
}
var registry = {}, seen = {}, state = {};
var FAILED = false;
define = function(name, deps, callback) {
if (!_isArray(deps)) {
callback = deps;
deps = [];
}
registry[name] = {
deps: deps,
callback: callback
};
};
function reify(deps, name, seen) {
var length = deps.length;
var reified = new Array(length);
var dep;
var exports;
for (var i = 0, l = length; i < l; i++) {
dep = deps[i];
if (dep === 'exports') {
exports = reified[i] = seen;
} else {
reified[i] = require(resolve(dep, name));
}
}
return {
deps: reified,
exports: exports
};
}
requirejs = require = requireModule = function(name) {
if (state[name] !== FAILED &&
seen.hasOwnProperty(name)) {
return seen[name];
}
if (!registry[name]) {
throw new Error('Could not find module ' + name);
}
var mod = registry[name];
var reified;
var module;
var loaded = false;
seen[name] = { }; // placeholder for run-time cycles
try {
reified = reify(mod.deps, name, seen[name]);
module = mod.callback.apply(this, reified.deps);
loaded = true;
} finally {
if (!loaded) {
state[name] = FAILED;
}
}
return reified.exports ? seen[name] : (seen[name] = module);
};
function resolve(child, name) {
if (child.charAt(0) !== '.') { return child; }
var parts = child.split('/');
var nameParts = name.split('/');
var parentBase;
if (nameParts.length === 1) {
parentBase = nameParts;
} else {
parentBase = nameParts.slice(0, -1);
}
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
if (part === '..') { parentBase.pop(); }
else if (part === '.') { continue; }
else { parentBase.push(part); }
}
return parentBase.join('/');
}
requirejs.entries = requirejs._eak_seen = registry;
requirejs.clear = function(){
requirejs.entries = requirejs._eak_seen = registry = {};
seen = state = {};
};
})();
;define("ember-intl/index",
["ember-intl/models/locale","ember-intl/formatter-base","ember-intl/format-cache/memoizer","ember-intl/helpers/base","ember-intl/utils/streams","ember-intl/utils/data","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var LocaleModel = __dependency1__["default"];
var FormatterBase = __dependency2__["default"];
var createFormatCache = __dependency3__["default"];
var HelperBase = __dependency4__["default"];
var Stream = __dependency5__.Stream;
var read = __dependency5__.read;
var addLocaleData = __dependency6__.addLocaleData;
var IntlRelativeFormat = __dependency6__.IntlRelativeFormat;
var IntlMessageFormat = __dependency6__.IntlMessageFormat;
__exports__.LocaleModel = LocaleModel;
__exports__.addLocaleData = addLocaleData;
__exports__.IntlRelativeFormat = IntlRelativeFormat;
__exports__.IntlMessageFormat = IntlMessageFormat;
__exports__.Stream = Stream;
__exports__.read = read;
__exports__.createFormatCache = createFormatCache;
__exports__.FormatterBase = FormatterBase;
__exports__.HelperBase = HelperBase;
});
;define("ember-intl/models/locale",
["ember","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var LocaleModel = Ember.Object.extend({
locale: Ember.required(),
messages: {},
addMessage: function (key, value) {
this.set('messages.' + key, value);
return value;
},
addMessages: function (messageObject) {
var messages = this.get('messages');
// shallow merge intentional
for (var key in messageObject) {
if (messageObject.hasOwnProperty(key)) {
messages[key] = messageObject[key];
}
}
return messages;
},
// Exposes an accesor on the locale modules
// so that if you want to implement your own custom logic
// for example, this[key] versus Ember.get
getValue: function (key) {
return this.get(key);
}
});
__exports__["default"] = LocaleModel;
});
;define("ember-intl/formatter-base",
["ember","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var FormatBase = Ember.Object.extend({
buildOptions: function (value, hash) {
var args = [value];
if (typeof hash.format !== 'undefined') {
args.push(hash.format);
}
var helperOptions = this.filterFormatOptions(hash) || {};
if (hash.locales) {
helperOptions.locales = hash.locales;
}
args.push(helperOptions);
return args;
},
filterFormatOptions: function (hash) {
hash = hash || {};
var match = false;
var options = this.constructor.formatOptions.reduce(function (opts, name) {
if (hash.hasOwnProperty(name)) {
match = true;
opts[name] = hash[name];
}
return opts;
}, {});
if (match) {
return options;
}
}
});
FormatBase.reopenClass({
formatOptions: Ember.A()
});
__exports__["default"] = FormatBase;
});
;define("ember-intl/format-cache/memoizer",
["exports"],
function(__exports__) {
"use strict";
/*
Copyright (c) 2014, Yahoo! Inc. All rights reserved.
Copyrights licensed under the New BSD License.
See the accompanying LICENSE file for terms.
*/
/* jshint esnext: true */
// -----------------------------------------------------------------------------
function orderedProps(obj) {
var props = [], keys = [];
var key, i, len, prop;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
var orderedKeys = keys.sort();
for (i = 0, len = orderedKeys.length; i < len; i += 1) {
key = orderedKeys[i];
prop = {};
prop[key] = obj[key];
props[i] = prop;
}
return props;
}
function getCacheId(inputs) {
// When JSON is not available in the runtime, we will not create a cache id.
if (typeof JSON === 'undefined') { return; }
var cacheId = [];
var i, len, input;
for (i = 0, len = inputs.length; i < len; i += 1) {
input = inputs[i];
if (input && typeof input === 'object') {
cacheId.push(orderedProps(input));
} else {
cacheId.push(input);
}
}
return JSON.stringify(cacheId);
}
function createFormatCache(FormatConstructor) {
var cache = Object.create(null);
return function () {
var args = Array.prototype.slice.call(arguments);
var cacheId = getCacheId(args);
var format = cacheId && cache[cacheId];
if (!format) {
format = Object.create(FormatConstructor.prototype);
FormatConstructor.apply(format, args);
if (cacheId) {
cache[cacheId] = format;
}
}
return format;
};
}
__exports__["default"] = createFormatCache;
});
;define("ember-intl/helpers/base",
["ember","ember-intl/utils/streams","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Stream = __dependency2__.Stream;
var read = __dependency2__.read;
var readHash = __dependency2__.readHash;
var destroyStream = __dependency2__.destroyStream;
__exports__["default"] = function (formatterName) {
function throwError () {
return new Error(formatterName + ' requires a single unname argument. {{' + formatterName + ' value}}');
}
if (Ember.HTMLBars) {
return Ember.HTMLBars.makeBoundHelper(function (params, hash, options, env) {
if (!params || (params && !params.length)) {
return throwError();
}
var formatter = this.container.lookup('formatter:' + formatterName);
var args = [];
args.push(read(params[0]));
args.push(readHash(hash));
args.push(Ember.get(env, 'data.view.context'));
return formatter.format.apply(formatter, args);
});
} else {
var SimpleBoundView = Ember._SimpleHandlebarsView || Ember._SimpleBoundView;
return function (value, options) {
if (typeof value === 'undefined') {
return throwError();
}
var args = Ember.A();
var streams = Ember.A();
var view = options.data.view;
var types = options.types;
var hash = Ember.$.extend({}, options.hash);
var formatter = view.container.lookup('formatter:' + formatterName);
var stream;
function rerenderView () {
Ember.run.scheduleOnce('render', view, view.rerender);
}
args.push(hash);
args.push(this);
if (types[0] === 'ID') {
value = view.getStream(value);
}
stream = new Stream(function () {
var currentValue = value;
if (currentValue.isStream) {
currentValue = read(currentValue);
}
return formatter.format.apply(formatter, [currentValue].concat(args));
});
var simpleView = new SimpleBoundView(stream, options.escaped);
Ember.keys(options.hashTypes).forEach(function (key) {
if (options.hashTypes[key] === 'ID') {
var hashStream = view.getStream(options.hash[key]);
hash[key] = read(hashStream);
if (!options.data.isUnbound) {
hashStream.subscribe(function () {
// update the hash with the new value
// since the above stream closes over `hash`
// within `args`
hash[key] = read(hashStream);
stream.notify();
});
streams.push(hashStream);
}
}
});
if (!options.data.isUnbound) {
stream.subscribe(view._wrapAsScheduled(function () {
Ember.run.scheduleOnce('render', simpleView, 'rerender');
}));
if (value.isStream) {
value.subscribe(stream.notify, stream);
streams.push(value);
}
formatter.intl.one('localesChanged', rerenderView);
}
view.on('willDestroyElement', function () {
streams.forEach(destroyStream);
streams = [];
formatter.intl.off('localesChanged', rerenderView);
});
view.appendChild(simpleView);
};
}
}
});
;define("ember-intl/utils/streams",
["ember","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Ember = __dependency1__["default"];
var Stream = Ember.__loader.require('ember-metal/streams/stream')['default'];
// The below read, readHash methods are from Ember.js
// https://github.com/emberjs/ember.js/blob/master/packages/ember-metal/lib/streams/utils.js
// License: https://github.com/emberjs/ember.js/blob/master/LICENSE
function read (object) {
if (object && object.isStream) {
return object.value();
} else {
return object;
}
}
function readHash (object) {
var ret = {};
for (var key in object) {
ret[key] = read(object[key]);
}
return ret;
}
__exports__.readHash = readHash;
function destroyStream (stream) {
if (stream && !stream.destroyed) {
stream.destroy();
}
}
var readHash = readHash;
__exports__.readHash = readHash;var destroyStream = destroyStream;
__exports__.destroyStream = destroyStream;var Stream = Stream;
__exports__.Stream = Stream;var read = read;
__exports__.read = read;
__exports__["default"] = {
Stream: Stream,
read: read
};
});
;define("ember-intl/utils/data",
["exports"],
function(__exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
// ideally these would be imported as node modules
var IntlMessageFormat = messageformat;
var IntlRelativeFormat = relativeformat;
function addLocaleData(data) {
IntlMessageFormat.__addLocaleData(data);
IntlRelativeFormat.__addLocaleData(data);
}
__exports__.addLocaleData = addLocaleData;
__exports__.IntlRelativeFormat = IntlRelativeFormat;
__exports__.IntlMessageFormat = IntlMessageFormat;
});
;define("app/formatters/format-date",
["ember","ember-intl/formatter-base","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Formatter = __dependency2__["default"];
var FormatDate = Formatter.extend({
format: function (value, hash) {
var args = this.buildOptions(value, hash);
var intl = this.intl;
return intl.formatDate.apply(intl, args);
}
});
FormatDate.reopenClass({
formatOptions: [
'localeMatcher', 'timeZone', 'hour12', 'formatMatcher', 'weekday',
'era', 'year', 'month', 'day', 'hour', 'minute', 'second',
'timeZoneName'
]
});
__exports__["default"] = FormatDate;
});
;define("app/formatters/format-html-message",
["ember","app/formatters/format-message","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var FormatterMessage = __dependency2__["default"];
var FormatHtmlMessage = FormatterMessage.extend({
escapeProps: function (props) {
return Object.keys(props).reduce(function (escapedProps, name) {
var value = props[name];
// TODO: Can we force string coersion here? Or would that not be needed
// and possible mess with IntlMessageFormat?
if (typeof value === 'string') {
value = Ember.Handlebars.Utils.escapeExpression(value);
}
escapedProps[name] = value;
return escapedProps;
}, {});
},
format: function (value, hash, context) {
var icuKeys = this.extractICUKeys(value);
var model = {};
if (icuKeys && icuKeys.length) {
model = Ember.$.extend(Ember.getProperties(context, icuKeys), hash);
}
var formatOptions = {
formats: hash.format || this.filterFormatOptions(hash)
};
if (hash.locales) {
formatOptions.locales = hash.locales;
}
return Ember.String.htmlSafe(this.intl.formatMessage(value, this.escapeProps(model), formatOptions));
}
});
__exports__["default"] = FormatHtmlMessage;
});
;define("app/formatters/format-message",
["ember","ember-intl/formatter-base","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Formatter = __dependency2__["default"];
var validKey = /[\w|.]/;
var FormatMessage = Formatter.extend({
extractICUKeys: function (msg) {
var length = msg.length;
var buf = [], out = Ember.A();
var i = 0;
var char, key;
for (; i < length; i++) {
char = msg[i];
if (buf.length && !validKey.test(char)) {
buf.shift();
key = buf.join('');
// do not include empty strings: {}
if (key) { out.addObject(key); }
buf = [];
}
else if (
// does not include escaped curly braces
// and double curly braces does not mistake the first
// as the starting point of the key {{foo}} should return `foo`
(char === '{' && msg[i-1] !== "\\" && msg[i+1] !== '{') ||
buf.length
)
{
buf.push(char);
}
}
return out;
},
format: function (value, hash, context) {
var icuKeys = this.extractICUKeys(value);
var model;
if (icuKeys && icuKeys.length) {
model = Ember.$.extend(Ember.getProperties(context, icuKeys), hash);
}
var formatOptions = {
formats: hash.format || this.filterFormatOptions(hash)
};
if (hash.locales) {
formatOptions.locales = hash.locales;
}
return this.intl.formatMessage(value, model, formatOptions);
}
});
FormatMessage.reopenClass({
formatOptions: [
'localeMatcher', 'timeZone', 'hour12', 'formatMatcher', 'weekday',
'era', 'year', 'month', 'day', 'hour', 'minute', 'second',
'timeZoneName'
]
});
__exports__["default"] = FormatMessage;
});
;define("app/formatters/format-number",
["ember","ember-intl/formatter-base","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Formatter = __dependency2__["default"];
var FormatNumber = Formatter.extend({
format: function (value, hash) {
var args = this.buildOptions(value, hash);
var intl = this.intl;
return intl.formatNumber.apply(intl, args);
}
});
FormatNumber.reopenClass({
formatOptions: [
'localeMatcher', 'style', 'currency', 'currencyDisplay',
'useGrouping', 'minimumIntegerDigits', 'minimumFractionDigits',
'maximumFractionDigits', 'minimumSignificantDigits',
'maximumSignificantDigits'
]
});
__exports__["default"] = FormatNumber;
});
;define("app/formatters/format-relative",
["ember","ember-intl/formatter-base","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Formatter = __dependency2__["default"];
var FormatRelative = Formatter.extend({
format: function (value, hash) {
var args = this.buildOptions(value, hash);
var intl = this.intl;
return intl.formatRelative.apply(intl, args);
}
});
FormatRelative.reopenClass({
formatOptions: ['style', 'units']
});
__exports__["default"] = FormatRelative;
});
;define("app/formatters/format-time",
["ember","ember-intl/formatter-base","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Formatter = __dependency2__["default"];
var FormatTime = Formatter.extend({
format: function (value, hash) {
var args = this.buildOptions(value, hash);
var intl = this.intl;
return intl.formatTime.apply(intl, args);
}
});
FormatTime.reopenClass({
formatOptions: [
'localeMatcher', 'timeZone', 'hour12', 'formatMatcher', 'weekday',
'era', 'year', 'month', 'day', 'hour', 'minute', 'second',
'timeZoneName'
]
});
__exports__["default"] = FormatTime;
});
;define("app/helpers/format-date",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-date');
});
;define("app/helpers/format-html-message",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-html-message');
});
;define("app/helpers/format-message",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-message');
});
;define("app/helpers/format-number",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-number');
});
;define("app/helpers/format-relative",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-relative');
});
;define("app/helpers/format-time",
["ember-intl/helpers/base","exports"],
function(__dependency1__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FormatHelper = __dependency1__["default"];
__exports__["default"] = FormatHelper('format-time');
});
;define("app/helpers/intl-get",
["ember","ember-intl/utils/streams","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Stream = __dependency2__.Stream;
var read = __dependency2__.read;
var destroyStream = __dependency2__.destroyStream;
function normalize (fullName) {
Ember.assert('Lookup name must be a string', typeof fullName === 'string');
return fullName.toLowerCase();
}
function intlGet (key) {
Ember.assert('You must pass in a message key in the form of a string.', typeof key === 'string');
var intl = this.container.lookup('intl:main');
var locales = intl.get('current');
for (var i=0; i < locales.length; i++) {
var locale = this.container.lookup('locale:' + normalize(locales[i]));
if (locale) {
var value = locale.getValue(key);
if (typeof value !== 'undefined') {
return value;
}
}
}
throw new ReferenceError('Could not find Intl object: ' + key);
}
var helper;
if (Ember.HTMLBars) {
helper = Ember.HTMLBars.makeBoundHelper(function (params) {
var intl = this.container.lookup('intl:main');
var self = this;
var currentValue;
var outStream = new Stream(function () {
return currentValue;
});
function render () {
currentValue = intlGet.call(self, read(params[0]));
outStream.notify();
}
intl.on('localesChanged', self, render);
this.on('willDestroyElement', this, function () {
intl.off('localesChanged', self, render);
destroyStream(outStream);
});
render();
return outStream;
});
}
else {
helper = function (value) {
return intlGet.call(this, value);
};
}
__exports__["default"] = helper;
});
;define("app/initializers/ember-intl",
["ember","app/services/intl","ember-intl/utils/data","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var IntlService = __dependency2__["default"];
var addLocaleData = __dependency3__.addLocaleData;
__exports__["default"] = {
name: 'ember-intl',
initialize: function (container, app) {
var seen = requirejs._eak_seen;
var prefix = app.modulePrefix;
container.optionsForType('formats', {
singleton: true,
instantiate: false
});
container.optionsForType('locale', {
singleton: true,
instantiate: true
});
Object.keys(seen).filter(function (key) {
return key.indexOf(prefix + '\/cldrs\/') === 0;
}).forEach(function (key) {
addLocaleData(require(key, null, null, true)['default']);
});
var ServiceKlass = app.IntlService || IntlService;
var service = ServiceKlass.create({ container: container });
app.register('intl:main', service, {
singleton: true,
instantiate: false
});
app.intl = service;
app.inject('controller', 'intl', 'intl:main');
app.inject('component', 'intl', 'intl:main');
app.inject('route', 'intl', 'intl:main');
app.inject('model', 'intl', 'intl:main');
app.inject('view', 'intl', 'intl:main');
app.inject('formatter', 'intl', 'intl:main');
}
}
});
;define("app/services/intl",
["ember","ember-intl/models/locale","ember-intl/format-cache/memoizer","ember-intl/utils/data","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
"use strict";
/**
* Copyright 2015, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var Ember = __dependency1__["default"];
var Locale = __dependency2__["default"];
var createFormatCache = __dependency3__["default"];
var IntlRelativeFormat = __dependency4__.IntlRelativeFormat;
var IntlMessageFormat = __dependency4__.IntlMessageFormat;
var ServiceKlass = Ember.Service || Ember.Controller;
var makeArray = Ember.makeArray;
var get = Ember.get;
var on = Ember.on;
var computed = Ember.computed;
var observer = Ember.observer;
var isEmpty = Ember.isEmpty;
var isPresent = Ember.isPresent;
var run = Ember.run;
function assertIsDate (date, errMsg) {
Ember.assert(errMsg, isFinite(date));
}
__exports__["default"] = ServiceKlass.extend(Ember.Evented, {
locales: null,
defaultLocale: null,
getDateTimeFormat: null,
getRelativeFormat: null,
getMessageFormat: null,
getNumberFormat: null,
setupMemoizers: on('init', function () {
this.setProperties({
getDateTimeFormat: createFormatCache(Intl.DateTimeFormat),
getRelativeFormat: createFormatCache(IntlRelativeFormat),
getNumberFormat: createFormatCache(Intl.NumberFormat),
getMessageFormat: createFormatCache(IntlMessageFormat)
});
}),
current: computed('locales', 'defaultLocale', function () {
var locales = makeArray(get(this, 'locales'));
var defaultLocale = get(this, 'defaultLocale');
if (isPresent(defaultLocale) && locales.indexOf(defaultLocale) === -1) {
locales.push(defaultLocale);
}
return locales;
}).readOnly(),
formats: computed(function () {
return this.container.lookup('formats:main', {
instantiate: false
}) || {};
}).readOnly(),
localeChanged: observer('current', function () {
run.once(this, this.notifyLocaleChanged);
}),
addMessage: function (locale, key, value) {
var localeInstance = this._getLocaleInstance(locale);
return localeInstance.addMessage(key, value);
},
addMessages: function (locale, messageObject) {
var localeInstance = this._getLocaleInstance(locale);
return localeInstance.addMessages(messageObject);
},
notifyLocaleChanged: function () {
this.trigger('localesChanged');
},
formatMessage: function (message, values, options) {
// When `message` is a function, assume it's an IntlMessageFormat
// instance's `format()` method passed by reference, and call it. This
// is possible because its `this` will be pre-bound to the instance.
if (typeof message === 'function') {
return message(values);
}
var locales = makeArray(options.locales);
var formats = options.formats || get(this, 'formats');
if (isEmpty(locales)) {
locales = get(this, 'current');
}
if (typeof message === 'string') {
message = this.getMessageFormat(message, locales, formats);
}
return message.format(values);
},
formatTime: function (date, formatOptions, options) {
date = new Date(date);
assertIsDate(date, 'A date or timestamp must be provided to formatTime()');
return this._format('time', date, formatOptions, options);
},
formatRelative: function (date, formatOptions, options) {
date = new Date(date);
assertIsDate(date, 'A date or timestamp must be provided to formatRelative()');
return this._format('relative', date, formatOptions, options);
},
formatDate: function (date, formatOptions, options) {
date = new Date(date);
assertIsDate(date, 'A date or timestamp must be provided to formatDate()');
return this._format('date', date, formatOptions, options);
},
formatNumber: function (num, formatOptions, options) {
return this._format('number', num, formatOptions, options);
},
_format: function (type, value, formatOptions, helperOptions) {
if (!helperOptions) {
helperOptions = formatOptions;
formatOptions = null;
}
var locales = makeArray(helperOptions.locales);
var formats = get(this, 'formats');
if (isEmpty(locales)) {
locales = get(this, 'current');
}
if (formatOptions) {
if (typeof formatOptions === 'string' && formats) {
formatOptions = get(formats, type + '.' + formatOptions);
}
formatOptions = Ember.$.extend({}, formatOptions, helperOptions);
} else {
formatOptions = helperOptions;
}
switch (type) {
case 'date':
case 'time':
return this.getDateTimeFormat(locales, formatOptions).format(value);
case 'number':
return this.getNumberFormat(locales, formatOptions).format(value);
case 'relative':
return this.getRelativeFormat(locales, formatOptions).format(value);
default:
throw new Error('Unrecognized simple format type: ' + type);
}
},
_getLocaleInstance: function (locale) {
if (locale instanceof Locale) {
return locale;
}
if (typeof locale === 'string') {
return this.container.lookup('locale:' + localeId.toLowerCase());
}
throw new Error('`locale` must be a string or a locale instance');
}
});
});
;define('ember-intl-shim', ["exports"], function(__exports__) {__exports__.initialize = function(container){
container.register('formatter:format-date', require('app/formatters/format-date')['default']);
container.register('formatter:format-html-message', require('app/formatters/format-html-message')['default']);
container.register('formatter:format-message', require('app/formatters/format-message')['default']);
container.register('formatter:format-number', require('app/formatters/format-number')['default']);
container.register('formatter:format-relative', require('app/formatters/format-relative')['default']);
container.register('formatter:format-time', require('app/formatters/format-time')['default']);
container.register('helper:format-date', require('app/helpers/format-date')['default']);
container.register('helper:format-html-message', require('app/helpers/format-html-message')['default']);
container.register('helper:format-message', require('app/helpers/format-message')['default']);
container.register('helper:format-number', require('app/helpers/format-number')['default']);
container.register('helper:format-relative', require('app/helpers/format-relative')['default']);
container.register('helper:format-time', require('app/helpers/format-time')['default']);
container.register('helper:intl-get', require('app/helpers/intl-get')['default']);
container.register('initializer:ember-intl', require('app/initializers/ember-intl')['default']);
container.register('service:intl', require('app/services/intl')['default']);
container.register('ember-intl@model:locale', require('ember-intl/models/locale')['default'])
};});
;/* global define, require */
define('ember', ["exports"], function(__exports__) {
__exports__['default'] = window.Ember;
});
define('ember-intl', ["exports"], function(__exports__) {
var lf = require('ember-intl/index');
Object.keys(lf).forEach(function(key) {
__exports__[key] = lf[key];
});
});
window.Ember.Application.initializer({
name: 'ember-intl-standalone',
initialize: function(container, app) {
require('ember-intl-shim').initialize.apply(this, arguments);
require('app/initializers/ember-intl')['default'].initialize.apply(this, arguments);
}
});
var relativeformat = (function() {
"use strict";
// Purposely using the same implementation as the Intl.js `Intl` polyfill.
// Copyright 2013 Andy Earnshaw, MIT License
var $$es5$$hop = Object.prototype.hasOwnProperty;
var $$es5$$toString = Object.prototype.toString;
var $$es5$$realDefineProp = (function () {
try { return !!Object.defineProperty({}, 'a', {}); }
catch (e) { return false; }
})();
var $$es5$$es3 = !$$es5$$realDefineProp && !Object.prototype.__defineGetter__;
var $$es5$$defineProperty = $$es5$$realDefineProp ? Object.defineProperty :
function (obj, name, desc) {
if ('get' in desc && obj.__defineGetter__) {
obj.__defineGetter__(name, desc.get);
} else if (!$$es5$$hop.call(obj, name) || 'value' in desc) {
obj[name] = desc.value;
}
};
var $$es5$$objCreate = Object.create || function (proto, props) {
var obj, k;
function F() {}
F.prototype = proto;
obj = new F();
for (k in props) {
if ($$es5$$hop.call(props, k)) {
$$es5$$defineProperty(obj, k, props[k]);
}
}
return obj;
};
var $$es5$$arrIndexOf = Array.prototype.indexOf || function (search, fromIndex) {
/*jshint validthis:true */
var arr = this;
if (!arr.length) {
return -1;
}
for (var i = fromIndex || 0, max = arr.length; i < max; i++) {
if (arr[i] === search) {
return i;
}
}
return -1;
};
var $$es5$$isArray = Array.isArray || function (obj) {
return $$es5$$toString.call(obj) === '[object Array]';
};
var $$es5$$dateNow = Date.now || function () {
return new Date().getTime();
};
var $$utils$$hop = Object.prototype.hasOwnProperty;
function $$utils$$extend(obj) {
var sources = Array.prototype.slice.call(arguments, 1),
i, len, source, key;
for (i = 0, len = sources.length; i < len; i += 1) {
source = sources[i];
if (!source) { continue; }
for (key in source) {
if ($$utils$$hop.call(source, key)) {
obj[key] = source[key];
}
}
}
return obj;
}
// Purposely using the same implementation as the Intl.js `Intl` polyfill.
// Copyright 2013 Andy Earnshaw, MIT License
var $$es51$$realDefineProp = (function () {
try { return !!Object.defineProperty({}, 'a', {}); }
catch (e) { return false; }
})();
var $$es51$$es3 = !$$es51$$realDefineProp && !Object.prototype.__defineGetter__;
var $$es51$$defineProperty = $$es51$$realDefineProp ? Object.defineProperty :
function (obj, name, desc) {
if ('get' in desc && obj.__defineGetter__) {
obj.__defineGetter__(name, desc.get);
} else if (!$$utils$$hop.call(obj, name) || 'value' in desc) {
obj[name] = desc.value;
}
};
var $$es51$$objCreate = Object.create || function (proto, props) {
var obj, k;
function F() {}
F.prototype = proto;
obj = new F();
for (k in props) {
if ($$utils$$hop.call(props, k)) {
$$es51$$defineProperty(obj, k, props[k]);
}
}
return obj;
};
var $$compiler$$default = $$compiler$$Compiler;
function $$compiler$$Compiler(locales, formats, pluralFn) {
this.locales = locales;
this.formats = formats;
this.pluralFn = pluralFn;
}
$$compiler$$Compiler.prototype.compile = function (ast) {
this.pluralStack = [];
this.currentPlural = null;
this.pluralNumberFormat = null;
return this.compileMessage(ast);
};
$$compiler$$Compiler.prototype.compileMessage = function (ast) {
if (!(ast && ast.type === 'messageFormatPattern')) {
throw new Error('Message AST is not of type: "messageFormatPattern"');
}
var elements = ast.elements,
pattern = [];
var i, len, element;
for (i = 0, len = elements.length; i < len; i += 1) {
element = elements[i];
switch (element.type) {
case 'messageTextElement':
pattern.push(this.compileMessageText(element));
break;
case 'argumentElement':
pattern.push(this.compileArgument(element));
break;
default:
throw new Error('Message element does not have a valid type');
}
}
return pattern;
};
$$compiler$$Compiler.prototype.compileMessageText = function (element) {
// When this `element` is part of plural sub-pattern and its value contains
// an unescaped '#', use a `PluralOffsetString` helper to properly output
// the number with the correct offset in the string.
if (this.currentPlural && /(^|[^\\])#/g.test(element.value)) {
// Create a cache a NumberFormat instance that can be reused for any
// PluralOffsetString instance in this message.
if (!this.pluralNumberFormat) {
this.pluralNumberFormat = new Intl.NumberFormat(this.locales);
}
return new $$compiler$$PluralOffsetString(
this.currentPlural.id,
this.currentPlural.format.offset,
this.pluralNumberFormat,
element.value);
}
// Unescape the escaped '#'s in the message text.
return element.value.replace(/\\#/g, '#');
};
$$compiler$$Compiler.prototype.compileArgument = function (element) {
var format = element.format;
if (!format) {
return new $$compiler$$StringFormat(element.id);
}
var formats = this.formats,
locales = this.locales,
pluralFn = this.pluralFn,
options;
switch (format.type) {
case 'numberFormat':
options = formats.number[format.style];
return {
id : element.id,
format: new Intl.NumberFormat(locales, options).format
};
case 'dateFormat':
options = formats.date[format.style];
return {
id : element.id,
format: new Intl.DateTimeFormat(locales, options).format
};
case 'timeFormat':
options = formats.time[format.style];
return {
id : element.id,
format: new Intl.DateTimeFormat(locales, options).format
};
case 'pluralFormat':
options = this.compileOptions(element);
return new $$compiler$$PluralFormat(element.id, format.offset, options, pluralFn);
case 'selectFormat':
options = this.compileOptions(element);
return new $$compiler$$SelectFormat(element.id, options);
default:
throw new Error('Message element does not have a valid format type');
}
};
$$compiler$$Compiler.prototype.compileOptions = function (element) {
var format = element.format,
options = format.options,
optionsHash = {};
// Save the current plural element, if any, then set it to a new value when
// compiling the options sub-patterns. This conform's the spec's algorithm
// for handling `"#"` synax in message text.
this.pluralStack.push(this.currentPlural);
this.currentPlural = format.type === 'pluralFormat' ? element : null;
var i, len, option;
for (i = 0, len = options.length; i < len; i += 1) {
option = options[i];
// Compile the sub-pattern and save it under the options's selector.
optionsHash[option.selector] = this.compileMessage(option.value);
}
// Pop the plural stack to put back the original currnet plural value.
this.currentPlural = this.pluralStack.pop();
return optionsHash;
};
// -- Compiler Helper Classes --------------------------------------------------
function $$compiler$$StringFormat(id) {
this.id = id;
}
$$compiler$$StringFormat.prototype.format = function (value) {
if (!value) {
return '';
}
return typeof value === 'string' ? value : String(value);
};
function $$compiler$$PluralFormat(id, offset, options, pluralFn) {
this.id = id;
this.offset = offset;
this.options = options;
this.pluralFn = pluralFn;
}
$$compiler$$PluralFormat.prototype.getOption = function (value) {
var options = this.options;
var option = options['=' + value] ||
options[this.pluralFn(value - this.offset)];
return option || options.other;
};
function $$compiler$$PluralOffsetString(id, offset, numberFormat, string) {
this.id = id;
this.offset = offset;
this.numberFormat = numberFormat;
this.string = string;
}
$$compiler$$PluralOffsetString.prototype.format = function (value) {
var number = this.numberFormat.format(value - this.offset);
return this.string
.replace(/(^|[^\\])#/g, '$1' + number)
.replace(/\\#/g, '#');
};
function $$compiler$$SelectFormat(id, options) {
this.id = id;
this.options = options;
}
$$compiler$$SelectFormat.prototype.getOption = function (value) {
var options = this.options;
return options[value] || options.other;
};
var intl$messageformat$parser$$default = (function() {
/*
* Generated by PEG.js 0.8.0.
*
* http://pegjs.majda.cz/
*/
function peg$subclass(child, parent) {
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor();
}
function SyntaxError(message, expected, found, offset, line, column) {
this.message = message;
this.expected = expected;
this.found = found;
this.offset = offset;
this.line = line;
this.column = column;
this.name = "SyntaxError";
}
peg$subclass(SyntaxError, Error);
function parse(input) {
var options = arguments.length > 1 ? arguments[1] : {},
peg$FAILED = {},
peg$startRuleFunctions = { start: peg$parsestart },
peg$startRuleFunction = peg$parsestart,
peg$c0 = [],
peg$c1 = function(elements) {
return {
type : 'messageFormatPattern',
elements: elements
};
},
peg$c2 = peg$FAILED,
peg$c3 = function(text) {
var string = '',
i, j, outerLen, inner, innerLen;
for (i = 0, outerLen = text.length; i < outerLen; i += 1) {
inner = text[i];
for (j = 0, innerLen = inner.length; j < innerLen; j += 1) {
string += inner[j];
}
}
return string;
},
peg$c4 = function(messageText) {
return {
t