pieroxy / lz-string Goto Github PK
View Code? Open in Web Editor NEWLZ-based compression algorithm for JavaScript
License: MIT License
LZ-based compression algorithm for JavaScript
License: MIT License
The license you are using is not OSI approved. I can't use your software in our software until there is an appropriate legal disclaimer. You'll also begin caring a great deal about the license you use if someone decides to sue you using legal terminology such as warranties, merchantability, claims, damages, and/or liabilities where you will have to defend yourself in a court of law and you will most likely lose any such lawsuits.
If an organization interested in your software cares about their legal rear (most do), they can't use your software because using it could drag them into a lawsuit in the event of a catastrophic failure of your software product. As-is, organizations that do proper legal due diligence will simply avoid your software.
The MIT license is the most liberal OSI approved license that contains the appropriate legalese that protects everyone using your software - including yourself! Given the current legal landscape, the best option is to cover your butt with a license that has been run through a gauntlet of lawyers. The MIT license is harmless and much more widely used than the current license of this project. You should adopt it or any of the other OSI approved licenses. You can even dual-license the software if you want - that is, give people a choice of which license they wish to license your software under.
What's the browser support for this lib? I couldn't find any info on the web site. Or at least what js features does it use? so I can look it up, and also possibly for polyfills. Thanks.
When an array of an odd length is provided to decompressFromUint8Array, an exception is thrown. This is because, internally, a new Array of length / 2 is created, which can result in an invalid (decimal) length.
Specifically, this happens when I store the results of compressToUint8Array to a Blob, persist it to an Object URI and try to decompress it later. Checking the array length and adding the necessary padding to the end would allow arrays of all sizes to be used.
I used compressToUTF16
on JSON.stringify'd data then stored it in an SQLlite db using cordova.sqllite. However, when I retrieve the data from the db it causes SyntaxError: Unexpected EOF
Storing a normal string or a compressToBase64
'd string does not cause an error so I don't think it's a problem with the DB.
Is there any ready code to decompress the compressed string in PHP?
Hi, my app need to compress some svg code and save them into MongoDB using Mongoose, save as String or Buffer neither of them will work! the decompress all return null; the output of comressed string and mongodb string are same string,same length.
i checked lz-string code and here is some info:
// from line 468
if (dictionary[c]) {
entry = dictionary[c];
} else {
if (c === dictSize) {
entry = w + w.charAt(0);
} else {
console.log(c)
console.log( dictionary )
console.log( result )
console.log( entry )
console.log("__can not decompress? but why?__")
return null;
}
}
// and herer is the log message:
31
[ 0,
1,
2,
'<',
's',
'<s',
'v',
'sv',
'g',
'vg',
' ',
'g ',
'x',
' x',
'm',
'xm',
'l',
'ml',
'n',
'ln',
'ns',
'=',
's=',
'"',
'="',
'h',
'"h',
'ô',
'hô' ]
[ '<', 's', 'v', 'g', ' ', 'x', 'm', 'l', 'n', 's', '=', '"', 'h', 'ô' ]
ô
__can not decompress? but why?__
is mongodb changed some of binary data? or is it a lz-string's bug?
if anyone knows how to solve this problem, great thanks.
or, is save gziped data to mongodb is a better choice?
Hi,
we have a webpage that compresses a generated JSONObject with the compressToBase64 method.
This is send over to the server where we use lz-string4java to decompress.
Sometes a compressToBase64 string fails to decompress.
So we tried to decompressFromBase64 using this javascript library to see if this in an error in the Java port or an error in this library ?
We can't decompress the example below with this library.
Could you have look and see what the problem is ?
For your information:
The compressed string is send over in a Ajax Post request (where the string below and some other info is encodeURIComponent before added to the request body).
The string that fail to decompressFromBase64 👍
"66BaC_Q3_vXoKBfKCB7CKdL-TpV_ANXzAftPGaRnspUWaWfvsLY3xQKpH1h1nSX6p0EGb95smC3YdSYqGHPYUmvGtn_XqtJxPLndWBDpBz4YRAM_mSDDRPElCeGSHAKBQ5wIx-I5dy_Hdv29puDknZX6utRpb0s6OeNi-9wDs4L-AXd7pOiOSLJbgZMC1eVKLoCha4lVtoLi8J29LgHaPzpg9bj8HvkbpTnm7ti_cpyZA1jNGS5LDO-NApu3K2WAhxtkriP2KFUQhai2TtvUoMMVRQQH-DjmxSknEQvRzHQX2SseHu1Sd6l66ZjsLvHQFbvMpCLgizRWKSK7GGPISzFb1P01IU1UC4WszTtWN0eRfc6NpvmM8ZkylvLR6l-GU3m6K9jIVTa_njpYAEzCJtO3Ib-QxQlueNNV5eIICHstys2U006Me1vBq5V5Z-KeL6IUprUMSTvv2RNQWYxNIos-fpfeM4QjHxSeLe8UpteZSAdMizcAbC52potvhubZZVfyqEAWQILPELx4b5adTNIhWv4xTRASumS5R_UDUjv5RgrC8UkZXlqkbprrDSun6e4EU47mrZuXIjmEHEPh4ZYEfCuBVPvyGcOUKxinwfRVA1EsgNeDOA1WaP9D-ZVd9ErD0QSawU7x-7I3uTDTxZ5DwO5pFu1igFarYd4MOQUeFjs7Yc-nA2YU-2ivH08IrkIr77Zc7z8bdaBV2-8AFpZqavTuhwe9zefLvK-NuEBTLNyJo4bO1T6KtD2VZrWtaze0T5U-Lznp0NNJcr—r2kT2fi-FZBo3PUe3foFcpuDYRG6nrKmN-Hmlpn_0B5CUwap_M2MaCcHVA8FptnexaIXgiisehbjy65SqlySARH55lbWtzpxk4KczErguNkQb7m4tTqM3T1eG1ot5m8KvK0S8_jit399CCVuJz68mfXGAWrdZjqiQPfmBT2_YlTlrZpxwl_tlI9ypJYAz6Z-bKUUcyOvl2gPTTv6jef5F7Q5ca-6vT5PRUAkqrHzHznycny2MIr0scnvT8MymcdCzDPVkKiU7uPpGcJtG9K7J52KvbuKTLProcQ5FSHeMmbG2r8Mx81qn-fKMxbEX44DFsRIwgr_uyLImJjVLCDu2gc-2OxbBoXS4MidGwN6-qxFoxB204VQoSds6JSHrUuiXRaWN7-yIm4nC1jheKUYLb2sLaEHToEeCmkbJk-pgnYjLYwln6FhSmHRe-jCZ9-uhwP2oSfY9wXLSqRTAUCc_pIf1PMudcFWf4c6fOdsbZXbzDBoX2KH9DISGAFClpn7lSL3bJIIZYh-p9r2ZZ3amxedgPYZ0vCvNdFfng48uO4Kpby_7o_i_zkT3AuIBQS30jdWWjHrnViTI_Ig3lzjIBOYeoVBPp-blPH-uyqUBBg4Tq092cfPYMGagLh3NJHAQnZqvnF5Kzn2AICZJyPejV6iJtakclYz9M0YkL4pInyW_DXPKoPflby1NQ-pElW2DcCgCIxNmSQo9GRPxahyo03ZBg_lh-fGwpyrE9x1kondKP0CQ5p8ruUobuP1zvXU9ovWyjzhUP-CJLRaKgT1FSIvsaGhyZHNgRrkl7Fcv6ZBgI34YzGaCDuzhgNaG2a0DpRhItupAmsFJSIDqAtwJao3zAvYen8fJLQZkPEmB-x7xhXKjQMnra5GUKnYy_vW8i1JeqTebDxTvDWdT8AWZvws3PYdNg7Ga3t99NnjMfe6XynoP0bJhRhk6vmquHzmBri2nez5gqvkO2qCSJOpVtF4C9zk6cRux7GhPBgoNEEBNcC5VNOU-0iw6pbNwSU1TPIUkR7s0abILFxTseLD_KmafGTOUQy9z_uNTJXnE77Wj0cR0AwwPsOq0JaX3lGaXTGnefgppXQOQ2pz-eFCCHOFDykoRh89m6TtBTYGlkOYXdvHZ6BUSH_nnCe8rmhPc8-2ifDpx_cvTRLXo6IwHXDlRs3tNe1zR0syqFG2e62fhMZ4VT4QRFs7tU_tb97hcU7FMkoUE7QPko9QZyE5Wzp0TDK86ZH4fQxpAQ3n41HLf2XrRryKakwiiJ6TL14NCmrhosxaY0JQyVvQsrBl8cJ2TPGlHC2Q-vzKJiyPMNhAdzKwA5LYebYCI2yu8AndV1u-YLIK7xLPbbozjWEpKx0QwVQJSjzOcMWxUtwwtITHtbD18D-oaXxZgax9KK-zlF-2gJ77cnEMXM-yrE2qHVkWqt_FpDocj6uorTowxArTn3R6yxXjWfWRVxFeWkOyKBIyZjH2yW5GwZw1kAa3JtF2-DDvd8fTuieAYMV2DYu1TBnsIve_T6kB8nDF_3j5XwtFnKjXpnPev03VohefDFG8-6ClSdaUpZcYGocSAXP_fENAJZmLgDmxYMQjSvgrxWezZOZx3UNWFW4oKao0DBu5T28umVUpyJEikDr96gWPkK-mDgk7A4iVtP254g0UMqTKPanDnvWyta3wZ9VNcFewnWL1OMebVLrENBGac5BxPZ0mSUyToY_XzoAzKgfbkIebW1A-upKGtQZubBi5pQIsiuXYNDoP3r8FvVa6ZXsX_1-bFw8h6KJtwIN5WH-wzpttL4cLf7pxktBUOTnoSwQTTEozKoxH5w_gR5dMvcn8xBQFt-TkexR4Ul2825cVLfl-kkZHMQmhy7OT2eCK3gaD6e-TeqCXcevPy3tZWeJvjvgu_3M80RdrcpJm9LZ69_FTv1GlIja301RYG_ja9KsFnJBRjh6f1BMVPD_sZ_F89ZQkzg7pSBpix4nYL1q2zcjKuLrcw7ySyD6gby5iVbdD8iA5-lvFj3P1mBBQTrbb0ffCqilFt690Amc12pmn02CCTrDQi-DFAncOyEgE4hWueA_2edCB7F1ryTE7mJrJJDHHZQa0-ahWIuZYZYuvm0Tu6iiL5dnxtLo83aQmox6-WJxQPKzL5XuxBOGpX0SoLc5ZA3xUDYM8ym9NztkSsaWHo3S2rYYnWByA_QJOWMa1527HzIaHRRkomaw6K_OHf_fSXzwVhhwl8RVj7-XTFdbTtqj23lP3nrzJ9kt5LrTCKAVcSj2kyxQeuR-H4BmVBUpf11O2kQaN_8QfsZDOLd3IL0sIxR6yStrycB7Ym7x_bKIAfKM7S9_uXHKCCom04a37gFEovEqZ8loUFhYvSHuiQogF69RTBM6Hakh1gssoy0gJXidUROr20yF_SBXqbkWms2OjRKt8Ofz2Fa8rZpgcwTJbz9Zv1QSFDhq1Otpq83Oh0iGsilbcSDL143WFZdoszPc0jih0t4rkC_Z08AMZw-9RyuldDpZ78zmrwBOROQlxOagLvjlNfKZ692Lxd7kKhm5YDni-L9sz8V4rzhY1W_-EXHG7waJpyd3E8BO2MqU9IT6wNCKOj4Qly_njY8RTydzq-OqB1AFkEz3eJGpYnN_66iPlGI9P3tKieiHUYLEaY6N1Z1zdpreJaFbEJs8hyosgd4O_Mrc-Tf9njPAACA-jmjuuCGc2T7ER3a0VZeO4uWszzpxFKXW9SsNDimMrpa9LWrYElbVwKK1y8NLykIk442Yo8AuvZ2u9u3vNkldgIFVnCYKLYEuXlQQ04YAbMUu50t0SZ16tAL9gt6_nDrWmbGvQXNYz2HLU-RfeyjeE6gI2CJROV-Qdh8DPNwft91XfVt_RLOurG3L31lpaqPXuUcEsIWzMCcq_CpaauoLDV2X1z4kqAx9ftxkkwfPG30KykcZuShBGyhij7Wd9orrYd19yHCmGfvIs0tYUdkItE0c2yseTXfDFTkBOV3HiY7QhyHHpYaURQUGoddStMrNmJnX-Dg1kqkYJkVHNIHiq9xRyC7sbUHZE0RJ853gzqYEtpl9GXw3F-dOZ5UTczuQrLCchKq-bVdv-vXgGTHl0uD2PRC9CEmyt0VqQfox7vdYJgLpZT-j7pr_SUsxMkY8Wq-BQDcTPpSKtTXJ8npY5cRdLm7kkDQYuNOT23Pex2WOnRH9c8NPf7gczBiPDauAHUSV3ij_HAwtM2GRigJ9ivIEF-ZW6NYcp-sCmlF7PaUJhroUp-lyzNlEoLguBSedzobY0ZX28bUbRrqWzingoZgDYQRKTyBE6hxE6gI3My6B7Q20WgOorL-vY9gyQH0nhh3LwAljrxOxfjskm-xhU1tyHApsZt7MsXRI6ofP1j9ZOpMLFHv_u0pt66ZPNelksXWqVdmeW4VOdmBSbanJuPvuuTuI-FViXUc7ZtyUpGjGE5i7Tv0uMvsSC83zwknIfLcPdGKVKIdgrsPR8hWAJq-9drJZDNDwMF744w6skij2CVPqLLgvmWwjPdPt1cIp1ifGRZu0Sj0k6CZsRDY1yUuBOU3wXouKMOGgsNYHPBvUhEBHEp-u8JJfYP5beEjEj85QPmv0H6supniwxmI2JmC6Ks1M3mKgYm-IVisUgpRk4d_ns9yVNd44PiHHh23L0h8cCXy0nd5F6H4aNlEYGkFcuuUieWKtJNPsMaLeVZ6HfNcfkp1DxHkltGVDizC4q0Q6fP1VN-toDmEiMLyBSD2xbytfsqpqvInV9wSmDTnF8HhAwaxVUbT7OXhu0HecwqziRh277Ktb9VrNxK_RpgcFCi3yZXkJ8TuETE3kRhtR1LrZGTCY7BrHxUIGUdGgxZVbzk_w3wv_tpqQkjY2hv4YakMEk4k8kN66Tn5niwRf0iG-SwpJRfiR7vbFFfsoWD72BdnopksH99bUft2AyL5xQ6OH-sn5rfszU3RAUPt_1fDopxm7oJulOTqfRlbfg4kMVpbb2BPi4VKgRdqF3yqJeidCssipztCT_F1bf_AKkJ8SnVG1mWfSfyUhqekb9mdT1-hHi5kiCcB73dgzP5BHawGNSlR4sI7QeSTFUV922I4tbNMxhkooI0vSBQKorxU4U8ShYXZ1CcnjSX2TXPn8snPhFD9eXDIsXPgEdErdR_Sn5PHLweuBLKKlaegxb_YNEumc3OpGRZxsAjsvlZOz2mnvOh0wVXyjT7H2kasPi5mHLJmTfwY3IlOIssaSUA-aCuXhKvNZbFdboFbPvP4n-OaZfrJ9WG2ddcSDsaueIxjCvl4eUAp2HmjYpraw_FdL0xlnHiXA5VEOQ1TiJj37-kzgUKgU9rthPjtK34PLGorLXYiXp6RxFgNCtNWEDn3p4d8IeAGu5afMWbB5mJVECQahCNsZQZ0wutaJnjlRWyxCl6bVZNFEudS_nxqCTnmqUR31d2dtzOwbjqYRp4rovfLm6lEO6J7Fw_DaQs-EFhqT_sZyHA0xJz-9GXHSWkaAtnWsgP40zI6cjhq0d4soRAvVsBQk3smH5BwXCicQC4rKckV7e-bN0v3ZEOKrbu8BmNrqWAoIiIXe805KnpkBcgEjT3w56dQvhrj4Vf965-agDnIBATzVIisHkySEkB7H5DmtTWh1X_ShCab6WWvGnvCtdQPO36179jE0K4yTDT7Qc4GEQtK70JJtJXYOYMYRTK3TyVPiLe7_3vo7Yw3snxT9Ow1nbcARBGaDuU1bfB0OGRLgB5XhrzEQGidVNh2kxOjtltawZFyW83glL1hGl5SPhF9yWfNalOD5DKOWfgbJlWLkG9eShbjdz5xF7wdKOn-oT6QZOP9MGnitgrbV-XyRY_u-mdnCoSsgjpFE2BrFaTu8WUYh0dZeI_660LQZfu8h3e1E9FPE5Adfmc3V94Zj_hVZ9HYwEfTfhcV2sisLRlxyRPc8wwRUGYqFM3jp4IaFbvMLcOXXwWCNqxBwhcaife3T-AAgKs70jNc6FgzFND5U0_v4QdDmYMdHau5BCOgxfeXUFrdH-O_vG2DCItSs1BRZX7brUbC_IeBFSHNCpJpMmidWCguckFtKxbIWQCxPtyC-ajpX0yx18SuenswUCNOJWlzK494maJDMDSLXmnXA750Lb7xMFEQKjEXtQ2lye7uerR7pHQIMsr90D1NxktIlCbYHzv9Ri5CZ4MrB0yAHgWM-hsTLGO2Zk6M4siQXqTCESHBbNbMYJhZncGOigJ7F9uWORMMtG3qTiBDS8WT6nkcGPQgvuAzcgvk_uR_83IVrWhbsK0VkMZ5hT8f-DbWA6xOE4XU-Q4fNw9rl19cjAOYYtUl6Ikgczhty4hHotdfMYRf20L7GBdQDNkSVdXQXYnagCl3p3GiZTDJ6WgYr40kNEboq5jC1AeSeSCn54OUAWE4JhBq4wtkvMy8b128t-aB7HSW1nKA8GdWXE71ofFUDaaStFBM7V9DLy6P_oPLnf1N9Q-5yBxiI2Gu-mA1dlLvkiauFHjgs70w35d5x0U9mT426NLpm_l4JWag_5Eu1inTrBw6fK0ILZ4UeKfeFhxcuPvKrlNXzprO52dgDJSIOfZv30Q-B9FYCYvwzCZ-Ytn8CyMzADjbXRSLqy1425YMiu-MX2wdW8WiXElfBt-sMCg3qD95kcCblemvuiY5VYFmG-4-jcDF8ak5I-AECJ7Ht67LjwchtAfpvf4F-Dc9qYZYnEwxWJxPg6Qy6-5POBNi2bMA-xVFCp-KmVmRbhJELwd7XylvAkAx6Ov4vt8Ql1HVIIbPxUKk5c5pTwaoDkwbAjHldDj8bJE3NRW9SVLoK_gzpdyRgKEd3GFZ787sJK3wSHAUXMom7XM1qdJHIiad5inzQLRYvhE2n_4eDqB7i0sH9Gk0vMNEyL8N7hXwFWFXL30Y5WWpI-JPL_Q6sSBqEc0dclkOl0ZeCYH1Z6_DqcNJRybn2oEi08Wjyfojl0HZkkbU76XzbvNvVCcjzZiQZEH7kY3_d48hOgDdxNvMgk_FExSd-7qeQJzj-f3UmjpIZppXZKQ0lXQXLEnGI1KX4aNghrOmTLL51KlEycKm4x3a0gH1ILy12_KPzTlRFSWhL4vX5MDiGXFFUMERNnC1qshrBTvQXiLKDNTQ42Vw-NwBnzFDVAZJsYw3f1U0LV7G8N_srCXyr1qIgbOICbjP_gnKevX4zQBE5wx4hiMWSHqmYXnnbNpe5vtPEGOj7wD4qF_H3U7jH94RLHweOEwCqAXTsBG9uJDNrI3Jw3H1DUmLfNTm0IEfpJW05V2WXMJepO1hsyfR6oWr67Rm1uRZGnIXKbr95UjJdjcPVg5hWNRtFKw-IWkAX7H68AEbjcmXNk0UfdlTdszEvhdKII2LtcCZYTiEMZeplvcRtMNZYK-FsN2Y9WZB2KVZkWbPaPX14F6DVM5zaLba3iqUTj2qgMv1fQdeRYYTINS3Qd7w0yOM6ob4c_RcYkdvw-QVIoe31YYgWodC5gSZlJ7HSXPCvg9MbLNX5mXsCS01jd-yIW-R26BFGkiW1gATTqWLdLtiOdUg0AjMuaTYaP0Gi2K6C5H2RFJcwk5YhB3UXEBveeTrZC2TMSC8hGElAyTZDFfRtK9EszeU29wPT4hQYBhKSQOwUpKOg7ieIkEWnd_exbUS2DxoR0fbaxAtziyw6urBwU6NanncYr6y8hDsWru_QyI1MtqNE2zKdnOix1AKBXubeWwaCjo0gD2grAhjLlTDLO82jPtTuus4oii1GHPzQL66V74lNZHH_flMVkqsmpm-x2KuR9C4DYYyOyH-RQ1-yNmIKB3VlYqMQb9vzLE1oOfCW7q_qJ_m_kr9LSzhMHRduPWn8VOm_ntsC9IbyjFQvLPwv8KtKFlrsfSeb50qpWcB_1OsRdZEO_pv60i3fG3wFawEeK6Vlq5oTEIsso-dsgNDeLJldpclsbiADSMbkVaQOjq75OjAT0ZVo0Kh-keC_hiqJKTlZojvtpRd5tj1Ag2sviXmmmcZQTe5fmEszO2v7L_8afjmxasmz_aOh66-L5rvJ55oo9kTvxddka9W4bJuzDlcMu1PsJ1Wm6C8q9d78mCAI0aMqE1GN4MjgVmhNWyMtJIcwcC6fGqxioCjJMGsIb-9wtuXZYJzVhpoQnzlzF0scqSmS7nFYjjT10fY_-ALJyKfeKPkarwG48N-yhO_I4ChCamRa6ZOMOSoTsoIIjqLBJOrFULCld1UA5l22Hfs0dZLYp9quyo9Y3J5_OyRfHfrBJtvEwnOAFYaAxhG3qvIFR8SIuYH0Gd65m4L87AR1JNscvPd22ySW5f_5S_lsVbFC33AFejPchzmkHrGz1CzeVuI1jacg5DMAviBVSD17CFxnNFAB15GWNeujQ7lD2DmrTPiYUq1Iwyl81Q4h-voPNfUqsVinroIXm7UvWvx2VGI42V1tyILHKl6u-bU49hWut3_qwnT90uCxG7CNozYwSR14h4GmiModkCqLA5rti8sdkKglv5JeBdZH31GAouekNLuYNc_bFN6irYMSr693YHvpsYJiWGzNnhFohlydzke6B5wTdKsKYasdvyQT_OZtoW-lc1qAnouTPlbAuTAWdVynloKz8AYVojEC1O9mv8_4pdyZ0771eOydrdX_aiBI84I—0azGjX4lCfmW2_mZclxGmQyco8PNIb1JbSjXgeVzG54Yum_cNiqmb9hX5UWt-NN1UBaD2PJlGSKXvzeT_LnVs2NkdbgxgSdAWPi6Mi6Hc3qF_9oyhTcRynQYW-hgBOX7xpFcPIlInvxnc4rWg5V2vCx1lLlNn_QPIXhG6FY5xIkpluhT5irUi1gKKN1rITe_LNavXygxRfB2kMFvUFIEgqz8WZM-K7lvG7VBkHdnLa38hVHrg9IDm93_It0BwrvEt6AzeJNlRysKNwgBy208hjelfcezyxZDzB7jkPyHk91ypZmytONq9Y0gKMzO9089FEH2U48bavvMvl1hQ_jjZ5n0KoycyoMXF-f1gPb3P_7_VDN3TtE0ZFd2i8aWECyLq0Y2ciYR1ekJeEZlSywM6vrfi3MdWoEF6fns-cu4kw2fWtxETbU2MGO3HuGAZQem4-wwhyuz9wHf_TAR_ld8PcNvOc1831IuyVydUltAeTfHI0Ypg6W_UJt3htacngRLenol42xIrlWZNanz08pbaSy4hMV0T4E6lT4eqPI0UtUbFOPixjW9B72xX-9jbSgDd99nY2HNWH-8sTcwKj52Ekrc6oe4IGJqE_6O_1bguTVw3eZJkTIshZpmNVqL8jTMANmUBMqpWQrsGRevt1NfG8jLPyrMjq1oriLKq0-ryxw58ePS-vZ7D8hLDaOg9y1uRu2okylkvYMI8B0HYtuGPAOym9J0FDX2a1ZSowbT-AniNUyZEgIDoVXX_B92bNhvAjO5lsMvVf-17SzbqcmsP51NGDE2ba73ly0jbCOFNcrZz_O6JVmPmLf_IjZdNswWPBbSQzhwbAZPYPtQihkXwwVsDru3uvtVpp4Q4larp6WCILpIbnf11fvjQ8kbp91795hTeB3t8ZezSqmaR1HcjkNqoQWub6wjm1_Sd24fZbQCRBWeAGuBQRAHVlhCkyR5UnMZtMffCmx6aXZO-LsiXTDvftaqD688My9kHDYAX-n8FAIQQkSk0QQtzmD4OYVF4FcK3c8jSaZ-CEPBxj6WmflQn9G8fdj_kvOjHTBh_6Bh2uLX2Z1lbRnUNwMasT2ow72usxc8FKhtndUWBD66QzpLsCEkIit5DhohQO-8KZMaGnzmCcOm4CoEtUiJeVmg-0U4uAdAwOMtt5vEScKV90jSvrnUVCMUf0OW65deYF8z1tLXgqFFwCNbnjITyaeo9ISq_XADdlGi_gpN4DXPAw-kzC2nuoDaXDQbjPbQ2Wfd47pdniixH2GIWGuEmT1CIe58AwkcoVTmEYJZThl9vJbnUKDNUFROPz0ecYLQdXsz-Q63eNjUOQ0ECL0lDhCbiUqFYPEIIAqJpzNrL50RMayL2-660nbzox9ePwOVKDbrTBFC4oMtUfcVhT3h04n1Gntw2kQjpZv3xpnLZlVXIxt0xLvDJxgXBpdiET6e9nSDd5DhZNiI9nFZjsKktLFeQXDOTifJtDvaiMjYrlDrq6wDNcYx60R75lAoruZAF4szyC5VY85tH6JhvuwB0GW80iaTH4Sq-6RXvEn_mgvzJoGIq_lk43ZuhxWNThk-t8mptOuopFFTccQGdsjGeFMrhl5zOG5TSdkuCFMQokFye6nhB-jnH4cV1XIcTVrjcepoEYdFVe0CHniXwCN5Cj-pfhWR7qP93HxhTYD479zkEUt58KW2UGtgEaXOnqrydqbiWoFrSGeN7ju4IwnSUXPARTS99_6WuiDcbZnso9pRKhc1dmdLApM5A9O4lqTPbyiMtyCpKnpgbebLDq6aEGhR_okkqa5ll3XNN6l6rERspuLnwiVfaQDidCVR3vBixg_BEqwks3rKFlvKwSb58zroEUmftgeUWqx2cHB0utqaVU8CGhe0-6jvPKYrNA1rhtL-53gKms1ccCB7txRWIFUFy2CaBFUYjUtM50TP3Kmc1-GGzJb1YmiSnqN45BqlS8LNnj18PTmEWFwarbbqrpYB3G_0iCLjegGdVFOmXpanZG6HVYCZsTp_Ik66ves2uMzuIfwFY3C0fblGG3zgcsZ8suB7wy0bnfL2szej4x5TEJN0jLT7Tq3ig6JDiujhbw7FbRc-8i-nv07Wfvmi9YYl5a3mWKZWVj8SJBPl4zTWEBDlIqJr77JeFSMNVxpx6GQRDKSOukvvrYX0aUEScEEoagRE9BDkCHPCAipPfivlTAaN0zSxv8x4XeDnaYgO58F0qVTxt8pZdWfoVkC7cOpeQYu2eSHc1pxM941vK0E-iRFrG6mtvN-MQOX4hNtO2RdT2kZWOnzEUwQzDu35-uDMqQqlCpqOEmZtiVwzDBhfOkMUdAA0OTvMTRH7wjvXNWq6QhwZUroEvvny5pTkiwCpGWqHeGa3fplV4rMLbcseiL1lfUynUJ_IXGhh0_Nn7tfU9vjqyGj9SpgOj_7L3F7Mcep_FPQLRzdmSnJNq6xEJ9XGosTwqoRQBNgyafruAuy-WpexMqmyD5WZJfk1IukCMLguB3oPFz5j5I9OebnyAcrqf4TD9QkGI11N_qIJD_Dm5hmmmKFfslVUGxR9MbPTfPJifBz9_YczXlN8DXZTu-Ym0tgrA5aAjylwaKcgzFhFpTZFvzfelGjdgMDA2l7N0Iw5d5I1ud5HT48nSmhniOuerJcbTdibny7HmFx-4JderfUKf7na9YYy4VwgQU1U_TqM28uJM8PsvWc79_HYUW-vFMwFNSWqcgGgSbVCAb3rcIQU09yqHynmjHXyD5ArOHnAQU1fw92Y1nfzpZkxxRXBgvnvR2QhZazktEDKTYwdoJlnSalRlc4anjM1tYru-GWneCEZj2niUDTSvmy2fao73V30vSFDUTZM6ngNyKSMKP-7L60si6pFJvv8nh0LpRI7HkCd99HWqKQz9XdtiSSJqvsNlOHV21IrtngMrqKqiybGRw3oQCt0o3qPKL8RVDaPXTG0mF8dCYKI2AwSY2SDQemb-DZPQuhAF-TdrckcmlRMx7WzHBiILJJYkCzW-P63FGe2A4O3ON_cogMbmwAwDvmR0W98BhMlfRRK8N-tOKT6fHr7DsMYkbdIDdpuNgIhJe4LOiG1qMF-3bfuhKc2ylT4RFTUFg4Ur3IkxhoJjKARDoqYF6BwSu3WrIFzmmwKbGwjG67gXGe2B7dWyOnuizWyU0p3jwz3ue1vhLLdqV1UslyBRes41DXPvWfDnTSOi2cJITTITxJkJH23exdxduP3UtRp5v_GD0bgnxj2UuDTiYWPO0quH4sYseR2JVkyAXCyBJg_T32YkMMi_wyEGz46rgm6Fkj3FlNS6H-sTXS32c5gIjC488IGvbZbTWLTAb2GuLolvXSqu3o2lQvAY0AWw-l8J5DYo_BJDBI2ZR3t6Ap0RcbLogKxlW-KS9oZAaX5s8fyggo6PxC-1mCpwUT5b97oiqSDyD_ouYUMYU6EEl7zNtm_4JWlqIvRjj8KeGAbWXtBsBFnvDwy7CHT7QW9JU7HWjXsUpVyRuK3Gp6LCrmsP7yjJpEwjZ6Fyp-CFKIlpM5pl-7mtHaqgsWb0Ee1xFwdqV5es9hqmcGLhJgXxdogBzk8Omn16q25vyMWSnoIhE0l1LfGo0FxiE2_Gwd3Mqi6N5e4fqvyLL8Rv5VxnjzePjoiFUylFAzUkUzTfbM9FvnBD5Sokh5y07G01maZMfKWXLHy2AOfOxJiU98CdMLSgqLnvTCKeB7Ql-a5dykEzieGXKx8-kDoDdZ_BowcH0UWtzP9RY1DDZOWjPe67A9mw02nOHWzxSeJVhOpoM4wsF2BdTVtp_w7kuvGKcoX5H72sb2tDGwntEli-WeLLO4jAkbEcoUuTFcUS1LmdaYSWx4gz45hWfvHTpYMNRDBq_7ez5dFZrUWV3bPArSvD23b-mOHfBhJFnvrQsXuEreQCvi5IaLJVVZogyuLDluGR1-v3vQzsV869mF1tcfi4QAgzRLtFzJnybylOL3b-WHkVGI43B3akF4efP4xK8aMvtXYCcDwV9nIkbcLqPBqk_kVyvx6b2gp8a5XsJRas8XqZgu2aSnEQ32mmt5KA6XgQ-P46UoPhr-wrSMa70j2wfKLNMS3x8HHUM5QnRa9X7jZC5PUQm_FT_BLCu_GKs0w2Wxvw2V9MCUETDlEPU7TUHCpPzEm9uQljrrojkamlclRt-Eo5e2g7rsJCxT9egVU0xZniAvfGTsfq4vlVi-cob6-vcmsOrn036-nv2C-NGNdb42L_d7DGq8exVdFYWe7hIXJKBILxTmzb014zqkrNVKB3uXVhR1sswYITuiJ79TCRUU23tfVydpljWPkzJWvukBevpi1Dv1LE4_JZRMjiSeAF3-na5NMqQqo2cF4RVZKELTREjBU8-ffBJwMFLg3miMKtqcOOdw6uQqMbUPaMa6-uSqPND6Z2cDSKMVBbkeN_Lhvty4b5UY9qCvMgX4IAntfu1Fp4GcC6CNdK6LpWoXxOqJb7bucpyTWK5Velguf_skgOeWJJo1T8Eq14gHsUtgAuR0mQnuMADjp0mHdQEJTiuXzZkLZdrkN4tAgbfIYOynMZuam0FCCrr5Oj7uAZxdWustdtT_e8_VXDsK7S3HbCmytYfobJU9dYQZJZjGBJZnSlesnM6FAMr1VuXWySGkDuSoHM5g4L7aKZIMTTCpazBYNUBCyEwiQHnTYtRpOWPWxGmURxjsWvzT5ie6j1gsUKndA_teAHoJ_izT1ZpHx3rzBMPfQktC97yqc2aH7Jdmud4kzdrOK1y-gb4i5zVSC_NPiMlsfTuTLQSIstiNbYvBe9FiPGU0OVSWM9HASOUdSEcUOkZsDdVlZfaCybqpgJtKNgmdnqXiTLIRmFw5FhWtJ6R1qtcZJNjKafHPAXutGEFYkLdvwV5vpHzr8SJnt6fK3aeflWqPOKETQUCwzfob4zIvn1CMSKP5kGkN9Mqq1F1IqkDE1GiWtMUD6zxFKPvenX7YqFq1WO-a4hc3bZnPHDmsROjAOnCuJeVhCDOGgL97ddOgY76LOjo4q7iQJRDoJioN20ADWzKuWGf6RwsObH4E9yQ9Gk2FcJUltawmkWHKZT1qJK4X3Gi3YPMNEqlh_BcbpYVp8Zrb4cB1M-Z5DojqY3edsRz8VqyHjYdXTiENGWrizF89kTx5QhoSLi9ZA-MG7Kxnq0PRATHNDHCrDmCqxmHhCOPqxpmAtyA8yrCKH5IIT669VG-91vfO9budF-RJlF6es9lhxlEvSBj269JNfIkCw5v_8rw_ktYpVcQHTcIpZ-5fFvG9SC6k2k9BNcRoD1IGhI1NpOAsr_0uSCN-GSo5Zo5U0xt0Jk0_zmOXSID75JA016BQf4PjSsSmSm391PZiJJ-VHoZoPiPMEkaxrnouV4iK7D2pvNSjDb6G8mClaAGkusSPYBtDOBVsizGW4yircs3LrolLWuXxjW5oF8i_B1-E2ejWYvagTs6_0qqR-s-kFhOY11pFinxz6h4KPfSqioLpfktMWEA_amGjFwlHci5g5vo7AhT8zp3SML8z7OcaX3Wq52mjZtZlbomaQY72xYOU-Mfy9mBQbs8rJjVo6B8Oq5Db9vyKUQowQgMpJzhqkNDgraXNkhuMI2xKUNZqalnsjv02ZduZF4m-FY38BuhkHRG1I6XT6duNkSS8D4IuGcYi207q5_8KlzGfANGQUD_TewkdCXSg1FcZr81Ajjnkb-9O9gH7QJxgU5f9ACpKPZSgV9TgXR62JyI-hfcG6IDVCewoDdkQVjaJgCEtDEjLySGCOuGcvv-sJQo8TCGrLe9l1SrHll-LWrED9j0Dirwres1yu81SB2hUkghPMHrKY4HtIzNTThJI_jBxwtyW29rNCXGgJQxlpIOddlSmmvoVODPztflh4imrm-09BLRVx9O4ftUf4ANjsk9JLT3iqrUHw-PIsbGOjlI4jEQkXXS8QIBB50aG6OJYS1LfvWAe5NS4P697IFcycEhjolOhQk90j_ASzigVNFBKFm0_HP9-SDVh5OhJAr9ROONrgpPafRtVVt1SMpSYT5BuwCgs1Eft1jODkLop-Fm7zcWigqbDzZCaStce5vhSpmekJO5XjtzZHU_SOvBnRhEwuICOJSzEiGR4OJlaCo_ixiWs5S-GF6-kKr-FkxqaOVUooE7yeEEQM0GPb88Mxif3vvppDQ-IQjNWNf7cXTMSwVYJZGJABtLdxv8Hv64zcxanpMiYTH3Gl_kJnQf467Acf-u42AyB6r42-1CyNXGagaZlD1blsranAdtii1zNBI8liZQJ6FeaOuQefhZ69JjRDvW-YnLntMsV45KgXOAHY7nV1L37eFVaMavFgdXQ6Ueh7mlla0XOo3FfrKagXXs0RjQg_GeZ6RgBBIJZJXc-ogUrFLhDUpI-4A7NsI6qmq8jtLoGJUaf8kcx19Ya7HeV9I3gZQ2zKWrHNyyylPxx7_mxC456eY8x3XJVgf4pAwI8rbFLK0KhkJ4yN5X8PYRHQDhP6X8C7hrtWR9IUPV-l9b3l5xdq6YtFdBK40ALTFbYgGisGacANGKKOmk-S0mdG56p9baLk-1EP2AnCnj-2puzzKTyRtSabRAKp3zhY0YNMSB-n7V4hazyD9D6ukNfA6q_UFtK1L5JDZkOIvurMivR8PvGz5qFkyPGhexB8EKqsLzdoKfeTeBRQrKApooh2iIIqicNYlyCViJc8ZqLDCBt90dVqFlDfYgH31QDCx1VaRXvZLLxnGlxeoKc0gFTh-PYQsaQIcQzufXnFQ0oQASERB4YLS2T1do3cayiYPf_Ddmhn5ol_P531u_SgHA0fnfwjMDQqSrh8Le5JlU20-DrO0BmbKIZh8QU6fuIZJ-Zie_oL91yZ9xC2HQw8rO2LFrkGiCHK2gauld4NIOEEycYZA_PX6kPk7qhRs6eKqlzGjcrpsRFp7Brrcg00qkgnA53a5CxygqvHrEUH2PEWxcv_WQm4qcIjWWaoXtObAJPHPt5h9cDyM2S2Egy2NRBQiN2kGaKsk5o-oBunK0dIK19Z8eZkGlZE-GzKjKYy40yTB8-ZkrJ7dSBexLW22TnsBALa2pYAyrjrXNsO_t3vX0gvBdSSDaryvWdtT_KVCgHrsgZ604D-JoPGtu6-gAzAwT_Ic-2ngfJ_ZeXXP3uywbN59xtyrwXemUAjSh6jLSQiyqEwcr2CQDu8Nxty1NqVGzyYIiTQjqBFcfd8qXWhj-YfmFlBllfxL9KrJHrgpAwXVyDORKj4HuTMMPvrpL9hucYtY_Nck_ySuUVPuIPE-1SlFnffdXgfhaj0rS9dmWg4_yIJeXZ6KbMLTYFZyDajNdmkHHtv3Lw75lrAQV2E2GLRIhRlwcoTpkBCPLNUSincLZafgdNhti9BqTY-GmujOAY-aNGXMn3Ua5Yu-qmD7exJmZUeC0ZYNYfcp1XR1cpLx8fU3lWT-lh8nwg22NNu6M2qubDkd6txH6NCXkPNr6h_8v5blOlWR3y0APTSEQDMKbHvdHEeXQ2IEUVD0aAZIwIwzpjuhYs8zfH5b7XoGrh1v72ZvDut7fHW41Azwc9EljMn-SwN3zvzaXZ17R7xRzbf0-H98fQrgUWIQoUHN3pyA9I2xMP5toiKbPHuoewNjGB8KxJr2pcN3K4d7CFwfsdG06q-V1jWAte-2pVXUQNKhRYAVsoDjZ0MeUZABY1xPiBTx16ujTGX3NmMm4cMq1hPfytLe2Li-EimMoUHA7DNU40Sz26NZKc_nBgOHDBNlx3gklAVtfrR14GwDLz_WT0RweoV2m0n5XKiEaItIbTOdA9KXS-0_3okcYtEUKvI318Mz1wr-1XEhHTPwHi1miWOdjvdc_UUbFEt1RnCiqg1JRRJnAkB4XZtbkC0pLvD2R6Z-7m31jPFdP9oGFRvCC4-saqbLGPEkwYvSeUXj5kTamdJhEplKBfOWrjILn0hdXgngy-SbP7Gj0QIqGClKI2FqOuiuFAhVHpxBkzj0Cj4Z_xfrfjHxvh_O6aHWN-32TC74dbv0ZiLkCgtQwcvMoi1xlr1mrl77Kv8mhLfrsJbbraG4eG0Shh5vyOTET2SSizXKu7doNAy8ZBKvzToH5IfR8WECfYTtxTS4tzBggJJCtyyjNjFMsTIEF6iqGIi23eJAZTPi_TcX7yng95_bkBkIw6r9Y9rxGHN7vaO-dN6m7prqkRmtUtDU7QhJ8clu0K7vhGX0K-azvY_MR7Q6HA1OgPVQeG1CnwvuJ2lA1PIHbDf-0lvEB1FeASb_YfFpUujjolSMEtBh28ELoSlfsNdfAyOgI7fRlzuiA-xP92hEVOV1BClYQBLz7kydX8JK5wbIVFMOxWdWxtNEE-xLelgPhHPjtKMi-U4PQpjokP7m634Q0y0BLG9QXdOY7ddApOOcZBSKoqhAK2DaGk8gqwcAoH0jg7W3fwZMwUMspLPSVUYz5Guxcw3maJhsKGtog8PAHVn8xL0zK4ydQUEYs_nWbLgTmOqK4WUSvx5perof1z2NEsXdVatPTrvLG0l-8KY4GZZUvFPF7OXMJAoey6s0h6nIb5V7IOOYlbMsy4zxokCCiNPQXcKVzMjW8_lATmiO161FmTw7Kq8hD28X8KuBM0nTJj71OqWX9A-ofYTMZG90NWtT9E3ocHZ1AAsCyKBHc3gYffgObinT1adxb1fPe5Bx6sOgANSXKQCFs_3EfNHmK-w-BHjCjS9Dssh13XMfURPg256480r_kZnHn5fop3CIOqnPACw9CWPwLVd2GWDyj9E4iajIaYp0-2eSy1sx-09Y_hBIF4QG5lxRSJVEeNhGO_YeyEWONT6l4872p83wjabnPDEkFJry2SRduY0EnfUJEhKd6-eZ3FmqnxT4dkL6hLwcp4vnEZjiiVscAKxYFIfyAiZ13XNJo2cpQE2XKa3s-ezvbWF79k2DG-oYsRPx9NgpfWcHhqvuuuTWZ-K9ZnHJsaXaJlJj35YEdNlXpPyZ-KqynaXjqZTJYtxC95GYymfRXU4pMdmP6l1MivwrvdnflgWR84oK24TXqKwEZMo0kCRz3xgateseBOxkSc51L5Sd2Iz3wFW4PUT_d39CFXVfE3h9qr8RAbDBzJ2xBSDJEg9d3B5XHa6ikZcM9uTFCzfFJdl137DVL_pSqA8xaoVqtJ493cVsLRWtqT9h1wJZ_3WQJ2QrHWkdXQqL_33QdJN-mzLs-njsiWOQhf7BpzNWRJpivYCAWT13jrF176qKZ_TdBU-kw8Rc1ghto_OazoGNHRo6u1kfA3dlsscSQmdGRBqStverQjb7B7y7LcnyCUw2Ck0uKOzPPqPs_v_19EZMuK3nVheSNGJxlVcsNqVk1rx8GRZhniWZ7-zrwQqHOIh5HQTcjHHcg74-MuHWH3IIyzRed7bd9eWEKloOPHJVbo2jxo7-vLgpCox8BvISmOxeJ93HqO3BezBDkgEU9FZVJXsPkRn7AD6s86UR2Qz42xMQtSK2gCZhRfuU9OQ7CPn4QE3s81sTShE29n-KoDtU18eIxTriATM5q3JbFZvVK0vNhbHPQU07WPo0VXENNI45aQAObrpnWVRQVAvAFB4PN3nl4_PTgOyJy_mCNZKmuVC9ArCjQPIsCC0lpqRUj6RDe4xh2-l94YSDOrSHMyBWsjNEeXsPHhtgK4QpearKsIDdQukni4bI-uAUb7QjYKdgM_17oVM_98isGGKfObeR5VPGHfNTD7bR9U0zpbVKlfHg7IiMkVaikj8vLD-1-Nx6g4erLee2H8yPBTfoXDOC5zlPmpT-6UvaRWxGUs9kuBHxgLdvmF5j2R4vZap099jca7_XQBYzPWYOd8rdDMapGBQYMoYKy6O3b-5KeNeXEYpNWabNXaX-5wQe4cR7zBSqewAUNHQ-aXY4OamZuneWkcvlqWQzHA5LyE9Ug5zb0nNP3OKeaHi6O1ynhaOEhgzgVyRWSr3euov3iNcswgSziLvRLr6EMtt4vMMwOIQ8YG4VjMQRqBujQkKNOKcKhVJ9a96yDDG1p_7Xpzi9BiWSQUjI-cWTCKtVmue9ZqANS-Iwj7kSpqaoG9n_eiabFe_WICabk3Xg-QBE_yvwfpbBaEaANhDavnnRfpEr72fX8Nf6JuYEOdCuLfqgQQGPmn23AlCjOPD_j1cyD8KUoCAdXK_BBQ23Kx9rHOr2z0e2lQpKgrgE-0WY1t672bAUpQZDtf8fEnc68OkXesXYJzg625MOKlCM6l4tyhSbc9RSFwrnhzF6sxuMSVyQWYnM4eGJD5vODSTOCJH1yAfmIWzO5k3MghupBYCn0914knqLUSvFdzVe_bU34g7qqTU_DzcxFe4AbkavmcksdraNJiSJkrLsDk-Kn6rlg4bQgl7i-pzJhSDjsXS1x3YjAdoYswDx1D7Zp_O_5y0gOr8s9MSvwFtV1wx_hWc1aeAQKoG9vJUV4YDY5UsdL_CFBECWCXNdcnXGb3g92djKfxe_2J_RcxhldOODK82DEawoHf79LTs3-D2Lc3c967sxMpFRNovijVrEA_bmGFuM0tlHEFzwip-NT-XxCR_Fa7a3ilWzESLtNQeivaMFysyg0AHsrMbf_ORqpNGFrHIz9DRSzHY9QeJj_6zVCiTaZ7asEjcjFDFmzrKJ5og38r1cQKYuIumXq3uSoI4S8rnHA5-cToeWayNTOM1OLH3l_ipDM_diLwjIppH0jD7XZJu27nvM5YXH4gJYKtXCwHHxYm_U6gp1bZkp7kwmQnM803Vp2GiK7VWCPztbvMgKCc1qOg_qXJzPe4V31-bnopw5KbhDgTxRLy1IzMNczl2fXIQO9xyAU3zqOYMnmrxQ8if2XbjjpNTT9czWNIBVxS3r2Y39MkGJwX-BJIcMbYJAI64z7uaIAh1r7HM11HyyEnCLeu7pQYU5u6sdD8Ae4DvDogkH5WOiwn9or5Ku8v-wPjOxPtKnVa4qXarUDfQhH8iwAlwQQVEFp4TS-S4RTrewTOCQOJFUy3N_e2rcTja_gArOq4bdwcNB0WAKDjDVaUFauOz9N8tPsF3sL_Uk-lXFYhuHJ6qU6UGhY5vzUWEQ7lqp93-ZlA9R5wLA5on0vnV81FPvA5hk-2OjP_NYnmub0cI-2Y4lj_6JXHSs3zoJCjv076hrbjxnT3ZQNDWuT_ONZvmivCgzTBF-4LqXTxK4OVp088QABFL4sQKjOovUABQcZVWL8eU8iZiyEbctRYT_YBKc6S_NyPR8g0_5omDy_4lj5ZlR28MqVJEkCQZ33IdhBxntGPoqJWy7TfiQcI3_sALbexK7NySnt5qvPDBsWVnKyYGJfOueO24JYmRxXpXVvBpN7WEyLSQk_OQeS1lTbzinR7702vZnF_e3x_rIOjsfQOjs7Tl6gKg8Q7xGyrqrDS0EuhXAyARbc1hwVrkz2B5WZv724APp6b-TatIBnU5Mby5VcgdwZcjdc4SiEsuwwHmrMDSaojuAc3qyIuVZL1qhGV6U9RWVe_dk-6PkJ5BPi4edsL4PaiXvaRul9D6fBlDJMM0RoFVcRLihDc4Obv1ULXCTnu04HThJAR55bqNr6OpaQtqPVV5pA9A1m_grUnLtqDWyKNgMMEM_nrGOISND8qW3Mu_0AB1ZYDqQS6Xr1qrXiaLWalBQo1o1IVTSF5oU8-eSFZZx0THF4V0BwL1fESbh8sFiT0FBCfV2wkY8qVCIPiTiujBITCKjNLQV1jIKvWAzdRDlnY9DbisRsHdQ7-qTAina3Fc_LEN-LtdWDwbtdFk7ITUQe0bTv1wpwDgV0BY1mjZqpTfI6ycazfyfnCkChAM6cXpF-rWxW8tewkd_MyjlO6nWtoVpJNvi0GCZOxvnBH4F4vxxTy1TpI6wRPytJC8hPvFu0PNF2whvEDuZUcUK7cLCBD1FntBAxNqThCrCk9NqINw_FvZdelTlkx7aoiwtLSaT68l9gRTahR0iB6wpdbnakB7sM6tBAQll5S1q15BjDSK_u4PZus-k2Aom-Sy9d3KdYXFjeixvQYLNGEf9pDtfBFHoi8UqNNkbPyjCF8dPXRAmsWB73zpRXl_MQopG7JI7ec5sQRDA19eqNqEjTAgFWiA8m8qxI_DfdWc_EAnZCtC4kIMsD4ynw1tC9MaFdA2kKS8SMli5mK8a3TPKfYMmPFxinxfhG6QmlX_eBp-xYNrxmY0TMJBSnt8cSIjuVoNW7fNmgO_JQy4uSHNMzceRTaiTJxvBvWjy_37HypW0kFHwnWsl0ufi9XKJwAxeds-HShFe8wCOFA1WmUwQZoM-IGFXgHSkbxICaqObwfXIN_mDNbZTI_f1X69IBz0PV6cuZO-oYpK9QlrydFqTeTdN5s_oZsFydc1D5CzDCrIozrFuhpKi8vuOHI2hS-OcyESN_k6HkUvFlCb7N0Xa7l2CEarkU87gnobA_4-ZIVFhc_pTK6DA3zR6ysdoTYamJvLSHL6LOkXthbj3y-MS1G-s0W8_aHeJBU8ROnVB7IhFXA6xMB8HQ0fMH-67LLfZxrqAXFC6lbswKIdPcCOauaF_nPy4J3-4UuOrGdM4f665DmQouGlM8XmU-C9zhUHLz71Jckza_BDhxAvOylnOmeAj8IzwNMGTzt95WDuUSxznzNaVEuV-8II2gEV5zdBni_G0TdwlX3IUrs0viD0BwMUdDKsG4V08uU3U2ao2w-awqd9IvFaKuXNPtYXmlZX1f6uHRVrP8AID3_pBQ-BR801sgXHU5LZG54LpMJ1fvtpn7TGijhnYRwMcQnzk9Qm2qh9Gn0Pc5PA7omyZSyL2nbFfdjXd0Lqx_FGfDxv8HlZs7ts62i47-f8YlrS3lC61vj8EywPnGIKds3J86TD_BwO8SUeph1zKkGnUvhGafCiLhzoHJsT05ak1SG5cwL_AFd5CTsf6bRwLx1tkBbHMDkdlB5LOCmGNWirt47Qq2gOH-TuAPIGKC6ooDzBd_WKgKN0VKSUhoKmll8moYonucZqEGwpnU-kjo50L_QOXfS24-QS8qQ-8UDZvcB-2AmzH7EUIJuT_Y1ymPNLEoxsfWGJgPP85jX4yC6Qcpe7pd0_CQpl9bLzV6LFggTPcrGPAZAAt_OV609HmBrlC_k9iX8vHt3L-81Kux1GZXVWI-dGijpMrRz-dh5DycOkyGrCJxysBbXVwh1ii_EmBlwbx6VhcC5hOzCPprY5MoAmFBdSVOliIK7eSKJGLwJTiS0tpTeLi9NUyAkDJCvFwmm7SmoAqh-WZ1PikfCRxLaP1vcZ3MO5FOFxh7vjJYBwmy0YvS2V6JcsWVrP0drkTTPFb4x11Ta124z5KKRhbDA348OVzgWnwLlNlDQJ86KGrXmmEko-rlIgNiSIS4bagAWtuhFO-Reb7xHxADivy21Zkl07yzhDkSZID-aSE4fiUmR4kA1_eEfgDeAzLoPDvK3UK1vEBqHsYEPXW0NCsItSr_wG9kZk6qUUj6mDT4EMl6BhxioWQj4zj2QgDL9L-e-4U1r-0oT5HdBsJtmpk-86mJdlXB08-B4a6s9_rqr1-8W5kPzcB3t1iY734JPwSJ_qFdshf7VhlNd0u0GVZZV1vHwHQDaS1piXABURZdmBrJdjG11ms9Awyii0w1WFqsyby7gBnElk1kq1PxKojwiSO3e5qjuEVFcrptCziuqwZ2rPq4bwB4OoRMR-HNxSqKbgueVnsc1ACBCyUDN1p7rJE169g4VaWlyPvcO5xrVNpRFwaRK3go7wCL6kXWh0WkdIFznNCY_zSKKOMSuc8GhPdLcO7PCdPZ54xciPmafAvASRLIYnmt7NIV77lsZ9HU5s4yQaYwnlCwJzwN3Vh8mfjhF0Bql-Kbot1Rkd6vdW2CuECWioTh2H3fDjevALElTEu3zMULG2YE6Npq3vEzRRSeTIW0OBeyRuIBWZ-5KNif3fk8iLADth_pXUasCUughIJxx3E0zMsJl61gzqMHPAuCQaO9TOrH4zvgfuxGX1npxaZIgONF3wLH-SOaDFM4xq1GOFGEJxidBy_eX93jWZ_pPHnVtijcto48gCcjVom5nFwZDgnylq0WnBK-BCYlG_Du90hrNlKB5yO48G8Xu1b6QyS7MkIyL_V2HQKaqyVtwSU9dvI-o9zVCTjZT7BzEZTrjaVrxuoxLaJMlBEh_tHjo08IV680tgQaOzoX5Dbbuev_9LGjTAhLalmw-TaN7eusWqQSVs3wbUjk7BzcGImCIqrIGWbeyLnJfoz7BWvMrOL1ptjgrUkHVRce9E4wiq2xRXcW6GXIdy5YCmTcBPhmfeTEimlXJ3YTOumhGh5bki0H7mmExsTfuUPprAHrhJUORCHfYcOxL-rwBqak_Kbj1jbuJI5BS1KPRduwsJ5Y5g9SbO_cOQTKh2iqA53eypWZB6DSuY3W1zykXACu_mWtv5p9cGyUwhRpHNf5t6mfZmqhNX1qbTzrb8Y2M5eW9QFE5fFSubbiB4iOZDVAS4t1-OsP-aXSm04TGfXKJksa9uYoK9KobnJeQMmPkHSPeU2_ul3ulU6wskunw0ERwjs90OFsvcQFtpQ9ixO9a6BCj8xrf_sxT7VlbQkIDICE0lB6WfSvrKwF1kunKXYElq8u3Jxeysrfxl_8oPzH579g3EIIdJZnx9od0eOdSmKjkU7HVJOOqds1HOQYZbvJ_EKSdNekqq7WS3tSPiMNyIuztouzNcdR09fGEkI76qZluxcC7RghstmBwA7a3GAaCupNFJ9u1Eg7x506-NDcGm7C3xuUQ2Z_nYeXbB95W7gdWnjs_-1XFnEABFildkXcCcW8fJePC8w59_bEMBnxTCj6iI8RiDd3aBfXuhlNDGBKSc0yCm4QegW7qkSi5zS21mbI-lNZx-7g6HqP2jJuu2HUmKKzy8samULePulkhUs3Bq-r4r2YN_CyYHEv3LTVghM95F-QheC4gj6—UPOVGggNnRsNdlnuxTtk91a258FBJA37i7DZqPgxewbLupPn2qxiVF_NPIcwzwGNp7X08aoSkcYypPGMnLqixmoWDPaV-ykzpNj_a4wD4KUfK_k9FqKtfmg0G6KRfdhrSKJbpu6enUItZvm5QqlNSJkJPLDiNP4WMS2ut1QFC3vCoeEQOqMxIkyxeamCOGf29S1YdVktdmvQDFD-L_Dh71XsnbOv9kreiNG0HD2i1AL-ezQ25h30WhQpCE_vcv92DSgtB7d2DGq4p7OcF5ikKe3vF9G5EVAfql5GPX0yOt_vXp4x7q_td6VBA13kvr9sz4MoyrrKXj01lonOySxwJPTeT2upsOQ1_Iiwva1zP3KTEaJU7Efn5RrlrIeqO5zKra1b9JAMnpNMAkdX8SknFLN5yfXYvAV2-kwt-cng4qY9RluT9z_ltIPWCDEUIMck8k3EKYfp-YRglJwAl2oIXG_mLBgIkJdjeLLLgAsnctEfPvDRhpIuv_MUGR0f4dcULxyNma5UObUpwyxQC1_D44gORHWEiYUeagL208ecXtpNpLBVZ9v7aLLOrTav-4SiDJZDD6bk_mVQ2t_Xsp-RCe2ylzzxD3jJ6NPb-apRt5MNLw4e7OrFWa9uvrpZ7z4JAWVVXvYy8idFK3COa25GWh4ZhW8lt88sL5G9nshwm_wyxaSIyuoSebeejjaTGsDRbhf6Cql92rh4wIWBP5y1kRO5YzwHRkA6R-VsaVkoVikIrZ6LsSGPWPevxVtNtbKSbpK2QiDeqAMSdKaHj-S_Z2cQTwl1K-AviHZt8-zeU0AQcaepi-u4dnpFtSxjCrCTJPwIMTazXwj64GyKzuEo2VgtRF3_mcZ9z1DCYUTKFY1d2xOMszy1fNqylz7MvAMFhl9mvfuZdUn5iXr4GVrNGfSjONGfLzA5DaYij7tqpZgqKYvEboFts6XP0ZMqpF-btNlOcGB_1cOYbmFzphDpb4u9u_LylCsTj0d_Gl4El3TE8eZX5HTnM5udIQLI-AfHGJGQfyMtnl3EzFP5fwbznKqsXEnXpVW7g7huX7p64xFrie8-vm50CKh8l5xLiYGrxFa-v4JlK5kKygWiqCfAWQUiktk7XHiWHqaeX30VGvnZdOt2WMHkD86sN7otgOqDqBgQ06JRHFqsKRjZBdE906AW_xjHDPb1pfT4BcWSr7_dOnFbJHFSeyd9wjKnsycHABXRTRPleabCaakA1RyhiApj5BqQUhVI-NpHs8DnorsQDgjlWSdrLVLXXAqxRNUuu6BgfGRqjl23_6PbKXoWPHktF05ScCqB5bc6baaNCsN4Agxz6xiqwTE9UUEwgW_mFpAY9L3f9dVax-xFgQO9URrofZUIswlYd-oJVCThiNh9URWGScm54Z6DBJnoeHC8rWrNYYqp_G1KNiEpKC_hNDjwmsgJnspwGv7Uq4UyTrhXEDTowL52IY6mJ-S5s76DhlgGWXKtgjqcRlVzM-sGng-idOFZAhIwRe0MLEpMdbX6qI_L183g2-yhcTFRQ73T8OWxzD3MDI6uOBqEAnj3HE2Z70CLpTT3QylMwD7g_Ds0D_iIerA_AAuUYp6s2ahLR-6SD6FToDiCFeRaDBoroF3VbWJxyMDHGjTtVbbADPdxtp4eN4GZskp0prJEhBD735i2Dp-1ZfiXQqE8J8g03IwE9OznOvg-5Xq2_N39JuhY7vwNOyWwn4WLiQ0RQyDFac4UF-RnoZNYqAFWuVQBPbfquZbwyP85tEdMbW-fx5I0qFjF6pEEoxZ6XUBn2xhmUjLTc27IXVsUf1p7Uo7oqQEIKHZLLiFTp97rq1x2lmNYBWx81ZCE2I1difoZiE4xGdVSQZqv2bvgh8H_10Q-HKkv7CSE1Z7Oy_jv6_m1I8sJD9_xcMfoYzLIim60rXlcfeviy2vPFuz7Sty2A4L2YektKhJLJzcnCR9dDZzQl6FlhVeiDp4_jiEH7XrCc_bcM1_67h3-v8DImjZvij8fOGGSabK2GkIOVzPaBKse3pjPV9VajRzqhOTM2Oxn7gX-LBjMg_Je683GGVhZ2scyMOhb4wy0t5MGSfwdQDOInG6vwtKZRmvljI61zY-JVl8fdDgSqhFxJOqij81wOufucjCuFpRb5_Lptt8fo9LKH5dB_9ybUt0YPVmgWPdfyOdobmi51_IX6GckfwUHsbea8uevIpCqorfKRnZCL1V_EOfghDkQimrj1mofFBodw-sTcMIu9M5GWD_PGvvT9AvlGR7puVGn51mzkqOOAP7JZnbxA4rWH742Nwjd1n24ecdQi5REEM4S18hqUZy6Ccdxx4ibtAdlXC2FNUhk4jT2hSxu1pdsly45J-oERfRNLLaxp_9HUed5y7HCd5tx1sGyEO2cMIPUfWjnAw0-8ZdIW30j374ZiPcQJW9lSA2ygIO95SZkbuGEr78wrEnmJpgq8gVWTJ2oojMVGSbMO9NheWbXEPmV9AW1J1mvrtdvlwR-PAPKypL9c4eCFb8vIQ6vJkuo3NH2PJeP90LAdf57hzn0FgTDMuTadSfOymLZ0jiJDv7xpqeE0cCE_F22SfySPc4vabbH55TnvwgHGLKmhxIfhMfSZsibY3oMiNx2S3MmqEho_E7tblDlcwWHirEgUfNeNfScTwNYQVjRG_vlgXeB2OSTC7eCiXvdTIhUdG47HNRnTGqP8yqExJjYUboJore_cwDEcTNl7xJnH4eCPipViw8IikzLNPEK0Yj_UJTOlxwQM4ug_BYkDEOlWYSJQq1UMJaGMe7ScFNsuYs5T1DhoKVfPrSrYPqDSNqRTA0WmsipyT6dmSwRHtlzWQNcWRwYj4gsqcA2lqWcVllaCed0OtYYjlllVTL9QozHQKK50FvGC4Sc-Pp2dwTaeKscCZZMXwR5_KyKFVlNT6S5xyd9c2LiMKSqi6ku1psQhLpG_mIpZkl1TN0sG1FEin7ZDViFglU86M7vl7PsO0XNh2e7cKGsolupfFNeJgkZTpy_CNsnLeiNgJWYk1vpO4cKxi2QEPd7choYL7HxQZ7FFHHguTxHkSO-93KZLI4rEAPLN4hQW5IPZNfKqSpY2iKL1X8wkY6ZbKtLSCADZ1ttcjVUG7YjxQDQGHSHjKtFbCjvti4J2YupjiHwFQqYswgU5vNMlfutja4mc2PFZrmQwJ3QRQMCPU4CubAPbW1PTqx_OcJShogW1k_-XCgmhYdsXifqo9TuhdxV8i3Q4dCC0s73X1YmeUSHmwkgdZmIRwaDcQGGpOJBu8gh5jovBYP2Ez9RIjTrMBExf_WiV4EAffXTkOLxzaZ_3e3JWiBobx9Z8tFl7m6HKkb5xs0neDEZiNSXpcgcE_qVcasaeWx9hk8fGDrI4TkEdIOyTnvLq2B2H6asfdQLFpnTI3kohnmvlfZzj9h6AHrbDp1ckalrACBm_mXwsBQO1T2_bHvtf1s3CRpWEe_5u18zkISJ4lz6h0GvJYHnudV52lVJ8QgUJnb2hq2ZlRgO_NZMyh_Wu8bxLlpGRFH7rMj7Hy0cDhWjXwhSixGXOD-OPrLhv4NRyhFu9UKOlRZTKxNGB0tOM-mUm3PQ8N84cy8Vkf1Kzku_rVSfMgz_4AgULj5jtwPOjCy_ehRHw-c9Y-XGDgzaYG1OGxyzr8ZzaGY7e2ikn4kS96fr4o4RVeCdW0AKpQUkcIywQu3ECJCdAxo2lt91npmKfmo05_Nc_vGfT_VnIook_dJeLMmfVvd4cwrGrVEmyA3KUc_1vhpXgqAOHDc6w74_wsHtp6wWgrr1z4rUlZfQc3NeXZZlJ0X-1VWOB0MU-4pOIOv3tkVrRRy718MGTx67XMdC9ih8OKFjyRMewzj431l-H7bfAuKvQqnrGt_B2DgeFDolCBCvkSj6TkHF0S0XCzXtqwON-8O_ufJP5C0jXpcRi6f7dYw5UvSvGlmHA0hhxTGeK6EBQKLObb-G-BIwLdTpHp8-algCpWiL5QgF31-y6hccGQzSbuaFIeU9XdqDWllleoCtbtsZGjl2tEaAKbnGEowCSl6xUy7lTm0R2p15ixRmKREoB5Jw5l56VbiWRI7UezhodIeciBiDoeFoGyeF4GuVy5hviHk3Xvd9LST4C3hbF6YxQuYYsv1CSJbKN4=";
Trying to install version 1.4.3 via bower doesn't seem to work. Crucially, this is the version that seems to add support for AMD, which we need.
Is there a way to read compressed data with compressToUTF16 directly without decompressing?
As you can see here (http://en.wikipedia.org/wiki/Base64#Implementations_and_history), there are various reasons for using different chars for index 62 and 63, the main one being using "web safe" chars in regards to using base64 encoded strings in the url (as + and / have specific meanings in the url).
I currently run a regex on encoded/decoded strings before using them as a workaround.
I suggest providing a method that allows changing those chars.
If you'll approve, I'll fork and push this functionality.
Thanks.
Hey there,
unfortunately we recently discovered a bug where we would compress data, append it to a URI and then be unable to decompress it after parsing the url because the compressed string contained +
characters which were interpreted as whitespace.
When you check the base64url standard, the _keyStrUriSafe
map, should actually be
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="
without the +
character. In fact +
is a reserved character in URIs (RFC3986).
I wanted to write a pull request but was uncertain about the consequences for backwards compatibility.
Is there anything I can do to help?
Cheers
if we can guarantee that the original text (in our case JS, CSS, html templates) is ASCII, this should potentially help achieve better compression. Does it make sense to you?
Have run into an issue when using the compressToBase64 from lz-string.js and then trying to use the decompressFromBase64 from lz-string-php https://github.com/nullpunkt/lz-string-php I have tried 1.4.4 and 1.5 Beta - both seem to handle Base64 the same. The PHP is what is current at the link above.
Most of the time it is fine, but on some strings it fails. Think I have tracked it down to how the Base64 is done. Appears for the PHP support has been added for extended characters which is causing the issues.
In testing, found a simple sample. "ABC".
Compress it with JS and I get: IIIQwkA=
Compress it with PHP and I get: IIIQwkAA
The result from PHP will decompress in PHP or JS just fine. The result from JS will decompress in JS but causes the PHP code to throw an error.
My original sample was a much larger string, but the ending of each was similar. JS ended with A== and the PHP ended with AA=.
Any thoughts on adding extended character support to lz-string.js?
I have a use case that I believe is quite common in JS frameworks.
We are using LocalStorage for caching app assets (js, css, html templates, etc.). To offload the main thread we use web workers, that xhr the app assets from the server. Ideally we would compress and save to LocalStorage in a web worker, but they do not have access to LS.
So, we need to compress in web worker, pass the result via postMessage to the main and then save arraybuffer to LocalStorage. To avoid expensive copy, postMessage allows to pass the result as a 'transferable' arraybuffer.
So it seems converting a compressed arraybuffer to utf16 needs to be done in a separate pass on the main thread.
Hey there,
I've run into bug when using the library to compress javascript source code. It's extremely intermittent and doesn't happen with every file; looking at the instances it wasn't even obvious what was causing it.
It seems that the context_dictionary can store a key called 'hasOwnProperty' (which exists in the uncompressed file) which overrides the object's own hasOwnProperty() method, which then errors out on subsequent runs through the loop.
I've worked around it by using the strategy outlined here:
http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/
Basically, calling the hasOwnProperty method on the prototype rather than the object itself.
-m
Thanks for the nice library! But while packaging up a version for Angular (https://github.com/carlansley/angular-lz-string) I noticed a test was failing in Safari. The issue is the apply is failing. Patched the my angular version to use forEach instead.
Failing 1 spec
37 specs | 1 failing
LZString uint8array compresses and decompresses all printable UTF-16 characters.
RangeError: Maximum call stack size exceeded. in file:///Users/carl/Development/lz-string/libs/lz-string.js (line 263)
decompressFromUint8Array@file:///Users/carl/Development/lz-string/libs/lz-string.js:263:61
file:///Users/carl/Development/lz-string/tests/lz-string-spec.js:69:38
execute@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:1064:22
next_@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2096:38
start@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2049:13
execute@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2376:19
next_@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2096:38
start@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2049:13
execute@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2521:19
next_@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2096:38
onComplete@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2092:23
finish@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2478:15
file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2522:16
next_@file:///Users/carl/Development/lz-string/tests/lib/jasmine-1.3.1/jasmine.js:2106:24
when the encoding string is long enough, there will be ONE Character size difference.
for the following file:
“hello1hello2hello3hello4hello5hello6hello7hello8hello9helloAhelloBhelloChelloDhelloEhelloF”
compress("hello1hello2hello3hello4hello5hello6hello7hello8hello9helloAhelloBhelloChelloDhelloEhelloF").length()
1.3.3 ver result length is 23.
1.0.2 ver result length is 22.
1.3.3 ver add a ZERO character at the end of the string.
This issue makes the "Porting to other languages" on blog cannot be achieved.
AS:
"
Port the compress and/or decompress methods from the version 1.0.1. All versions are binary-compatible and further versions just incorporate ugly optimizations for JavaScript, so you shouldn't bother.
Port the (de)compressToBase64 and/or (de)compressToBaseUTF16 from the latest version depending on your needs.
"
compressToEncodedURIComponent: function (uncompressed) {
return LZString.compressToBase64(uncompressed).replace("=","$").replace("/","-");
}
replace can only replace first matched character in compressed, so the compressed still contain '=' and '/'.
I'd like to store (short) compressed data in URL, after hash.
Could you add [de]compressToURIComponent
? Base64 should be encoded, thus lengthening the data even more...
The title says it all!
To facilitate cleaner integration with bower (instead of using the latest commit's hash)
In the demo (http://pieroxy.net/blog/pages/lz-string/demo.html), after compressing the readable text, clicking on the LZ decompress button causes does not re-populate the readable text.
(question, not problem)
I'd like to use LZString to pre-compress some long strings for inclusion in JS code, then decompress them during code execution as needed. When I run compress() on text in a JS console, it produces what looks like chinese or japanese characters --- IOW something I can't copy/paste into code. Is there a way to get what I need with LZString?
BTW, the code does great compressing my long strings. About an 80% reduction in size.
Using ES6 Map
for context_dictionary
and ES6 Set
(or Map
) for context_dictionaryToCreate
instead of a plain Object
speeds up the compression twice in v8.
See #46 (comment) for test results.
Map
and Set
are supported in current Chrome and Firefox versions.
IE11 has partial support for them, but that should be enough: see «Map → basic functionality» here: https://kangax.github.io/compat-table/es6/
I haven't tested the speed in Firefox and IE11, but it shouldn't be worse than using an Object
.
Supporting old browsers would require some kind of feature detection.
npm is currently on version 1.3.3 of lz-string.
I'm looking through the code, trying to find any way to speed it up even more. I think I found one way (at least for browsers that need it, like IE). I see a lot of loops that use the string's length. Some browsers will recalculate that on each read, so it would speed things (slightly) up to set a local variable to be the input's length and then just reference that, instead of the property itself. Also, in compressToBase64, the while loop is testing against length * 2, which will have to be recalculated each time, so a local variable would help there too.
Also, great lib. Using it to store a rather large bit of state information in local storage with no (as far as I've seen) issues.
In Windows 7 (at least), LZString.compressToBase64
results in a leading space character.
console.log (LZString.compressToBase64("{}"))
This will yield " N4XyAA=="!!!
Hey there,
It looks like the hex output on the demo page is incorrect. It seems to be swapping pairs of bytes.
For the string "ab"
, the hex output is 82 21 00 32
, which is 130 33 0 50
in decimal.
Whereas LZString144.compressToUint8Array("ab")
gives [33, 130, 50, 0]
.
Could this be published to npm?
When trying to use LZString to post to a Go HTTP server I ran into invalid code points being replaced with the unicode replacement character (65533) by Chrome.
While this is addressed with alternative compression methods, e.g. Base64, the drawbacks appeared avoidable (and I had already written the decompressor in go which I didn't want to write again).
I found this could be avoided using the Uint16Array type. A drawback in this approach is it's default to the endianess architecture of browser - in my case LittleEndian. This could be circumvented with DataView.
See implementation with tests here. Minified version not updated.
Comments on implementation or a more ideal way of handling this problem?
Am just wondering about the feasibility of adding some form of passphrase protection. Am well aware that it's a relatively weak form of protection but increasing the level of obfuscation even by a tiny bit could be helpful in slowing/ deterring would-be crackers.
I've got a fairly contrived use-case whereby I am using the URI-safe base64 methods to encode URI-encoded URIs (my SPA uses the browser history API to produce completely RESTful URIs and every significant action modifies the URI and then decodes it to infer application state: the result is that any application state is bookmarkable and shareable).
In this scenario, the core decompression method always returns null
using Firefox (everything behaves as expected in Chrome, the only other environment I've tested with any rigour).
After a bit of stepping through, it appears the core decompression loop always manages to reconstruct part of the string, but always eventually encounters a failure switch case and returns null
. I suspect certain characters or substrings are to blame and I will try to isolate these for a reduced test case.
dfhjksfhjas fgjdhsaf lSDFHLF ljljkahjdfhaljkhfdlknvjasnfhlHLEUYRIUORWYIUjdkjhafkjdhfhjdafclkj:
93 characters, 93 bytes
TO
ӡ䰥䃌析䄬〡Чᡸメፀᬡ䨠䐣ࠡဦ⩡ਖ䃄僠⽴てྴČǚს眯䕠ᑠᕠ፠ॠቢ⁜䙠㪴䋬⠰ⱡ㖇䘫䀸淢ࠠ:
44 characters, 128 bytes
HI there, I am testing different methods in Lz-string to compress strings and store results to localstorage.
it shows a good result of compression:
Orginal Size of sample is: 148920
Size of compressed sample is: 13349
Size of utf16 sample is: 14240
Size of compressToBase64 sample is: 35600
BUT I noticed local storage tab of Dev tools in chrome would be freezed once I store compressed string produced by methods: compressed/compressToUTF16. There is no issue with compressToBase64.
Any clue?
Dummy code:
var strings = "........."
var compressed = LZString.compress(strings);
disk.set("key1", compressed);
Thanks
This code:
var x = '601141b710b1f1b8a916f51dfbb3006fcff6b9d22a278ae1b39577fc769f19117bb4a1b87028c1d97b1d1cadcb0833a0000000000000000000007e2058e704be20dcbffaa883cca0ee64f9e4646985321a110f1e3e9ab96bef86768e958fa793f569d03fe8e18cfe74ea9e2772942aa734c3e761efe7b919240c95c1d26b563b591be9074af935899a61f0158b674de70eea061ce0e7cbf00fc799180ec22d5d6fb769cda33332fe646ba9002b2f9832555f9a5e904e4bd2f43cfoofoofoofoofoofoofoo15153e156fc9534bafd6b5d66fc6275d 601141b710b1f1b8a916f51dfbb3006fcff6b9d22a278ae1b39577fc769f19117bb4a1b87028c1d97b1d1cadcb0833a0000000000000000000007e2058e704be20dcbffaa883cca0ee64f9e4646985321a110f1e3e9ab96bef86768e958fa793f569d03fe8e18cfe74ea9e2772942aa734c3e761efe7b919240c95c1d26b563b591be9074af935899a61f0158b674de70eea061ce0e7cbf00fc799180ec22d5d6fb769cda33332fe646ba9002b2f9832555f9a5e904e4bd2f43cfoofoofoofoofoofoofoo15153e156fc9534bafd6b5d66fc6275d';
var m = [];
for (var i = 0; i < 50000; i++) {
var y = i + x;
y = LZString.compress(y); // Without lz-string: 17M. With lz-string: 900M.
m.push(y);
}
Takes about 900M in v8 and about 700M (inaccurate) in Firefox.
That memory is released later by the gc, but the peak memory usage is very high, and if you increase the number of rounds even more, gc will kick in at the middle and will slow things down.
The x
string in the code above isn't special, that happens generally.
You could test the memory usage with console.log(process.memoryUsage());
at the end of the loop in iojs/node.
Using the 1.4.4 version of your javascript file, after I compress a string with LZString.compressToEncodedURIComponent(), and then call LZString.decompressFromEncodedURIComponent() on it, it fails 3 quarters of the way through not being able to find an entry in the dictionary and returns null:
} else {
if (c === dictSize) {
entry = w + w.charAt(0);
} else {
return null;
}
}
Any idea why? I'm testing with Internet Explorer 11. The decompress call is below...
var test = LZString.decompressFromEncodedURIComponent("N4IgpgliBc4G4EYC0CQBoQCcCOVY4QGpUMBnSGEcxAEhJAGMHKBVAZXSzyzFIAd6pbvTgAXSgHsAiiwASAdwBqAJgCuADgAW62QDMAwgHFCAMQBsAEQA2AEwBymALJg2 + 0QGY7ZgEYBWOLJsLABKDACeAFIAHgDmALycfNzKAAxoaWnKAOzKAD6 + aAhoACwIymXpuWAAdgCG3lZgNrkIRRmVuZ1duZw2fJQAggC2YJgQDLUA9HZg8gD6AJoSmADWucq + ZikAGgjFxSnrxUjKxbmimKpguQDqENXueQjqAJwvuY9nuYcAKpqqAAIIrVqgDlOoAQh3NBfAhoAcAQBRNg - MEpBBmD4pQ41JDsc6Xa4XK75GIALWUMUcVgssikCH0 + mKUhWtXUcCsAAU2CZMCwJBFisETEIADIREx2CwxBhkgDSLGKcVJFKpNLpDKZLLZHM5P0mpCkb3cFj4tQQUTM2AA8j8bmSFikYvJlbldLUrOROGB + rAWp1DocNlsWu51Fl1m6srV3GYXspamANt53Lpii9SuozLpsylfC8UgcGC9dN8y3kg2WA5w4L7QGAhpQbLU4BAbAABYm8WpDPiNAB0DAkjYwfE0MGqqisVjIojAlFhANFYQk1VIAJutTCnAY3Dsy1EmgBA2qNgkcFGnFI4lgjgGiWYsHR6mKvl6jdgXdIPb7YEHw84aoPxACwWzbAE2FEfsAU5CBRkwecMHkUhKE0URRD4aBJkmeRcP7L8fwHIdGwAXwwGxHwAbSKZQAF0MAuGAuxIoA");
I noticed a strange behavior when using LZString.compressToUTF16 (in JavaScript), sending the data (a compressed string) via XMLHttpRequest to a web server written in Java, and then using decompressFromUTF16 (I tried both proposed porting of LZString in Java).
When I do all of this with Chrome or Firefox, everything works. Instead, when I use Safari, it sends the UTF16 string generated by LZString, but, when I decode the string on the Java web service, I got a null string.
After a bit of debugging, I noticed that:
Are there issues in UTF16 encoding in Javascript for Safari, or it's a LZString limitation?
Firefox localStorage
works great with this compression scheme, until you restart the browser. When the browser restarts, it seems that the reloading mechanism silently changes bytes resulting in data corruption. If you're experiencing maddening corruption issues when Firefox restarts with your localStorage data, this is why. If you always clear your localStorage
you'll never see this bug.
An example from my debugging output, the "RESTORED" data (data put in localStorage after a browser restart) is 442 bytes, here shown in hexadecimal, the base36 number that follows after the ! is the sum of the row and the one at the bottom of the column is the sum of the column, I used these just to help me identify which data was changed without going blind. The original data prior to compression is just JSON.
The "CHK" data is the original data saved before the browser restarted. There are two errors in the restored data in the second to last row (yg in RESTORED, uw in CHK) in columns 6 and 8. d9 cf df ad
has become dd cf 5b ad
.
"RESTORED" 442
82 37 7a 20 5c 20 c0 08 0c 2c ! jz
36 c0 72 02 ac 20 03 d0 90 35 ! r2
44 26 42 03 54 00 40 51 00 07 ! bf
6a 46 09 c0 b2 8d 4a 5b 19 03 ! op
3b 60 97 26 bc 4b 9a 01 27 67 ! p4
8e d6 2c 34 05 f8 e0 33 da 10 ! xq
5c 39 62 95 04 61 00 40 48 99 ! lu
5b b8 e7 73 0b 93 e5 09 48 a7 ! yw
9a 9c 34 0b 13 d9 cf df ad 1c ! yg
35 64 a7 a1 9a eb 72 7e 02 20 ! vs
00 f9
----------------------------------
0d 07 0a 0z 07 00 01 0y 01 0u
" app.js:63:172
"CHK" 442
82 37 7a 20 5c 20 c0 08 0c 2c ! jz
36 c0 72 02 ac 20 03 d0 90 35 ! r2
44 26 42 03 54 00 40 51 00 07 ! bf
6a 46 09 c0 b2 8d 4a 5b 19 03 ! op
3b 60 97 26 bc 4b 9a 01 27 67 ! p4
8e d6 2c 34 05 f8 e0 33 da 10 ! xq
5c 39 62 95 04 61 00 40 48 99 ! lu
5b b8 e7 73 0b 93 e5 09 48 a7 ! yw
9a 9c 34 0b 13 dd cf 5b ad 1c ! uw
35 64 a7 a1 9a eb 72 7e 02 20 ! vs
00 f9
----------------------------------
0d 07 0a 0z 07 04 01 0a 01 0u
"
From https://en.wikipedia.org/wiki/UTF-16#U.2B10000_to_U.2B10FFFF it appears that
0xD800..0xDBFF and 0xDC00..0xDFFF are the values to avoid (at least on Firefox) but if you're
going to share compressed data between browsers, these values should be considered toxic.
Would be great to handle streams on the NodeJS side.
UglifyJS does provide a stream output. Another example (maybe better) would be JSONStream
Do you think it is possible?
I am taking audio samples, which are stored in a Float32Array. I take the buffer data of that typed array to create a string, which mostly creates chinese characters. (Just as a background information why my strings look so weird.)
I thought I could compress them using compressToUTF16. It works in that way, that I can decompress them correctly afterwards, but the compressed String has about 150% of the original size. This also happens in your demo on the website. Here is an example string to test it:
'㢁촘㢨㤓韇㢮ꍖ력孺㟀�㜻₨㖠അ룃ꀨ룍Ḵ㚡৷떌璀㎢ᗬ뒙튦㜝驝㡸糳㢌ᑺ㤡띋㡿獳㢀驆㡹갃㤚㡰笲㤄운㦱ꉿ㥺鮊㟟哜㟧Ť㚳쎘똏㋉㤀ᰬ㤁렆푓뤔랶㞥ꃪ룳篾룃ऍ뢺뤦䂮뤞ﺼ륺富릡푮릕䫴륉壌뤬猪뤇﹑룞ᱸ뗑떎搰㗒ꃂ롻ᄇ뢼෯룥�률䦆륤䋈랦㢩껜뗢曀㓏㢇㡱㛂Ŝ뙢㲟㜗夸㢮῞럎짽㟦㤰⨆㢢ᒤ뤉뤜幰똢ꌘ㖦솆뒱ݠ㒪涠㑳뛌邾㣃䖳㢴ꭻ㟨蹌럽ौ㟐㧋㟷Ⴘ㥏慑㦊⣺㠢籶뙞聬㠼뎺띅䧤㜨럩潼떘먢㔪룤뉶덧㓦닎脐㎔䢀㏖떍뛙렲䟊릕ጼ릐徾뤟茱뢼诂뢿ꗬ뛵�럆䗑뢞鶦뢖�㟠㻶㖫㒗㖜꿠딹幚㟙ꃳ㚫䒬뜧⃢뢹丿㡏迄㡱쿿㣵툊㟭嫯뚅䐀둌㢷銂㥤ਦ㤟⺶㟁⡟㞽蕊㡿ꀋ㠻袠㡜歹럣㇑뗘渤㕂㝄㍁낀됷椀㎞㗹圔뤁롶齌뛕ꄬ뢇필㠉䪪렁ﴀ㛐裏뤛쏖룑㠄㞪럷�룞뤖茹뢷猪㡿Ὓ㣻肤㠲϶랝핼㠹垊료谦뢎㤔㟆㗹恀똕쌑룃蓱뢸斔릥혂릂�㟦뇒롄庴룩룃飓럙औ떌㤌뗆鿨딶㱰㠧㳭룳쾎뤝펌뢶㛑攱뢜ᤑ㞈秢㡖羟㙷Ꮪ뚯ႎ㘩쿚㡯꜇㣻셰뢎�뢞㞂뭒뢥褌롥钕㡽⟲㠈羘똃㟌톒㢉烀㝔춣㚦竘㘯笒㟵㨚㢅썤뚼쫷㠍麵㡺炀딌㻀㓶蛰뎿﹜늞鱜㑫嘘듾ᙸ㘙鿷㟳狠똍禼㣇ዧ㤘ᕼ㥂떉㣸ࢆ㢀仂㡿㔈㡽⸞㞙㨴㜒듾㤀渘㥞㟩㦐㤪狾㣄Ӫ똦쒭㢫놘㢃㡱⬗룘틎뤝뫲뢂竴뛯쏐㜙뇅㜛뤆ᠷ뢞萍뤃弑뤄眢뤎㘝뤛鼐뤁Ҽ뢵栏뤢笰름뽶뤉썲럔⟢㠺壊롓埿륄攍륙롹뇌㢃ⲟ렖壟똼渄㠿剮렗⍹㠌呞㟌뮈렞٨뤥졌룾딨뢻꼰뚆颎렯暝뢳䙞똩턀듾䠅㝂숖㠈痉㣼빾뚃⿐㘶읪㡲騖㢄볨㖥㋗롾�㞺탥띝ꡠ뗕ᘬ뤀ፔ㟧२㕶籠땃ﰴ럏찷뢗롫칎㜱擋㣧�㣹㗚뜽Ǩ둔귁렅㧣룃ࢥ뢊呐㡃馵㤼꽛㤴ߐ㡸瞘㢅̥㣁䟰㡻藨㖡똰䭖㟓蚬㚀뒱ꮓ랁츂룅ꮊ뢽斒룓ẉ뢁ᑪ뤃驭뤛歚㡦롢㠋䯭롴揖룇虘㛹熞렯벧롏窴뢪䫟럡욅㟺㕶䁒둗װ땋ꐺ딉렲涺뤁ϐ㡴ञ㡒車㣂䝘㟡藂럨遍㚏拂뗃Һ㑭䷳㏞π㍌儀㍂ㅐ뗀鿇㣜ꯆ㥛㤄룒㠀ᒐ㙦鮋뢱ࣿ뢀썪렫逢㞤的렗㊁㟲ᦴ㖣蛕㖗䎳듌ᑲ던쀘눼鉀㎗멐㏺秜뗰㻢㢇贀㡞ᜀ똏룄倂륿Ȃ뤃娾㞕飼럂펒뤔륧�뤓쏄㟩깯㚹㠁攍럳呂㟷愥㟆ᡊ㢡婐㠋埛랮겦㡠豴략᧴띥룬ﵫ㞾供㣄䡺㣹쾄㢺ꂦ뚝ဖ㘕�㠟㣾㞠蒒뤄뤞薀뚾漽롇鉟료긓련徃㠖┋렵뤄䴜롥锐뢄蜐릐∃릠癬륈嶚뤠䇖뤊赇럎㾸띪扐룞䂪뢀ಮ㚻咦뙧壖㠆殍뚼⌐㓅髦㣴餑㣼轋㢸酁뜊筤㢐枒렕⏰㢅ୢ㥽陦㦡쵧㥩时㣿⥹㤀㢁곾뚝ꏇ㠬ឍ뜋瓩㚣筆럼螵떒⬊㟓궖㠋䍶렖鐱뜑렗렇ꀈ㝄粘㝛团뚫ɠ㠗좿㡱鬋럣朜뙥蛄롖괅뤃%뢐�랤赮똷㿈뗀꣔㗆ݠ뗯疌뤲ʶ륭Ὰ뤋簓㠤첨룻䡤룄銊뢾尒룁⛥렄斻㚧쨶뜋녤㘙呂됺땉㝝◪㢼尘㓒儸㜒䬰㡵侙㠑钎뚻㘤㘑垀㡨騶㢁⃓㢀㡫쉏㣑怇㢥䲼룏썢뤝䣬뛅ẟ㢆뱲㢀㣧Ɱ㤚瀿㥇挈㞑Ⰸ뚂峺룎剧럡₦㡿竛㢁읆㢂ﴂ럑懊똧䙚뒄쿂㒦䲮댕지껗댿됁똜㖁쮀떋�렣릘㶌륛既룺⠖뢎�룀뢼ᄐ떃�롦ﮂ룐₨뢹쉸㜷䳆㡃ࡒ럸珀룫蠦룧X뚒柤㠊⡸㡺묷렒�땥並㔈㊀㐅♩뚂㡲㢫왝㡀媘㖾饾렉␚롿沈㚵ノ뤞뢙퀩㟃偌뤑㹛뤓�㛈顰뛒뤣륝躅뤦뢊㠨㡢둶㡉䘒렗켼룕㫌뢄⚼랪㟕嵓㤠瞔㢱攆㢋㤩풰㤺ҙ㤉皶띮원뙋꒤㢎흿㤞ᾨ㥟敀㤢ⁱ㢞㊈뙙稘뗞汦㢆펐㡗霸럧〟㟫쟈㣆㲇㡱扂㤊퐋㠘ퟥ㚎뢜藶뢽㎰띐㗶㤋뜣⍶㙁秚뗄詘㍹Ṩ㏆税㌩杰돁勴듐槴㘡뇪뢎뢫땓㟾썒렊舺륺�륂涧륋槈뢽ዴ룇暴랶꧀㔲娰㛊袆뤇籚률䤎뢆㿬똚젰㔇ﭸ㐀湒뎉觨뇬ƈ㌤㏕骜딂䴀㏡軬롵걟룋憒렔㠉葤㡃媀뗀䕊렆ᕔ뤕일㠃ᶰ딍⽬㖸ب듩⊀듈Ỵ㞗㢂裳똀樸땖�렬뤬㴝룼㢆緀㤸䷂㣦Ἲ띧襃㖢Ҧ떆ֻ㟖湾㢀�㢂튰㡶宠뒀韠딅ଗ㡾䩮㣜⦄똚�㣯㣼㢹菘뚮ꗱ㣋⺖㣄뚤峙㠣뜢Ꮸ㚈뢩簓룇䧋띪ὰ㟕駸뗻笏뙋挸㟲徰㖦꘠룗چ륤绢뢅襉㠏䎎㠈뢧鳞뤨䄭뤷鄿뢅緒륂⏖릃흅륓モ뤘ꥺ렰∉룇锊뤦㴲뤭㛞뤟뤠䒂뤟㍊뢗�㜕ﳔ떹㉴㕆ᥰ㡰埭㢛♩㠏棾㟙⸀㗞诊㠈属㣅➯㣧셄㥴̆㤇佪㤪与㤩쌇㤲闶㥟㫍㥀ݻ㣆쏄㢀º㠆셺㣙沊㣚兑㠑疣뢢뢥㢃ﺔ딉뒽⾤㐚�ㇸ騄눟�뎨䫠㍋騪㔝ꌰ뛹ᙎ룑न㜸寄㥣䕆㥇俪럎肻룃曀㝄揩㥖䒈㥙巊뜂砒㠄턜㤧惵㤼脗㠎㺩롪Ц랡ɠ㢢ږ㢊㡷㞗萎럐欸뤂㇖륇릱됎륂뢉袲뤁웅륇쓫릐쾨륀쥅뢷酲룍뙲릢°링훚릾릴ﮛ륂䧦릥匈릹镶릚뒰륟鲰릘鸢릋埆뤿媰뤝띦뤽˖륮懲뢗ঢ㠋晾럆廿랛豲땗囨딀က됷硸㢀愌㣾ᅭ㠒㍺㤗汰㤽㑨㤈猗㤞蟤㡨⼒㤨謾㦁�㦏㥣㣂㡳ㄎ㣦㣖攎㢱躷㢀䡰㣈歪㥚ꄆ㤄㡪昐㢃朽㢁㖤㡃緦㡀⌌㤒훶㤋㬥㥃�㤽㣠㣳⇰㠒䔺㡳薩㢀ἣ㠫꼐랿⒃㢢宷㣪�랈뒂㠍轆㤀双㣊恪㣵䕲㤋㟛탴랧覕랪䢄㘍塓뢙鳐릀㒥뤠饸뜅뢐릓玢맆趾만뉯맄ꏰ먀맼矾맏럒릿閕릞瑬릟n망䭃맹甡맱鸗륿韧륲㜛릫ሀ뤶เ뗄럣鄔륕ꁰ릓浂뢻뗀룬㥨롆䨐㠗⎼㚣菓㣾鲼㥄䮢㣼턛㢊㤮诰㦉䑄㦧蔜㣶긬㢎끘㥁꺃㤽︼㡽싰㣼լ㠎䲽㠄䑂띖䞧㢈㡛⤠략閘뙘⦤떿屨㗪ጙ㢅㦨땼䇜㚃踀룀$㟆壡럀쎎뗭憼뛨罸㚻ᣲ㤀ಲ㠅Ɪ롾ꬤ뛷큚㛴䗁㡑磛㠙墆㢢㢭㣾᪑㤀᷂㤁摖㠃竈㟋⺈㤡㤁ޞ㢙狢㠗頻㡇魿㡸赓럮卆㕤ඛ뙱⏯럑䮒뢌䬏㞕룓⇣㟬틒㢪㜒煠럚뤀쫣㠊퍃㡹架㠖붔렷ꨘ룏앦렭咗㞦℠듡ﵢ딜皴㐻ਠ됎엀돢羈㘟둩뤒�뢮쟄㞔먴룢ꌸ뢻�롎ݻ렚鞤륛숰륂耄룵켗뤉픠뢫㚶뢻ฏ뤨뵳뤠ஒ뤠אּ뤚㡴륆뤟ᓩ뢶䵽룓ﯧ뤷谯룼侼뢆ẖ㞰렴鲛뤖༘㟬詤뢁떳ꗖ㚬㟜�㝨䅔㢮뤺㢰�㡓ꨰ뛼ⷰ료漢륾↿뢾鹈뢍闠㗊㟠룞䓀뤟흌뤟ᑔ뤠�뤟鬱뤠ⵜ륂걔륢姢뤽ᄘ뤊犸롑�㝿객㚣⼰㗤ݛ㠖'
On IE11 we can save a compressed string to localStorage.
But if we refresh the page, the data is not present anymore in the localStorage.
Seems caused by special caracters. Some caracters fail the storage.
This caracter breaks :
This is working :
〮⁜ॠ똠猂頞耎ΰ䆸ѢƜ逍耖iꀍ䀡Ǥɐ᷀
This is not working
〮⁜ॠ똠猂頞耎ΰ䆸ѢƜ逍耖iꀍ䀡Ǥɐ᷀ꐇ၀笁
Could you add the project to bower?
Thanks in advance
Great project! Did you decide on any license for the code? Could you please provide a license file for it? Thank you.
I have a JSON response, about 700,000 characters. I stringify it, then compress. The compression takes about 11s.
However, when I paste that same stringifed text into a textbox, grab the .value, then compress, it only takes about 1s.
Any idea why?
Hi,
I have used this without any problem to compress and decompress a string running in Node.js, but when I send the same compressed string to a Google Apps Script API that I made, and try to decompress it, the same code doesn't work. In that case, decompress returns null. I have verified that the compressed string is the same length at both ends of its trip. Maybe there's something else that happened to it on the trip or Google Apps Script treats characters differently. I'm not sure what else to check.
Do you have any ideas why this might be happening?
Thanks,
Dan
Hi!
Would it be possible to throw an Exception on error instead of a custom string ? I would like to be sure that an error is in deed one and not a compressed "Error" string.
Thanks !
Would be great to have this on JSDelivr so we can download it with our other scripts (via JSDelivr's concatenation feature).
See https://github.com/jsdelivr/jsdelivr/blob/master/CONTRIBUTING.md
Is there a way to detect if a string is compressed? We are looking to use LZString in an single page EPOS app.
Ideally, if I supplied uncompressed data, it should pass through the decompress methods clean.
If not, signing the data with a prefix ('LZ#' maybe) and detecting that, would be OK, but I don't know how to determine if that could be part of the data and therefore a false positive identification.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.