Punto più importante: le cache dei browser sono volatili e i vecchi contenuti vengono aggressivamente scartati. La tua scala di “quanto presto agire” si misura in minuti fino a ore.
Supponendo che CTRL+F in about:cache trovi l'URL che stai cercando, lo script sottostante tenterà di salvare tutto ciò che corrisponde a quell'URL. È completamente automatizzato. Ho scritto questo quando what.cd è andato giù.
Se non c'è niente nella tua cache, congratulazioni :( sei in modalità “hard”. Se volete davvero riavere i dati della vostra cache dovrete far funzionare TestDisk http://www.cgsecurity.org/wiki/TestDisk ) e vedere se può recuperare qualcosa nella vostra cartella della cache. Se i dati vengono ripristinati in modo pulito, potreste essere in grado di recuperarli da Chrome, ma potreste essere bloccati cercando di analizzare direttamente il formato su disco. (Potreste avere fortuna nell'alimentare i dati recuperati al visualizzatore di cache NirSoft.)
Se avete effettivamente qualcosa in about:cache, impressionante!
- Create due cartelle da qualche parte, una chiamata “file” e una chiamata “raw” (o nomi simili).
- Aprire chrome://settings/search#Download%20location
Creare due cartelle://settings/search#Download%20location
. 3. Cambiare la cartella dei download nella cartella raw
Aprire chrome://settings/searchings/search#Download%20location
Aprire about:cache (lasciare aperta la scheda delle impostazioni)
Premere F12 per aprire i devtools (nota - ignorare eventuali errori di Content Security Policy che si vedono per tutto il tempo in cui i devtools sono aperti)
Premere F12 per aprire i devtools (nota - ignorare eventuali errori di Content Security Policy che si vedono per tutto il tempo in cui i devtools sono aperti)
Premere F12 per aprire i devtools. 7. Copiare tutto quello che c'è sotto negli appunti (assicurarsi di avere il gigantesco mazzo di JS minificato alla fine, c'è un commento “fine del testo”)
Andare alla scheda console nei devtools
- Incolla, aspetta che Chrome ti raggiunga e premi invio.
Ora dovreste avere due pulsanti sulla pagina web della cache. Digitare la stringa URL (non regex per semplicità) che si desidera abbinare. Premere il pulsante “raw” e divertitevi a guardare Chrome spazz out. :P
Ora andate a cambiare la cartella dei download nella cartella “files”, tornate indietro e cliccate sul pulsante “files”.
(11. Ricordatevi di cambiare la cartella dei download indietro)
Ora avete due cartelle piene di dati.
Se lo script si è bloccato (si spera non sia così) o ha stampato messaggi di “salvataggio errori” nei devtools quando avete premuto il pulsante “files”, c'è stato un errore di parsing quando è stato deobfuscating i file, e dovrete grattare la testa attraverso le versioni raw. Questo è solo un problema di parsing e può essere risolto modificando lo script, ma non ho idea di tutte le risposte che Chrome può sputare indietro in questo scenario.
ATTENZIONE: i dati grezzi includono informazioni di intestazione HTTP, e fate attenzione se li state inviando a qualcun altro per aiutarvi a recuperarli.
Un problema importante è la decompressione - sto usando una libreria JS gunzip casuale che ho trovato online, potrebbe non essere perfetta (anche se dovrebbe andare bene). Se sembra che questa libreria si sia bloccata o abbia un problema, commentate la linea JXG.decompress() per salvare i dati in forma gzippata e vedere se è possibile rigonfiarla localmente.
Un altro problema è che Chrome si bloccherà quando si apre la cartella dei download perché sta tentando stupidamente di rappresentare il testo completo del file scaricato come stringa base64. Colpendo la ‘x’ su questi download si eviterà che ciò avvenga.
Si noti che questo salva le barre di avanzamento come ^ (caret) caratteri e sostituisce tutti gli altri caratteri proibiti (Windows) con “#” nei nomi dei file, in modo da catturare l'URL completo nel nome del file salvato.
Di dominio pubblico, senza proprietà. Migliora a piacimento; è stato costruito in un paio (3-4) ore (il codice è terribile). Testato solo sul mio portatile Linux; potrebbero esserci dei bug :D
Inoltre - molti complimenti al team di Stack Exchange per aver accettato questo post da 20KB+. Ho deciso di portare all'estremo la cosa del “non pubblicare link”. Detto questo, tutti sono i benvenuti a correre via con questo script (e speriamo di migliorarlo!)
// CC0 | November 2016 by i336_ (asmqb7@gmail.com)
var ui = document.createElement('div');
document.body.appendChild(ui);
var iframe = document.createElement('iframe')
document.body.appendChild(iframe);
var dl = document.createElement('a');
document.body.appendChild(dl);
var list = document.querySelector('table');
var len = list.children[0].childElementCount;
var save_raw, dl_raw, dl_files, status, search, entries, donecount, url, next, save_errors = "";
ui.innerHTML =
'<div style="position: fixed; text-align: center; padding: 0px 20px 20px 20px; top: 20px; left: 20px; background: #cf0">' +
'<h2 id="status">Type a string</h2>' +
'<div><input id="search" /></div><br>' +
'<button style="display: none" id="dl-files">Download as files</button><br><br>' +
'<button style="display: none" id="dl-raw">Download raw data</button>' +
'</div>';
status = document.querySelector('#status').innerHTML;
search = document.querySelector('#search');
dl_files = document.querySelector('#dl-files');
dl_files.onclick = function() {
document.querySelector('#dl-files').style.fontWeight = 'bold';
dl_files.disabled = dl_raw.disabled = 1;
donecount = 1;
save_raw = 0;
next = len - 1;
findnext();
}
dl_raw = document.querySelector('#dl-raw');
dl_raw.onclick = function() {
document.querySelector('#dl-raw').style.fontWeight = 'bold';
dl_files.disabled = dl_raw.disabled = 1;
donecount = 1;
save_raw = 1;
next = len - 1;
findnext();
}
document.querySelector('#search').oninput = function() {
url = search.value;
if (url.length == 0) {
setstatus('Empty string doesnt work');
return;
}
entries = 0;
for (i = 0; i < len; i++) {
if (list.children[0].children[i].children[0].children[0].href.indexOf(url) > -1) entries++;
}
if (entries > 0) {
setstatus(entries + ' entry(s)!');
dl_files.style.display = dl_raw.style.display = 'inline-block';
} else {
setstatus('No data :(');
}
}
function setstatus(text) {
document.querySelector('#status').innerHTML = text;
}
function wait() {
console.log('waiting');
var dosave = 0;
try {
if (frames[0].document.body.innerHTML.substr(-36) == '</pre><hr><pre></pre><table></table>') dosave = 1;
} catch (e) { }
if (dosave) {
setTimeout(save, 100);
} else {
setTimeout(wait, 100);
}
}
function parse(rawhtml) {
var lines = Math.ceil(rawhtml.length / 76);
var str = "";
for (i = 0; i < lines; i++) {
line = rawhtml.substr(10 + (76 * i), 47);
for (j = 0; j < line.length; j += 3) {
str += String.fromCharCode(parseInt(line.substr(j, 2), 16));
}
}
if (str.substr(10, 8) == '1f 8b 08') {
str = JXG.decompress(btoa(str));
}
return str;
}
function save() {
console.log('triggering download');
dl.download = iframe.src.substr(25).replace(/:\/\//, '___').replace(/\//g, '^').replace(/[\<\>\:\"\\/\|\?\*]/, '#');
var dl_data = "";
var dosave = 0;
if (save_raw) {
dl.download = 'raw_' + dl.download;
dl.href = 'data:text/plain;base64,' + btoa(frames[0].document.body.innerHTML);
dosave = 1;
} else {
try {
var dl_data = frames[0].document.querySelectorAll('pre')[2].innerText;
if (dl_data != "") {
dl.href = 'data:text/plain;base64,' + btoa(parse(dl_data));
dosave = 1;
} else {
console.log('No data while saving: ' + iframe.src, e);
save_errors += "ERROR: NO DATA WHILE SAVING " + iframe.src + "\n";
}
} catch (e) {
console.log('Frame load error while saving: ' + iframe.src, e);
save_errors += "ERROR: FRAME LOAD ERROR WHILE SAVING " + iframe.src + "\n";
}
}
if (dosave == 1) {
dl.click();
}
frames[0].document.body.innerHTML = "";
donecount++;
setTimeout(findnext, 100);
}
function load(index) {
console.log('loading ' + donecount + ' of ' + entries);
setstatus('Saving ' + donecount + '/' + entries);
iframe.src = list.children[0].children[index].children[0].children[0].href;
setTimeout(wait, 100);
}
function findnext() {
console.log('findnext');
s = -1;
for (i = next; i > -1; i--) {
if (list.children[0].children[i].children[0].children[0].href.indexOf(url) > -1) {
s = i;
break;
}
}
if (s != -1) {
load(s);
next = s - 1;
} else {
console.log('done!!');
if (save_errors != "") console.error(save_errors);
save_errors = "";
setstatus((save_raw ? 'Raw data' : 'Files') + ' saved!');
dl_files.disabled = dl_raw.disabled = 0;
document.querySelector('#dl-raw').style.fontWeight = document.querySelector('#dl-files').style.fontWeight = 'normal';
}
}
!function(){var e,r,n;!function(t){function o(e,r){return w.call(e,r)}function i(e,r){var n,t,o,i,u,a,c,f,s,l,p=r&&r.split("/"),h=k.map,d=h&&h["*"]||{};if(e&&"."===e.charAt(0))if(r){for(p=p.slice(0,p.length-1),e=p.concat(e.split("/")),f=0;f<e.length;f+=1)if(l=e[f],"."===l)e.splice(f,1),f-=1;else if(".."===l){if(1===f&&(".."===e[2]||".."===e[0]))break;f>0&&(e.splice(f-1,2),f-=2)}e=e.join("/")}else 0===e.indexOf("./")&&(e=e.substring(2));if((p||d)&&h){for(n=e.split("/"),f=n.length;f>0;f-=1){if(t=n.slice(0,f).join("/"),p)for(s=p.length;s>0;s-=1)if(o=h[p.slice(0,s).join("/")],o&&(o=o[t])){i=o,u=f;break}if(i)break;!a&&d&&d[t]&&(a=d[t],c=f)}!i&&a&&(i=a,u=c),i&&(n.splice(0,u,i),e=n.join("/"))}return e}function u(e,r){return function(){return h.apply(t,C.call(arguments,0).concat([e,r]))}}function a(e){return function(r){return i(r,e)}}function c(e){return function(r){b[e]=r}}function f(e){if(o(m,e)){var r=m[e];delete m[e],y[e]=!0,p.apply(t,r)}if(!o(b,e)&&!o(y,e))throw new Error("No "+e);return b[e]}function s(e){var r,n=e?e.indexOf("!"):-1;return n>-1&&(r=e.substring(0,n),e=e.substring(n+1,e.length)),[r,e]}function l(e){return function(){return k&&k.config&&k.config[e]||{}}}var p,h,d,g,b={},m={},k={},y={},w=Object.prototype.hasOwnProperty,C=[].slice;d=function(e,r){var n,t=s(e),o=t[0];return e=t[1],o&&(o=i(o,r),n=f(o)),o?e=n&&n.normalize?n.normalize(e,a(r)):i(e,r):(e=i(e,r),t=s(e),o=t[0],e=t[1],o&&(n=f(o))),{f:o?o+"!"+e:e,n:e,pr:o,p:n}},g={require:function(e){return u(e)},exports:function(e){var r=b[e];return"undefined"!=typeof r?r:b[e]={}},module:function(e){return{id:e,uri:"",exports:b[e],config:l(e)}}},p=function(e,r,n,i){var a,s,l,p,h,k,w=[];if(i=i||e,"function"==typeof n){for(r=!r.length&&n.length?["require","exports","module"]:r,h=0;h<r.length;h+=1)if(p=d(r[h],i),s=p.f,"require"===s)w[h]=g.require(e);else if("exports"===s)w[h]=g.exports(e),k=!0;else if("module"===s)a=w[h]=g.module(e);else if(o(b,s)||o(m,s)||o(y,s))w[h]=f(s);else{if(!p.p)throw new Error(e+" missing "+s);p.p.load(p.n,u(i,!0),c(s),{}),w[h]=b[s]}l=n.apply(b[e],w),e&&(a&&a.exports!==t&&a.exports!==b[e]?b[e]=a.exports:l===t&&k||(b[e]=l))}else e&&(b[e]=n)},e=r=h=function(e,r,n,o,i){return"string"==typeof e?g[e]?g[e](r):f(d(e,r).f):(e.splice||(k=e,r.splice?(e=r,r=n,n=null):e=t),r=r||function(){},"function"==typeof n&&(n=o,o=i),o?p(t,e,r,n):setTimeout(function(){p(t,e,r,n)},4),h)},h.config=function(e){return k=e,k.deps&&h(k.deps,k.callback),h},n=function(e,r,n){r.splice||(n=r,r=[]),o(b,e)||o(m,e)||(m[e]=[e,r,n])},n.amd={jQuery:!0}}(),n("../node_modules/almond/almond",function(){}),n("jxg",[],function(){var e={};return"object"!=typeof JXG||JXG.extend||(e=JXG),e.extend=function(e,r,n,t){var o,i;n=n||!1,t=t||!1;for(o in r)(!n||n&&r.hasOwnProperty(o))&&(i=t?o.toLowerCase():o,e[i]=r[o])},e.extend(e,{boards:{},readers:{},elements:{},registerElement:function(e,r){e=e.toLowerCase(),this.elements[e]=r},registerReader:function(e,r){var n,t;for(n=0;n<r.length;n++)t=r[n].toLowerCase(),"function"!=typeof this.readers[t]&&(this.readers[t]=e)},shortcut:function(e,r){return function(){return e[r].apply(this,arguments)}},getRef:function(e,r){return e.select(r)},getReference:function(e,r){return e.select(r)},debugInt:function(){var e,r;for(e=0;e<arguments.length;e++)r=arguments[e],"object"==typeof window&&window.console&&console.log?console.log(r):"object"==typeof document&&document.getElementById("debug")&&(document.getElementById("debug").innerHTML+=r+"<br/>")},debugWST:function(){var r=new Error;e.debugInt.apply(this,arguments),r&&r.stack&&(e.debugInt("stacktrace"),e.debugInt(r.stack.split("\n").slice(1).join("\n")))},debugLine:function(){var r=new Error;e.debugInt.apply(this,arguments),r&&r.stack&&e.debugInt("Called from",r.stack.split("\n").slice(2,3).join("\n"))},debug:function(){e.debugInt.apply(this,arguments)}}),e}),n("utils/zip",["jxg"],function(e){var r=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],t=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],o=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],i=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],u=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],a=256;return e.Util=e.Util||{},e.Util.Unzip=function(c){function f(){return R+=8,O>X?c[X++]:-1}function s(){B=1}function l(){var e;try{return R++,e=1&B,B>>=1,0===B&&(B=f(),e=1&B,B=128|B>>1),e}catch(r){throw r}}function p(e){var n=0,t=e;try{for(;t--;)n=n<<1|l();e&&(n=r[n]>>8-e)}catch(o){throw o}return n}function h(){J=0}function d(e){A++,G[J++]=e,z.push(String.fromCharCode(e)),32768===J&&(J=0)}function g(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function b(){for(;;){if(M[H]>=x)return-1;if(U[M[H]]===H)return M[H]++;M[H]++}}function m(){var e,r=P[F];if(17===H)return-1;if(F++,H++,e=b(),e>=0)r.b0=e;else if(r.b0=32768,m())return-1;if(e=b(),e>=0)r.b1=e,r.jump=null;else if(r.b1=32768,r.jump=P[F],r.jumppos=F,m())return-1;return H--,0}function k(e,r,n){var t;for(P=e,F=0,U=n,x=r,t=0;17>t;t++)M[t]=0;return H=0,m()?-1:0}function y(e){for(var r,n,t,o=0,i=e[o];;)if(t=l()){if(!(32768&i.b1))return i.b1;for(i=i.jump,r=e.length,n=0;r>n;n++)if(e[n]===i){o=n;break}}else{if(!(32768&i.b0))return i.b0;o++,i=e[o]}}function w(){var a,c,b,m,w,C,v,A,j,U,x,S,z,I,E,L,O;do if(a=l(),b=p(2),0===b)for(s(),U=f(),U|=f()<<8,S=f(),S|=f()<<8,65535&(U^~S)&&e.debug("BlockLen checksum mismatch\n");U--;)c=f(),d(c);else if(1===b)for(;;)if(w=r[p(7)]>>1,w>23?(w=w<<1|l(),w>199?(w-=128,w=w<<1|l()):(w-=48,w>143&&(w+=136))):w+=256,256>w)d(w);else{if(256===w)break;for(w-=257,j=p(t[w])+n[w],w=r[p(5)]>>3,i[w]>8?(x=p(8),x|=p(i[w]-8)<<8):x=p(i[w]),x+=o[w],w=0;j>w;w++)c=G[32767&J-x],d(c)}else if(2===b){for(v=new Array(320),I=257+p(5),E=1+p(5),L=4+p(4),w=0;19>w;w++)v[w]=0;for(w=0;L>w;w++)v[u[w]]=p(3);for(j=q.length,m=0;j>m;m++)q[m]=new g;if(k(q,19,v,0))return h(),1;for(z=I+E,m=0,O=-1;z>m;)if(O++,w=y(q),16>w)v[m++]=w;else if(16===w){if(w=3+p(2),m+w>z)return h(),1;for(C=m?v[m-1]:0;w--;)v[m++]=C}else{if(w=17===w?3+p(3):11+p(7),m+w>z)return h(),1;for(;w--;)v[m++]=0}for(j=T.length,m=0;j>m;m++)T[m]=new g;if(k(T,I,v,0))return h(),1;for(j=T.length,m=0;j>m;m++)q[m]=new g;for(A=[],m=I;m<v.length;m++)A[m-I]=v[m];if(k(q,E,A,0))return h(),1;for(;;)if(w=y(T),w>=256){if(w-=256,0===w)break;for(w-=1,j=p(t[w])+n[w],w=y(q),i[w]>8?(x=p(8),x|=p(i[w]-8)<<8):x=p(i[w]),x+=o[w];j--;)c=G[32767&J-x],d(c)}else d(w)}while(!a);return h(),s(),0}function C(){var e,r,n,t,o,i,u,c,s=[];try{if(z=[],L=!1,s[0]=f(),s[1]=f(),120===s[0]&&218===s[1]&&(w(),E[I]=[z.join(""),"geonext.gxt"],I++),31===s[0]&&139===s[1]&&(S(),E[I]=[z.join(""),"file"],I++),80===s[0]&&75===s[1]&&(L=!0,s[2]=f(),s[3]=f(),3===s[2]&&4===s[3])){for(s[0]=f(),s[1]=f(),v=f(),v|=f()<<8,c=f(),c|=f()<<8,f(),f(),f(),f(),u=f(),u|=f()<<8,u|=f()<<16,u|=f()<<24,i=f(),i|=f()<<8,i|=f()<<16,i|=f()<<24,o=f(),o|=f()<<8,o|=f()<<16,o|=f()<<24,t=f(),t|=f()<<8,n=f(),n|=f()<<8,e=0,N=[];t--;)r=f(),"/"===r|":"===r?e=0:a-1>e&&(N[e++]=String.fromCharCode(r));for(j||(j=N),e=0;n>e;)r=f(),e++;A=0,8===c&&(w(),E[I]=new Array(2),E[I][0]=z.join(""),E[I][1]=N.join(""),I++),S()}}catch(l){throw l}}var v,A,j,U,x,S,z=[],I=0,E=[],G=new Array(32768),J=0,L=!1,O=c.length,X=0,B=1,R=0,T=new Array(288),q=new Array(32),F=0,P=null,H=(new Array(64),new Array(64),0),M=new Array(17),N=[];M[0]=0,S=function(){var e,r,n,t,o,i,u=[];if(8&v&&(u[0]=f(),u[1]=f(),u[2]=f(),u[3]=f(),80===u[0]&&75===u[1]&&7===u[2]&&8===u[3]?(e=f(),e|=f()<<8,e|=f()<<16,e|=f()<<24):e=u[0]|u[1]<<8|u[2]<<16|u[3]<<24,r=f(),r|=f()<<8,r|=f()<<16,r|=f()<<24,n=f(),n|=f()<<8,n|=f()<<16,n|=f()<<24),L&&C(),u[0]=f(),8===u[0]){if(v=f(),f(),f(),f(),f(),f(),t=f(),4&v)for(u[0]=f(),u[2]=f(),H=u[0]+256*u[1],o=0;H>o;o++)f();if(8&v)for(o=0,N=[],i=f();i;)("7"===i||":"===i)&&(o=0),a-1>o&&(N[o++]=i),i=f();if(16&v)for(i=f();i;)i=f();2&v&&(f(),f()),w(),e=f(),e|=f()<<8,e|=f()<<16,e|=f()<<24,n=f(),n|=f()<<8,n|=f()<<16,n|=f()<<24,L&&C()}},e.Util.Unzip.prototype.unzipFile=function(e){var r;for(this.unzip(),r=0;r<E.length;r++)if(E[r][1]===e)return E[r][0];return""},e.Util.Unzip.prototype.unzip=function(){return C(),E}},e.Util}),n("utils/encoding",["jxg"],function(e){var r=0,n=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,0,12,24,36,60,96,84,12,12,12,48,72,12,12,12,12,12,12,12,12,12,12,12,12,12,0,12,12,12,12,12,0,12,0,12,12,12,24,12,12,12,12,12,24,12,24,12,12,12,12,12,12,12,12,12,24,12,12,12,12,12,24,12,12,12,12,12,12,12,24,12,12,12,12,12,12,12,12,12,36,12,36,12,12,12,36,12,12,12,12,12,36,12,36,12,12,12,36,12,12,12,12,12,12,12,12,12,12];return e.Util=e.Util||{},e.Util.UTF8={encode:function(e){var r,n,t="",o=e.length;if(e=e.replace(/\r\n/g,"\n"),"function"==typeof unescape&&"function"==typeof encodeURIComponent)return unescape(encodeURIComponent(e));for(r=0;o>r;r++)n=e.charCodeAt(r),128>n?t+=String.fromCharCode(n):n>127&&2048>n?(t+=String.fromCharCode(192|n>>6),t+=String.fromCharCode(128|63&n)):(t+=String.fromCharCode(224|n>>12),t+=String.fromCharCode(128|63&n>>6),t+=String.fromCharCode(128|63&n));return t},decode:function(e){var t,o,i,u=0,a=0,c=r,f=[],s=e.length,l=[];for(t=0;s>t;t++)o=e.charCodeAt(t),i=n[o],a=c!==r?63&o|a<<6:255>>i&o,c=n[256+c+i],c===r&&(a>65535?f.push(55232+(a>>10),56320+(1023&a)):f.push(a),u++,0===u%1e4&&(l.push(String.fromCharCode.apply(null,f)),f=[]));return l.push(String.fromCharCode.apply(null,f)),l.join("")},asciiCharCodeAt:function(e,r){var n=e.charCodeAt(r);if(n>255)switch(n){case 8364:n=128;break;case 8218:n=130;break;case 402:n=131;break;case 8222:n=132;break;case 8230:n=133;break;case 8224:n=134;break;case 8225:n=135;break;case 710:n=136;break;case 8240:n=137;break;case 352:n=138;break;case 8249:n=139;break;case 338:n=140;break;case 381:n=142;break;case 8216:n=145;break;case 8217:n=146;break;case 8220:n=147;break;case 8221:n=148;break;case 8226:n=149;break;case 8211:n=150;break;case 8212:n=151;break;case 732:n=152;break;case 8482:n=153;break;case 353:n=154;break;case 8250:n=155;break;case 339:n=156;break;case 382:n=158;break;case 376:n=159}return n}},e.Util.UTF8}),n("utils/base64",["jxg","utils/encoding"],function(e,r){function n(e,r){return 255&e.charCodeAt(r)}function t(e,r){var n=o.indexOf(e.charAt(r));if(-1===n)throw new Error("JSXGraph/utils/base64: Can't decode string (invalid character).");return n}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="=";return e.Util=e.Util||{},e.Util.Base64={encode:function(e){var t,u,a,c,f,s=[];for(f=r.encode(e),a=f.length,c=a%3,t=0;a-c>t;t+=3)u=n(f,t)<<16|n(f,t+1)<<8|n(f,t+2),s.push(o.charAt(u>>18),o.charAt(63&u>>12),o.charAt(63&u>>6),o.charAt(63&u));switch(c){case 1:u=n(f,a-1),s.push(o.charAt(u>>2),o.charAt(63&u<<4),i,i);break;case 2:u=n(f,a-2)<<8|n(f,a-1),s.push(o.charAt(u>>10),o.charAt(63&u>>4),o.charAt(63&u<<2),i)}return s.join("")},decode:function(e,n){var o,u,a,c,f,s,l=[],p=[];if(o=e.replace(/[^A-Za-z0-9\/=]/g,""),a=o.length,0!==a%4)throw new Error("JSXGraph/utils/base64: Can't decode string (invalid input length).");for(o.charAt(a-1)===i&&(c=1,o.charAt(a-2)===i&&(c=2),a-=4),u=0;a>u;u+=4)f=t(o,u)<<18|t(o,u+1)<<12|t(o,u+2)<<6|t(o,u+3),p.push(f>>16,255&f>>8,255&f),0===u%1e4&&(l.push(String.fromCharCode.apply(null,p)),p=[]);switch(c){case 1:f=t(o,a)<<12|t(o,a+1)<<6|t(o,a+2),p.push(f>>10,255&f>>2);break;case 2:f=t(o,u)<<6|t(o,u+1),p.push(f>>4)}return l.push(String.fromCharCode.apply(null,p)),s=l.join(""),n&&(s=r.decode(s)),s},decodeAsArray:function(e){var r,n=this.decode(e),t=[],o=n.length;for(r=0;o>r;r++)t[r]=n.charCodeAt(r);return t}},e.Util.Base64}),n("../build/compressor.deps.js",["jxg","utils/zip","utils/base64"],function(e,r,n){return e.decompress=function(e){return unescape(new r.Unzip(n.decodeAsArray(e)).unzip()[0][0])},e}),window.JXG=r("../build/compressor.deps.js")}();
console.log('ready');
// If you can see this you've copied the whole thing