Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net> | |
2 // This work is free. You can redistribute it and/or modify it | |
3 // under the terms of the WTFPL, Version 2 | |
Sebastian Noack
2016/08/22 16:49:19
While this license should theoretically work for u
Oleksandr
2016/08/25 02:02:37
Done. Judith is fine with this.
| |
4 // For more information see LICENSE.txt or http://www.wtfpl.net/ | |
5 // | |
6 // For more information, the home page: | |
7 // http://pieroxy.net/blog/pages/lz-string/testing.html | |
8 // | |
9 // LZ-based compression algorithm, version 1.4.4 | |
10 var LZString = (function() { | |
11 | |
12 // private property | |
13 var f = String.fromCharCode; | |
14 var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567 89+/="; | |
15 var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 789+-$"; | |
16 var baseReverseDic = {}; | |
17 | |
18 function getBaseValue(alphabet, character) { | |
19 if (!baseReverseDic[alphabet]) { | |
20 baseReverseDic[alphabet] = {}; | |
21 for (var i=0 ; i<alphabet.length ; i++) { | |
22 baseReverseDic[alphabet][alphabet.charAt(i)] = i; | |
23 } | |
24 } | |
25 return baseReverseDic[alphabet][character]; | |
26 } | |
27 | |
28 var LZString = { | |
29 compressToBase64 : function (input) { | |
30 if (input == null) return ""; | |
31 var res = LZString._compress(input, 6, function(a){return keyStrBase64.charA t(a);}); | |
32 switch (res.length % 4) { // To produce valid Base64 | |
33 default: // When could this happen ? | |
34 case 0 : return res; | |
35 case 1 : return res+"==="; | |
36 case 2 : return res+"=="; | |
37 case 3 : return res+"="; | |
38 } | |
39 }, | |
40 | |
41 decompressFromBase64 : function (input) { | |
42 if (input == null) return ""; | |
43 if (input == "") return null; | |
44 return LZString._decompress(input.length, 32, function(index) { return getBa seValue(keyStrBase64, input.charAt(index)); }); | |
45 }, | |
46 | |
47 compressToUTF16 : function (input) { | |
48 if (input == null) return ""; | |
49 return LZString._compress(input, 15, function(a){return f(a+32);}) + " "; | |
50 }, | |
51 | |
52 decompressFromUTF16: function (compressed) { | |
53 if (compressed == null) return ""; | |
54 if (compressed == "") return null; | |
55 return LZString._decompress(compressed.length, 16384, function(index) { retu rn compressed.charCodeAt(index) - 32; }); | |
56 }, | |
57 | |
58 //compress into uint8array (UCS-2 big endian format) | |
59 compressToUint8Array: function (uncompressed) { | |
60 var compressed = LZString.compress(uncompressed); | |
61 var buf=new Uint8Array(compressed.length*2); // 2 bytes per character | |
62 | |
63 for (var i=0, TotalLen=compressed.length; i<TotalLen; i++) { | |
64 var current_value = compressed.charCodeAt(i); | |
65 buf[i*2] = current_value >>> 8; | |
66 buf[i*2+1] = current_value % 256; | |
67 } | |
68 return buf; | |
69 }, | |
70 | |
71 //decompress from uint8array (UCS-2 big endian format) | |
72 decompressFromUint8Array:function (compressed) { | |
73 if (compressed===null || compressed===undefined){ | |
74 return LZString.decompress(compressed); | |
75 } else { | |
76 var buf=new Array(compressed.length/2); // 2 bytes per character | |
77 for (var i=0, TotalLen=buf.length; i<TotalLen; i++) { | |
78 buf[i]=compressed[i*2]*256+compressed[i*2+1]; | |
79 } | |
80 | |
81 var result = []; | |
82 buf.forEach(function (c) { | |
83 result.push(f(c)); | |
84 }); | |
85 return LZString.decompress(result.join('')); | |
86 | |
87 } | |
88 | |
89 }, | |
90 | |
91 | |
92 //compress into a string that is already URI encoded | |
93 compressToEncodedURIComponent: function (input) { | |
94 if (input == null) return ""; | |
95 return LZString._compress(input, 6, function(a){return keyStrUriSafe.charAt( a);}); | |
96 }, | |
97 | |
98 //decompress from an output of compressToEncodedURIComponent | |
99 decompressFromEncodedURIComponent:function (input) { | |
100 if (input == null) return ""; | |
101 if (input == "") return null; | |
102 input = input.replace(/ /g, "+"); | |
103 return LZString._decompress(input.length, 32, function(index) { return getBa seValue(keyStrUriSafe, input.charAt(index)); }); | |
104 }, | |
105 | |
106 compress: function (uncompressed) { | |
107 return LZString._compress(uncompressed, 16, function(a){return f(a);}); | |
108 }, | |
109 _compress: function (uncompressed, bitsPerChar, getCharFromInt) { | |
110 if (uncompressed == null) return ""; | |
111 var i, value, | |
112 context_dictionary= {}, | |
113 context_dictionaryToCreate= {}, | |
114 context_c="", | |
115 context_wc="", | |
116 context_w="", | |
117 context_enlargeIn= 2, // Compensate for the first entry which should not count | |
118 context_dictSize= 3, | |
119 context_numBits= 2, | |
120 context_data=[], | |
121 context_data_val=0, | |
122 context_data_position=0, | |
123 ii; | |
124 | |
125 for (ii = 0; ii < uncompressed.length; ii += 1) { | |
126 context_c = uncompressed.charAt(ii); | |
127 if (!Object.prototype.hasOwnProperty.call(context_dictionary,context_c)) { | |
128 context_dictionary[context_c] = context_dictSize++; | |
129 context_dictionaryToCreate[context_c] = true; | |
130 } | |
131 | |
132 context_wc = context_w + context_c; | |
133 if (Object.prototype.hasOwnProperty.call(context_dictionary,context_wc)) { | |
134 context_w = context_wc; | |
135 } else { | |
136 if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,cont ext_w)) { | |
137 if (context_w.charCodeAt(0)<256) { | |
138 for (i=0 ; i<context_numBits ; i++) { | |
139 context_data_val = (context_data_val << 1); | |
140 if (context_data_position == bitsPerChar-1) { | |
141 context_data_position = 0; | |
142 context_data.push(getCharFromInt(context_data_val)); | |
143 context_data_val = 0; | |
144 } else { | |
145 context_data_position++; | |
146 } | |
147 } | |
148 value = context_w.charCodeAt(0); | |
149 for (i=0 ; i<8 ; i++) { | |
150 context_data_val = (context_data_val << 1) | (value&1); | |
151 if (context_data_position == bitsPerChar-1) { | |
152 context_data_position = 0; | |
153 context_data.push(getCharFromInt(context_data_val)); | |
154 context_data_val = 0; | |
155 } else { | |
156 context_data_position++; | |
157 } | |
158 value = value >> 1; | |
159 } | |
160 } else { | |
161 value = 1; | |
162 for (i=0 ; i<context_numBits ; i++) { | |
163 context_data_val = (context_data_val << 1) | value; | |
164 if (context_data_position ==bitsPerChar-1) { | |
165 context_data_position = 0; | |
166 context_data.push(getCharFromInt(context_data_val)); | |
167 context_data_val = 0; | |
168 } else { | |
169 context_data_position++; | |
170 } | |
171 value = 0; | |
172 } | |
173 value = context_w.charCodeAt(0); | |
174 for (i=0 ; i<16 ; i++) { | |
175 context_data_val = (context_data_val << 1) | (value&1); | |
176 if (context_data_position == bitsPerChar-1) { | |
177 context_data_position = 0; | |
178 context_data.push(getCharFromInt(context_data_val)); | |
179 context_data_val = 0; | |
180 } else { | |
181 context_data_position++; | |
182 } | |
183 value = value >> 1; | |
184 } | |
185 } | |
186 context_enlargeIn--; | |
187 if (context_enlargeIn == 0) { | |
188 context_enlargeIn = Math.pow(2, context_numBits); | |
189 context_numBits++; | |
190 } | |
191 delete context_dictionaryToCreate[context_w]; | |
192 } else { | |
193 value = context_dictionary[context_w]; | |
194 for (i=0 ; i<context_numBits ; i++) { | |
195 context_data_val = (context_data_val << 1) | (value&1); | |
196 if (context_data_position == bitsPerChar-1) { | |
197 context_data_position = 0; | |
198 context_data.push(getCharFromInt(context_data_val)); | |
199 context_data_val = 0; | |
200 } else { | |
201 context_data_position++; | |
202 } | |
203 value = value >> 1; | |
204 } | |
205 | |
206 | |
207 } | |
208 context_enlargeIn--; | |
209 if (context_enlargeIn == 0) { | |
210 context_enlargeIn = Math.pow(2, context_numBits); | |
211 context_numBits++; | |
212 } | |
213 // Add wc to the dictionary. | |
214 context_dictionary[context_wc] = context_dictSize++; | |
215 context_w = String(context_c); | |
216 } | |
217 } | |
218 | |
219 // Output the code for w. | |
220 if (context_w !== "") { | |
221 if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,contex t_w)) { | |
222 if (context_w.charCodeAt(0)<256) { | |
223 for (i=0 ; i<context_numBits ; i++) { | |
224 context_data_val = (context_data_val << 1); | |
225 if (context_data_position == bitsPerChar-1) { | |
226 context_data_position = 0; | |
227 context_data.push(getCharFromInt(context_data_val)); | |
228 context_data_val = 0; | |
229 } else { | |
230 context_data_position++; | |
231 } | |
232 } | |
233 value = context_w.charCodeAt(0); | |
234 for (i=0 ; i<8 ; i++) { | |
235 context_data_val = (context_data_val << 1) | (value&1); | |
236 if (context_data_position == bitsPerChar-1) { | |
237 context_data_position = 0; | |
238 context_data.push(getCharFromInt(context_data_val)); | |
239 context_data_val = 0; | |
240 } else { | |
241 context_data_position++; | |
242 } | |
243 value = value >> 1; | |
244 } | |
245 } else { | |
246 value = 1; | |
247 for (i=0 ; i<context_numBits ; i++) { | |
248 context_data_val = (context_data_val << 1) | value; | |
249 if (context_data_position == bitsPerChar-1) { | |
250 context_data_position = 0; | |
251 context_data.push(getCharFromInt(context_data_val)); | |
252 context_data_val = 0; | |
253 } else { | |
254 context_data_position++; | |
255 } | |
256 value = 0; | |
257 } | |
258 value = context_w.charCodeAt(0); | |
259 for (i=0 ; i<16 ; i++) { | |
260 context_data_val = (context_data_val << 1) | (value&1); | |
261 if (context_data_position == bitsPerChar-1) { | |
262 context_data_position = 0; | |
263 context_data.push(getCharFromInt(context_data_val)); | |
264 context_data_val = 0; | |
265 } else { | |
266 context_data_position++; | |
267 } | |
268 value = value >> 1; | |
269 } | |
270 } | |
271 context_enlargeIn--; | |
272 if (context_enlargeIn == 0) { | |
273 context_enlargeIn = Math.pow(2, context_numBits); | |
274 context_numBits++; | |
275 } | |
276 delete context_dictionaryToCreate[context_w]; | |
277 } else { | |
278 value = context_dictionary[context_w]; | |
279 for (i=0 ; i<context_numBits ; i++) { | |
280 context_data_val = (context_data_val << 1) | (value&1); | |
281 if (context_data_position == bitsPerChar-1) { | |
282 context_data_position = 0; | |
283 context_data.push(getCharFromInt(context_data_val)); | |
284 context_data_val = 0; | |
285 } else { | |
286 context_data_position++; | |
287 } | |
288 value = value >> 1; | |
289 } | |
290 | |
291 | |
292 } | |
293 context_enlargeIn--; | |
294 if (context_enlargeIn == 0) { | |
295 context_enlargeIn = Math.pow(2, context_numBits); | |
296 context_numBits++; | |
297 } | |
298 } | |
299 | |
300 // Mark the end of the stream | |
301 value = 2; | |
302 for (i=0 ; i<context_numBits ; i++) { | |
303 context_data_val = (context_data_val << 1) | (value&1); | |
304 if (context_data_position == bitsPerChar-1) { | |
305 context_data_position = 0; | |
306 context_data.push(getCharFromInt(context_data_val)); | |
307 context_data_val = 0; | |
308 } else { | |
309 context_data_position++; | |
310 } | |
311 value = value >> 1; | |
312 } | |
313 | |
314 // Flush the last char | |
315 while (true) { | |
316 context_data_val = (context_data_val << 1); | |
317 if (context_data_position == bitsPerChar-1) { | |
318 context_data.push(getCharFromInt(context_data_val)); | |
319 break; | |
320 } | |
321 else context_data_position++; | |
322 } | |
323 return context_data.join(''); | |
324 }, | |
325 | |
326 decompress: function (compressed) { | |
327 if (compressed == null) return ""; | |
328 if (compressed == "") return null; | |
329 return LZString._decompress(compressed.length, 32768, function(index) { retu rn compressed.charCodeAt(index); }); | |
330 }, | |
331 | |
332 _decompress: function (length, resetValue, getNextValue) { | |
333 var dictionary = [], | |
334 next, | |
335 enlargeIn = 4, | |
336 dictSize = 4, | |
337 numBits = 3, | |
338 entry = "", | |
339 result = [], | |
340 i, | |
341 w, | |
342 bits, resb, maxpower, power, | |
343 c, | |
344 data = {val:getNextValue(0), position:resetValue, index:1}; | |
345 | |
346 for (i = 0; i < 3; i += 1) { | |
347 dictionary[i] = i; | |
348 } | |
349 | |
350 bits = 0; | |
351 maxpower = Math.pow(2,2); | |
352 power=1; | |
353 while (power!=maxpower) { | |
354 resb = data.val & data.position; | |
355 data.position >>= 1; | |
356 if (data.position == 0) { | |
357 data.position = resetValue; | |
358 data.val = getNextValue(data.index++); | |
359 } | |
360 bits |= (resb>0 ? 1 : 0) * power; | |
361 power <<= 1; | |
362 } | |
363 | |
364 switch (next = bits) { | |
365 case 0: | |
366 bits = 0; | |
367 maxpower = Math.pow(2,8); | |
368 power=1; | |
369 while (power!=maxpower) { | |
370 resb = data.val & data.position; | |
371 data.position >>= 1; | |
372 if (data.position == 0) { | |
373 data.position = resetValue; | |
374 data.val = getNextValue(data.index++); | |
375 } | |
376 bits |= (resb>0 ? 1 : 0) * power; | |
377 power <<= 1; | |
378 } | |
379 c = f(bits); | |
380 break; | |
381 case 1: | |
382 bits = 0; | |
383 maxpower = Math.pow(2,16); | |
384 power=1; | |
385 while (power!=maxpower) { | |
386 resb = data.val & data.position; | |
387 data.position >>= 1; | |
388 if (data.position == 0) { | |
389 data.position = resetValue; | |
390 data.val = getNextValue(data.index++); | |
391 } | |
392 bits |= (resb>0 ? 1 : 0) * power; | |
393 power <<= 1; | |
394 } | |
395 c = f(bits); | |
396 break; | |
397 case 2: | |
398 return ""; | |
399 } | |
400 dictionary[3] = c; | |
401 w = c; | |
402 result.push(c); | |
403 while (true) { | |
404 if (data.index > length) { | |
405 return ""; | |
406 } | |
407 | |
408 bits = 0; | |
409 maxpower = Math.pow(2,numBits); | |
410 power=1; | |
411 while (power!=maxpower) { | |
412 resb = data.val & data.position; | |
413 data.position >>= 1; | |
414 if (data.position == 0) { | |
415 data.position = resetValue; | |
416 data.val = getNextValue(data.index++); | |
417 } | |
418 bits |= (resb>0 ? 1 : 0) * power; | |
419 power <<= 1; | |
420 } | |
421 | |
422 switch (c = bits) { | |
423 case 0: | |
424 bits = 0; | |
425 maxpower = Math.pow(2,8); | |
426 power=1; | |
427 while (power!=maxpower) { | |
428 resb = data.val & data.position; | |
429 data.position >>= 1; | |
430 if (data.position == 0) { | |
431 data.position = resetValue; | |
432 data.val = getNextValue(data.index++); | |
433 } | |
434 bits |= (resb>0 ? 1 : 0) * power; | |
435 power <<= 1; | |
436 } | |
437 | |
438 dictionary[dictSize++] = f(bits); | |
439 c = dictSize-1; | |
440 enlargeIn--; | |
441 break; | |
442 case 1: | |
443 bits = 0; | |
444 maxpower = Math.pow(2,16); | |
445 power=1; | |
446 while (power!=maxpower) { | |
447 resb = data.val & data.position; | |
448 data.position >>= 1; | |
449 if (data.position == 0) { | |
450 data.position = resetValue; | |
451 data.val = getNextValue(data.index++); | |
452 } | |
453 bits |= (resb>0 ? 1 : 0) * power; | |
454 power <<= 1; | |
455 } | |
456 dictionary[dictSize++] = f(bits); | |
457 c = dictSize-1; | |
458 enlargeIn--; | |
459 break; | |
460 case 2: | |
461 return result.join(''); | |
462 } | |
463 | |
464 if (enlargeIn == 0) { | |
465 enlargeIn = Math.pow(2, numBits); | |
466 numBits++; | |
467 } | |
468 | |
469 if (dictionary[c]) { | |
470 entry = dictionary[c]; | |
471 } else { | |
472 if (c === dictSize) { | |
473 entry = w + w.charAt(0); | |
474 } else { | |
475 return null; | |
476 } | |
477 } | |
478 result.push(entry); | |
479 | |
480 // Add w+entry[0] to the dictionary. | |
481 dictionary[dictSize++] = w + entry.charAt(0); | |
482 enlargeIn--; | |
483 | |
484 w = entry; | |
485 | |
486 if (enlargeIn == 0) { | |
487 enlargeIn = Math.pow(2, numBits); | |
488 numBits++; | |
489 } | |
490 | |
491 } | |
492 } | |
493 }; | |
494 return LZString; | |
495 })(); | |
496 | |
497 if (typeof define === 'function' && define.amd) { | |
498 define(function () { return LZString; }); | |
499 } else if( typeof module !== 'undefined' && module != null ) { | |
500 module.exports = LZString | |
501 } else if( typeof angular !== 'undefined' && angular != null ) { | |
502 angular.module('LZString', []) | |
503 .factory('LZString', function () { | |
504 return LZString; | |
505 }); | |
506 } | |
OLD | NEW |