Created
January 4, 2025 02:17
-
-
Save zuriby/a2ed82f6d93ecf42b065b7d1acfdf704 to your computer and use it in GitHub Desktop.
Mandelbrot Set Viewer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<!-- | |
Work by David Eck - Online version: https://math.hws.edu/eck/js/mandelbrot/MB.html | |
All credit to him! | |
I simply changed the worker to be loaded internally from the page, and minified the css and JS | |
Web page written by David Eck, https://math.hws.edu/eck/index.html | |
You can do anything you like with this web page and with the code, but | |
if you use a substantial portion of it, you should include attribution. | |
This is a fairly complete "Mandelbrot Set" viewer program, including | |
the ability to do arbitrary precision computation (very slowly) when you | |
zoom in too far to do the calcultions with regular floating point numbers. | |
It can save and load examples as XML in a clunky way, by copy-and-paste | |
between files and a textarea that appears when "Show XML Input/Export" | |
is clicked. All of the ideas and some of the code were ported from | |
an older program that was written in java. | |
This file depends on the scripts mandelbrot-worker.js and Daniel Trebbien's | |
BigDecimal-all-last.min.js. | |
August, 2019. Added Palette Editor. | |
January, 2020. Improved Palette Editor. | |
April, 2020. Cleaned up standard palettes, removed a few, added Dark Colors palette. | |
May, 2020. Change maximum image width and height from 2500 to 10000 (but that | |
doesn't necessarily mean very large images will work on every device). | |
October, 2021. Fixed a bug in startJob() and startSecondPass() that showed up | |
when the change in y-value from one line to the next is very small. This was | |
done previously by successive subtraction, which introduced errors. Thanks to | |
Robert Munafo for finding and fixing the bug. | |
August, 2022. Use localStorage to save workerCount between sessions. | |
May, 2023. Corrected use of putImageData (which was bizarrely wrong in its | |
interpretation of the difference between CSS pixels and device pixels -- but | |
in practice the error had no effect on any device where I used this app. | |
October, 2023. Added "Save file" and "Load file" buttons. | |
__ | |
/* | |
Copyright (c) 2012 Daniel Trebbien and other contributors | |
Portions Copyright (c) 2003 STZ-IDA and PTV AG, Karlsruhe, Germany | |
Portions Copyright (c) 1995-2001 International Business Machines Corporation and others | |
All rights reserved. | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. | |
*/ | |
--> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Mandelbrot Viewer</title> | |
<style type="text/css"> | |
#canvas-holder,#controls{display:inline-block;padding:0}#controls p,#imagediv p,#status{white-space:nowrap}body{background-color:#d8d8d8}canvas{display:block;background-color:#bbb}#canvas-holder{border:2px solid #000;margin:0}#controls{background-color:#fff;border-left:2px solid #000;border-right:2px solid #000;border-top:2px solid #000;margin-right:10px}#controls p{margin:12px 0}div.group{padding:0 8px;border-bottom:2px solid #000}#imagediv p{margin:4px 0}#imagediv{margin-left:20px;padding:0}#status{font-weight:700;color:#a00}#xmlimportbg{position:fixed;z-index:10;opacity:.7;background-color:#000;left:0;top:0;width:100%;height:100%;display:none}#paletteEditor,#xmlimport{position:absolute;left:50px;top:50px;z-index:20;padding:10px;background-color:#d8d8ff;border:2px solid #009;border-radius:16px;box-shadow:5px 5px 8px #000;display:none}textarea{white-space:pre;word-wrap:normal;overflow-x:scroll} | |
</style> | |
<script type="javascript/worker" id="service-worker"> | |
var xmin,dx,yval,columnCount,rowNumber,maxIterations,highPrecision,taskNumber,jobNumber,workerNumber,iterationCounts,xs,y,work1,work2,work3,zx,zy,chunks,ArrayType=this.Uint32Array||Array;function countIterations(r,o){for(var n=0,a=r,t=o;n<maxIterations&&a*a+t*t<8;){var $=a*a-t*t+r;t=2*a*t+o,a=$,n++}return n<maxIterations?n:-1}function countIterationsHP(r,o){arraycopy(r,0,zx,0,chunks),arraycopy(o,0,zy,0,chunks);for(var n=0;n<maxIterations&&(arraycopy(zx,0,work2,0,chunks),multiply(work2,zx,chunks),arraycopy(zy,0,work1,0,chunks),multiply(work1,zy,chunks),arraycopy(work1,0,work3,0,chunks),add(work1,work2,chunks),(65528&work1[0])==0||(65528&work1[0])==65520);)negate(work3,chunks),add(work2,work3,chunks),add(work2,r,chunks),arraycopy(zx,0,work1,0,chunks),add(work1,zx,chunks),multiply(work1,zy,chunks),add(work1,o,chunks),arraycopy(work1,0,zy,0,chunks),arraycopy(work2,0,zx,0,chunks),n++;return n<maxIterations?n:-1}function arraycopy(r,o,n,a,t){for(var $=0;$<t;$++)n[a+$]=r[o+$]}onmessage=function(r){var o=r.data;if("setup"==o[0])jobNumber=o[1],maxIterations=o[2],highPrecision=o[3],workerNumber=o[4];else if("task"==o[0]){if(taskNumber=o[1],iterationCounts=Array(columnCount=o[2]),highPrecision){xmin=o[3],dx=o[4],yval=o[5],createHPData();for(var n=0;n<columnCount;n++)iterationCounts[n]=countIterationsHP(xs[n],yval)}else for(var a=o[3],t=o[4],$=o[5],n=0;n<columnCount;n++)iterationCounts[n]=countIterations(a+t*n,$);postMessage([jobNumber,taskNumber,iterationCounts,workerNumber])}};var log2of10=Math.log(10)/Math.log(2);function createHPData(){chunks=xmin.length-1,y=new ArrayType(chunks+1),(xs=Array(columnCount))[0]=xmin;for(var r=1;r<columnCount;r++){xs[r]=new ArrayType(chunks+1);var o=0;for(j=chunks;j>=0;j--)xs[r][j]=xmin[j]+dx[j]*r+o,o=xs[r][j]>>>16,xs[r][j]=65535&xs[r][j]}zx=new ArrayType(chunks),zy=new ArrayType(chunks),work1=new ArrayType(chunks),work2=new ArrayType(chunks),work3=new ArrayType(chunks)}function add(r,o,n){for(var a=0,t=n-1;t>=0;t--)r[t]+=o[t],r[t]+=a,a=r[t]>>>16,r[t]&=65535}function multiply(r,o,n){var a=(32768&r[0])!=0;a&&negate(r,n);var t=(32768&o[0])!=0;if(t&&negate(o,n),0==r[0])for(var $=0;$<n;$++)work3[$]=0;else for(var u=0,$=n-1;$>=0;$--)work3[$]=r[0]*o[$]+u,u=work3[$]>>>16,work3[$]&=65535;for(var e=1;e<n;e++){var $=n-e,u=r[e]*o[$]>>>16;$--;for(var k=n-1;$>=0;)work3[k]+=r[e]*o[$]+u,u=work3[k]>>>16,work3[k]&=65535,$--,k--;for(;0!=u&&k>=0;)work3[k]+=u,u=work3[k]>>>16,work3[k]&=65535,k--}arraycopy(work3,0,r,0,n),t&&negate(o,n),a!=t&&negate(r,n)}function negate(r,o){for(var n=0;n<o;n++)r[n]=65535-r[n];++r[o-1];for(var n=o-1;n>0&&(65536&r[n])!=0;n--)r[n]&=65535,++r[n-1];r[0]&=65535} | |
</script> | |
<script> | |
(function(){var m,k=function(){this.form=this.digits=0;this.lostDigits=!1;this.roundingMode=0;var a=this.DEFAULT_FORM,b=this.DEFAULT_LOSTDIGITS,c=this.DEFAULT_ROUNDINGMODE;if(4==k.arguments.length)a=k.arguments[1],b=k.arguments[2],c=k.arguments[3];else if(3==k.arguments.length)a=k.arguments[1],b=k.arguments[2];else if(2==k.arguments.length)a=k.arguments[1];else if(1!=k.arguments.length)throw"MathContext(): "+k.arguments.length+" arguments given; expected 1 to 4";var d=k.arguments[0];if(d!=this.DEFAULT_DIGITS){if(d<this.MIN_DIGITS)throw"MathContext(): Digits too small: "+d;if(d>this.MAX_DIGITS)throw"MathContext(): Digits too large: "+d}if(a!=this.SCIENTIFIC&&a!=this.ENGINEERING&&a!=this.PLAIN)throw"MathContext() Bad form value: "+a;if(!this.isValidRound(c))throw"MathContext(): Bad roundingMode value: "+c;this.digits=d;this.form=a;this.lostDigits=b;this.roundingMode=c};k.prototype.getDigits=function(){return this.digits};k.prototype.getForm=function(){return this.form};k.prototype.getLostDigits=function(){return this.lostDigits};k.prototype.getRoundingMode=function(){return this.roundingMode};k.prototype.toString=function(){var a=null,b=0,c=null,a=this.form==this.SCIENTIFIC?"SCIENTIFIC":this.form==this.ENGINEERING?"ENGINEERING":"PLAIN",d=this.ROUNDS.length,b=0;a:for(;0<d;d--,b++)if(this.roundingMode==this.ROUNDS[b]){c=this.ROUNDWORDS[b];break a}return"digits="+this.digits+" form="+a+" lostDigits="+(this.lostDigits?"1":"0")+" roundingMode="+c};k.prototype.isValidRound=function(a){var b=0,c=this.ROUNDS.length,b=0;for(;0<c;c--,b++)if(a==this.ROUNDS[b])return!0;return!1};k.PLAIN=k.prototype.PLAIN=0;k.SCIENTIFIC=k.prototype.SCIENTIFIC=1;k.ENGINEERING=k.prototype.ENGINEERING=2;k.ROUND_CEILING=k.prototype.ROUND_CEILING=2;k.ROUND_DOWN=k.prototype.ROUND_DOWN=1;k.ROUND_FLOOR=k.prototype.ROUND_FLOOR=3;k.ROUND_HALF_DOWN=k.prototype.ROUND_HALF_DOWN=5;k.ROUND_HALF_EVEN=k.prototype.ROUND_HALF_EVEN=6;k.ROUND_HALF_UP=k.prototype.ROUND_HALF_UP=4;k.ROUND_UNNECESSARY=k.prototype.ROUND_UNNECESSARY=7;k.ROUND_UP=k.prototype.ROUND_UP=0;k.prototype.DEFAULT_FORM=k.prototype.SCIENTIFIC;k.prototype.DEFAULT_DIGITS=9;k.prototype.DEFAULT_LOSTDIGITS=!1;k.prototype.DEFAULT_ROUNDINGMODE=k.prototype.ROUND_HALF_UP;k.prototype.MIN_DIGITS=0;k.prototype.MAX_DIGITS=999999999;k.prototype.ROUNDS=[k.prototype.ROUND_HALF_UP,k.prototype.ROUND_UNNECESSARY,k.prototype.ROUND_CEILING,k.prototype.ROUND_DOWN,k.prototype.ROUND_FLOOR,k.prototype.ROUND_HALF_DOWN,k.prototype.ROUND_HALF_EVEN,k.prototype.ROUND_UP];k.prototype.ROUNDWORDS="ROUND_HALF_UP ROUND_UNNECESSARY ROUND_CEILING ROUND_DOWN ROUND_FLOOR ROUND_HALF_DOWN ROUND_HALF_EVEN ROUND_UP".split(" ");k.prototype.DEFAULT=new k(k.prototype.DEFAULT_DIGITS,k.prototype.DEFAULT_FORM,k.prototype.DEFAULT_LOSTDIGITS,k.prototype.DEFAULT_ROUNDINGMODE);m=k;var v,G=function(a,b){return(a-a%b)/b},K=function(a){var b=Array(a),c;for(c=0;c<a;++c)b[c]=0;return b},h=function(){this.ind=0;this.form=m.prototype.PLAIN;this.mant=null;this.exp=0;if(0!=h.arguments.length){var a,b,c;1==h.arguments.length?(a=h.arguments[0],b=0,c=a.length):(a=h.arguments[0],b=h.arguments[1],c=h.arguments[2]);"string"==typeof a&&(a=a.split(""));var d,e,i,f,g,j=0,l=0;e=!1;var k=l=l=j=0,q=0;f=0;0>=c&&this.bad("BigDecimal(): ",a);this.ind=this.ispos;"-"==a[0]?(c--,0==c&&this.bad("BigDecimal(): ",a),this.ind=this.isneg,b++):"+"==a[0]&&(c--,0==c&&this.bad("BigDecimal(): ",a),b++);e=d=!1;i=0;g=f=-1;k=c;j=b;a:for(;0<k;k--,j++){l=a[j];if("0"<=l&&"9">=l){g=j;i++;continue a}if("."==l){0<=f&&this.bad("BigDecimal(): ",a);f=j-b;continue a}if("e"!=l&&"E"!=l){("0">l||"9"<l)&&this.bad("BigDecimal(): ",a);d=!0;g=j;i++;continue a}j-b>c-2&&this.bad("BigDecimal(): ",a);e=!1;"-"==a[j+1]?(e=!0,j+=2):j="+"==a[j+1]?j+2:j+1;l=c-(j-b);(0==l||9<l)&&this.bad("BigDecimal(): ",a);c=l;l=j;for(;0<c;c--,l++)k=a[l],"0">k&&this.bad("BigDecimal(): ",a),"9"<k?this.bad("BigDecimal(): ",a):q=k-0,this.exp=10*this.exp+q;e&&(this.exp=-this.exp);e=!0;break a}0==i&&this.bad("BigDecimal(): ",a);0<=f&&(this.exp=this.exp+f-i);q=g-1;j=b;a:for(;j<=q;j++)if(l=a[j],"0"==l)b++,f--,i--;else if("."==l)b++,f--;else break a;this.mant=Array(i);l=b;if(d){b=i;j=0;for(;0<b;b--,j++)j==f&&l++,k=a[l],"9">=k?this.mant[j]=k-0:this.bad("BigDecimal(): ",a),l++}else{b=i;j=0;for(;0<b;b--,j++)j==f&&l++,this.mant[j]=a[l]-0,l++}0==this.mant[0]?(this.ind=this.iszero,0<this.exp&&(this.exp=0),e&&(this.mant=this.ZERO.mant,this.exp=0)):e&&(this.form=m.prototype.SCIENTIFIC,f=this.exp+this.mant.length-1,(f<this.MinExp||f>this.MaxExp)&&this.bad("BigDecimal(): ",a))}},H=function(){var a;if(1==H.arguments.length)a=H.arguments[0];else if(0==H.arguments.length)a=this.plainMC;else throw"abs(): "+H.arguments.length+" arguments given; expected 0 or 1";return this.ind==this.isneg?this.negate(a):this.plus(a)},w=function(){var a;if(2==w.arguments.length)a=w.arguments[1];else if(1==w.arguments.length)a=this.plainMC;else throw"add(): "+w.arguments.length+" arguments given; expected 1 or 2";var b=w.arguments[0],c,d,e,i,f,g,j,l=0;d=l=0;var l=null,k=l=0,q=0,t=0,s=0,n=0;a.lostDigits&&this.checkdigits(b,a.digits);c=this;if(0==c.ind&&a.form!=m.prototype.PLAIN)return b.plus(a);if(0==b.ind&&a.form!=m.prototype.PLAIN)return c.plus(a);d=a.digits;0<d&&(c.mant.length>d&&(c=this.clone(c).round(a)),b.mant.length>d&&(b=this.clone(b).round(a)));e=new h;i=c.mant;f=c.mant.length;g=b.mant;j=b.mant.length;if(c.exp==b.exp)e.exp=c.exp;else if(c.exp>b.exp){l=f+c.exp-b.exp;if(l>=j+d+1&&0<d)return e.mant=i,e.exp=c.exp,e.ind=c.ind,f<d&&(e.mant=this.extend(c.mant,d),e.exp-=d-f),e.finish(a,!1);e.exp=b.exp;l>d+1&&0<d&&(l=l-d-1,j-=l,e.exp+=l,l=d+1);l>f&&(f=l)}else{l=j+b.exp-c.exp;if(l>=f+d+1&&0<d)return e.mant=g,e.exp=b.exp,e.ind=b.ind,j<d&&(e.mant=this.extend(b.mant,d),e.exp-=d-j),e.finish(a,!1);e.exp=c.exp;l>d+1&&0<d&&(l=l-d-1,f-=l,e.exp+=l,l=d+1);l>j&&(j=l)}e.ind=c.ind==this.iszero?this.ispos:c.ind;if((c.ind==this.isneg?1:0)==(b.ind==this.isneg?1:0))d=1;else{do{d=-1;do if(b.ind!=this.iszero)if(f<j||c.ind==this.iszero)l=i,i=g,g=l,l=f,f=j,j=l,e.ind=-e.ind;else if(!(f>j)){k=l=0;q=i.length-1;t=g.length-1;c:for(;;){if(l<=q)s=i[l];else{if(k>t){if(a.form!=m.prototype.PLAIN)return this.ZERO;break c}s=0}n=k<=t?g[k]:0;if(s!=n){s<n&&(l=i,i=g,g=l,l=f,f=j,j=l,e.ind=-e.ind);break c}l++;k++}}while(0)}while(0)}e.mant=this.byteaddsub(i,f,g,j,d,!1);return e.finish(a,!1)},x=function(){var a;if(2==x.arguments.length)a=x.arguments[1];else if(1==x.arguments.length)a=this.plainMC;else throw"compareTo(): "+x.arguments.length+" arguments given; expected 1 or 2";var b=x.arguments[0],c=0,c=0;a.lostDigits&&this.checkdigits(b,a.digits);if(this.ind==b.ind&&this.exp==b.exp){c=this.mant.length;if(c<b.mant.length)return-this.ind;if(c>b.mant.length)return this.ind;if(c<=a.digits||0==a.digits){a=c;c=0;for(;0<a;a--,c++){if(this.mant[c]<b.mant[c])return-this.ind;if(this.mant[c]>b.mant[c])return this.ind}return 0}}else{if(this.ind<b.ind)return-1;if(this.ind>b.ind)return 1}b=this.clone(b);b.ind=-b.ind;return this.add(b,a).ind},p=function(){var a,b=-1;if(2==p.arguments.length)a="number"==typeof p.arguments[1]?new m(0,m.prototype.PLAIN,!1,p.arguments[1]):p.arguments[1];else if(3==p.arguments.length){b=p.arguments[1];if(0>b)throw"divide(): Negative scale: "+b;a=new m(0,m.prototype.PLAIN,!1,p.arguments[2])}else if(1==p.arguments.length)a=this.plainMC;else throw"divide(): "+p.arguments.length+" arguments given; expected between 1 and 3";return this.dodivide("D",p.arguments[0],a,b)},y=function(){var a;if(2==y.arguments.length)a=y.arguments[1];else if(1==y.arguments.length)a=this.plainMC;else throw"divideInteger(): "+y.arguments.length+" arguments given; expected 1 or 2";return this.dodivide("I",y.arguments[0],a,0)},z=function(){var a;if(2==z.arguments.length)a=z.arguments[1];else if(1==z.arguments.length)a=this.plainMC;else throw"max(): "+z.arguments.length+" arguments given; expected 1 or 2";var b=z.arguments[0];return 0<=this.compareTo(b,a)?this.plus(a):b.plus(a)},A=function(){var a;if(2==A.arguments.length)a=A.arguments[1];else if(1==A.arguments.length)a=this.plainMC;else throw"min(): "+A.arguments.length+" arguments given; expected 1 or 2";var b=A.arguments[0];return 0>=this.compareTo(b,a)?this.plus(a):b.plus(a)},B=function(){var a;if(2==B.arguments.length)a=B.arguments[1];else if(1==B.arguments.length)a=this.plainMC;else throw"multiply(): "+B.arguments.length+" arguments given; expected 1 or 2";var b=B.arguments[0],c,d,e,i=e=null,f,g=0,j,l=0,k=0;a.lostDigits&&this.checkdigits(b,a.digits);c=this;d=0;e=a.digits;0<e?(c.mant.length>e&&(c=this.clone(c).round(a)),b.mant.length>e&&(b=this.clone(b).round(a))):(0<c.exp&&(d+=c.exp),0<b.exp&&(d+=b.exp));c.mant.length<b.mant.length?(e=c.mant,i=b.mant):(e=b.mant,i=c.mant);f=e.length+i.length-1;g=9<e[0]*i[0]?f+1:f;j=new h;var g=this.createArrayWithZeros(g),m=e.length,l=0;for(;0<m;m--,l++)k=e[l],0!=k&&(g=this.byteaddsub(g,g.length,i,f,k,!0)),f--;j.ind=c.ind*b.ind;j.exp=c.exp+b.exp-d;j.mant=0==d?g:this.extend(g,g.length+d);return j.finish(a,!1)},I=function(){var a;if(1==I.arguments.length)a=I.arguments[0];else if(0==I.arguments.length)a=this.plainMC;else throw"negate(): "+I.arguments.length+" arguments given; expected 0 or 1";var b;a.lostDigits&&this.checkdigits(null,a.digits);b=this.clone(this);b.ind=-b.ind;return b.finish(a,!1)},J=function(){var a;if(1==J.arguments.length)a=J.arguments[0];else if(0==J.arguments.length)a=this.plainMC;else throw"plus(): "+J.arguments.length+" arguments given; expected 0 or 1";a.lostDigits&&this.checkdigits(null,a.digits);return a.form==m.prototype.PLAIN&&this.form==m.prototype.PLAIN&&(this.mant.length<=a.digits||0==a.digits)?this:this.clone(this).finish(a,!1)},C=function(){var a;if(2==C.arguments.length)a=C.arguments[1];else if(1==C.arguments.length)a=this.plainMC;else throw"pow(): "+C.arguments.length+" arguments given; expected 1 or 2";var b=C.arguments[0],c,d,e,i=e=0,f,g=0;a.lostDigits&&this.checkdigits(b,a.digits);c=b.intcheck(this.MinArg,this.MaxArg);d=this;e=a.digits;if(0==e){if(b.ind==this.isneg)throw"pow(): Negative power: "+b.toString();e=0}else{if(b.mant.length+b.exp>e)throw"pow(): Too many digits: "+b.toString();d.mant.length>e&&(d=this.clone(d).round(a));i=b.mant.length+b.exp;e=e+i+1}e=new m(e,a.form,!1,a.roundingMode);i=this.ONE;if(0==c)return i;0>c&&(c=-c);f=!1;g=1;a:for(;;g++){c<<=1;0>c&&(f=!0,i=i.multiply(d,e));if(31==g)break a;if(!f)continue a;i=i.multiply(i,e)}0>b.ind&&(i=this.ONE.divide(i,e));return i.finish(a,!0)},D=function(){var a;if(2==D.arguments.length)a=D.arguments[1];else if(1==D.arguments.length)a=this.plainMC;else throw"remainder(): "+D.arguments.length+" arguments given; expected 1 or 2";return this.dodivide("R",D.arguments[0],a,-1)},E=function(){var a;if(2==E.arguments.length)a=E.arguments[1];else if(1==E.arguments.length)a=this.plainMC;else throw"subtract(): "+E.arguments.length+" arguments given; expected 1 or 2";var b=E.arguments[0];a.lostDigits&&this.checkdigits(b,a.digits);b=this.clone(b);b.ind=-b.ind;return this.add(b,a)},r=function(){var a,b,c,d;if(6==r.arguments.length)a=r.arguments[2],b=r.arguments[3],c=r.arguments[4],d=r.arguments[5];else if(2==r.arguments.length)b=a=-1,c=m.prototype.SCIENTIFIC,d=this.ROUND_HALF_UP;else throw"format(): "+r.arguments.length+" arguments given; expected 2 or 6";var e=r.arguments[0],i=r.arguments[1],f,g=0,g=g=0,j=null,l=j=g=0;f=0;g=null;l=j=0;(-1>e||0==e)&&this.badarg("format",1,e);-1>i&&this.badarg("format",2,i);(-1>a||0==a)&&this.badarg("format",3,a);-1>b&&this.badarg("format",4,b);c!=m.prototype.SCIENTIFIC&&c!=m.prototype.ENGINEERING&&(-1==c?c=m.prototype.SCIENTIFIC:this.badarg("format",5,c));if(d!=this.ROUND_HALF_UP)try{-1==d?d=this.ROUND_HALF_UP:new m(9,m.prototype.SCIENTIFIC,!1,d)}catch(h){this.badarg("format",6,d)}f=this.clone(this);-1==b?f.form=m.prototype.PLAIN:f.ind==this.iszero?f.form=m.prototype.PLAIN:(g=f.exp+f.mant.length,f.form=g>b?c:-5>g?c:m.prototype.PLAIN);if(0<=i)a:for(;;){f.form==m.prototype.PLAIN?g=-f.exp:f.form==m.prototype.SCIENTIFIC?g=f.mant.length-1:(g=(f.exp+f.mant.length-1)%3,0>g&&(g=3+g),g++,g=g>=f.mant.length?0:f.mant.length-g);if(g==i)break a;if(g<i){j=this.extend(f.mant,f.mant.length+i-g);f.mant=j;f.exp-=i-g;if(f.exp<this.MinExp)throw"format(): Exponent Overflow: "+f.exp;break a}g-=i;if(g>f.mant.length){f.mant=this.ZERO.mant;f.ind=this.iszero;f.exp=0;continue a}j=f.mant.length-g;l=f.exp;f.round(j,d);if(f.exp-l==g)break a}b=f.layout();if(0<e){c=b.length;f=0;a:for(;0<c;c--,f++){if("."==b[f])break a;if("E"==b[f])break a}f>e&&this.badarg("format",1,e);if(f<e){g=Array(b.length+e-f);e-=f;j=0;for(;0<e;e--,j++)g[j]=" ";this.arraycopy(b,0,g,j,b.length);b=g}}if(0<a){e=b.length-1;f=b.length-1;a:for(;0<e;e--,f--)if("E"==b[f])break a;if(0==f){g=Array(b.length+a+2);this.arraycopy(b,0,g,0,b.length);a+=2;j=b.length;for(;0<a;a--,j++)g[j]=" ";b=g}else if(l=b.length-f-2,l>a&&this.badarg("format",3,a),l<a){g=Array(b.length+a-l);this.arraycopy(b,0,g,0,f+2);a-=l;j=f+2;for(;0<a;a--,j++)g[j]="0";this.arraycopy(b,f+2,g,j,l);b=g}}return b.join("")},F=function(){var a;if(2==F.arguments.length)a=F.arguments[1];else if(1==F.arguments.length)a=this.ROUND_UNNECESSARY;else throw"setScale(): "+F.arguments.length+" given; expected 1 or 2";var b=F.arguments[0],c,d;c=c=0;c=this.scale();if(c==b&&this.form==m.prototype.PLAIN)return this;d=this.clone(this);if(c<=b)c=0==c?d.exp+b:b-c,d.mant=this.extend(d.mant,d.mant.length+c),d.exp=-b;else{if(0>b)throw"setScale(): Negative scale: "+b;c=d.mant.length-(c-b);d=d.round(c,a);d.exp!=-b&&(d.mant=this.extend(d.mant,d.mant.length+1),d.exp-=1)}d.form=m.prototype.PLAIN;return d};v=function(){var a,b=0,c=0;a=Array(190);b=0;a:for(;189>=b;b++){c=b-90;if(0<=c){a[b]=c%10;h.prototype.bytecar[b]=G(c,10);continue a}c+=100;a[b]=c%10;h.prototype.bytecar[b]=G(c,10)-10}return a};var u=function(){var a,b;if(2==u.arguments.length)a=u.arguments[0],b=u.arguments[1];else if(1==u.arguments.length)b=u.arguments[0],a=b.digits,b=b.roundingMode;else throw"round(): "+u.arguments.length+" arguments given; expected 1 or 2";var c,d,e=!1,i=0,f;c=null;c=this.mant.length-a;if(0>=c)return this;this.exp+=c;c=this.ind;d=this.mant;0<a?(this.mant=Array(a),this.arraycopy(d,0,this.mant,0,a),e=!0,i=d[a]):(this.mant=this.ZERO.mant,this.ind=this.iszero,e=!1,i=0==a?d[0]:0);f=0;if(b==this.ROUND_HALF_UP)5<=i&&(f=c);else if(b==this.ROUND_UNNECESSARY){if(!this.allzero(d,a))throw"round(): Rounding necessary"}else if(b==this.ROUND_HALF_DOWN)5<i?f=c:5==i&&(this.allzero(d,a+1)||(f=c));else if(b==this.ROUND_HALF_EVEN)5<i?f=c:5==i&&(this.allzero(d,a+1)?1==this.mant[this.mant.length-1]%2&&(f=c):f=c);else if(b!=this.ROUND_DOWN)if(b==this.ROUND_UP)this.allzero(d,a)||(f=c);else if(b==this.ROUND_CEILING)0<c&&(this.allzero(d,a)||(f=c));else if(b==this.ROUND_FLOOR)0>c&&(this.allzero(d,a)||(f=c));else throw"round(): Bad round value: "+b;0!=f&&(this.ind==this.iszero?(this.mant=this.ONE.mant,this.ind=f):(this.ind==this.isneg&&(f=-f),c=this.byteaddsub(this.mant,this.mant.length,this.ONE.mant,1,f,e),c.length>this.mant.length?(this.exp++,this.arraycopy(c,0,this.mant,0,this.mant.length)):this.mant=c));if(this.exp>this.MaxExp)throw"round(): Exponent Overflow: "+this.exp;return this};h.prototype.div=G;h.prototype.arraycopy=function(a,b,c,d,e){var i;if(d>b)for(i=e-1;0<=i;--i)c[i+d]=a[i+b];else for(i=0;i<e;++i)c[i+d]=a[i+b]};h.prototype.createArrayWithZeros=K;h.prototype.abs=H;h.prototype.add=w;h.prototype.compareTo=x;h.prototype.divide=p;h.prototype.divideInteger=y;h.prototype.max=z;h.prototype.min=A;h.prototype.multiply=B;h.prototype.negate=I;h.prototype.plus=J;h.prototype.pow=C;h.prototype.remainder=D;h.prototype.subtract=E;h.prototype.equals=function(a){var b=0,c=null,d=null;if(null==a||!(a instanceof h)||this.ind!=a.ind)return!1;if(this.mant.length==a.mant.length&&this.exp==a.exp&&this.form==a.form){c=this.mant.length;b=0;for(;0<c;c--,b++)if(this.mant[b]!=a.mant[b])return!1}else{c=this.layout();d=a.layout();if(c.length!=d.length)return!1;a=c.length;b=0;for(;0<a;a--,b++)if(c[b]!=d[b])return!1}return!0};h.prototype.format=r;h.prototype.intValueExact=function(){var a,b=0,c,d=0;a=0;if(this.ind==this.iszero)return 0;a=this.mant.length-1;if(0>this.exp){a+=this.exp;if(!this.allzero(this.mant,a+1))throw"intValueExact(): Decimal part non-zero: "+this.toString();if(0>a)return 0;b=0}else{if(9<this.exp+a)throw"intValueExact(): Conversion overflow: "+this.toString();b=this.exp}c=0;var e=a+b,d=0;for(;d<=e;d++)c*=10,d<=a&&(c+=this.mant[d]);if(9==a+b&&(a=G(c,1E9),a!=this.mant[0])){if(-2147483648==c&&this.ind==this.isneg&&2==this.mant[0])return c;throw"intValueExact(): Conversion overflow: "+this.toString()}return this.ind==this.ispos?c:-c};h.prototype.movePointLeft=function(a){var b;b=this.clone(this);b.exp-=a;return b.finish(this.plainMC,!1)};h.prototype.movePointRight=function(a){var b;b=this.clone(this);b.exp+=a;return b.finish(this.plainMC,!1)};h.prototype.scale=function(){return 0<=this.exp?0:-this.exp};h.prototype.setScale=F;h.prototype.signum=function(){return this.ind};h.prototype.toString=function(){return this.layout().join("")};h.prototype.layout=function(){var a,b=0,b=null,c=0,d=0;a=0;var d=null,e,b=0;a=Array(this.mant.length);c=this.mant.length;b=0;for(;0<c;c--,b++)a[b]=this.mant[b]+"";if(this.form!=m.prototype.PLAIN){b="";this.ind==this.isneg&&(b+="-");c=this.exp+a.length-1;if(this.form==m.prototype.SCIENTIFIC)b+=a[0],1<a.length&&(b+="."),b+=a.slice(1).join("");else if(d=c%3,0>d&&(d=3+d),c-=d,d++,d>=a.length){b+=a.join("");for(a=d-a.length;0<a;a--)b+="0"}else b+=a.slice(0,d).join(""),b=b+"."+a.slice(d).join("");0!=c&&(0>c?(a="-",c=-c):a="+",b+="E",b+=a,b+=c);return b.split("")}if(0==this.exp){if(0<=this.ind)return a;d=Array(a.length+1);d[0]="-";this.arraycopy(a,0,d,1,a.length);return d}c=this.ind==this.isneg?1:0;e=this.exp+a.length;if(1>e){b=c+2-this.exp;d=Array(b);0!=c&&(d[0]="-");d[c]="0";d[c+1]=".";var i=-e,b=c+2;for(;0<i;i--,b++)d[b]="0";this.arraycopy(a,0,d,c+2-e,a.length);return d}if(e>a.length){d=Array(c+e);0!=c&&(d[0]="-");this.arraycopy(a,0,d,c,a.length);e-=a.length;b=c+a.length;for(;0<e;e--,b++)d[b]="0";return d}b=c+1+a.length;d=Array(b);0!=c&&(d[0]="-");this.arraycopy(a,0,d,c,e);d[c+e]=".";this.arraycopy(a,e,d,c+e+1,a.length-e);return d};h.prototype.intcheck=function(a,b){var c;c=this.intValueExact();if(c<a||c>b)throw"intcheck(): Conversion overflow: "+c;return c};h.prototype.dodivide=function(a,b,c,d){var e,i,f,g,j,l,k,q,t,s=0,n=0,p=0;i=i=n=n=n=0;e=null;e=e=0;e=null;c.lostDigits&&this.checkdigits(b,c.digits);e=this;if(0==b.ind)throw"dodivide(): Divide by 0";if(0==e.ind)return c.form!=m.prototype.PLAIN?this.ZERO:-1==d?e:e.setScale(d);i=c.digits;0<i?(e.mant.length>i&&(e=this.clone(e).round(c)),b.mant.length>i&&(b=this.clone(b).round(c))):(-1==d&&(d=e.scale()),i=e.mant.length,d!=-e.exp&&(i=i+d+e.exp),i=i-(b.mant.length-1)-b.exp,i<e.mant.length&&(i=e.mant.length),i<b.mant.length&&(i=b.mant.length));f=e.exp-b.exp+e.mant.length-b.mant.length;if(0>f&&"D"!=a)return"I"==a?this.ZERO:this.clone(e).finish(c,!1);g=new h;g.ind=e.ind*b.ind;g.exp=f;g.mant=this.createArrayWithZeros(i+1);j=i+i+1;f=this.extend(e.mant,j);l=j;k=b.mant;q=j;t=10*k[0]+1;1<k.length&&(t+=k[1]);j=0;a:for(;;){s=0;b:while(!0){if(l<q)break b;if(l==q){c:do{var r=l,n=0;for(;0<r;r--,n++){p=n<k.length?k[n]:0;if(f[n]<p)break b;if(f[n]>p)break c}s++;g.mant[j]=s;j++;f[0]=0;break a}while(0);n=f[0]}else n=10*f[0],1<l&&(n+=f[1]);n=G(10*n,t);0==n&&(n=1);s+=n;f=this.byteaddsub(f,l,k,q,-n,!0);if(0!=f[0])continue b;p=l-2;n=0;c:for(;n<=p;n++){if(0!=f[n])break c;l--}if(0==n)continue b;this.arraycopy(f,n,f,0,l)}if(0!=j||0!=s){g.mant[j]=s;j++;if(j==i+1)break a;if(0==f[0])break a}if(0<=d&&-g.exp>d)break a;if("D"!=a&&0>=g.exp)break a;g.exp-=1;q--}0==j&&(j=1);if("I"==a||"R"==a){if(j+g.exp>i)throw"dodivide(): Integer overflow";if("R"==a){do{if(0==g.mant[0])return this.clone(e).finish(c,!1);if(0==f[0])return this.ZERO;g.ind=e.ind;i=i+i+1-e.mant.length;g.exp=g.exp-i+e.exp;i=l;n=i-1;b:for(;1<=n&&g.exp<e.exp&&g.exp<b.exp;n--){if(0!=f[n])break b;i--;g.exp+=1}i<f.length&&(e=Array(i),this.arraycopy(f,0,e,0,i),f=e);g.mant=f;return g.finish(c,!1)}while(0)}}else 0!=f[0]&&(e=g.mant[j-1],0==e%5&&(g.mant[j-1]=e+1));if(0<=d)return j!=g.mant.length&&(g.exp-=g.mant.length-j),e=g.mant.length-(-g.exp-d),g.round(e,c.roundingMode),g.exp!=-d&&(g.mant=this.extend(g.mant,g.mant.length+1),g.exp-=1),g.finish(c,!0);if(j==g.mant.length)g.round(c);else{if(0==g.mant[0])return this.ZERO;e=Array(j);this.arraycopy(g.mant,0,e,0,j);g.mant=e}return g.finish(c,!0)};h.prototype.bad=function(a,b){throw a+"Not a number: "+b};h.prototype.badarg=function(a,b,c){throw"Bad argument "+b+" to "+a+": "+c};h.prototype.extend=function(a,b){var c;if(a.length==b)return a;c=K(b);this.arraycopy(a,0,c,0,a.length);return c};h.prototype.byteaddsub=function(a,b,c,d,e,i){var f,g,j,h,k,m,p=0;f=m=0;f=a.length;g=c.length;b-=1;h=j=d-1;h<b&&(h=b);d=null;i&&h+1==f&&(d=a);null==d&&(d=this.createArrayWithZeros(h+1));k=!1;1==e?k=!0:-1==e&&(k=!0);m=0;p=h;a:for(;0<=p;p--){0<=b&&(b<f&&(m+=a[b]),b--);0<=j&&(j<g&&(m=k?0<e?m+c[j]:m-c[j]:m+c[j]*e),j--);if(10>m&&0<=m){do{d[p]=m;m=0;continue a}while(0)}m+=90;d[p]=this.bytedig[m];m=this.bytecar[m]}if(0==m)return d;c=null;i&&h+2==a.length&&(c=a);null==c&&(c=Array(h+2));c[0]=m;a=h+1;f=0;for(;0<a;a--,f++)c[f+1]=d[f];return c};h.prototype.diginit=v;h.prototype.clone=function(a){var b;b=new h;b.ind=a.ind;b.exp=a.exp;b.form=a.form;b.mant=a.mant;return b};h.prototype.checkdigits=function(a,b){if(0!=b){if(this.mant.length>b&&!this.allzero(this.mant,b))throw"Too many digits: "+this.toString();if(null!=a&&a.mant.length>b&&!this.allzero(a.mant,b))throw"Too many digits: "+a.toString();}};h.prototype.round=u;h.prototype.allzero=function(a,b){var c=0;0>b&&(b=0);var d=a.length-1,c=b;for(;c<=d;c++)if(0!=a[c])return!1;return!0};h.prototype.finish=function(a,b){var c=0,d=0,e=null,c=d=0;0!=a.digits&&this.mant.length>a.digits&&this.round(a);if(b&&a.form!=m.prototype.PLAIN){c=this.mant.length;d=c-1;a:for(;1<=d;d--){if(0!=this.mant[d])break a;c--;this.exp++}c<this.mant.length&&(e=Array(c),this.arraycopy(this.mant,0,e,0,c),this.mant=e)}this.form=m.prototype.PLAIN;c=this.mant.length;d=0;for(;0<c;c--,d++)if(0!=this.mant[d]){0<d&&(e=Array(this.mant.length-d),this.arraycopy(this.mant,d,e,0,this.mant.length-d),this.mant=e);d=this.exp+this.mant.length;if(0<d){if(d>a.digits&&0!=a.digits&&(this.form=a.form),d-1<=this.MaxExp)return this}else-5>d&&(this.form=a.form);d--;if(d<this.MinExp||d>this.MaxExp){b:do{if(this.form==m.prototype.ENGINEERING&&(c=d%3,0>c&&(c=3+c),d-=c,d>=this.MinExp&&d<=this.MaxExp))break b;throw"finish(): Exponent Overflow: "+d}while(0)}return this}this.ind=this.iszero;if(a.form!=m.prototype.PLAIN)this.exp=0;else if(0<this.exp)this.exp=0;else if(this.exp<this.MinExp)throw"finish(): Exponent Overflow: "+this.exp;this.mant=this.ZERO.mant;return this};h.prototype.isGreaterThan=function(a){return 0<this.compareTo(a)};h.prototype.isLessThan=function(a){return 0>this.compareTo(a)};h.prototype.isGreaterThanOrEqualTo=function(a){return 0<=this.compareTo(a)};h.prototype.isLessThanOrEqualTo=function(a){return 0>=this.compareTo(a)};h.prototype.isPositive=function(){return 0<this.compareTo(h.prototype.ZERO)};h.prototype.isNegative=function(){return 0>this.compareTo(h.prototype.ZERO)};h.prototype.isZero=function(){return this.equals(h.prototype.ZERO)};h.ROUND_CEILING=h.prototype.ROUND_CEILING=m.prototype.ROUND_CEILING;h.ROUND_DOWN=h.prototype.ROUND_DOWN=m.prototype.ROUND_DOWN;h.ROUND_FLOOR=h.prototype.ROUND_FLOOR=m.prototype.ROUND_FLOOR;h.ROUND_HALF_DOWN=h.prototype.ROUND_HALF_DOWN=m.prototype.ROUND_HALF_DOWN;h.ROUND_HALF_EVEN=h.prototype.ROUND_HALF_EVEN=m.prototype.ROUND_HALF_EVEN;h.ROUND_HALF_UP=h.prototype.ROUND_HALF_UP=m.prototype.ROUND_HALF_UP;h.ROUND_UNNECESSARY=h.prototype.ROUND_UNNECESSARY=m.prototype.ROUND_UNNECESSARY;h.ROUND_UP=h.prototype.ROUND_UP=m.prototype.ROUND_UP;h.prototype.ispos=1;h.prototype.iszero=0;h.prototype.isneg=-1;h.prototype.MinExp=-999999999;h.prototype.MaxExp=999999999;h.prototype.MinArg=-999999999;h.prototype.MaxArg=999999999;h.prototype.plainMC=new m(0,m.prototype.PLAIN);h.prototype.bytecar=Array(190);h.prototype.bytedig=v();h.ZERO=h.prototype.ZERO=new h("0");h.ONE=h.prototype.ONE=new h("1");h.TEN=h.prototype.TEN=new h("10");v=h;"function"===typeof define&&null!=define.amd?define({BigDecimal:v,MathContext:m}):"object"===typeof this&&(this.BigDecimal=v,this.MathContext=m)}).call(this) | |
"use strict";var OSC,OSG,canvas,graphics,workers,repaintTimeout,xmin_requested,ymin_requested,xmax_requested,ymax_requested,xmin,ymin,xmax,ymax,dx,dy,xminArray,yvalArray,dxArray,jobs,jobsCompleted,jobStartTime,timePerJob,highPrecision,maxIterations,palette,stretchPalette,fixedPaletteLength,paletteLength,paletteOffsetFraction,paletteColors,savedIterationCounts,savedIterationCounts2ndPass,imageData,hres,vres,digits,chunks,copyOfCurrentPalette,paletteInEditor,paletteLengthInEditor,paletteOffsetFractionInEditor,histogram,histogramPalette,palettePreview,leftRightColorsLocked,saveRightColorWhileLocked,colorsInEditor,colorSliders,paletteLengthSlider,paletteOffsetSlider,updateDuringDrag,HP_CUTOFF_EXP=16,HP_CUTOFF=new BigDecimal("1e-16"),TEN=new BigDecimal("10"),TWO=new BigDecimal("2"),ArrayType=window.Uint32Array||Array,wokerCount=1,jobNum=0,running=!1,workerCount=1,COMPUTING_FIRST_PASS=1,DONE_FIRST_PASS=2,COMPUTING_SECOND_PASS=3,IDLE=4,state=IDLE,dragbox=null,currentXML=null,undoList=null,undoCount=0,applyUndoInProgress=!1,paletteEditInProgress=!1,interlaced=!0,interlaceOrder=function(){for(var e=[127],t=64;t>=1;t/=2)for(var n=e.length,i=0;i<n;i++)e.push(e[i]-t);return e}(),twoTo16=new BigDecimal("65536"),log2of10=Math.log(10)/Math.log(2);function convert(e,t,n){var i=!1;-1==t.signum()&&(i=!0,t=t.negate()),e[0]=Number(t.setScale(0,BigDecimal.ROUND_DOWN).toString());for(var o=1;o<n;o++)t=(t=t.subtract(new BigDecimal(""+e[o-1]))).multiply(twoTo16),e[o]=Number(t.setScale(0,BigDecimal.ROUND_DOWN).toString());i&&function e(t,n){for(var i=0;i<n;i++)t[i]=65535-t[i];++t[n-1];for(var i=n-1;i>0&&(65536&t[i])!=0;i--)t[i]&=65535,++t[i-1];t[0]&=65535}(e,n)}function setLimits(e,t,n,i,o){var a=[xmin_requested,xmax_requested,ymin_requested,ymax_requested];if(xmin_requested=e,xmax_requested=t,ymin_requested=n,ymax_requested=i,0>xmax_requested.compareTo(xmin_requested)){var l=xmin_requested;xmin_requested=xmax_requested,xmax_requested=l}if(0>ymax_requested.compareTo(ymin_requested)){var l=ymax_requested;ymax_requested=ymin_requested,ymin_requested=l}checkAspect(),o&&addUndoItem("Change Limits",a,[xmin_requested,xmax_requested,ymin_requested,ymax_requested])}function checkAspect(){xmin=xmin_requested,xmax=xmax_requested,ymin=ymin_requested,ymax=ymax_requested,xmin.scale()<HP_CUTOFF_EXP+8&&(xmin=xmin.setScale(HP_CUTOFF_EXP+8)),xmax.scale()<HP_CUTOFF_EXP+8&&(xmax=xmax.setScale(HP_CUTOFF_EXP+8)),ymin.scale()<HP_CUTOFF_EXP+8&&(ymin=ymin.setScale(HP_CUTOFF_EXP+8)),ymax.scale()<HP_CUTOFF_EXP+8&&(ymax=ymax.setScale(HP_CUTOFF_EXP+8));var e=xmax.subtract(xmin).setScale(2*Math.max(xmax.scale(),HP_CUTOFF_EXP),BigDecimal.ROUND_HALF_EVEN);e=e.divide(new BigDecimal(""+canvas.width),BigDecimal.ROUND_HALF_EVEN);for(var t=0;0>e.compareTo(TWO);)t++,e=e.multiply(TEN);t<HP_CUTOFF_EXP&&(t=HP_CUTOFF_EXP);var n=t+5+Math.floor((t-10)/10);xmin=xmin.setScale(n,BigDecimal.ROUND_HALF_EVEN),xmax=xmax.setScale(n,BigDecimal.ROUND_HALF_EVEN),ymin=ymin.setScale(n,BigDecimal.ROUND_HALF_EVEN),ymax=ymax.setScale(n,BigDecimal.ROUND_HALF_EVEN);var i=xmax.subtract(xmin),o=ymax.subtract(ymin),a=i.divide(o,BigDecimal.ROUND_HALF_EVEN),l=new BigDecimal(""+canvas.width/canvas.height);if(0>a.compareTo(l)){var r=i.multiply(l).divide(a,BigDecimal.ROUND_HALF_EVEN),s=xmax.add(xmin).divide(TWO,BigDecimal.ROUND_HALF_EVEN);xmax=s.add(r.divide(TWO,BigDecimal.ROUND_HALF_EVEN)).setScale(n,BigDecimal.ROUND_HALF_EVEN),xmin=s.subtract(r.divide(TWO,BigDecimal.ROUND_HALF_EVEN)).setScale(n,BigDecimal.ROUND_HALF_EVEN)}else if(a.compareTo(l)>0){var d=o.multiply(a).divide(l,BigDecimal.ROUND_HALF_EVEN),s=ymax.add(ymin).divide(TWO,BigDecimal.ROUND_HALF_EVEN);ymax=s.add(d.divide(TWO,BigDecimal.ROUND_HALF_EVEN)).setScale(n,BigDecimal.ROUND_HALF_EVEN),ymin=s.subtract(d.divide(TWO,BigDecimal.ROUND_HALF_EVEN)).setScale(n,BigDecimal.ROUND_HALF_EVEN)}}function doDraw(){graphics.drawImage(OSC,0,0),dragbox&&dragbox.width>2&&dragbox.height>2&&dragbox.draw()}function repaint(){if(doDraw(),running){repaintTimeout=setTimeout(repaint,500);var e=state==COMPUTING_SECOND_PASS?" second pass":"",t=highPrecision?"high precision, "+digits+" digits":"normal precision";document.getElementById("status").innerHTML="Computing"+e+", "+t+"... Completed "+jobsCompleted+" of "+canvas.height+" rows"}else document.getElementById("status").innerHTML="Idle"}function genNewWorker(){return new Worker(window.URL.createObjectURL(new Blob([document.querySelector("#service-worker").textContent],{type:"text/javascript"})))}function newWorkers(e){var t;if(workers)for(t=0;t<workers.length;t++)workers[t].terminate();for(t=0,workers=[];t<e;t++)workers[t]=genNewWorker(),workers[t].onmessage=jobFinished}function stopJob(){running&&(jobNum++,running=!1,document.getElementById("stop").disabled=!0,repaintTimeout&&clearTimeout(repaintTimeout),repaintTimeout=null,repaint(),(timePerJob<0||timePerJob>150)&&newWorkers(workerCount))}function startJob(){running&&stopJob(),graphics.fillRect(0,0,canvas.width,canvas.height),OSG.fillStyle="#BBBBBB",OSG.fillRect(0,0,canvas.width,canvas.height),hres=Math.round((imageData=OSG.getImageData(0,0,canvas.width,1)).width/canvas.width),vres=imageData.height,dx=xmax.subtract(xmin).divide(new BigDecimal(""+(canvas.width-1)),BigDecimal.ROUND_HALF_EVEN),highPrecision=0>(dy=ymax.subtract(ymin).divide(new BigDecimal(""+(canvas.height-1)),BigDecimal.ROUND_HALF_EVEN)).compareTo(HP_CUTOFF),jobs=[];var e=ymax.add(new BigDecimal("0")),t=canvas.height,n=canvas.width;if(savedIterationCounts=Array(t),savedIterationCounts2ndPass=Array(t+1),highPrecision){chunks=Math.floor((digits=xmin.scale())*log2of10/16+2),dxArray=new ArrayType(chunks+1),convert(xminArray=new ArrayType(chunks+1),xmin,chunks+1),convert(dxArray,dx,chunks+1);for(var i=0;i<t;i++){var o=new ArrayType(chunks+1);convert(o,e,chunks+1),jobs[t-1-i]={row:i,columns:n,xmin:xminArray,dx:dxArray,yVal:o},e=e.subtract(dy)}}else for(var a=Number(xmin.toString()),l=Number(ymax.toString()),r=Number(dx.toString()),s=Number(dy.toString()),i=0;i<t;i++){var d=l-i*s;jobs[t-1-i]={row:i,columns:n,xmin:a,dx:r,yVal:d}}if(interlaced){var c=jobs;jobs=[];for(var u=0;u<interlaceOrder.length;u++)for(var h=interlaceOrder[u];h<c.length;h+=interlaceOrder.length)jobs.push(c[h])}jobsCompleted=0;for(var u=0;u<workerCount;u++){var h=jobs.pop();h.workerNum=u,workers[u].postMessage(["setup",jobNum,maxIterations,highPrecision,u]),workers[u].postMessage(["task",h.row,h.columns,h.xmin,h.dx,h.yVal])}running=!0,document.getElementById("stop").disabled=!1;var m=highPrecision?"high precision, "+digits+" digits":"normal precision";document.getElementById("status").innerHTML="Computing, "+m+"...",repaintTimeout=setTimeout(repaint,333),timePerJob=-1,jobStartTime=new Date().getTime(),state=COMPUTING_FIRST_PASS,currentXML=currentExampletoXML()}function jobFinished(e){var t=e.data;if(t[0]==jobNum){if(jobs.length>0){var n=workers[t[3]],i=jobs.pop();n.postMessage(["task",i.row,i.columns,i.xmin,i.dx,i.yVal])}timePerJob=(new Date().getTime()-jobStartTime)/jobsCompleted;var o=t[2],a=t[1];state==COMPUTING_FIRST_PASS?(savedIterationCounts[a]=o,putRow(a),paletteEditInProgress&&(histogram.update(o),palettePreview.update(a,o))):(savedIterationCounts2ndPass[a]=o,a>0&&putRow(a-1)),jobsCompleted++,state==COMPUTING_FIRST_PASS?jobsCompleted==canvas.height&&(state=DONE_FIRST_PASS,stopJob(),document.getElementById("secondpass").checked&&startSecondPass()):jobsCompleted==canvas.height+1&&(state=IDLE,stopJob())}}function startSecondPass(){running&&stopJob(),dx=xmax.subtract(xmin).divide(new BigDecimal(""+(canvas.width-1)),BigDecimal.ROUND_HALF_EVEN),dy=ymax.subtract(ymin).divide(new BigDecimal(""+(canvas.height-1)),BigDecimal.ROUND_HALF_EVEN);var e=dx.divide(TWO,BigDecimal.ROUND_HALF_EVEN),t=dy.divide(TWO,BigDecimal.ROUND_HALF_EVEN);highPrecision=0>dy.compareTo(HP_CUTOFF),jobs=[];var n=ymax.add(t),i=xmin.subtract(e),o=canvas.height+1,a=canvas.width+1;if(highPrecision){chunks=Math.floor((digits=xmin.scale())*log2of10/16+2),dxArray=new ArrayType(chunks+1),convert(xminArray=new ArrayType(chunks+1),i,chunks+1),convert(dxArray,dx,chunks+1);for(var l=0;l<o;l++){var r=new ArrayType(chunks+1);convert(r,n,chunks+1),jobs[o-1-l]={row:l,columns:a,xmin:xminArray,dx:dxArray,yVal:r},n=n.subtract(dy)}}else for(var s=Number(i.toString()),d=Number(dx.toString()),c=Number(dy.toString()),u=Number(ymax.toString())+c/2,l=0;l<o;l++){var h=u-l*c;jobs[o-1-l]={row:l,columns:a,xmin:s,dx:d,yVal:h}}jobsCompleted=0;for(var m=0;m<workerCount;m++){var g=jobs.pop();g.workerNum=m,workers[m].postMessage(["setup",jobNum,maxIterations,highPrecision,m]),workers[m].postMessage(["task",g.row,g.columns,g.xmin,g.dx,g.yVal])}running=!0,document.getElementById("stop").disabled=!1;var $=highPrecision?"high precision, "+digits+" digits":"normal precision";document.getElementById("status").innerHTML="Computing 2nd Pass, "+$+"...",repaintTimeout=setTimeout(repaint,500),timePerJob=-1,jobStartTime=new Date().getTime(),state=COMPUTING_SECOND_PASS}function putRow(e){var t,n,i,o=savedIterationCounts[e],a=savedIterationCounts2ndPass[e],l=savedIterationCounts2ndPass[e+1],r=a&&l;if(r){var s=(n=a[0])<0?[0,0,0]:paletteColors[n%paletteLength],d=(n=l[0])<0?[0,0,0]:paletteColors[n%paletteLength];t=[s[0]+d[0],s[1]+d[1],s[2]+d[2]]}for(var c=canvas.width,u=0;u<c;u++){if(i=(n=o[u])<0?[0,0,0]:paletteColors[o[u]%paletteLength],r){var s=(n=a[u+1])<0?[0,0,0]:paletteColors[n%paletteLength],d=(n=l[u+1])<0?[0,0,0]:paletteColors[n%paletteLength],h=[s[0]+d[0],s[1]+d[1],s[2]+d[2]];i=[(4*i[0]+t[0]+h[0])/8,(4*i[1]+t[1]+h[1])/8,(4*i[2]+t[2]+h[2])/8],t=h}for(var m=0;m<vres;m++)for(var g=(c*m+u)*4*hres,$=0;$<hres;$++)imageData.data[g]=i[0],imageData.data[g+1]=i[1],imageData.data[g+2]=i[2],imageData.data[g+3]=255}OSG.putImageData(imageData,0,e)}function setDefaults(){var e=currentXML;stopJob(),setLimits(new BigDecimal("-2.2"),new BigDecimal("0.8"),new BigDecimal("-1.2"),new BigDecimal("1.2"),!1),stretchPalette=!1,fixedPaletteLength=250,maxIterations=1e3,paletteOffsetFraction=0,palette=new Palette,createPaletteColors(),document.getElementById("maxIterSelect").value="1000",document.getElementById("custommaxiter").style.display="none",document.getElementById("custompallen").style.display="none",document.getElementById("custoffset").style.display="none",document.getElementById("customsize").style.display="none",document.getElementById("paletteLengthSelect").value="250",document.getElementById("paletteOffsetSelect").value="0",document.getElementById("imagesize").value="800 600",(800!=canvas.width||600!=canvas.height)&&(canvas.width=800,canvas.height=600,OSC.width=800,OSC.height=600,checkAspect()),startJob(),undoList&&addUndoItem("Restore Defaults",e,currentXML)}function remapColors(){for(var e=0;e<canvas.height;e++)savedIterationCounts[e]&&putRow(e);doDraw(),currentXML=currentExampletoXML()}function createPaletteColors(){var e=Math.round(paletteOffsetFraction*(paletteLength=stretchPalette?maxIterations:fixedPaletteLength));paletteColors=palette.makeRGBs(paletteLength,e)}function DragBox(e,t){this.x=this.left=e,this.y=this.top=t,this.width=0,this.height=0}function doZoomInOnRect(e,t,n,i){var o,a,l,r,s=new BigDecimal(""+Math.round(e)),d=new BigDecimal(""+Math.round(t)),c=new BigDecimal(""+Math.round(n)),u=new BigDecimal(""+Math.round(i)),h=new BigDecimal(""+canvas.width),m=new BigDecimal(""+canvas.height),g=xmax.subtract(xmin).divide(h,BigDecimal.ROUND_HALF_EVEN),$=ymax.subtract(ymin).divide(m,BigDecimal.ROUND_HALF_EVEN);o=xmin.add(g.multiply(s)),r=ymax.subtract($.multiply(d));var p=g.multiply(c),f=$.multiply(u);a=o.add(p),l=r.subtract(f),setLimits(o,a,l,r,!0)}function doZoomOutFromRect(e,t,n,i){var o,a,l,r,s=new BigDecimal(""+Math.round(e)),d=new BigDecimal(""+Math.round(t)),c=new BigDecimal(""+Math.round(n)),u=new BigDecimal(""+Math.round(i)),h=new BigDecimal(""+canvas.width),m=new BigDecimal(""+canvas.height),g=xmax.subtract(xmin).divide(c,BigDecimal.ROUND_HALF_EVEN),$=ymax.subtract(ymin).divide(u,BigDecimal.ROUND_HALF_EVEN);o=xmin.subtract(g.multiply(s)),r=ymax.add($.multiply(d));var p=g.multiply(h),f=$.multiply(m);a=o.add(p),l=r.subtract(f),setLimits(o,a,l,r,!0)}function zoom(e,t,n,i){stopJob();var o,a,l,r,s=new BigDecimal(""+n),d=new BigDecimal(""+Math.round(e)),c=new BigDecimal(""+Math.round(t)),u=new BigDecimal(""+canvas.width),h=new BigDecimal(""+canvas.height),m=xmax.subtract(xmin),g=ymax.subtract(ymin),$=m.multiply(s),p=g.multiply(s);if($.compareTo(new BigDecimal("100"))>0){document.getElementById("status").innerHTML="Zooming out that far would reduce the whole Mandelbrot set to a dot. Ignored.";return}var f=$.divide(u,BigDecimal.ROUND_HALF_EVEN),v=p.divide(h,BigDecimal.ROUND_HALF_EVEN),y=xmin.add(d.multiply(m).divide(u,BigDecimal.ROUND_HALF_EVEN)),E=ymax.subtract(c.multiply(g).divide(h,BigDecimal.ROUND_HALF_EVEN));i?(o=y.subtract($.divide(TWO,BigDecimal.ROUND_HALF_EVEN)),r=E.add(p.divide(TWO,BigDecimal.ROUND_HALF_EVEN))):(o=y.subtract(d.multiply(f)),r=E.add(c.multiply(v))),l=r.subtract(p),a=o.add($),setLimits(o,a,l,r,!0),startJob()}function setUpDragging(){var e,t,n;dragbox=null,canvas.addEventListener("dblclick",function e(t){if(!dragbox&&0==t.button){var n,i=canvas.getBoundingClientRect(),o=t.clientX-i.left;zoom(o,t.clientY-i.top,t.shiftKey?2:.5,!t.altKey)}},!1),new Mouser(canvas,function i(o,a,l){return(!l||0==l.button)&&(t=o,n=a,dragbox=null,e=!(l&&l.shiftKey),!0)},function e(i,o){if(null==dragbox){if(3>Math.abs(t-i)&&3>Math.abs(n-o))return;dragbox=new DragBox(t,n)}dragbox.setCorner(i,o),doDraw()},function t(){null!=dragbox&&(dragbox.zoom(e),dragbox=null,doDraw())},!0)}function Mouser(e,t,n,i,o){var a=!1;function l(t){if(a){var i,o=e.getBoundingClientRect();n(t.clientX-o.left,t.clientY-o.top,t)}}function r(t){a&&(a=!1,(o?e:document).removeEventListener("mousemove",l,!1),document.removeEventListener("mouseup",r,!1),i(t))}function s(t){if(a){if(t.preventDefault(),1!=t.touches.length){c();return}var i,o=e.getBoundingClientRect();n(t.touches[0].clientX-o.left,t.touches[0].clientY-o.top)}}function d(e){c()}function c(){a&&(e.removeEventListener("touchmove",s),e.removeEventListener("touchend",d),e.removeEventListener("touchcancel",c),i(),a=!1)}e.addEventListener("mousedown",function n(i){if(!a){var s,d=e.getBoundingClientRect();t(i.clientX-d.left,i.clientY-d.top,i)&&(a=!0,(o?e:document).addEventListener("mousemove",l,!1),document.addEventListener("mouseup",r,!1))}},!1),e.addEventListener("touchstart",function n(i){if(1!=i.touches.length){c();return}if(i.preventDefault(),!a){var o,l=e.getBoundingClientRect();t(i.touches[0].clientX-l.left,i.touches[0].clientY-l.top)&&(a=!0,e.addEventListener("touchmove",s),e.addEventListener("touchend",d),e.addEventListener("touchcancel",c))}},!1)}function changeWorkerCount(){var e=Number(document.getElementById("threadCountSelect").value);if(!workers||e!=workers.length){var t=running;running&&stopJob(),workerCount=e,newWorkers(e),t&&startJob();try{localStorage.setItem("mandelbrotWorkerCount",""+e)}catch(n){}}}function changeMaxIterations(){var e,t=document.getElementById("maxIterSelect").value;"Custom"==t?(document.getElementById("maxiterinput").value=""+maxIterations,document.getElementById("custommaxiter").style.display="inline"):(document.getElementById("custommaxiter").style.display="none",setMaxIterations(e=Number(t)))}function setMaxIterations(e){if(e!=maxIterations){var t=maxIterations;stopJob(),maxIterations=e,createPaletteColors(),startJob(),addUndoItem("Change MaxIterations",t,maxIterations)}}function doCustomMaxIterations(){var e=Math.round(Number(document.getElementById("maxiterinput").value.trim()));if(isNaN(e)||e<10){document.getElementById("status").innerHTML="Illegal value for max iterations. Must be an integer greater than 9.";return}setMaxIterations(e)}function changePaletteLength(){var e,t=document.getElementById("paletteLengthSelect").value;if("Custom"==t){var n=stretchPalette?maxIterations:fixedPaletteLength;stretchPalette=!1,fixedPaletteLength=n,document.getElementById("palleninput").value=""+n,document.getElementById("custompallen").style.display="inline"}else if("Match"==t){var i=[stretchPalette,stretchPalette?maxIterations:fixedPaletteLength];stretchPalette=!0,paletteLength!=maxIterations&&(stopJob(),createPaletteColors(),startJob(),addUndoItem("Change PaletteLength",i,[stretchPalette,paletteLength])),document.getElementById("custompallen").style.display="none"}else(e=parseInt(t))!=paletteLength&&addUndoItem("Change PaletteLength",[stretchPalette,paletteLength],[!1,e]),setFixedPaletteLength(e),document.getElementById("custompallen").style.display="none"}function setFixedPaletteLength(e){stretchPalette=!1,(fixedPaletteLength=e)!=paletteLength&&(createPaletteColors(),remapColors())}function doCustomPaletteLength(){var e,t=Math.round(Number(document.getElementById("palleninput").value.trim()));if(t!=fixedPaletteLength){if(isNaN(t)||t<1){document.getElementById("status").innerHTML="Illegal value for number of colors. Must be an integer greater than zero.";return}addUndoItem("Change PaletteLength",[!1,fixedPaletteLength],[!1,t]),setFixedPaletteLength(t)}}function changePaletteOffset(){var e=document.getElementById("paletteOffsetSelect").value;if("Custom"==e){var t=100*paletteOffsetFraction;document.getElementById("offsetinput").value=t==Math.round(t)?t:t.toPrecision(3),document.getElementById("custoffset").style.display="inline"}else setPaletteOffset(Number(e)),document.getElementById("custoffset").style.display="none"}function doApplyCustomPaletteOffset(){var e=Number(document.getElementById("offsetinput").value.trim());isNaN(e)||e<0||e>100?document.getElementById("status").innerHTML="Illegal value for percentage offset. Must be a number in the range 0 to 100.":setPaletteOffset(e/100)}function setPaletteOffset(e){document.getElementById("status").innerHTML="Idle",e!=paletteOffsetFraction&&(addUndoItem("Change PaletteOffset",paletteOffsetFraction,e),paletteOffsetFraction=e,createPaletteColors(),remapColors())}function changeInterlaced(){var e=document.getElementById("interlaced").checked;e!=interlaced&&(interlaced=e,running&&(stopJob(),startJob()))}function changeImageSize(){var e=document.getElementById("imagesize").value;if("Custom"==e)document.getElementById("customwidth").value=""+canvas.width,document.getElementById("customheight").value=""+canvas.height,document.getElementById("customsize").style.display="inline";else{document.getElementById("customsize").style.display="none";var t,n=e.split(" ");setImageSize(Number(n[0]),Number(n[1]),!0)}}function setImageSize(e,t){if(e!=canvas.width||t!=canvas.height){var n=[canvas.width,canvas.height];stopJob(),canvas.width=e,canvas.height=t,OSC.width=e,OSC.height=t,checkAspect(),startJob(),addUndoItem("Change Image Size",n,[canvas.width,canvas.height])}}function doCustomSize(){var e=Math.round(Number(document.getElementById("customwidth").value.trim())),t=Math.round(Number(document.getElementById("customheight").value.trim()));if(isNaN(e)||e<50||e>1e4){document.getElementById("status").innerHTML="Illegal value for image width. Must be an integer in the range 50 to 10000.";return}if(isNaN(t)||t<50||t>1e4){document.getElementById("status").innerHTML="Illegal value for image height. Must be an integer in the range 50 to 10000.";return}setImageSize(e,t,!0)}function doApplyStandardPalette(){var e=document.getElementById("standardPaletteSelect").value,t=palette;palette=Palette.createStandardPalette(e),createPaletteColors(),remapColors(),addUndoItem("Change Palette",t.copy(),palette.copy())}function changeSecondPass(){document.getElementById("secondpass").checked&&!running&&state==DONE_FIRST_PASS&&startSecondPass()}function doZoomIn(){zoom(canvas.width/2,canvas.height/2,document.getElementById("zoomInAmount").value,!1)}function doZoomOut(){zoom(canvas.width/2,canvas.height/2,document.getElementById("zoomOutAmount").value,!1)}function doUndo(){if(undoCount>0){var e=undoList[undoCount-1];undoCount--,document.getElementById("undo").disabled=0==undoCount,document.getElementById("undo").innerHTML=undoCount?"Undo "+undoList[undoCount-1].name:"Undo",document.getElementById("redo").disabled=!1,document.getElementById("redo").innerHTML="Redo "+e.name,applyUndoItem(e.name,e.oldValue)}}function doRedo(){if(undoCount<undoList.length){var e=undoList[undoCount];undoCount++,document.getElementById("undo").disabled=!1,document.getElementById("undo").innerHTML="Undo "+e.name,document.getElementById("redo").disabled=undoCount==undoList.length,document.getElementById("redo").innerHTML=undoCount<undoList.length?"Redo "+undoList[undoCount].name:"Redo",applyUndoItem(e.name,e.newValue)}}function addUndoItem(e,t,n){!applyUndoInProgress&&(undoList.length=undoCount,undoList.push({name:e,oldValue:t,newValue:n}),undoList.length>100&&undoList.shift(),undoCount=undoList.length,document.getElementById("undo").disabled=!1,document.getElementById("undo").innerHTML="Undo "+e,document.getElementById("redo").disabled=!0,document.getElementById("redo").innerHTML="Redo")}function applyUndoItem(e,t){switch(applyUndoInProgress=!0,e){case"Restore Defaults":case"Import Example":case"Load File":installExampleFromXML(t,!1,!0);break;case"Change PaletteOffset":o(t),createPaletteColors(),remapColors();break;case"Change Limits":stopJob(),setLimits(t[0],t[1],t[2],t[3],!1),startJob();break;case"Change Image Size":setImageSize(t[0],t[1]);var n=t[0]+" "+t[1];0>["200 150","400 300","640 480","800 600","1024 768","1200 900","1600 900","425 550","850 1100"].indexOf(n)?(document.getElementById("imagesize").value="Custom",document.getElementById("customsize").style.display="inline",document.getElementById("customwidth").value=""+t[0],document.getElementById("customheight").value=""+t[1]):(document.getElementById("imagesize").value=n,document.getElementById("customsize").style.display="none");break;case"Change PaletteLength":i(t[0],t[1]),createPaletteColors(),remapColors();break;case"Change MaxIterations":setMaxIterations(t),0>[25,50,100,250,500,1e3,2500,5e3,1e4,25e3,5e4].indexOf(t)?(document.getElementById("custommaxiter").style.display="inline",document.getElementById("maxIterSelect").value="Custom",document.getElementById("maxiterinput").value=""+t):(document.getElementById("custommaxiter").style.display="none",document.getElementById("maxIterSelect").value=""+t);break;case"Change Palette":palette=t.copy(),createPaletteColors(),remapColors();break;case"Edit Palette":palette=t[0].copy(),i(t[1],t[2]),o(t[3]),createPaletteColors(),remapColors()}function i(e,t){e?(stretchPalette=!0,document.getElementById("paletteLengthSelect").value="Match",document.getElementById("custompallen").style.display="none"):(stretchPalette=!1,fixedPaletteLength=t,0>[50,100,250,500,1e3,2500,5e3].indexOf(t)?(document.getElementById("custompallen").style.display="inline",document.getElementById("paletteLengthSelect").value="Custom",document.getElementById("palleninput").value=""+t):(document.getElementById("custompallen").style.display="none",document.getElementById("paletteLengthSelect").value=""+t))}function o(e){paletteOffsetFraction=e,0>[0,.1,.2,.3,.4,.5,.6,.7,.8,.9].indexOf(e)?(document.getElementById("paletteOffsetSelect").value="Custom",document.getElementById("custoffset").style.display="inline",e*=100,document.getElementById("offsetinput").value=e==Math.round(e)?e:e.toPrecision(3)):(document.getElementById("paletteOffsetSelect").value=""+e,document.getElementById("custoffset").style.display="none")}applyUndoInProgress=!1}function Palette(e,t,n){this.colorType=e||"HSB",this.divisionPoints=t||[0,1],this.divisionColors=n||("HSB"==this.colorType?[[0,1,1],[1,1,1]]:[[1,1,1],[0,0,0]])}function showPaletteEditor(){function e(){document.getElementById("xmlimportbg").style.display="none",document.getElementById("paletteEditor").style.display="none",document.removeEventListener("keydown",t,!1),paletteEditInProgress=!1,histogram=null,palettePreview=null,paletteInEditor=null,colorsInEditor=null}function t(t){27==t.keyCode&&e()}colorEditCanvas||(document.getElementById("applyPaletteEdit").onclick=function t(){var n=[paletteInEditor,!1,paletteLengthInEditor,paletteOffsetFractionInEditor];addUndoItem("Edit Palette",[copyOfCurrentPalette,stretchPalette,fixedPaletteLength,paletteOffsetFraction],n),applyUndoItem("Edit Palette",n),e()},document.getElementById("revertPaletteEdit").onclick=function e(){installPaletteInEditor(copyOfCurrentPalette),palettePreview.redraw(),document.getElementById("applyPaletteEdit").disabled=!0,document.getElementById("revertPaletteEdit").disabled=!0},document.getElementById("dismissPaletteEdit").onclick=e,document.getElementById("addcolorstop").onclick=function(){colorEditCanvas.addColorStop()},document.getElementById("deletecolorstop").onclick=function(){colorEditCanvas.deleteColorStop()},document.getElementById("lockcolors").onchange=setLeftRightColorsLocked,document.getElementById("paletteEditStandardInstall").onclick=function e(){var t=document.getElementById("paletteEditStandardSelect").value;installPaletteInEditor(Palette.createStandardPalette(t),paletteLengthInEditor,paletteOffsetFractionInEditor),document.getElementById("applyPaletteEdit").disabled=!1,document.getElementById("revertPaletteEdit").disabled=!1,palettePreview.redraw()},document.getElementById("paletteEditStandardSelect").value="EarthAndSky",document.addEventListener("keydown",t,!1),updateDuringDrag=document.getElementById("updateWhileDraggingCheck").checked,document.getElementById("updateWhileDraggingCheck").oninput=function(){updateDuringDrag=document.getElementById("updateWhileDraggingCheck").checked},histogramPalette=document.getElementById("histogrampalette"),colorEditCanvas=new ColorEditCanvas,(colorSliders=[new SliderAndInput(document.getElementById("colorslider0"),document.getElementById("colorinput0"),0,1),new SliderAndInput(document.getElementById("colorslider1"),document.getElementById("colorinput1"),0,1),new SliderAndInput(document.getElementById("colorslider2"),document.getElementById("colorinput2"),0,1)])[0].onchange=function(e){newColorSliderValue(0,e)},colorSliders[1].onchange=function(e){newColorSliderValue(1,e)},colorSliders[2].onchange=function(e){newColorSliderValue(2,e)},paletteLengthSlider=new SliderAndInput(document.getElementById("lengthslider"),document.getElementById("editorlengthinput"),1,maxIterations,paletteLength,!0,!0),paletteOffsetSlider=new SliderAndInput(document.getElementById("offsetslider"),document.getElementById("editoroffsetinput"),0,100,100*paletteOffsetFraction),paletteLengthSlider.onchange=newPaletteMappingInEditor,paletteOffsetSlider.onchange=newPaletteMappingInEditor),paletteEditInProgress=!0,document.getElementById("paletteEditor").style.display="block",document.getElementById("xmlimportbg").style.display="block",copyOfCurrentPalette=palette.copy(),histogram=new Histogram,palettePreview=new PalettePreview,installPaletteInEditor(palette),paletteLengthSlider.reset(1,maxIterations,paletteLength),paletteOffsetSlider.setValue(100*paletteOffsetFraction),document.getElementById("applyPaletteEdit").disabled=!0,document.getElementById("revertPaletteEdit").disabled=!0}DragBox.prototype.draw=function(){graphics.strokeStyle="#FFFFFF",graphics.lineWidth=4,graphics.strokeRect(this.left,this.top,this.width,this.height),graphics.strokeStyle="#000000",graphics.lineWidth=2,graphics.strokeRect(this.left,this.top,this.width,this.height)},DragBox.prototype.setCorner=function(e,t){var n=Math.abs(e-this.x),i=Math.abs(t-this.y);if(n<3||i<3){this.width=this.height=0;return}var o=canvas.width/canvas.height,a=n/i;o>a?n=Math.round(n*o/a):o<a&&(i=Math.round(i*a/o)),this.x<e?this.left=this.x:this.left=this.x-n,this.y<t?this.top=this.y:this.top=this.y-i,this.width=n,this.height=i},DragBox.prototype.zoom=function(e){this.width<=2||this.height<=2||(stopJob(),!1==e?doZoomOutFromRect(this.left,this.top,this.width,this.height):doZoomInOnRect(this.left,this.top,this.width,this.height),startJob())},Palette.prototype.getColor=function(e){for(var t=1;e>this.divisionPoints[t];)t++;var n=(e-this.divisionPoints[t-1])/(this.divisionPoints[t]-this.divisionPoints[t-1]),i=this.divisionColors[t-1],o=this.divisionColors[t],a=i[0]+n*(o[0]-i[0]),l=i[1]+n*(o[1]-i[1]),r=i[2]+n*(o[2]-i[2]);return this.toRGB(a,l,r)},Palette.prototype.toRGB=function(e,t,n){var i;return e="HSB"==this.colorType?e-Math.floor(e):o(e),t=o(t),n=o(n),(i="HSB"==this.colorType?function e(t,n,i){var o,a,l,r,s;switch(t*=360,s=(r=i*n)*(1-Math.abs((s=t<120?t/60:t<240?(t-120)/60:(t-240)/60)-1)),s+=i-r,Math.floor(t/60)){case 0:o=i,a=s,l=i-r;break;case 1:o=s,a=i,l=i-r;break;case 2:o=i-r,a=i,l=s;break;case 3:o=i-r,a=s,l=i;break;case 4:o=s,a=i-r,l=i;break;case 5:o=i,a=i-r,l=s}return[o,a,l]}(e,t,n):[e,t,n])[0]=Math.round(255*i[0]),i[1]=Math.round(255*i[1]),i[2]=Math.round(255*i[2]),i;function o(e){return(e=2*(e/2-Math.floor(e/2)))>1&&(e=2-e),e}},Palette.prototype.makeRGBs=function(e,t){var n=Array(e);n[t%e]=this.toRGB(this.divisionColors[0][0],this.divisionColors[0][1],this.divisionColors[0][2]);for(var i=1/(e-1),o=1;o<e-1;o++)n[(t+o)%e]=this.getColor(o*i);var a=this.divisionColors.length-1;return n[(t+e-1)%e]=this.toRGB(this.divisionColors[a][0],this.divisionColors[a][1],this.divisionColors[a][2]),n},Palette.prototype.makeCanvasColors=function(e,t){for(var n=this.makeRGBs(e,t),i=Array(n.length),o=0;o<n.length;o++)i[o]="rgb("+n[o][0]+","+n[o][1]+","+n[o][2]+")";return i},Palette.prototype.toXMLString=function(){for(var e="<palette colorType='"+this.colorType+"'>\n",t=0;t<this.divisionPoints.length;t++)e+=" <divisionPoint position='"+this.divisionPoints[t]+"' color='"+this.divisionColors[t][0]+";"+this.divisionColors[t][1]+";"+this.divisionColors[t][2]+"'/>\n";return e+"</palette>\n"},Palette.prototype.copy=function(){for(var e=[],t=0;t<this.divisionColors.length;t++)e.push(this.divisionColors[t].slice(0));return new Palette(this.colorType,this.divisionPoints.slice(0),e)},Palette.fromXML=function(e){try{var t=e.childNodes,n=e.getAttribute("colorType")||"RBG";if("HSB"!=n&&"RGB"!=n)throw"Bad colorType.";for(var i=[],o=[],a=0;a<t.length;a++){var l=t.item(a);if(1==l.nodeType&&"divisionPoint"==l.tagName){var r=l.getAttribute("position"),s=l.getAttribute("color");if(null===r||null===s)throw"Missing data for divisionPoint";if(r=Number(r),s=s.split(";"),s=[Number(s[0]),Number(s[1]),Number(s[2])],isNaN(r)||r<0||r>1)throw"Bad data for divisionPoint";for(var d=0;d<3;d++){if(isNaN(s[d])||s[d]<0)throw"Bad data for divisionPoint color";if(s[d]<0)throw"Color component number "+(d+1)+" can't be less than zero.";if(s[d]>1&&(d>0||"RGB"==n))throw"Color component number "+(d+1)+" can't be greater than one."}if(a>0&&r<=i[i.length-1])throw"Division points out of order";i.push(r),o.push(s)}}if(i.length<2||0!=i[0]||1!=i[i.length-1])throw"Illegal divisionPoint data";return new Palette(n,i,o)}catch(c){throw"Illegal palette definition: "+c}},Palette.createStandardPalette=function(e){var t;switch(e){case"Grayscale":t=new Palette("RGB");break;case"CyclicGrayscale":t=new Palette("RGB",[0,.5,1],[[0,0,0],[1,1,1],[0,0,0]]);break;case"Red/Cyan":t=new Palette("RGB",[0,.5,1],[[1,0,0],[0,1,1],[1,0,0]]);break;case"Blue/Gold":t=new Palette("RGB",[0,.5,1],[[.1,.1,1],[1,.6,0],[.3,.3,1]]);break;case"EarthAndSky":t=new Palette("RGB",[0,.15,.33,.67,.85,1],[[1,1,1],[1,.8,0],[.53,.12,.075],[0,0,.6],[0,.4,1],[1,1,1]]);break;case"HotAndCold":t=new Palette("RGB",[0,.16,.5,.84,1],[[1,1,1],[0,.4,1],[.2,.2,.2],[1,0,.8],[1,1,1]]);break;case"Fire":t=new Palette("RGB",[0,.17,.83,1],[[0,0,0],[1,0,0],[1,1,0],[1,1,1]]);break;case"Cyclic Fire":t=new Palette("RGB",[0,.2,.4,.5,.6,.8,1],[[0,0,0],[1,0,0],[1,1,0],[1,1,1],[1,1,0],[1,0,0],[0,0,0]]);break;case"TreeColors":t=new Palette("HSB",[0,.33,.66,1],[[.1266,.5955,.2993],[.0896,.3566,.6575],[.6195,.8215,.4039],[.1266,.5955,.2993]]);break;case"Seashore":t=new Palette("RGB",[0,.1667,.3333,.5,.6667,.8333,1],[[.7909,.9961,.763],[.8974,.8953,.6565],[.9465,.3161,.1267],[.5184,.1109,.0917],[.0198,.4563,.6839],[.5385,.8259,.8177],[.7909,.9961,.763]]);break;case"Pastels":t=new Palette("RGB",[0,.180781,.418566,.627035,.858306,1],[[.80585,.81648,.8218],[.43882,.52393,1],[1,.35904,.58244],[1,1,.52127],[.54787,.93351,.56914],[.80585,.81648,.8218]]);break;case"Dark":t=new Palette("RGB",["0","0.18241042","0.38599348","0.57166123","0.78338762","1"],[[.65957446,0,0],[0,.30585106,.58776595],[.81648936,.41489361,.07180851],[0,.48670212,.16489361],[.29787234,.13829787,.75],[.65957446,0,0]]);break;case"Random":var n=[Math.random(),Math.random(),Math.random()];(t=new Palette("RGB",[],[])).divisionPoints[0]=0,t.divisionColors[0]=n;for(var i=1;i<=5;i++)t.divisionPoints[i]=i/6,t.divisionColors[i]=[Math.random(),Math.random(),Math.random()];t.divisionPoints[6]=1,t.divisionColors[6]=n;break;default:t=new Palette}return t};var colorEditCanvas=null;function installPaletteInEditor(e,t,n){var i=(paletteInEditor=e.copy()).divisionColors[0],o=paletteInEditor.divisionColors[paletteInEditor.divisionColors.length-1],a=i[1]==o[1]&&i[2]==o[2]&&(i[0]==o[0]||"HSB"==paletteInEditor.colorType&&i[0]-Math.floor(i[0])==o[0]-Math.floor(o[0]));if(colorEditCanvas.setLocked(a,!0),document.getElementById("lockcolors").checked=a,paletteLengthInEditor=void 0!==t?t:paletteLength,paletteLengthSlider.setValue(paletteLengthInEditor),paletteOffsetFractionInEditor=void 0!==n?n:paletteOffsetFraction,paletteOffsetSlider.setValue(100*paletteOffsetFractionInEditor),colorEditCanvas.colorsChanged(),colorEditCanvas.select(0),newColorsInEditor(),updateDuringDrag||palettePreview.redraw(),"RGB"==e.colorType?(document.getElementById("colorlabel0").innerHTML="Red",document.getElementById("colorlabel1").innerHTML="Green",document.getElementById("colorlabel2").innerHTML="Blue"):(document.getElementById("colorlabel0").innerHTML="Hue",document.getElementById("colorlabel1").innerHTML="Saturation",document.getElementById("colorlabel2").innerHTML="Brightness"),"HSB"==e.colorType?colorSliders[0].setAllowOutOfRange(!0,!0):colorSliders[0].setAllowOutOfRange(!1,!1),"HSB"==e.colorType){var l=Math.floor(e.divisionColors[0][0]);colorSliders[0].reset(l,l+1,e.divisionColors[0][0]),colorSliders[0].canvas.title="Drag the slider to set the hue of the selected color stop to a value in the range "+l+" to "+(l+1)+". Values outside this range can be set in the textbox."}else colorSliders[0].reset(0,1,e.divisionColors[0][0]),colorSliders[0].canvas.title="Drag the slider to set the red component of the selected color stop to a value in the range 0.0 to 1.0.";colorSliders[1].setValue(e.divisionColors[0][1]),colorSliders[2].setValue(e.divisionColors[0][2])}function newColorsInEditor(){var e=Math.round(paletteLengthInEditor*paletteOffsetFractionInEditor);colorsInEditor=paletteInEditor.makeCanvasColors(paletteLengthInEditor,e),colorEditCanvas.draw(),updateDuringDrag&&palettePreview.redraw(),redrawHistogramPalette(),document.getElementById("applyPaletteEdit").disabled=!1,document.getElementById("revertPaletteEdit").disabled=!1}function newPaletteMappingInEditor(){var e=Math.round((paletteLengthInEditor=paletteLengthSlider.value)*(paletteOffsetFractionInEditor=paletteOffsetSlider.value/100));colorsInEditor=paletteInEditor.makeCanvasColors(paletteLengthInEditor,e),updateDuringDrag&&palettePreview.redraw(),redrawHistogramPalette(),document.getElementById("applyPaletteEdit").disabled=!1,document.getElementById("revertPaletteEdit").disabled=!1}function newColorSliderValue(e,t){var n=colorEditCanvas.getSelected();paletteInEditor.divisionColors[n][e]=t;var i=null;if(leftRightColorsLocked&&(0==n?i=paletteInEditor.divisionColors[paletteInEditor.divisionColors.length-1]:n==paletteInEditor.divisionColors.length-1&&(i=paletteInEditor.divisionColors[0])),null!=i){if(0==e&&"HSB"==paletteInEditor.colorType){var o=Math.floor(i[0]);i[0]=o+(t-Math.floor(t))}else i[e]=t;saveRightColorWhileLocked=null}colorEditCanvas.colorsChanged(),newColorsInEditor()}function redrawHistogramPalette(){for(var e=histogramPalette.getContext("2d"),t=paletteLengthInEditor/maxIterations*(histogramPalette.width-2),n=1;n<histogramPalette.width-1;n++){var i=(n-1)%t/t,o=Math.max(0,Math.min(colorsInEditor.length,Math.round(i*colorsInEditor.length)));e.fillStyle=colorsInEditor[o],e.fillRect(n,0,1,histogramPalette.height)}e.strokeStyle="black",e.strokeRect(.5,.5,histogramPalette.width-1,histogramPalette.height-1)}function setLeftRightColorsLocked(){var e=document.getElementById("lockcolors").checked;colorEditCanvas.setLocked(e)}function ColorEditCanvas(){var e,t,n=document.getElementById("coloredit"),i=n.getContext("2d"),o=n.width-16,a=null,l=this;new Mouser(n,function(n,i){for(var a=0;a<paletteInEditor.divisionPoints.length;a++){var r=8+Math.floor(paletteInEditor.divisionPoints[a]*o);if(n>r-2&&n<r+3||i>48&&n>r-6&n<r+7)return t=n,a!=e&&(l.select(a),l.draw()),a>0&&a<paletteInEditor.divisionPoints.length-1}return!1},function(n,i){var l=8+Math.floor(paletteInEditor.divisionPoints[e]*o),r=8+Math.floor(paletteInEditor.divisionPoints[e-1]*o),s=8+Math.floor(paletteInEditor.divisionPoints[e+1]*o),d=n-t;t=n;var c=Math.min(s-10,Math.max(r+10,l+d));c!=l&&(paletteInEditor.divisionPoints[e]=(c-8)/o,a=null,newColorsInEditor())},function(){updateDuringDrag||palettePreview.redraw()}),n.ondblclick=function(e){if(0==e.button){var t=n.getBoundingClientRect(),i=e.clientX-t.left;if(!(e.clientY-t.top>50))for(var a=1;a<paletteInEditor.divisionPoints.length;a++){var r=paletteInEditor.divisionPoints[a-1],s=paletteInEditor.divisionPoints[a],d=8+Math.floor(s*o);if(i>8+Math.floor(r*o)+9&&i<d-9){var c=(i-8)/o,u=(c-r)/(s-r),h=paletteInEditor.divisionColors[a-1],m=paletteInEditor.divisionColors[a],g=[(1-u)*h[0]+u*m[0],(1-u)*h[1]+u*m[1],(1-u)*h[2]+u*m[2]];paletteInEditor.divisionPoints.splice(a,0,c),paletteInEditor.divisionColors.splice(a,0,g),l.select(a),l.draw();break}}}},this.addColorStop=function(){for(var t=e-1,n=e+1;t>=0||n<paletteInEditor.divisionPoints.length;){if(i(n-1,n)||(n++,i(t,t+1)))return;t--}function i(e,t){if(e<0||t>=paletteInEditor.divisionPoints.length)return!1;var n=paletteInEditor.divisionPoints[e],i=paletteInEditor.divisionPoints[t];if((i-n)*o>19){var a=paletteInEditor.divisionColors[e],r=paletteInEditor.divisionColors[t],s=[(a[0]+r[0])/2,(a[1]+r[1])/2,(a[2]+r[2])/2];return paletteInEditor.divisionPoints.splice(t,0,(n+i)/2),paletteInEditor.divisionColors.splice(t,0,s),l.select(t),l.draw(),!0}return!1}alert("Sorry, can't find room for another color stop.")},this.deleteColorStop=function(){e>0&&e<paletteInEditor.divisionPoints.length-1&&(paletteInEditor.divisionPoints.splice(e,1),paletteInEditor.divisionColors.splice(e,1),l.select(e-1),a=null,newColorsInEditor(),l.draw())},this.setLocked=function(t,n){if(leftRightColorsLocked=t,n){saveRightColorWhileLocked=null;return}var i=paletteInEditor.divisionColors[0],o=paletteInEditor.divisionColors[paletteInEditor.divisionColors.length-1];if(leftRightColorsLocked){var r=[];if(r.push(o[0]),r.push(o[1]),r.push(o[2]),o[1]=i[1],o[2]=i[2],"HSB"==paletteInEditor.colorType){var s=Math.floor(o[0]);o[0]=s+(i[0]-Math.floor(i[0]))}else o[0]=i[0];a=null,newColorsInEditor(),e==paletteInEditor.divisionColors.length-1&&l.select(e),saveRightColorWhileLocked=r}else null!=saveRightColorWhileLocked&&(o[0]=saveRightColorWhileLocked[0],o[1]=saveRightColorWhileLocked[1],o[2]=saveRightColorWhileLocked[2],saveRightColorWhileLocked=null,a=null,newColorsInEditor(),e==paletteInEditor.divisionColors.length-1&&l.select(e))},this.select=function(t){if(e=t,"HSB"==paletteInEditor.colorType){var n=Math.floor(paletteInEditor.divisionColors[e][0]);colorSliders[0].reset(n,n+1,paletteInEditor.divisionColors[e][0]),colorSliders[0].canvas.title="Drag the slider to set the hue of the selected color stop to a value in the range "+n+" to "+(n+1)+". Values outside this range can be set in the textbox."}else colorSliders[0].setValue(paletteInEditor.divisionColors[e][0]);colorSliders[1].setValue(paletteInEditor.divisionColors[e][1]),colorSliders[2].setValue(paletteInEditor.divisionColors[e][2]),document.getElementById("deletecolorstop").disabled=!(e>0&&e<paletteInEditor.divisionPoints.length-1)},this.getSelected=function(){return e},this.colorsChanged=function(){a=null},this.draw=function(){i.fillStyle="#e8e8e8",i.fillRect(0,0,n.width,n.height),null==a&&(a=paletteInEditor.makeCanvasColors(o,0));for(var t=0;t<o;t++)i.fillStyle=a[t],i.fillRect(8+t,3,1,40);i.lineWidth=2,i.strokeRect(7,2,o+2,41);for(var t=0;t<paletteInEditor.divisionPoints.length;t++){var l=8+Math.floor(paletteInEditor.divisionPoints[t]*o),r=paletteInEditor.divisionColors[t];r="rgb("+(r=paletteInEditor.toRGB(r[0],r[1],r[2]))[0]+","+r[1]+","+r[2]+")",t==e&&(i.fillStyle="black",i.fillRect(l-3,1,6,42),i.fillRect(l-7,51,14,29),i.fillStyle="lightgray",i.fillRect(l-2,2,4,40),i.fillRect(l-6,52,12,27),i.fillStyle=r,i.fillRect(l-1,3,2,38)),i.fillStyle="black",i.fillRect(l-1,43,2,10),i.fillRect(l-5,53,10,25),i.fillStyle=r,i.fillRect(l-4,54,8,23)}}}function PalettePreview(){var e,t,n,i=document.getElementById("preview"),o=i.getContext("2d");if(canvas.width>=canvas.height){var a=Math.round(canvas.height/canvas.width*(i.height-2));e={left:1,top:1+Math.floor((i.height-a)/2),width:i.width-2,height:a}}else{var l=Math.round(canvas.width/canvas.height*(i.width-2));e={left:1+Math.floor((i.width-l)/2),top:1,width:l,height:i.height-2}}var r=Array(e.height),s=Array(e.height+1),d=Array(e.height);for(t=0;t<e.height;t++)s[t]=Math.floor(t*canvas.height/e.height),d[t]=-1;for(t=0,s[e.height+1]=canvas.height;t<e.height;t++)for(n=s[t];n<s[t+1];n++)if(savedIterationCounts[n]){d[t]=n,r[t]=new Int32Array(e.width);for(var c=0;c<e.width;c++){var u=Math.floor(c/e.width*savedIterationCounts[n].length);r[t][c]=savedIterationCounts[n][u]}break}function h(t,n){r[t]=new Int32Array(e.width);for(var i=0;i<e.width;i++){var o=Math.floor(i/e.width*n.length);r[t][i]=n[o]}m(t)}function m(t){for(var n=0;n<e.width;n++){if(-1==r[t][n])o.fillStyle="black";else{var i=r[t][n]%paletteLengthInEditor;o.fillStyle=colorsInEditor[i]}o.fillRect(n+e.left,t+e.top,1,1)}}this.update=function(t,n){for(var i=0;i<e.height;i++)if(t<s[i+1]){(-1==d[i]||d[i]!=s[i]&&t<d[i])&&(d[i]=t,h(i,n));break}},this.redraw=function(){o.fillStyle="#e8e8e8",o.fillRect(0,0,i.width,i.height),o.lineWidth=1,o.strokeStyle="black",o.strokeRect(e.left-.5,e.top-.5,e.width+1,e.height);for(var t=0;t<r.length;t++)r[t]&&m(t)}}function Histogram(){for(var e=document.getElementById("histogram"),t=e.width-15,n=e.height-15,i=new Int32Array(maxIterations+1),o=0;o<savedIterationCounts.length;o++)if(savedIterationCounts[o])for(var a=savedIterationCounts[o],l=0;l<a.length;l++)i[a[l]]++;function r(){var o,a,l,r=e.getContext("2d");r.fillStyle="white",r.fillRect(0,0,e.width,e.height),r.lineWidth=2,r.strokeStyle="red",r.beginPath(),r.moveTo(8,5),r.lineTo(8,e.height-8),r.lineTo(e.width-5,e.height-8),r.stroke();var s=0;for(o=1;o<i.length;o++)s=Math.max(i[o],s);if(0!=s){for(r.lineWidth=1,r.strokeStyle="black",r.beginPath(),o=1;o<i.length;o++)i[o]>0&&(a=Math.round(o/i.length*t)+10.5,l=Math.ceil(i[o]/s*n)+.5,r.moveTo(a,e.height-10),r.lineTo(a,e.height-10-l));r.stroke()}}this.update=function(e){for(var t=0;t<e.length;t++)i[e[t]]++;r()},r()}function SliderAndInput(e,t,n,i,o,a,l){this.canvas=e,this.textbox=t,this.min="number"==typeof n?n:0,this.max="number"==typeof i?i:this.min+100,this.value="number"==typeof o?o:this.min,this.integerOnly=void 0!==a&&a,this.allowOutOfRange=void 0!==l&&l,this.allowLessThanMin=!1,this.g=this.canvas.getContext("2d"),this.g.translate(0,-8),this.size=this.canvas.width-25,this.allowOutOfRange&&(this.size-=20),this.setTabLeft(),this.valueToTextbox(),this.draw(),this.onchange=null;var r,s,d,c,u=this;function h(){var e=Number(t.value);return isNaN(e)?(t.style.backgroundColor="#ff9090",t.title="The value in the input box is not a number!",!1):(u.integerOnly&&(e=Math.round(e)),e<0||e<u.min&&!u.allowLessThanMin||e>u.max&&!u.allowOutOfRange)?(t.style.backgroundColor="#ffff90",t.title="The value in the textbox is not in the legal range for the slider",!1):(r=e,t.style.backgroundColor="#d8ffd8",t.title="Editing slider value. Press return or move to another input box to apply the new value, if legal.",!0)}t.style.color="black",t.style.backgroundColor="white",t.style.padding="2px",t.onfocus=function(){r=s=this.value,t.style.backgroundColor="#d8ffd8",d=t.title,t.title="Editing slider value. Press return or move to another input box to apply the new value, if legal."},t.onblur=function(){t.style.backgroundColor="white",h()?u.setValue(r):u.setValue(s),updateDuringDrag||palettePreview.redraw(),u.valueToTextbox(),t.title=d,t.style.backgroundColor="white"},t.oninput=function(){h()},t.onkeydown=function(e){13==e.keyCode&&h()&&(u.setValue(r),r=u.value,updateDuringDrag||palettePreview.redraw())},new Mouser(this.canvas,function(e,t){if(t<23&&e>u.tabLeft-2&&e<u.tabLeft+22)return c=e-(u.tabLeft+10),!0;if(t>20&&e>14&&e<u.canvas.width-5){var n=(e-15)/u.size*(u.max-u.min)+u.min;return u.setValue(n),!1}},function(e,t){var n=((e-=c)-15)/u.size*(u.max-u.min)+u.min;n>u.max&&(n=u.max),n<u.min&&(n=u.min),u.setValue(n)},function(){updateDuringDrag||palettePreview.redraw()})}function currentExampletoXML(){var e=Math.round(paletteOffsetFraction*paletteLength);return"<?xml version='1.0'?>\n<mandelbrot_settings_2>\n<image_size width='"+canvas.width+"' height='"+canvas.height+"'/>\n<limits>\n <xmin>"+xmin_requested.toString()+"</xmin>\n <xmax>"+xmax_requested.toString()+"</xmax>\n <ymin>"+ymin_requested.toString()+"</ymin>\n <ymax>"+ymax_requested.toString()+"</ymax>\n</limits>\n"+palette.toXMLString()+"<palette_mapping length='"+paletteLength+"' offset='"+e+"'/>\n<max_iterations value='"+maxIterations+"'/>\n</mandelbrot_settings_2>\n"}function installExampleFromXML(e,t,n,i,o="Import Example"){var a=currentXML;stopJob();try{var l,r,s,d,c,u,h,m,g,$,p=new DOMParser().parseFromString(e,"text/xml").documentElement;if(n){var f=p.getElementsByTagName("image_size");0==f?n=!1:(l=Number(f[0].getAttribute("width")),r=Number(f[0].getAttribute("height")),(isNaN(l)||l>1e4||l<50||isNaN(r)||r>1e4||r<50)&&(n=!1))}s=p.getElementsByTagName("xmin").item(0).textContent,d=p.getElementsByTagName("xmax").item(0).textContent,c=p.getElementsByTagName("ymin").item(0).textContent,u=p.getElementsByTagName("ymax").item(0).textContent,h=Palette.fromXML(p.getElementsByTagName("palette").item(0));var v=p.getElementsByTagName("palette_mapping");if(v.length>0?(m=Number(v.item(0).getAttribute("length")),g=Number(v.item(0).getAttribute("offset"))):(m=250,g=0),$=Number(p.getElementsByTagName("max_iterations").item(0).getAttribute("value")),s=new BigDecimal(s),d=new BigDecimal(d),c=new BigDecimal(c),u=new BigDecimal(u),isNaN(m)||isNaN(g)||isNaN($))throw"Bad number.";if(0==m&&(m=$),palette=h,maxIterations=Math.round($),0>[25,50,100,250,500,1e3,2500,5e3,1e4,25e3,5e4].indexOf(maxIterations)?(document.getElementById("custommaxiter").style.display="inline",document.getElementById("maxIterSelect").value="Custom",document.getElementById("maxiterinput").value=""+$):(document.getElementById("custommaxiter").style.display="none",document.getElementById("maxIterSelect").value=""+maxIterations),m=Math.round(m),0==m?(stretchPalette=!0,document.getElementById("paletteLengthSelect").value="Match MaxIter",document.getElementById("custompallen").style.display="none"):(stretchPalette=!1,fixedPaletteLength=m,0>[50,100,250,500,1e3,2500,5e3].indexOf(m)?(document.getElementById("custompallen").style.display="inline",document.getElementById("paletteLengthSelect").value="Custom",document.getElementById("palleninput").value=""+m):(document.getElementById("custompallen").style.display="none",document.getElementById("paletteLengthSelect").value=""+m)),paletteOffsetFraction=g/m,paletteOffsetFraction-=Math.floor(paletteOffsetFraction),paletteOffsetFraction=Math.round(1e4*paletteOffsetFraction)/1e4,0==g)document.getElementById("custoffset").style.display="none",document.getElementById("paletteOffsetSelect").value="0";else{document.getElementById("custoffset").style.display="inline",document.getElementById("paletteOffsetSelect").value="Custom";var y=100*paletteOffsetFraction;document.getElementById("offsetinput").value=y==Math.round(y)?y:y.toPrecision(3)}if(createPaletteColors(),n){setImageSize(l,r);var E=l+" "+r;0>["200 150","400 300","640 480","800 600","1024 768","1200 900","1600 900","425 550","850 1100"].indexOf(E)?(document.getElementById("imagesize").value="Custom",document.getElementById("customsize").style.display="inline",document.getElementById("customwidth").value=""+l,document.getElementById("customheight").value=""+r):(document.getElementById("imagesize").value=E,document.getElementById("customsize").style.display="none")}return setLimits(s,d,c,u,!1),startJob(),t&&undoList&&addUndoItem(o,a,currentXML),null}catch(_){var I="Illegal data in XML example string: "+_;return i||(document.getElementById("status").innerHTML=I),I}}function installExampleWithAjax(e){document.getElementById("status").innerHTML="Trying to Fetch example from "+e;var t,n=new XMLHttpRequest;n.open("GET",e),n.overrideMimeType("text/plain"),n.addEventListener("error",function(){clearTimeout(t),document.getElementById("status").innerHTML="Error: Example could not be loaded from "+e}),n.addEventListener("load",function(){clearTimeout(t),installExampleFromXML(n.responseText,!1,!1)}),t=setTimeout(function(){n.abort(),document.getElementById("status").innerHTML="Error: Request timed out while trying to load from "+e},1e4);try{n.send()}catch(i){clearTimeout(t),document.getElementById("status").innerHTML="Error while trying to send request for example: "+e}}function importXML(){function e(){document.getElementById("xmlimportbg").style.display="none",document.getElementById("xmlimport").style.display="none",document.removeEventListener("keydown",t,!1)}function t(t){27==t.keyCode&&e()}document.getElementById("XMLtextinput").value="",document.getElementById("xmlimportbg").style.display="block",document.getElementById("xmlimport").style.display="block",document.addEventListener("keydown",t,!1),document.getElementById("cancelXMLimport").onclick=e,document.getElementById("applyXMLimport").onclick=function t(){var n=document.getElementById("XMLtextinput").value.trim();if(""==n)e();else{var i=installExampleFromXML(n,!0,!1);null==i?e():alert("Error in input: "+i)}},document.getElementById("grabcurrent").onclick=function e(){document.getElementById("XMLtextinput").value=currentXML}}function checkForExample(){var e=window.location.search.match("^\\?ex=([a-zA-Z0-9/.%_+-]+)");e&&(stopJob(),installExampleWithAjax(decodeURIComponent(e[1]),!1))}function setUpFileHandling(){var e=document.getElementById("saveBtn"),t=document.getElementById("loadBtn"),n=!1;if(window.showOpenFilePicker&&FileSystemFileHandle&&FileSystemFileHandle.prototype.getFile)t.addEventListener("click",l,!1);else{let i=document.createElement("input");i.type="file",i.id="chooseloadfile",i.style.display="none",document.getElementById("controls").appendChild(i),t.addEventListener("click",function e(){let t=document.getElementById("chooseloadfile");t.value="",document.getElementById("chooseloadfile").addEventListener("change",a,!1),t.click()},!1),t.title+=" This will look like uploading a file, but it will only be loaded locally."}async function o(){if(n)return;let e=currentExampletoXML(),t=new Blob([e],{type:"text/xml"});try{let i=await (await window.showSaveFilePicker({suggestedName:"mandelbrot_params.xml"})).createWritable();await i.write(t),await i.close(),s("File has been saved.")}catch(o){"AbortError"!==o.name&&(s("Error while attempting to save file!"),alert("Error while saving file:\n"+o))}}async function a(){t.disabled=!0,n=!0;try{let e=document.getElementById("chooseloadfile");if(e.removeEventListener("change",a,!1),0===e.files.length)return;if(s("Trying to load file "+e.files.name),e.files[0].type&&!/^text/i.test(e.files[0].type))throw"Only text files can be loaded.";let i=await e.files[0].text();r(i),s("Successfully loaded file "+e.files[0].name)}catch(o){s("File load failed!"),alert("File load failed:\n"+o)}finally{t.disabled=!1,n=!1}}async function l(){s("Load file -- select a file or cancel!"),n=!0,t.disabled=!0;try{let e=await window.showOpenFilePicker();if(0===e.length){s("File load canceled");return}let i=await e[0].getFile();if(i.type&&!/^text/i.test(i.type))throw"Only text files can be loaded.";let o=await i.text();r(o),s("Successfully loaded file "+i.name)}catch(a){"AbortError"===a.name?s("File load canceled"):(s("File load failed!"),alert("File load failed:\n"+a))}finally{t.disabled=!1,n=!1}}function r(e){if(installExampleFromXML(e,!0,!1,!0,"Load File"))throw"File could not be loaded because it does not contain\na legal Mandebrot parameter specification."}function s(e){document.getElementById("status").innerHTML=e}window.showSaveFilePicker&&FileSystemFileHandle&&FileSystemFileHandle.prototype.createWritable?e.addEventListener("click",o,!1):(e.addEventListener("click",function e(){if(n)return;let t=currentExampletoXML(),i=new Blob([t],{type:"text/xml"}),o=document.createElement("a");o.href=URL.createObjectURL(i),o.download="mandelbrot_params.xml",o.click(),URL.revokeObjectURL(o.href)},!1),e.title+=" This will look like downloading a file named 'mandelbrot_params.xml'.")}function init(){try{graphics=(canvas=document.getElementById("canvas")).getContext("2d"),(OSC=document.createElement("canvas")).width=canvas.width,OSC.height=canvas.height,OSG=OSC.getContext("2d")}catch(e){document.getElementById("message").innerHTML="Sorry, this page requires canvas support, which is not available in your browser.";return}if(!window.Worker){document.getElementById("message").innerHTML="Sorry, this page requires WebWorker support, which is not available in your browser.";return}palette=new Palette,document.getElementById("restoreButton").onclick=setDefaults,document.getElementById("stop").onclick=stopJob,document.getElementById("interlaced").onchange=changeInterlaced,document.getElementById("interlaced").checked=interlaced,document.getElementById("imagesize").onchange=changeImageSize,document.getElementById("applysize").onclick=doCustomSize;try{var t=Number(localStorage.getItem("mandelbrotWorkerCount"));!isNaN(t)&&t>0&&t<=16&&(workerCount=t)}catch(n){}document.getElementById("threadCountSelect").value=""+workerCount,document.getElementById("threadCountSelect").onchange=changeWorkerCount,document.getElementById("maxIterSelect").onchange=changeMaxIterations,document.getElementById("maxiterapply").onclick=doCustomMaxIterations,document.getElementById("paletteLengthSelect").onchange=changePaletteLength,document.getElementById("pallenapply").onclick=doCustomPaletteLength,document.getElementById("paletteOffsetSelect").onchange=changePaletteOffset,document.getElementById("offsetapply").onclick=doApplyCustomPaletteOffset,document.getElementById("standardPaletteButton").onclick=doApplyStandardPalette,document.getElementById("standardPaletteSelect").value="EarthAndSky",document.getElementById("showpaletteedit").onclick=showPaletteEditor,document.getElementById("secondpass").checked=!0,document.getElementById("secondpass").onchange=changeSecondPass,document.getElementById("zoomInAmount").value="0.1",document.getElementById("zoomOutAmount").value="10",document.getElementById("zoomin").onclick=doZoomIn,document.getElementById("zoomout").onclick=doZoomOut,document.getElementById("importXML").onclick=importXML,document.getElementById("undo").onclick=doUndo,document.getElementById("undo").disabled=!0,document.getElementById("redo").onclick=doRedo,document.getElementById("redo").disabled=!0,setUpFileHandling(),setUpDragging(),changeWorkerCount(),setDefaults(),checkForExample(),undoList=[],undoCount=0}SliderAndInput.prototype.setAllowOutOfRange=function(e,t){(this.allowOutOfRange!=e||this.allowLessThanMin!=t)&&(this.allowOutOfRange=e,t?this.allowLessThanMin=!0:this.allowLessThanMin=!1,this.size=this.canvas.width-25,this.allowOutOfRange&&(this.size-=20),this.setTabLeft(),this.draw())},SliderAndInput.prototype.reset=function(e,t,n){this.min=e,this.max=t,this.value="none",this.setValue(n)},SliderAndInput.prototype.setValue=function(e){var t=this.integerOnly?Math.round(e):e;this.allowOutOfRange||(t=Math.min(this.max,t)),this.allowOutOfRange||(t=Math.max(this.min,t)),t=Math.max(0,t),this.value!=t&&(this.value=t,this.valueToTextbox(),this.changed())},SliderAndInput.prototype.valueToTextbox=function(){this.integerOnly?this.textbox.value=""+this.value:this.textbox.value=this.value.toPrecision(3)},SliderAndInput.prototype.setTabLeft=function(){this.value>this.max||this.value<this.min?this.tabLeft=this.size+20:this.tabLeft=5+Math.floor((this.value-this.min)/(this.max-this.min)*this.size)},SliderAndInput.prototype.changed=function(){this.setTabLeft(),this.draw(),this.onchange&&this.onchange(this.value)},SliderAndInput.prototype.draw=function(){var e=this.g;e.save(),e.fillStyle="#e8e8e8",e.fillRect(0,8,this.canvas.width,this.canvas.height),e.beginPath(),e.moveTo(15,35),e.lineTo(15+this.size,35),e.strokeStyle="black",e.lineWidth=10,e.lineCap="round",e.stroke(),e.strokeStyle="gray",e.lineWidth=7.5,e.lineCap="butt",e.stroke(),e.beginPath(),e.moveTo(15,35),e.lineTo(Math.min(this.tabLeft+10,15+this.size),35),e.strokeStyle="lightgray",e.stroke(),e.fillStyle="black",e.lineWidth=1,e.beginPath(),e.moveTo(this.tabLeft+10,36),e.lineTo(this.tabLeft+20,30),e.lineTo(this.tabLeft+20,10),e.lineTo(this.tabLeft,10),e.lineTo(this.tabLeft,30),e.closePath(),e.fillStyle="#9090FF",e.fill(),e.strokeStyle="#000099",e.stroke(),e.beginPath(),e.moveTo(this.tabLeft+4.5,14),e.lineTo(this.tabLeft+4.5,26),e.moveTo(this.tabLeft+9.5,14),e.lineTo(this.tabLeft+9.5,26),e.moveTo(this.tabLeft+14.5,14),e.lineTo(this.tabLeft+14.5,26),e.stroke(),e.beginPath(),e.moveTo(this.tabLeft+6,16),e.lineTo(this.tabLeft+6,28),e.moveTo(this.tabLeft+11,16),e.lineTo(this.tabLeft+11,28),e.moveTo(this.tabLeft+16,16),e.lineTo(this.tabLeft+16,28),e.strokeStyle="white",e.stroke(),e.restore()}; | |
</script> | |
</head> | |
<body onload="init()"> | |
<noscript><b>Sorry, this page requires JavaScript.</b></noscript><h2 style=margin-top:0>Explore the Mandelbrot Set</h2><p><b>Drag on the image to draw a box, and the program will zoom in on that box.<br>(<a href=MB-info.html style=font-size:120%>Click here</a> for more info, instructions, and examples.)</b><p id=message><table border=0 cellpadding=0 cellspacing=0><tr valign=top><td><div id=controls><div class=group><p><button id=restoreButton title="Restore default limits, image size, palette, max iterations.">Restore Defaults</button><button id=stop title="Abort the current computation, if any, leaving an incomplete image."style=margin-left:20px>Stop</button></div><div class=group><p><label title="If checked, lines in image are computed out of order. This can give a general idea of the image more quickly."><input id=interlaced type=checkbox>Interlaced Drawing</label><p><label title="If checked, extra computations are done that can often give the completed image a smoother look, by computing two samples per pixel and averaging the resulting colors."><input id=secondpass type=checkbox>Do a Second Pass</label><p><label title="Increasing this might speed up computation by using more of your computer's processing time. (Values above the number of threads that your computer supports will not add additional speed.)">Workers: <select id=threadCountSelect><option value=1>1<option value=2>2<option value=3>3<option value=4>4<option value=5>5<option value=6>6<option value=7>7<option value=8>8<option value=10>10<option value=12>12<option value=16>16</select></label></div><div class=group><p><button id=undo>Undo</button><p><button id=redo>Redo</button></div><div class=group><p><label title="Width and height of the Mandelbrot picture, in pixels.">Image Size: <select id=imagesize><option value="200 150">200x150<option value="400 300">400x300<option value="640 480">640x480<option value="800 600">800x600<option value="1024 768">1024x768<option value="1200 900">1200x900<option value="1600 900">1600x900<option value="425 550">425x550<option value="850 1100">850x1100<option value=Custom>Custom</select></label><span id=customsize style=display:none><br><input id=customwidth size=4 maxlength=5>x<input id=customheight size=4 maxlength=5> <button id=applysize>Apply</button></span></div><div class=group><p><label title="How many steps in the Mandelbrot iteration before giving up and coloring the pixel black. Increasing this can fill black areas that aren't really part of the Mandelbrot set with color.">MaxIterations: <select id=maxIterSelect><option value=25>25<option value=50>50<option value=100>100<option value=250>250<option value=500>500<option value=1000>1000<option value=2500>2500<option value=5000>5000<option value=10000>10000<option value=25000>25000<option value=50000>50000<option value=Custom>Custom</select></label><span id=custommaxiter style=display:none><br><input id=maxiterinput size=5 maxlength=6> <button id=maxiterapply>Apply</button></span></div><div class=group><p><button id=showpaletteedit title="Show a popup dialog box that gives greater control over the palette.">Show Palette Editor</button> (<a href=palette-editor-info.png target=_blank title="Opens a guide to the Palette Editor in a separate tab or window.">info</a>)<p><label title="Size of the color palette for pixels outside the Mandebrot set.">PaletteLength: <select id=paletteLengthSelect><option value=Match>= MaxIter<option value=50>50<option value=100>100<option value=250>250<option value=500>500<option value=1000>1000<option value=2500>2500<option value=5000>5000<option value=Custom>Custom</select></label><span id=custompallen style=display:none><br><input id=palleninput size=4 maxlength=5><button id=pallenapply>Apply</button></span><p><label title="Offsets the colors within the palette to get a different mapping.">PaletteOffset: <select id=paletteOffsetSelect><option value=0>None<option value=0.1>10%<option value=0.2>20%<option value=0.3>30%<option value=0.4>40%<option value=0.5>50%<option value=0.6>60%<option value=0.7>70%<option value=0.8>80%<option value=0.9>90%<option value=Custom>Custom</select></label><span id=custoffset style=display:none><br><input id=offsetinput size=5 maxlength=6><b>%</b> <button id=offsetapply>Apply</button></span><p style=margin-bottom:4px><button id=standardPaletteButton title="Click here to apply the palette of colors selected in the popup menu below.">Apply Standard Palette:</button><p style=margin-top:0><select id=standardPaletteSelect title="Some palettes of colors to be applied to the Mandelbrot image. Click the above button to apply the selected palette."style=margin-left:70px><option value=Spectrum>Spectrum<option value=EarthAndSky>EarthAndSky<option value="Cyclic Fire">Fire<option value=Seashore>Seashore<option value=TreeColors>Forest<option value=Pastels>Pastel Colors<option value=Dark>Dark Colors<option value=HotAndCold>HotAndCold<option value=CyclicGrayscale>Grayscale<option value=Random>Random</select></div><div class=group><p><button id=zoomin>Zoom in by:</button> <select id=zoomInAmount><option value=0.5>2 X<option value=0.2>5 X<option value=0.1>10 X<option value=0.05>20 X<option value=0.02>50 X<option value=0.01>100 X<option value=0.001>1,000 X<option value=0.00001>10,000 X<option value=0.000001>100,000 X</select><p><button id=zoomout>Zoom out by:</button> <select id=zoomOutAmount><option value=2>2 X<option value=5>5 X<option value=10>10 X<option value=20>20 X<option value=50>50 X<option value=100>100 X<option value=1000>1,000 X<option value=10000>10,000 X<option value=100000>100,000 X</select></div><div class=group><p><button id=saveBtn title="Save XML code for the current image to a local file.">Save File</button> <button id=loadBtn title="Load image specification from a local XML file."style=margin-left:15px>Load file</button><p><button id=importXML title="Put up an input box into which you can copy-and-paste the XML code for an example, or get the XML for the current example.">Show XML Import/Export</button></div></div><td><div id=imagediv><p id=status>Image size 800x600. Idle.<p><div id=canvas-holder><canvas height=600 id=canvas width=800></canvas></div></div></table><div id=xmlimportbg></div><div id=xmlimport><p>Mandelbrot examples can be coded as "XML documents."<br>You can copy-and-paste the XML code for an example<br>into this text input box. Click "Apply" to import the<br>example. Click "Cancel" or press ESC to cancel. The<br>"Grab Current Example" button loads the XML for the<br>example that is currently shown in the program; this<br>allows you to save the example (or even edit it by hand).<p><button id=applyXMLimport style=margin-left:50px>Apply</button> <button id=cancelXMLimport style=margin-left:20px>Cancel</button> <button id=grabcurrent style=margin-left:20px>Grab Current Example</button><p><textarea cols=55 id=XMLtextinput placeholder="XML code goes here"rows=21></textarea></div><div id=paletteEditor><table border=2 cellpadding=3 cellspacing=0 bgcolor=#E8E8E8><tr><td colspan=2><table border=0 width=620><tr><td align=left><button id=paletteEditStandardInstall title="Click this button to replace the palette below with the standard palette that is selected on the right.">Install:</button> <select id=paletteEditStandardSelect title="Click the button on the left to apply this palette in the palette editor."><option value=Spectrum>Spectrum<option value=EarthAndSky>EarthAndSky<option value="Cyclic Fire">Fire<option value=Seashore>Seashore<option value=TreeColors>Forest<option value=Pastels>Pastel Colors<option value=Dark>Dark Colors<option value=HotAndCold>HotAndCold<option value=CyclicGrayscale>Grayscale<option value=Random>Random</select><td align=right><button id=addcolorstop title="Click to add a color stop to the palette below. The stop will be added next to the currently selected stop, if possible. You can also add a stop by double-clicking the palette.">Add Color Stop</button> <button id=deletecolorstop title="Click to delete the selected color stop. The first and last stops cannot be deleted.">Delete</button> <label title="Check this box to lock the colors of the first and last color stops so that the two colors are forced to be the same."style=margin-left:20pt>Lock<input id=lockcolors type=checkbox></label></table><p style="margin:5px 0 0 0"><canvas height=80 id=coloredit width=630 title="Click a color stop to select it. Drag selected color stop (except for the two at the ends) to move it. Double-click in a free area to add a color stop."></canvas><table border=0 cellpadding=0 style="margin:0 0 0 20px"><tr><td><canvas height=40 id=colorslider0 width=401 title="Drag the slider to set the first color component of the selected color stop to a value in the range 0.0 to 1.0."></canvas><td><input id=colorinput0 size=5 title="You can type a value for the first color component here, 0.0 to 1.0 for Red, anything greater than or equal to zero for Hue."> <span id=colorlabel0>Hue</span><tr><td><canvas height=40 id=colorslider1 width=401 title="Drag the slider to set the second color component of the selected color stop to a value in the range 0.0 to 1.0."></canvas><td><input id=colorinput1 size=5 title="You can type a value for the second color component here, in the range 0.0 to 1.0."> <span id=colorlabel1>Saturation</span><tr><td><canvas height=40 id=colorslider2 width=401 title="Drag the slider to set the third color component of the selected color stop to a value in the range 0.0 to 1.0."></canvas><td><input id=colorinput2 size=5 title="You can type a value for the third color component here, in the range 0.0 to 1.0."> <span id=colorlabel2>Brightness</span></table><tr><td valign=top><canvas height=100 id=histogram width=420 title="Shows the distribution of iteration counts in the image, from 1 up to MaxIterations. This can help with selecting a good palette length."></canvas><p style="margin:3px 0 0 9px"><canvas height=22 id=histogrampalette width=408 title="Shows how colors from palette will actually be applied to each iteration count, based on palette length and palette offset."style=display:inline></canvas><table border=0 cellpadding=0 style="margin:3px 0 0 0"><tr><td colspan=2><canvas height=40 id=lengthslider width=420 title="Drag the slider to set the palette length. Slider shows values between 1 and MaxIterations. You can set an even larger value in the input box below."></canvas><tr><td align=right colspan=2><input id=editorlengthinput size=5 title="You can type a value for the palette length here. It must be 1 or more.">Palette Length<tr><td align=right><canvas height=40 id=offsetslider width=250 title="Drag the slider to set the palette offset as a percentage in the range 0 to 100."></canvas><td align=left><input id=editoroffsetinput size=5 title="You can type a value for the palette offset percentage, in the range 0.0 to 100.0.">% Offset</table><td valign=top width=200><table border=0 cellpadding=0><tr><td><canvas height=200 id=preview width=200 title="A rough copy of the current image, with edited colors applied, giving a preview of the image with the edited palette."><tr><td><label title="If this box is unchecked, changes are only applied to the above preview when a drag action end. Uncheck the box if your computer is having trouble keeping up as you drag a slider or color stop."><input id=updateWhileDraggingCheck type=checkbox checked>UpdateDuringDrag</label></table><tr><td align=center colspan=2><button id=dismissPaletteEdit title="Cancel palette editing, leaving colors in the image unchanged.">Cancel</button> <button id=revertPaletteEdit title="Restore the palette to the its state when the palette editor was opened.">Revert Palette</button> <button id=applyPaletteEdit title="Dismiss the palette editor and apply the palette from the editor to the main image.">Apply and Close</button></table></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment