1 |
|
2 | !function(exports, Object, Function) {
|
3 |
|
4 | "use strict";
|
5 | var currentLang, currentMap
|
6 | , isArray = Array.isArray
|
7 | , cache = {}
|
8 | , formatRe = /{(?!;)({[\s\S]*}|\[[\s\S]*]|(?:("|')(?:\\\2|.)*?\2|[^;{}])+?)(?:;((?:(['"\/])(?:\\\4|.)*?\4[gim]*|[^}])*))?}/g
|
9 | , exprRe = /(['"\/])(?:\\\1|.)*?\1[gim]*|\b(?:[$_]|false|in|null|true|typeof|void)\b|\.\w+|\w+\s*:|\s+/g
|
10 | , wordRe = /(\$?)([a-z_][\w$]*)/ig
|
11 | , pattRe = /(\w+)(?::((?:(['"\/])(?:\\\3|.)*?\3[gim]*|[^;])*))?/g
|
12 | , pointerRe = /^([\w ]+)\.([\w ]+)$/
|
13 | , globalTexts = {}
|
14 | , globalVals = i18n.vals = {}
|
15 |
|
16 |
|
17 | , list = i18n.list = []
|
18 | , ext = i18n.ext = {}
|
19 | , fnScope = {}
|
20 |
|
21 | exports.i18n = i18n
|
22 | i18n.add = add
|
23 | i18n.get = get
|
24 | i18n.use = use
|
25 |
|
26 | function i18n(str, data) {
|
27 | if (typeof str === "number") return "" + str
|
28 | var out = cache[str] || (
|
29 | cache[str] = makeFn(get(str) || str)
|
30 | )
|
31 | return isString(out) ? out : out(data || {}, i18n, globalVals)
|
32 | }
|
33 |
|
34 | function get(str, fallback) {
|
35 | var tmp
|
36 | return isString(str) ? (
|
37 | isString(currentMap[str]) ? currentMap[str] :
|
38 | typeof currentMap[str] === "object" ? currentMap[str][""] :
|
39 | (tmp = pointerRe.exec(str)) && (
|
40 | typeof currentMap[tmp[1]] === "object" &&
|
41 | currentMap[tmp[1]][tmp[2]] ||
|
42 | currentMap[tmp[2]]
|
43 | ) || fallback
|
44 | ) :
|
45 | isArray(str) ?
|
46 | get(str[0], get(str[1], get(str[2], fallback))) :
|
47 | fallback
|
48 | }
|
49 |
|
50 |
|
51 | function makeFn(str) {
|
52 | var tmp, m, expr, pattern
|
53 | , args = ""
|
54 | , fn = ""
|
55 | , lastIndex = 0
|
56 | for (; m = formatRe.exec(str); ) {
|
57 | for (expr = m[1].replace(exprRe, ""); tmp = wordRe.exec(expr); ) {
|
58 | args += (args ? "," : "var ") + tmp[0] + (
|
59 | tmp[1] ? "=" : "=$['" + tmp[0] + "']!=null?$['" + tmp[0] + "']:"
|
60 | ) + "$g['" + tmp[2] + "']!=null?$g['" + tmp[2] + "']:''"
|
61 | }
|
62 | expr = m[1]
|
63 | if (pattern = get(m[3], m[3])) {
|
64 | if (ext[tmp = pattern.charAt(0)]) {
|
65 | expr = "_." + ext[tmp] + "(" + expr + "," + quote(pattern.slice(tmp == "#" ? 0 : 1)) + ")"
|
66 | } else {
|
67 | for (; tmp = pattRe.exec(pattern); ) {
|
68 | expr = "_." + tmp[1] + ".call($," + expr + (tmp[2] ? "," + tmp[2] : "") + ")"
|
69 | }
|
70 | }
|
71 | }
|
72 | fn += (fn ? "+" : "") + (
|
73 | lastIndex < m.index ?
|
74 | quote(str.slice(lastIndex, m.index)) + "+(" : "("
|
75 | ) + expr + ")"
|
76 | lastIndex = m.index + m[0].length
|
77 | }
|
78 |
|
79 | if (fn) try {
|
80 | return Function("$,_,$g", args + ";return(" + fn + (
|
81 | lastIndex < str.length ? ")+" + quote(str.slice(lastIndex)) : ")"
|
82 | ))
|
83 | } catch (e) {
|
84 | |
85 |
|
86 |
|
87 |
|
88 | }
|
89 | return str.replace(/{;/g, "{")
|
90 | }
|
91 |
|
92 | function add(lang, texts) {
|
93 | if (list.indexOf(lang) < 0) {
|
94 | i18n[lang] = Object.create(globalTexts)
|
95 | list.push(lang)
|
96 | if (!currentLang) use(lang)
|
97 | }
|
98 | merge(i18n[lang], texts)
|
99 | }
|
100 |
|
101 | function merge(target, map) {
|
102 | for (var k in map) {
|
103 | target[k] = map[k] && map[k].constructor === Object ? merge(Object.create(target), map[k]) : map[k]
|
104 | }
|
105 | return target
|
106 | }
|
107 |
|
108 | i18n.def = function(map) {
|
109 | for (var k in map) {
|
110 | add(k, map)
|
111 | }
|
112 | }
|
113 |
|
114 | function getLang(lang) {
|
115 | return lang && (
|
116 | i18n[lang = ("" + lang).toLowerCase()] ||
|
117 | i18n[lang = lang.split("-")[0]]
|
118 | ) && lang
|
119 | }
|
120 |
|
121 | function use(lang) {
|
122 | lang = getLang(lang)
|
123 | if (lang && currentLang != lang) {
|
124 | cache = {}
|
125 | currentMap = i18n[currentLang = i18n.current = lang] = i18n[currentLang]
|
126 | }
|
127 | return currentLang
|
128 | }
|
129 |
|
130 | function isString(str) {
|
131 | return typeof str === "string"
|
132 | }
|
133 | function isObject(obj) {
|
134 | return obj && obj.constructor === Object
|
135 | }
|
136 | function getStr(sub, word, fallback) {
|
137 | return currentMap && (
|
138 | isObject(currentMap[word]) && currentMap[word][sub] ||
|
139 | isObject(currentMap[sub]) && currentMap[sub][word] ||
|
140 | currentMap[word || sub]
|
141 | ) || isString(fallback) && fallback || ""
|
142 | }
|
143 | function quote(str) {
|
144 | return "'" + (str || "").replace(/'/g, "\\'").replace(/\n/g, "\\n") + "'"
|
145 | }
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | var dateRe = /([Md])\1\1\1?|([yMdHhmswSZ])(\2?)|[uUaSeoQ]|'((?:''|[^'])*)'|(["\\\n\r\u2028\u2029])/g
|
152 | , fns = Object.create(null)
|
153 | , tmp1 = new Date()
|
154 | , tmp2 = new Date()
|
155 | , map = {
|
156 | e: "Day()||7",
|
157 | M: "Month()+1",
|
158 | d: "Date()",
|
159 | H: "Hours()",
|
160 | h: "Hours()%12||12",
|
161 | m: "Minutes()",
|
162 | s: "Seconds()",
|
163 | S: "Milliseconds()"
|
164 | }
|
165 |
|
166 |
|
167 | i18n[ext["@"] = "date"] = date
|
168 | function date(input, _mask, _zone) {
|
169 | var offset, undef
|
170 | , d = typeof input === "number" ? input : isNaN(input) ? Date.parse(input) : +input
|
171 | , locale = currentMap["@"]
|
172 | , mask = locale[_mask] || _mask || locale.iso
|
173 | , zone = _zone != undef ? _zone : Date._tz != undef ? Date._tz : undef
|
174 | , utc = mask.slice(0, 4) == "UTC:"
|
175 | if (zone != undef && !utc) {
|
176 | offset = 60 * zone
|
177 | tmp1.setTime(d + offset * 6e4)
|
178 | utc = mask = "UTC:" + mask
|
179 | } else {
|
180 | tmp1.setTime(d)
|
181 | offset = utc ? 0 : -tmp1.getTimezoneOffset()
|
182 | }
|
183 | return isNaN(d) ? "" + d : (
|
184 | fns[mask] || (fns[mask] = Function("d,a,o,l", "var t;return \"" + dateStr(mask, utc) + "\"")))(
|
185 | tmp1,
|
186 | tmp2,
|
187 | offset,
|
188 | locale
|
189 | )
|
190 | }
|
191 |
|
192 | date.dateStr = dateStr
|
193 | function dateStr(mask, utc) {
|
194 | var get = "d.get" + (utc ? "UTC" : "")
|
195 | , setA = "a.setTime(+d+((4-(" + get + map.e + "))*864e5))"
|
196 | return (utc ? mask.slice(4) : mask).replace(dateRe, function(match, MD, single, pad, text, esc) {
|
197 | var str = (
|
198 | esc ? escape(esc).replace(/%u/g, "\\u").replace(/%/g, "\\x") :
|
199 | text !== void 0 ? text.replace(/''/g, "'") :
|
200 | MD ? "l.names[" + get + (MD == "M" ? "Month" : "Day" ) + "()+" + (match == "ddd" ? 24 : MD == "d" ? 31 : match == "MMM" ? 0 : 12) + "]" :
|
201 | match == "u" ? "(d/1000)>>>0" :
|
202 | match == "U" ? "+d" :
|
203 | match == "Q" ? "((" + get + "Month()/3)|0)+1" :
|
204 | match == "a" ? "l[" + get + map.H + ">11?'pm':'am']" :
|
205 | match == "o" ? setA + ",a" + get.slice(1) + "FullYear()" :
|
206 | single == "y" ? get + "FullYear()" + (pad == "y" ? "%100" : "") :
|
207 | single == "Z" ? "(t=o)?(t<0?((t=-t),'-'):'+')+(t<600?'0':'')+(0|(t/60))" + (pad ? "" : "+':'") + "+((t%=60)>9?t:'0'+t):'Z'" :
|
208 | single == "w" ? "Math.ceil(((" + setA + "-a.s" + get.slice(3) + "Month(0,1))/864e5+1)/7)" :
|
209 | get + map[single || match]
|
210 | )
|
211 | return text !== void 0 || esc ? str : "\"+(" + (
|
212 | match == "SS" ? "(t=" + str + ")>9?t>99?t:'0'+t:'00'+t" :
|
213 | pad && single != "Z" ? "(t=" + str + ")>9?t:'0'+t" :
|
214 | str
|
215 | ) + ")+\""
|
216 | })
|
217 | }
|
218 |
|
219 | /**/
|
220 |
|
221 | /*** i18n.detect ***/
|
222 | i18n.detect = function(fallback) {
|
223 | var navigator = exports.navigator || exports
|
224 |
|
225 |
|
226 | return use([navigator.language, navigator.userLanguage].concat(
|
227 | navigator.languages, fallback, list[0]
|
228 | ).filter(getLang)[0])
|
229 | }
|
230 |
|
231 |
|
232 |
|
233 | var numRe1 = /([^\d#]*)([\d# .,_·']*\/?\d+)(?:(\s*)([a-z%]+)(\d*))?(.*)/
|
234 | , numRe2 = /([.,\/])(\d*)$/
|
235 |
|
236 | i18n[ext["#"] = ext["+"] = "number"] = number
|
237 | function number(input, _format) {
|
238 | var format = getStr("#", _format.slice(1), _format)
|
239 | return (cache[format] || (cache[format] = Function(
|
240 | "d,g",
|
241 | "var N=d<0&&(d=-d),n,r,o;return " + numStr(format)
|
242 | )))(input, fnScope)
|
243 | }
|
244 | number.pre = {
|
245 | a: "(o+=d<1e3?'':d<1e6?(d/=1e3,'k'):d<1e9?(d/=1e6,'M'):d<1e12?(d/=1e9,'G'):d<1e15?(d/=1e12,'T'):d<1e18?(d/=1e15,'P'):(d/=1e18,'E')),"
|
246 | }
|
247 | number.post = {
|
248 | }
|
249 |
|
250 | function numStr(format) {
|
251 |
|
252 | var conf = format.split(";")
|
253 | , nan_value = conf[1] || "-"
|
254 | , m2 = numRe1.exec(conf[0])
|
255 | , m3 = numRe2.exec(m2[2])
|
256 | , decimals = m3 && m3[2].length || 0
|
257 | , full = m3 ? m2[2].slice(0, m3.index) : m2[2]
|
258 | , num = full.replace(/\D+/g, "")
|
259 | , sLen = num.length
|
260 | , step = decimals ? +(m3[1] === "/" ? 1 / m3[2] : num + "." + m3[2]) : num
|
261 | , decSep = m3 && m3[1]
|
262 | , fn = "d===Infinity?(N?" + quote(conf[5]||nan_value) + ":" + quote(conf[4]||nan_value) + "):d>0||d===0?(o=" + quote(m2[3]) + "," + (number.pre[m2[4]] || "") + "n=" + (
|
263 |
|
264 |
|
265 | decimals ?
|
266 | "d>1e-" + (decimals + 1) + "?(n=(d+'e" + decimals + "')/" + (step + "e" + decimals) + "":
|
267 | "d>"+num+"e-1?(n=d/" + num
|
268 | ) + ",Math.floor(n" + (
|
269 | conf[6] == 1 ? "%1?n+1:n" : "+" + (conf[6] || 0.5)
|
270 | ) + ")*" + step + "):0,r=" + (
|
271 | m2[5] ? "(''+(+n.toPrecision(" + (m2[5]) + ")))" :
|
272 | decimals ? "n.toFixed(" + decimals + ")" :
|
273 | "n+''"
|
274 | )
|
275 |
|
276 | if (decimals) {
|
277 | if (decSep == "/") {
|
278 | fn += ".replace(/\\.\\d+/,'" + (
|
279 | m3[2] == 5 ?
|
280 | "⅕⅖⅗⅘'.charAt(5" :
|
281 | "⅛¼⅜½⅝¾⅞'.charAt(8"
|
282 | ) + "*(n%1)-1))"
|
283 | } else if (decSep != ".") {
|
284 | fn += ".replace('.','" + decSep + "')"
|
285 | }
|
286 | if (sLen === 0) {
|
287 | fn += ",n<1&&(r=r.slice(1)||'0')"
|
288 | }
|
289 | }
|
290 | if (sLen > 1) {
|
291 | if (decimals) sLen += decimals + 1
|
292 | fn += ",r=(r.length<" + sLen + "?(1e15+r).slice(-" + sLen + "):r)"
|
293 | }
|
294 |
|
295 | if (num = full.match(/[^\d#][\d#]+/g)) {
|
296 | fn += ",r=" + numJunk(num, num.length - 1, 0, decimals ? decimals + 1 : 0)
|
297 | }
|
298 |
|
299 | if (m2[4] == "o") {
|
300 | number.post.o = "r+(o=g.o," + (
|
301 | fnScope.o = get("ordinal").split(";")
|
302 | ).pop() + ")"
|
303 | }
|
304 |
|
305 | fn += (
|
306 | (m2[4] ? ",r=" + (number.post[m2[4]] || "r+o") : "") +
|
307 | // negative format
|
308 | ",N&&n>0?" + quote(conf[2] || "-#").replace("#", "'+r+'") + ":" +
|
309 | (conf[3] ? "n===0?" + quote(conf[3]) + ":" : "") +
|
310 | (m2[1] ? quote(m2[1]) + "+r" : "r") +
|
311 | (m2[6] ? "+" + quote(m2[6]) : "")
|
312 | )
|
313 |
|
314 | return fn + "):" + quote(nan_value)
|
315 | }
|
316 |
|
317 | function numJunk(arr, i, lastLen, dec) {
|
318 | var len = lastLen + arr[i].length - 1
|
319 |
|
320 | return "(n<1e" + len + (
|
321 | lastLen ? "?r.slice(0,-" + (lastLen + dec) + "):" : "?r:"
|
322 | ) + (
|
323 | len < 16 ? numJunk(arr, i?i-1:i, len, dec) : "r.slice(0,-" + (lastLen + dec) + ")"
|
324 | ) + "+" + quote(arr[i].charAt(0)) + "+r.slice(-" + (len + dec) + (
|
325 | lastLen ? ",-" + (lastLen + dec) : ""
|
326 | ) + "))"
|
327 | }
|
328 |
|
329 |
|
330 |
|
331 | var pickRe1 = /(\w+)\?/g
|
332 | , pickRe2 = /[;=,]/
|
333 | i18n[ext["?"] = "pick"] = pick
|
334 | function pick(val, word) {
|
335 | for (var arr = getStr("?", word, word).replace(pickRe1, "$1=$1;").split(pickRe2), i = 1|arr.length; i > 0; ) {
|
336 | if ((i-=2) < 0 || arr[i] && (arr[i] == "" + val || +arr[i] <= val)) {
|
337 | return arr[i + 1] || ""
|
338 | }
|
339 | }
|
340 | }
|
341 |
|
342 |
|
343 |
|
344 | i18n[ext["*"] = "plural"] = plural
|
345 | function plural(n, word) {
|
346 | var expr = getStr("*", "", "n!=1")
|
347 | return (cache[expr] || (cache[expr] = Function(
|
348 | "a,n",
|
349 | "return (a[+(" + expr + ")]||a[0]).replace('#',n)"
|
350 | )))((getStr("*", word, "# " + word)).split(";"), n)
|
351 | }
|
352 |
|
353 |
|
354 | i18n.map = function(input, str, sep, lastSep) {
|
355 | if (!isArray(input)) return input
|
356 | var arr = input.map(function(data) {
|
357 | return i18n(str, data)
|
358 | })
|
359 | , end = lastSep && arr.length > 1 ? lastSep + arr.pop() : ""
|
360 | return arr.join(sep || ", ") + end
|
361 | }
|
362 | i18n.upcase = function(str) {
|
363 | return isString(str) ? str.toUpperCase() : "" + str
|
364 | }
|
365 | i18n.locase = function(str) {
|
366 | return isString(str) ? str.toLowerCase() : "" + str
|
367 | }
|
368 | i18n.json = JSON.stringify
|
369 |
|
370 |
|
371 | }(this, Object, Function)
|
372 |
|
373 |
|