0x122c…f8b5

All memos sent from and to 0x122c…f8b5.

class FastPoisson{constructor(){this.points=[],this.index=0,this.radius=7,this.dead=!1}solve(t){let s=45,e=80;8==t&&(s=25,e=45);let i=this.radius,$=myWidth,h=myHeight,_;i=Math.min(i,$/s*.9),i*=i;let l,r=createVector(R.random_dec(),R.random_dec());for(let a=0;a<e;a++)for(let g=0;g<s;g++){let p=0;for(;;){r=createVector(R.random_dec(),R.random_dec());let x=createVector(r.x+g,r.y+a);x.x/=s,x.y/=e,x.x*=$,x.y*=h;let o=g+a*e,f=g-1+a*e,c=g+(a-1)*e,n=g-1+(a-1)*e,d=g+1+(a-1)*e,y=this.points[f],b=this.points[c],P=this.points[n],u=this.points[d];if(0!=g&&0==a){if(p5.Vector.sub(y,x).magSq()>i){this.points[o]=x;break}}else if(0==g&&0!=a){if(p5.Vector.sub(b,x).magSq()>i){this.points[o]=x;break}}else if(0==g&&0==a){this.points[o]=x;break}else if(0!=g&&0!=a&&g!=s-1){let m=p5.Vector.sub(b,x);p5.Vector.sub(y,x),p5.Vector.sub(P,x),p5.Vector.sub(u,x);let k=m.magSq(),v=m.magSq(),w=m.magSq(),B=m.magSq();if(k>i&&v>i&&w>i&&B>i){this.points[o]=x;break}}else if(0!=g&&0!=a&&g==s-1){let S=p5.Vector.sub(b,x);p5.Vector.sub(y,x),p5.Vector.sub(P,x);let W=S.magSq(),q=S.magSq(),T=S.magSq();if(W>i&&q>i&&T>i){this.points[o]=x;break}}if(++p>1e3)break}}}render(t,s){for(let e=0;e<this.points.length;e++)if(this.points[e]){let i=this.points[e],$=i.x,h=i.y,_=R.random_num(5,7),l=palettes.getBg(R.random_num(0,1)),r=R.random_num(0,TWO_PI);0==s?drawCherryBlossom(t,$,h,_,l,r,0):1==s&&drawMum(t,$,h,3*_,l,r)}}}class Fabric{constructor(t,s){this.spacing=t,this.bgType=s,this.sw=.05*t,this.hexBgPs=[],this.gridBgPs=[],this.hexps=[],this.hexps2=[],this.gridps=[],this.buildPsArrays()}buildPsArrays(){let t=this.spacing,s=.5*t,e=myHeight/t+1,i=myWidth/(.866*t)+1;for(let $=0;$<e;$++)for(let h=0;h<i;h++){let _=h*t*.866,l=$*t;h%2==0&&(l+=s),this.hexBgPs.push({x:_,y:l,i:$,j:h})}this.hexBgPs.sort((t,s)=>t.y-s.y),e=myHeight/t+1,i=myWidth/s+1;for(let r=0;r<e;r++)for(let a=0;a<i;a++){let g=a*s,p=r*t;a%2==0&&(p+=s),this.gridBgPs.push({x:g,y:p,i:r,j:a})}this.gridBgPs.sort((t,s)=>t.y-s.y);let x=TWO_PI/6;for(let o=0;o<6;o++){let f=x*(o+.5),c=cos(f),n=sin(f);this.hexps.push({x:c,y:n,t:f}),f+=.5*x,c=cos(f),n=sin(f),this.hexps2.push({x:c,y:n,t:f})}x=TWO_PI/4;for(let d=0;d<4;d++){let y=x*(d+.5),b=cos(y),P=sin(y);this.gridps.push({x:b,y:P})}}drawFabric(t){if(t.background(palettes.getBg(0)),this.bgType<=6){t.stroke(palettes.getBg(1)),t.strokeWeight(this.sw);let s=R.random_int(0,2);for(let e of this.hexBgPs){let i=e.x,$=e.y,h=e.i,_=e.j;0==this.bgType?this.drawHexWeave(t,i,$,this.spacing):1==this.bgType?this.drawDiamondWaves(t,i,$,this.spacing):2==this.bgType?this.drawCircleWaves(t,i,$,h,_,this.spacing,s):3==this.bgType?this.drawHempLeaves(t,i,$,h,_,this.spacing):4==this.bgType?this.drawHexWeave2(t,i,$,this.spacing):5==this.bgType?this.drawBasketWeave(t,i,$,h,_,this.spacing,s):6==this.bgType&&this.drawHexStars(t,i,$,h,_,this.spacing,s)}}else 7==this.bgType?poisson.render(t,0):8==this.bgType&&poisson.render(t,1)}drawHexWeave(t,s,e,i){let $=.6*i,h=.3*i;t.noStroke();for(let _=0;_<6;_+=2){let l=map(_,0,6,0,1,!0),r=[],a=_,g=(_+1)%6,p=(_+5)%6,x=this.hexps[a].x,o=this.hexps[a].y,f=this.hexps[g].x,c=this.hexps[g].y,n=this.hexps[p].x,d=this.hexps[p].y,y=s,b=e,P=s+f*$,u=e+c*$,m=P+n*h,k=u+d*h,v=s+x*h,w=e+o*h,B=s+n*$,S=e+d*$,W=B+f*h,q=S+c*h;for(let T of(r.push({x:y,y:b}),r.push({x:P,y:u}),r.push({x:m,y:k}),r.push({x:v,y:w}),r.push({x:W,y:q}),r.push({x:B,y:S}),t.fill(palettes.getBg(l)),t.beginShape(),r))t.vertex(T.x,T.y);t.endShape(CLOSE)}}drawDiamondWaves(t,s,e,i){let $=.05*i;for(let h=0;h<4;h++){let _=map(h,0,3,.25,1),l=lerp(0,i,_),r=this.hexps[3].x,a=this.hexps[3].y,g=this.hexps[4].x,p=this.hexps[4].y,x=this.hexps[5].x,o=this.hexps[5].y;drawDottedLine(t,s+r*l,e+a*l,s+g*l,e+p*l,2*h+2,$),drawDottedLine(t,s+g*l,e+p*l,s+x*l,e+o*l,2*h+2,$)}}drawHexStars(t,s,e,i,$,h,_){let l=.15*h,r=.5*l,a=.25*h,g=this.hexps[4].x,p=this.hexps[4].y,x=this.hexps[3].x,o=this.hexps[3].y,f=this.hexps[5].x,c=this.hexps[5].y;if(i%3==(2+($+1)%2)%3){drawDottedLine(t,s+g,e+p,s+g*h,e+p*h,3,l);for(let n=1;n<6;n+=2){let d=n,y=this.hexps[d].x,b=this.hexps[d].y;t.line(s+y*r,e+b*r,s+y*a,e+b*a)}}else if(i%3==(1+($+1)%2)%3){drawDottedLine(t,s+x,e+o,s+x*h,e+o*h,3,l),drawDottedLine(t,s+f,e+c,s+f*h,e+c*h,3,l);for(let P=0;P<6;P+=2){let u=P,m=this.hexps[u].x,k=this.hexps[u].y;t.line(s+m*r,e+k*r,s+m*a,e+k*a)}}else if(i%3==(0+($+1)%2)%3){for(let v=0;v<6;v++){let w=v,B=this.hexps[w].x,S=this.hexps[w].y;t.line(s+B*r,e+S*r,s+B*a,e+S*a)}drawDottedHex(t,this.hexps,s,e,.6*h),0==_?drawDottedHex(t,this.hexps,s,e,.4*h):2==_&&drawDottedHex(t,this.hexps,s,e,.8*h)}}drawBasketWeave(t,s,e,i,$,h,_){let l=.15*h,r=.8;1==_?r=.7:2==_&&(r=.8);let a=h*r,g=.65*h;if(i%3==(0+($+1)%2)%3){for(let p=0;p<6;p++){let x=p,o=(p+1)%6,f=this.hexps2[x].x*a,c=this.hexps2[x].y*a,n=this.hexps2[o].x*a,d=this.hexps2[o].y*a,y=this.hexps2[x].x*g,b=this.hexps2[x].y*g,P=this.hexps2[o].x*g,u=this.hexps2[o].y*g,m=n-f,k=d-c;n=f+2*m,d=c+2*k,0==_?(t.strokeWeight(.5*this.sw),t.line(s+f,e+c,s+n,e+d),t.strokeWeight(2*this.sw),t.line(s+y,e+b,s+P,e+u)):drawDottedLine(t,s+f,e+c,s+n,e+d,5,l)}1==_?(drawDottedHex(t,this.hexps2,s,e,.5*h),drawDottedHex(t,this.hexps2,s,e,.6*h)):2==_&&(t.fill(palettes.getBg(1)),t.circle(s,e,.75*h))}}drawCircleWaves(t,s,e,i,$,h,_){let l=palettes.getBg(0),r=palettes.getBg(1);t.stroke(l);let a;if(0==_?a=8:1==_?a=int(map(noise(.008*s,.2*e),.25,.75,6,9,!0)):2==_&&(a=10),t.fill(color(0,45)),t.circle(s,e,2.1*h),2==_){if(i%2==0&&$%2==0)t.fill(r),t.circle(s,e,1.9*h),t.fill(l),t.circle(s,e,1.8*h);else for(let g=0;g<a;g++){let p=map(g,0,a-1,0,1),x=lerp(.95*h,h/a,p);t.fill(lerpColor(r,l,g%2)),t.circle(s,e,2*x)}}else for(let o=0;o<a;o++){let f=map(o,0,a-1,0,1),c=lerp(.95*h,h/a,f);t.fill(lerpColor(r,l,o%2)),t.circle(s,e,2*c)}}drawHempLeaves(t,s,e,i,$,h){let _=.5*h,l=.6*h;for(let r of this.hexps){let a=r.x,g=r.y;t.line(s,e,s+a*_,e+g*_)}for(let p of this.hexps2){let x=p.x,o=p.y;t.line(s,e,s+x*l,e+o*l)}}drawDottedWaves(t,s,e,i,$,h){t.noStroke(),t.fill(palettes.getBg(1)),t.circle(s,e,2*h),t.stroke(palettes.getBg(0));for(let _=0;_<8;_++){let l=map(_,0,7,0,1);drawDottedArc(t,s,e,.6*TWO_PI,.9*TWO_PI,lerp(.95*h,h/8,l),3)}}drawHexWeave2(t,s,e,i){let $=.1*i,h=.2*i,_=.225*i;for(let l=0;l<6;l+=2){let r=l,a=(l+1)%6,g=(l+5)%6,p=this.hexps[r].x,x=this.hexps[r].y,o=(this.hexps[r].t+10*TWO_PI)%TWO_PI/TWO_PI,f=this.hexps[a].x,c=this.hexps[a].y,n=(this.hexps[a].t+10*TWO_PI)%TWO_PI/TWO_PI,d=this.hexps[g].x,y=this.hexps[g].y,b=(this.hexps[g].t+10*TWO_PI)%TWO_PI/TWO_PI;t.stroke(palettes.getIri(o,50)),drawDottedLine(t,s,e,s+p*h*3,e+x*h*3,3,$),t.stroke(palettes.getIri(n,50)),drawDottedLine(t,s+f*_,e+c*_,s+f*_+p*_*2,e+c*_+x*_*2,3,$),t.stroke(palettes.getIri(b,50)),drawDottedLine(t,s+d*_,e+y*_,s+d*_+p*_*2,e+y*_+x*_*2,3,$)}}drawHempLeaves2(t,s,e,i,$,h){let _=1*h,l=.6*h;t.noStroke();for(let r=0;r<6;r++){let a=map(getNoise(s,e,.0025),.25,.75,.8,1,!0),g=map(r,0,6,a,1),p=this.hexps[r].x*_,x=this.hexps[r].y*_,o=this.hexps2[r].x*l,f=this.hexps2[r].y*l;t.strokeWeight(.25),t.stroke(palettes.getBg(1)),t.fill(palettes.getBg(.5*g)),t.beginShape(),t.vertex(s,e),t.vertex(s+p,e+x),t.vertex(s+o,e+f),t.endShape(CLOSE)}}drawSquareWeave(t,s,e,i,$,h){let _=.1*h,l=.25*h,r=.025*h;for(let a=0;a<4;a++){let g=a,p=(a+1)%4,x=this.gridps[g].x*l,o=this.gridps[g].y*l,f=this.gridps[p].x*l,c=this.gridps[p].y*l,n=f-x,d=c-o;$%2==1?drawDottedLine(t,s+(x=f-n*r),e+(o=c-d*r),s+f,e+c,2,_):(f=x+n*r,c=o+d*r,drawDottedLine(t,s+x,e+o,s+f,e+c,4,_))}t.circle(s,e,5)}drawSquareCircles(t,s,e,i,$,h){t.noFill(),t.strokeWeight(.5),t.circle(s,e,1*h),t.circle(s,e,.7*h)}}class Palettes{constructor(){this.fgPalettes=[],this.bgPalettes=[],this.loadPalettes(),this.numPalettes=this.fgPalettes.length,this.id=R.random_int(0,this.numPalettes-1),this.fgcs=[],this.bgcs=[],this.irics=[],this.createColors(this.id)}loadPalettes(){append(this.bgPalettes,[15,15,15,35,35,35]),append(this.fgPalettes,[33,72,106,51,130,18,254,221,210,235,163,177]),append(this.bgPalettes,[15,15,15,45,45,45]),append(this.fgPalettes,[5,5,5,15,15,15,25,25,25,35,35,35]),append(this.bgPalettes,[44,50,130,64,70,150]),append(this.fgPalettes,[49,19,140,33,51,151,112,91,78,168,150,144]),append(this.bgPalettes,[55,63,68,95,103,108]),append(this.fgPalettes,[142,61,39,176,145,112,117,131,141,204,213,218]),append(this.bgPalettes,[117,1,39,157,21,59]),append(this.fgPalettes,[75,75,75,100,88,88,205,111,111,225,144,111]),append(this.bgPalettes,[13,26,40,33,46,60]),append(this.fgPalettes,[23,37,51,68,87,99,206,199,187,142,174,196]),append(this.bgPalettes,[15,26,15,35,46,35]),append(this.fgPalettes,[17,33,14,59,73,63,116,142,121,174,210,213]),append(this.bgPalettes,[20,30,73,40,50,93]),append(this.fgPalettes,[25,36,84,219,68,73,232,203,172,235,143,108]),append(this.bgPalettes,[200,200,200,255,255,255]),append(this.fgPalettes,[0,0,0,10,10,10,25,25,25,55,55,55]),append(this.bgPalettes,[18,44,65,30,50,80]),append(this.fgPalettes,[48,74,95,205,62,62,18,44,65,48,74,95]),append(this.bgPalettes,[15,15,15,45,45,45]),append(this.fgPalettes,[255,255,255,225,225,225,200,200,200,180,180,180]),append(this.bgPalettes,[65,45,25,85,65,45]),append(this.fgPalettes,[75,55,35,165,85,105,95,75,55,185,105,125]),append(this.bgPalettes,[254,55,19,253,29,0]),append(this.fgPalettes,[255,80,50,0,37,189,0,52,221,0,92,255]),append(this.bgPalettes,[0,75,28,0,48,16]),append(this.fgPalettes,[0,221,90,255,210,0,0,244,130,255,198,0])}createColors(t){let s=this.bgPalettes[t],e=this.fgPalettes[t];this.fgcs=[];for(let i=0;i<4;i++){let $=3*i,h=e[$+0],_,l=color(h,e[$+1],e[$+2]);append(this.fgcs,l)}this.bgcs=[];for(let r=0;r<2;r++){let a=3*r,g=s[a+0],p,x=color(g,s[a+1],s[a+2]);append(this.bgcs,x)}this.irics=[],append(this.irics,color(255,150,255)),append(this.irics,color(150,150,255)),append(this.irics,color(150,255,255)),append(this.irics,color(150,255,150)),append(this.irics,color(255,255,150))}getFg(t,s){let e,i;for(let $=0;$<3;$++)if(t<=($+1)*.3334){e=map(t,.3334*$,($+1)*.3334,0,1),i=lerpColor(this.fgcs[$],this.fgcs[$+1],e);break}return void 0!==s?color(red(i),green(i),blue(i),s):i}getBg(t,s){let e=lerpColor(this.bgcs[0],this.bgcs[1],t);return void 0!==s?color(red(e),green(e),blue(e),s):e}getIri(t,s){let e,i;for(let $=0;$<4;$++)if(t<=($+1)*.25){e=map(t,.25*$,($+1)*.25,0,1),i=lerpColor(this.irics[$],this.irics[$+1],e);break}return void 0!==s?color(red(i),green(i),blue(i),s):i}getRandom(){return color(R.random_num(25,255),R.random_num(25,255),R.random_num(25,255))}}
let DEBUG=!1,SAVEFRAMES=!1,myWidth=900,myHeight=1600,halfWidth=myWidth/2,halfHeight=myHeight/2,imgScale=2,imgWidth=myWidth/imgScale,imgHeight=myHeight/imgScale,drawWidth,drawHeight,currentHash="",buffer,numCanvases=6,canvases=[],img,gfx,palettes,numPalettes,palette_id,fgPalettes=[],bgPalettes=[],fgcs=[],bgcs=[],iris=[],PALETTE,poisson,fabric,sakuraPs=[],embSakuraPs=[],mumPs=[],shx=1,shy=.5,roads=[],spawns=[],flowers=[],currentFrame=0,maxFrameCount=3e3,MAX_GEN=15,nOffsetX,nOffsetY,MAIN_RAND,IS_ANGLE_LOCKED,ANGLE_LOCK_GEN,BACKGROUND_ID,BACKGROUND_SPACING,SPAWN_ID,ZONE_ID,PRIMARY_CURVATURE,SECONDARY_CURVATURE,IS_TRADITIONAL,BG_DETAIL,numStripes,renderGridRes=1,prefillDotRadius,prefillGridXCount,prefillGridYCount,prefillRad0,prefillRad1,prefillRad2;class Random{constructor(){this.useA=!1;let t=function(t){let e=parseInt(t.substr(0,8),16),i=parseInt(t.substr(8,8),16),$=parseInt(t.substr(16,8),16),s=parseInt(t.substr(24,8),16);return function(){$|=0;let t=((e|=0)+(i|=0)|0)+(s|=0)|0;return s=s+1|0,e=i^i>>>9,i=$+($<<3)|0,$=($=$<<21|$>>>11)+t|0,(t>>>0)/4294967296}};this.prngA=new t(tokenData.hash.substr(2,32)),this.prngB=new t(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(t,e){return t+(e-t)*this.random_dec()}random_int(t,e){return Math.floor(this.random_num(t,e+1))}random_bool(t){return this.random_dec()<t}random_choice(t){return t[this.random_int(0,t.length-1)]}}function readColor(t,e){let i=4*(e*imgWidth+t);if(i>=img.pixels.length-3)return print("index out of range"),color(255,0,0,255);{let $=img.pixels[i+0],s;return color($,img.pixels[i+1],img.pixels[i+2],255)}}function writeColor(t,e,i,$,s){let r=4*(e*imgWidth+t);img.pixels[r+0]=i,img.pixels[r+1]=$,img.pixels[r+2]=s,img.pixels[r+3]=255}function writeCircle(t,e,i,$){gfx.clear(),gfx.fill($),gfx.ellipse(gfx.width/2,gfx.height/2,100,100),img.copy(gfx,0,0,gfx.width,gfx.height,t-i,e-i,2*i,2*i)}function writeRect(t,e,i,$,s){gfx.clear(),gfx.fill(s),gfx.rect(0,0,100,100),img.copy(gfx,0,0,gfx.width,gfx.height,t,e,i,$)}function getNoise(t,e,i){let $;return map(noise(t*i+nOffsetX,e*i+nOffsetY),.1,.9,0,1,!0)}function createGridSpawn(t,e,i,$,s){for(let r=0;r<t;r++)for(let h=0;h<e;h++){let a=map(r,-.5,t-.5,0,1),l=map(h,-.5,e-.5,0,1),n;addRoad(a*myWidth+i,l*myHeight+a*myHeight*.5+$,s,0,0)}}function createCircleSpawn(t,e,i,$,s){for(let r=0;r<$;r++){let h=map(r,0,$,0,TWO_PI),a=cos(h)*i,l=sin(h)*i;addRoad(t+a,e+l,h+s,0,0)}}function createWavySpawn(t,e,i){for(let $=0;$<t;$++){let s=$*myHeight*.05,r=.45*$;for(let h=0;h<e;h++){let a=map(h,0,e,0,1),l=myWidth*a,n=i+80*sin(a*PI*2+r+.05*i)+s+a*myHeight*.5;addRoad(l,n,HALF_PI,0,0)}}}function addRoad(t,e,i,$){let s=new Road(t,e,i,$);roads.push(s)}function addSpawn(t,e,i,$){let s=new Spawn(t,e,i,$);spawns.push(s)}function drawEmbroideredRing(t,e,i,$,s,r){for(let h=i-$;h<i+$;h+=r){let a=e-sqrt(sq($)-sq(h-i)),l=e+sqrt(sq($)-sq(h-i));if(a>=e-$&&l<=e+$){let n=e-sqrt(sq(s)-sq(h-i)),d=e+sqrt(sq(s)-sq(h-i));h>i-s&&h<i+s?(t.line(a,h,n,h),t.line(d,h,l,h)):t.line(a,h,l,h)}}}function drawDottedLine(t,e,i,$,s,r,h){let a=dist(e,i,$,s),l=(a-h*r)/r;for(let n=0;n<r;n++){let d=.5*h+n*(l+h),o=lerp(e,$,d/a),g=lerp(i,s,d/a),m=lerp(e,$,(l+d)/a),f=lerp(i,s,(l+d)/a);t.line(o,g,m,f)}}function drawDottedHex(t,e,i,$,s){for(let r=0;r<6;r++){let h=r,a=(r+1)%6,l=e[h].x*s,n=e[h].y*s,d;drawDottedLine(t,i+l,$+n,i+e[a].x*s,$+e[a].y*s,2,3)}}function drawDottedArc(t,e,i,$,s,r,h){let a=floor((s-$)*r/h),l=(s-$)/a;for(let n=0;n<=a;n++){let d=$+n*l,o=e+r*cos(d),g=i+r*sin(d);t.point(o,g)}}function drawStitchedCircle(t,e,i,$,s,r,h,a){let l=h+a,n=TWO_PI*r,d=n/l;t.stroke($),t.strokeWeight(s);for(let o=0;o<d;o++){let g=o*l/n*TWO_PI,m=g+h/n*TWO_PI,f=e+r*cos(g),c=i+r*sin(g),u=e+r*cos(m),p=i+r*sin(m);t.line(f,c,u,p)}}function drawStitchedLine(t,e,i,$,s,r,h,a,l){let n=dist(e,i,$,s),d=a+l,o=n/d;t.stroke(r),t.strokeWeight(h);for(let g=0;g<o;g++){let m=g*d/n,f=(g*d+a)/n;f=min(f,1);let c=lerp(e,$,m),u=lerp(i,s,m),p=lerp(e,$,f),y=lerp(i,s,f);t.line(c,u,p,y)}}function drawStitch(t,e,i,$,s,r,h,a,l,n,d){t.strokeWeight(a),t.stroke(palettes.getBg(0)),t.line($+shx,s+shy,r+shx,h+shy),e.strokeWeight(.25*a),e.stroke(d),e.line($,s,r,h);let o=.5*sin(2*n)+.5;i.strokeWeight(l),i.stroke(palettes.getIri(o,255*o)),i.line($-shx,s-shy,r-shx,h-shy)}function storeSakuraPs(){sakuraPs.push({x:0,y:.05}),sakuraPs.push({x:-.3,y:.5}),sakuraPs.push({x:-.3,y:.75}),sakuraPs.push({x:-.1,y:1}),sakuraPs.push({x:0,y:.9}),sakuraPs.push({x:.1,y:1}),sakuraPs.push({x:.3,y:.75}),sakuraPs.push({x:.3,y:.5}),sakuraPs.push({x:0,y:.05})}function storeEmbSakuraPs(){TWO_PI;let t=75;for(let e=0;e<t;e++){let i=map(e%15,0,15,0,1),$=pow(sin(i*PI),25),s=map(e,0,t,0,TWO_PI),r=map(e,0,t,0,5*PI),h=cos(s),a=sin(s),l=pow(abs(sin(r)),.25),n=h*(l-=.125*$),d=a*l;embSakuraPs.push({x:n,y:d,theta:s})}}function storeMumPs(){TWO_PI;for(let t=0;t<16;t++){let e=map(t,0,16,0,TWO_PI),i=cos(e),$=sin(e);mumPs.push({x:i,y:$})}}function sign(t){return t>0?1:t<0?-1:0}function roundAngle(t,e,i){let $=TWO_PI/e;return round(t/$)*$+i}function preload(){for(let t=0;t<numCanvases;t++){let e=createGraphics(myWidth,myHeight);e.noStroke(),append(canvases,e)}windowResized()}function prefillImg(t){(img=createImage(imgWidth,imgHeight)).loadPixels();for(let e=0;e<imgWidth;e++)for(let i=0;i<imgHeight;i++)img.set(e,i,color(0,0,0));if(img.updatePixels(),1==t){prefillDotRadius=R.random_num(10,30),prefillGridXCount=R.random_int(2,4),prefillGridYCount=R.random_int(2,6);let $=prefillDotRadius,s=2*$,r=prefillGridXCount,h=prefillGridYCount,a=color(15,15,15);for(let l=0;l<r;l++)for(let n=0;n<h;n++){let d=map(l,-.5,r-.5,0,1),o=map(n,-.5,h-.5,0,1),g=d*imgWidth,m=o*imgHeight+d*imgHeight*.5;writeCircle(g,m,s,a),g>imgWidth-$?writeCircle(g-=imgWidth,m,s,a):g<$&&writeCircle(g+=imgWidth,m,s,a),m>imgHeight-$?writeCircle(g,m-=imgHeight,s,a):m<$&&writeCircle(g,m+=imgHeight,s,a)}}else if(2==t){prefillRad0=R.random_num(100,250),prefillRad1=R.random_num(50,150),prefillRad2=R.random_num(20,70);let f=.5*imgWidth,c=.5*imgHeight,u=color(15,0,0);writeCircle(f,c,prefillRad0,u),writeCircle(f,c,prefillRad1,u=color(0,15,0)),writeCircle(f,c,prefillRad2,u=color(0,0,15))}else if(3==t){numStripes=R.random_int(2,4);let p=color(10,10,10),y=imgWidth/(2*numStripes),_=imgHeight;for(let w=0;w<numStripes;w++){let S=map(w,.5,numStripes-.5,0,1);writeRect(imgWidth*S,0,y,_,p)}}else if(4==t){let x=color(10,10,10);numStripes=R.random_int(2,7);for(let C=0;C<numStripes;C++){let W=map(C,.5,numStripes-.5,0,1);writeRect(0,imgHeight*W,imgWidth,imgHeight/(2*numStripes),x)}}}function windowResized(){dim=windowWidth<windowHeight?windowWidth:windowHeight,resizeCanvas(windowWidth,windowHeight);let t=myWidth/myHeight;width/height<t?(drawWidth=width,drawHeight=width/t):(drawHeight=height,drawWidth=height*t)}function keyTyped(){"s"==key?saveImage():"d"==key?DEBUG=!DEBUG:"r"==key?RESET=!0:"1"==key?renderGridRes=1:"2"==key?renderGridRes=2:"3"==key?renderGridRes=4:"4"==key&&(renderGridRes=8)}function saveImage(){let t=createGraphics(myWidth,myHeight);t.image(canvases[0],0,0);let e=2;for(let i=0;i<e;i++){let $=map(i,0,e,0,1),s=myWidth/e;for(let r=0;r<=e;r++){let h=myWidth*$,a=map(r,0,e,0,1),l=myHeight/e,n=myHeight*a;i%2==1&&(n-=l/2),t.image(canvases[1],h,n,s,l),t.image(canvases[2],h,n,s,l)}}e=renderGridRes;for(let d=0;d<e;d++){let o=map(d,0,e,0,1),g=myWidth/e;for(let m=0;m<=e;m++){let f=myWidth*o,c=map(m,0,e,0,1),u=myHeight/e,p=myHeight*c;d%2==1&&(p-=u/2);for(let y=1;y<numCanvases;y++)t.image(canvases[y],f,p,g,u)}}save(t,currentHash,"png")}function setupFeatures(){palettes=new Palettes,MAX_GEN=8,MAIN_RAND=R.random_dec(),IS_ANGLE_LOCKED=R.random_bool(.2),ANGLE_LOCK_GEN=R.random_int(0,1),BACKGROUND_ID=R.random_int(0,4),BACKGROUND_SPACING=20,SPAWN_ID=R.random_int(0,6),ZONE_ID=R.random_int(0,4),IS_TRADITIONAL=R.random_bool(.9),BG_DETAIL=R.random_bool(.2),PRIMARY_CURVATURE=R.random_num(1,2),SECONDARY_CURVATURE=R.random_num(.5,2),print("Palette = "+palettes.id),print("Spawn Id = "+SPAWN_ID),print("Background Id = "+BACKGROUND_ID),print("Zone Id = "+ZONE_ID),print("Is Angle Locked = "+IS_ANGLE_LOCKED),print("Angle Lock Gen = "+ANGLE_LOCK_GEN)}function reset(){for(let t of(print("Growth v3"),print(tokenData.hash),print("------------------------------------------------------------------------------"),R=new Random,noiseDetail(5,.5),noiseSeed(R.random_dec()),nOffsetX=R.random_num(150,1300),nOffsetY=R.random_num(150,1300),randomSeed(R.random_dec()),pixelDensity(2),smooth(),saveFrame=!1,currentFrame=0,setupFeatures(),buffer=createCanvas(windowWidth,windowHeight),img=createImage(imgWidth,imgHeight),(gfx=createGraphics(100,100)).noStroke(),prefillImg(ZONE_ID),canvases))t.clear(),t.strokeCap(ROUND),t.background(0,0,0,0);roads=[],spawns=[],flowers=[],storeSakuraPs(),storeEmbSakuraPs(),storeMumPs(),(poisson=new FastPoisson).solve(BACKGROUND_ID),(fabric=new Fabric(BACKGROUND_SPACING,BACKGROUND_ID)).drawFabric(canvases[0]),initialSpawn(),stitchZones(ZONE_ID)}function setup(){windowResized(),reset()}function initialSpawn(){if(0==SPAWN_ID)createWavySpawn(2,75,.25*myHeight),createWavySpawn(2,75,.75*myHeight);else if(1==SPAWN_ID)createGridSpawn(3,4,0,0,0),createGridSpawn(3,4,30,-10,PI);else if(2==SPAWN_ID)createCircleSpawn(halfWidth,halfHeight,.55*myWidth,70,HALF_PI),createCircleSpawn(halfWidth,halfHeight,.35*myWidth,50,PI),createCircleSpawn(halfWidth,halfHeight,.2*myWidth,30,-HALF_PI);else if(3==SPAWN_ID)createCircleSpawn(halfWidth,halfHeight,.55*myHeight,70,HALF_PI),createCircleSpawn(halfWidth,halfHeight,.35*myHeight,50,PI),createCircleSpawn(halfWidth,halfHeight,.2*myHeight,30,-HALF_PI);else if(4==SPAWN_ID)for(let t=0;t<3;t++)for(let e=0;e<4;e++){let i=map(t,-.5,2.5,0,1),$=map(e,-.5,3.5,0,1),s;createCircleSpawn(i*myWidth,$*myHeight+i*myHeight*.5,20,12,0)}else 5==SPAWN_ID?createGridSpawn(3,5,0,0,0):6==SPAWN_ID&&(createCircleSpawn(halfWidth,halfHeight,.35*myHeight,150,PI),createCircleSpawn(halfWidth,halfHeight,.15*myHeight,75,0))}function stitchZones(t){let e=canvases[numCanvases-1],i=palettes.getBg(0),$=palettes.getFg(0);if(1==t){let s=2*prefillDotRadius,r=2*s,h=prefillGridXCount,a=prefillGridYCount;for(let l=0;l<h;l++)for(let n=0;n<a;n++){let d=map(l,-.5,h-.5,0,1),o=map(n,-.5,a-.5,0,1),g=d*myWidth,m=o*myHeight+d*myHeight*.5;drawStitchedCircle(e,g,m,i,8,r,8,4),drawStitchedCircle(e,g,m,$,1.5,r,8,4),g>myWidth-s?(drawStitchedCircle(e,g-=myWidth,m,i,8,r,8,4),drawStitchedCircle(e,g,m,$,1.5,r,8,4)):g<s&&(drawStitchedCircle(e,g+=myWidth,m,i,8,r,8,4),drawStitchedCircle(e,g,m,$,1.5,r,8,4)),m>myHeight-s?(drawStitchedCircle(e,g,m-=myHeight,i,8,r,8,4),drawStitchedCircle(e,g,m,$,1.5,r,8,4)):m<s&&(drawStitchedCircle(e,g,m+=myHeight,i,8,r,8,4),drawStitchedCircle(e,g,m,$,1.5,r,8,4))}}else if(2==t){let f=.5*myWidth,c=.5*myHeight;drawStitchedCircle(e,f,c,i,8,2*prefillRad0,8,4),drawStitchedCircle(e,f,c,$,1.5,2*prefillRad0,8,4),drawStitchedCircle(e,f,c,i,8,2*prefillRad1,8,4),drawStitchedCircle(e,f,c,$,1.5,2*prefillRad1,8,4),drawStitchedCircle(e,f,c,i,8,2*prefillRad2,8,4),drawStitchedCircle(e,f,c,$,1.5,2*prefillRad2,8,4)}else if(3==t){let u=myHeight;for(let p=0;p<numStripes;p++){let y=map(p,.5,numStripes-.5,0,1),_=myWidth*y;drawStitchedLine(e,_,0,_,u,i,8,8,4),drawStitchedLine(e,_,0,_,u,$,1.5,8,4),drawStitchedLine(e,_+=myWidth/(2*numStripes),0,_,u,i,8,8,4),drawStitchedLine(e,_,0,_,u,$,1.5,8,4)}}else if(4==t){let w=myWidth;for(let S=0;S<numStripes;S++){let x=map(S,.5,numStripes-.5,0,1),C=myHeight*x;drawStitchedLine(e,0,C,w,C,i,8,8,4),drawStitchedLine(e,0,C,w,C,$,1.5,8,4),drawStitchedLine(e,0,C+=myHeight/(2*numStripes),w,C,i,8,8,4),drawStitchedLine(e,0,C,w,C,$,1.5,8,4)}}}function update(){if(currentFrame>0){for(let t of(img.loadPixels(),roads))t.update();for(let e of spawns)e.update();for(let i of roads)i.render();img.updatePixels()}}function draw(){if(currentFrame<maxFrameCount){if(update(),currentFrame>0)for(let t of roads)t.drawRoad();cleanUp()}if(image(canvases[0],0,0,drawWidth,drawHeight),BG_DETAIL)for(let e=0;e<3;e++){let i=map(e,0,3,0,1),$=drawWidth/3;for(let s=0;s<=3;s++){let r=drawWidth*i,h=map(s,0,3,0,1),a=drawHeight/3,l=drawHeight*h;e%2==1&&(l-=a/2),image(canvases[1],r,l,$,a)}}gr=renderGridRes;for(let n=0;n<gr;n++){let d=map(n,0,gr,0,1),o=drawWidth/gr;for(let g=0;g<=gr;g++){let m=drawWidth*d,f=map(g,0,gr,0,1),c=drawHeight/gr,u=drawHeight*f;n%2==1&&(u-=c/2);for(let p=2;p<numCanvases;p++)image(canvases[p],m,u,o,c)}}currentFrame++,DEBUG&&image(img,0,0,drawWidth,drawHeight)}function cleanUp(){for(let t=0;t<roads.length;t++)roads[t].isDead()&&roads.splice(t,1);for(let e=0;e<spawns.length;e++)spawns[e].isDead()&&spawns.splice(e,1)}function drawCherryBlossom(t,e,i,$,s,r,h){0==h?plainCherryBlossom(t,e,i,$,s,r):1==h?embroideredCherryBlossom(t,e,i,$,s,r):2==h&&embroideredCherryBlossomOutline(t,e,i,$,s,r)}function plainCherryBlossom(t,e,i,$,s,r){let h=TWO_PI/5;t.fill(s),t.stroke(palettes.getBg(0)),t.strokeWeight(.5),t.push(),t.translate(e,i),t.rotate(r);for(let a=0;a<5;a++){for(let l of(t.rotate(h),t.beginShape(),sakuraPs)){let n=l.x*$,d=l.y*$;t.curveVertex(n,d)}t.endShape(CLOSE)}t.pop()}function embroideredCherryBlossom(t,e,i,$,s,r){for(let h of(TWO_PI,t.push(),t.translate(e,i),t.rotate(r),t.strokeWeight(6),t.stroke(palettes.getBg(0)),embSakuraPs)){let a=h.x*$*.2,l=h.y*$*.2,n=h.x*$,d=h.y*$;t.line(a,l,n,d)}for(let o of(t.strokeWeight(1.5),t.stroke(color(0,20)),embSakuraPs)){let g=o.x*$*.2,m=o.y*$*.2,f=o.x*$,c=o.y*$;t.line(g+shx,m+shy,f+shx,c+shy)}for(let u of(t.strokeWeight(1),t.stroke(s),embSakuraPs)){let p=u.x*$*.2,y=u.y*$*.2,_=u.x*$,w=u.y*$;t.line(p,y,_,w)}for(let S of(t.strokeWeight(.3),embSakuraPs)){let x=S.x*$*.2,C=S.y*$*.2,W=S.x*$,H=S.y*$,A=.5*sin(2*S.theta)+.5;t.stroke(palettes.getIri(A,100*A)),t.line(x-shx,C-shy,W-shx,H-shy)}t.fill(palettes.getBg(1)),t.strokeWeight(1),t.stroke(palettes.getFg(0));for(let k=0;k<15;k++){let P=map(k,0,15,0,1),I=P*TWO_PI,D=$*R.random_num(.35,.4),v=cos(I),N=sin(I),G=v*$*.1,E=N*$*.1,B=v*D,L=N*D;t.fill(palettes.getIri(P,50)),t.line(G,E,B,L),t.circle(B,L,.075*$)}t.pop()}function embroideredCherryBlossomOutline(t,e,i,$,s,r){for(let h of(TWO_PI,t.push(),t.translate(e,i),t.rotate(r),t.fill(palettes.getBg(.5)),t.strokeWeight(.035*$),t.stroke(palettes.getFg(1)),t.beginShape(),embSakuraPs)){h.x,h.y;let a=h.x*$,l=h.y*$;t.vertex(a,l)}t.endShape(CLOSE);for(let n=0;n<15;n++){let d=map(n,0,15,0,1),o=d*TWO_PI,g=$*R.random_num(.35,.4),m=cos(o),f=sin(o),c=m*$*.1,u=f*$*.1,p=m*g,y=f*g;t.fill(palettes.getIri(d,250)),t.line(c,u,p,y),t.circle(p,y,.075*$)}t.pop()}function drawMum(t,e,i,$,s,r){plainMum(t,e,i,$,s,r)}function plainMum(t,e,i,$,s,r){t.fill(s),t.stroke(palettes.getBg(R.random_dec())),t.strokeWeight(.025*$);let h=mumPs.length;for(let a=0;a<h;a++){let l=a,n=(a+1)%h,d=mumPs[l].x,o=mumPs[l].y,g=mumPs[n].x,m=mumPs[n].y;t.beginShape(),t.curveVertex(e,i);for(let f=0;f<5;f++){let c=map(f,0,4,0,1),u=lerp(.8*$,$,sqrt(sin(c*PI))),p=e+lerp(d,g,c)*u,y=i+lerp(o,m,c)*u;t.curveVertex(p,y)}t.curveVertex(e,i),t.endShape(CLOSE)}t.fill(palettes.getBg(R.random_dec())),t.circle(e,i,.45*$)}class Spawn{constructor(t,e,i,$){this.x=t,this.y=e,this.theta=i,this.gen=$,this.age=0,this.life=250,this.dead=!1}update(){this.age++,this.age>this.life&&(addRoad(this.x,this.y,this.theta,this.gen),this.dead=!0)}isDead(){return this.dead}}class Road{constructor(t,e,i,$){this.x=t,this.y=e,this.theta=i,this.gen=$,this.genPer=map(this.gen,0,6,0,1),this.cd=palettes.getFg(fract(this.genPer+R.random_num(0,.05))),this.genPer=map(this.gen,0,3,0,1,!0),this.myRand=R.random_dec(),this.trajThresh=1.3,this.sw=1,this.sw2=3,this.swPer=0,this.ink=palettes.getRandom();let s=constrain(this.x,0,myWidth-1),r=constrain(this.y,0,myHeight-1),h=int(s/imgScale),a=int(r/imgScale);this.bg=readColor(h,a),this.speed=.5,this.xv=cos(this.theta)*this.speed,this.yv=sin(this.theta)*this.speed,this.px=t-this.xv,this.py=e-this.yv,this.age=0,this.life=1e3,this.agePer=this.age/this.life,this.dead=!1;let l=getNoise(this.x,this.y,.005),n=getNoise(this.y,this.x,.005);this.delta=map(l,0,1,-.015,.0075,!0),this.delta2=map(n,0,1,-.001,.001,!0),0==this.gen&&(this.delta=map(MAIN_RAND,0,1,-.01,-.04),this.delta2=15e-5),this.spawnIter=3,this.fillThresh=25,this.stitch=0,this.stitchInterval=7,this.stitchLength=.35*this.stitchInterval,this.stitchCount=0,this.isFlowering=!1}update(){this.dead||(this.updatePosition(),this.checkOverlap(),this.updateTrajectory(),this.updateAge(),this.createSpawn(),this.wrapBorder())}updatePosition(){let t=360;this.gen>=ANGLE_LOCK_GEN&&IS_ANGLE_LOCKED&&(t=6);let e=this.theta;e=roundAngle(this.theta,t,HALF_PI),this.xv=cos(e)*this.speed,this.yv=sin(e)*this.speed,this.px=this.x,this.py=this.y,this.x+=this.xv,this.y+=this.yv}checkOverlap(){let t=constrain(this.x+4*this.xv,0,myWidth-1),e=constrain(this.y+4*this.yv,0,myHeight-1),i=int(t/imgScale),$=int(e/imgScale),s=readColor(i,$),r=brightness(s);0==this.age&&(this.bg=s),r>20?s.toString()!=this.ink.toString()&&(this.dead=!0):this.age>0&&s.toString()!=this.bg.toString()&&(this.dead=!0)}updateTrajectory(){(this.myRand<this.trajThresh||IS_TRADITIONAL)&&(this.theta+=this.delta*PRIMARY_CURVATURE,this.delta+=this.delta2*SECONDARY_CURVATURE),abs(this.delta)>.066&&(this.dead=!0)}updateAge(){this.age++,this.agePer=this.age/this.life,this.age>=this.life&&(this.dead=!0)}createSpawn(){!this.dead&&this.age%this.spawnIter==0&&this.age>this.fillThresh&&this.gen<MAX_GEN&&(currentFrame%2==0?addSpawn(this.x,this.y,this.theta-HALF_PI,this.gen+1):addSpawn(this.x,this.y,this.theta+HALF_PI,this.gen+1))}render(){if(this.age>10){let t=int(this.x/imgScale),e=int(this.y/imgScale),i=red(this.ink),$;writeColor(t,e,i,green(this.ink),blue(this.ink))}}drawRoad(t){this.swPer=map(this.age,10,45,0,1,!0),this.sw=15*pow(map(abs(this.delta),0,.0666,1,0),2)+2+11*pow(1-this.genPer,2),this.sw*=this.swPer,this.sw2=min(this.sw+1,1.2*this.sw),this.stitchLength=.1*this.sw,this.isFlowering&&this.age%49==48&&currentFrame>300&&this.createFlower(),this.age%this.stitchInterval==0&&this.age>10&&(this.drawRunningStitch(),this.stitchCount++)}createFlower(){let t=this.x,e=this.y,i=R.random_num(17,35),$=2*i,s=R.random_int(0,2);this.age%2==0?(t+=this.yv*$,e+=-this.xv*$):(t+=-this.yv*$,e+=this.xv*$);let r=palettes.getFg(this.agePer),h=R.random_num(0,TWO_PI),a=canvases[2];if(drawCherryBlossom(a,t,e,i,r,h,s),t<50?(e<halfHeight?e+=halfHeight:e-=halfHeight,drawCherryBlossom(a,t+myWidth,e,i,r,h,s)):t>myWidth-50&&(e<halfHeight?e+=halfHeight:e-=halfHeight,drawCherryBlossom(a,t-myWidth,e,i,r,h,s)),e<50?drawCherryBlossom(a,t,e+myHeight,i,r,h,s):e>myHeight-50&&drawCherryBlossom(a,t,e-myHeight,i,r,h,s),this.age>10){let l=int(this.x/imgScale),n=int(this.y/imgScale),d=red(this.ink),o;writeColor(l,n,d,green(this.ink),blue(this.ink))}}drawRunningStitch(){let t=5;this.gen>=1&&this.gen<=2?t=4:this.gen>=3&&(t=3),canvases[0];let e=canvases[1],i=canvases[3],$=canvases[4],s=canvases[5],r=this.stitchLength,h=this.x-this.xv*r,a=this.x+this.xv*r,l=this.y-this.yv*r,n=this.y+this.yv*r;e.fill(palettes.getIri(.5,30)),e.circle(this.x,this.y,3),i.strokeWeight(this.sw2),i.stroke(palettes.getBg(0)),i.line(h,l,a,n),$.strokeWeight(.25*this.sw),$.stroke(this.cd),$.line(h,l,a,n);let d=.5*sin(2*this.theta)+.5;s.strokeWeight(1*this.swPer),s.stroke(palettes.getIri(d,255*d)),s.line(h-shx,l-shy,a-shx,n-shy)}wrapBorder(){this.x<0&&(this.x+=myWidth,this.px+=myWidth,this.y<halfHeight?(this.y+=halfHeight,this.py+=halfHeight):(this.y-=halfHeight,this.py-=halfHeight)),this.x>myWidth&&(this.x-=myWidth,this.px-=myWidth,this.y<halfHeight?(this.y+=halfHeight,this.py+=halfHeight):(this.y-=halfHeight,this.py-=halfHeight)),this.y<0&&(this.y+=myHeight,this.py+=myHeight),this.y>myHeight&&(this.y-=myHeight,this.py-=myHeight)}isDead(){return this.dead}}
Growth: Threads artworks are part of the Future Reflections generative art collection presented by Shiseido. The collection consists of 1,872 unique generative artworks created in partnership with leading contemporary artists, powered by Art Blocks Engine. Celebrating the parallel processes of generative, code-based art creation and the art and science of beauty product innovation, Future Reflections draws inspiration from Shiseido’s 150 years of Japanese heritage - past, present, and future - along with nutrient-rich ingredients in the brand’s Future Solution LX skincare collection. The Growth: Threads artworks were created by Robert’s sophisticated growth algorithm, and emulate the growth of various seeds, specifically the material essence of the Legendary Enmei herb. Their rich use of iridescent color is juxtaposed with a background of patterns inspired by Japanese embroidery designed and generated by the artist.
Recollection is released as part of reGEN, a special charitable auction of generative art to raise funds for Cure Alzheimer’s Fund, curated by Alex Estorick and Foteini Valeonti in collaboration with The Giving Block. It is curious how our memories can mislead. I vividly recall a childhood trek up Mt. Fuji with my parents through a foggy bamboo forest, and the image of my dad buying a walking stick from an older vendor. But as my mom later clarified, the adventure actually took place in a Tokyo park –– I’ve never even visited Fuji-san. Contemplating this blend of the real and the imagined has led me to create generative vistas whose clarity is eroded by the passing of time. The landscapes in Recollection are understated and familiar: rolling hills, distant mountains, and sporadic clusters of trees or forests. There is a path through grass and stone –– sometimes clear but, at other times, overgrown and obscure. Many of these paths culminate at a portal, its purpose enigmatic. It is pure mystery, both inviting and unsettling. It is an obscuring void, a memory half-recalled. Recollection is a meditation on the mysteries of the mind, and a tribute to the quest for understanding. It stands not only as a beacon of hope for those grappling with the disintegration of memory, but also a testament to the enduring pursuit of clarity in the midst of obscurity. While some details may fade with time, the essence — the emotions, the lessons, the significance — has the potential to regenerate through reflection, conversation, and creative expression. Recollection is part of the reGEN initiative for Alzheimer’s research. For many, this cause is deeply personal and, I believe, it is no exaggeration to say that almost everyone has witnessed the effects of Alzheimer’s, be it within their own family or through friends. This project not only creates funding but also plays a pivotal role in amplifying awareness about Alzheimer’s disease. The opportunity to merge the joy of artistic expression with a mission that has tangible, real-world implications is profoundly inspiring.
function drawSky($){let e=horizon_y-250,r=getColor(R.random_num(.6,.8)),o=getColor(R.random_num(.9,1));skyGlow&&(r=getSunColor(0),o=getSunColor(1)),drawGradientRect($,0,e,myWidth,0,o,r,0,4,10),$.noStroke(),$.fill(o),$.rect(0,e-5,myWidth,myHeight)}function drawStars($,e){let r=R.random_int(80,200),o=getSunColor(1),t=getSunColor(0),n=[];for(let l=0;l<r;l++){let a=R.random_num(-200,myWidth+200),d=R.random_num(-200,myHeight),_=3*pow(R.random_dec(),2)+1;n.push({x:a,y:d,r:_})}if($.noStroke(),1==e)for(let m of n){let i=m.x,u=m.y,s=m.r,f=R.random_dec();$.fill(lerpColor(o,t,f)),$.circle(i,u,s),drawRadialGradient($,i,u,s,10*s,getSunColor(f,.5),getSunColor(f,0),20,2)}else if(2==e){let c=R.random_int(50,350),x=R.random_bool(.5)?2.5*myWidth:-(2*myWidth),w=1.3*myHeight;for(let h=0;h<c;h++){let S=R.random_num(-100,myWidth+100),k=R.random_num(-100,myHeight+100),y=createVector(S-x,k-w),p=R.random_num(100,500);y.normalize();let g=R.random_dec(),v=3*pow(R.random_dec(),2)+1;$.fill(lerpColor(o,t,g)),$.circle(S,k,v),drawRadialGradient($,S,k,v,10*v,getSunColor(g,.5),getSunColor(g,0),20,2),R.random_bool(.5)&&(v*=.5,$.stroke(lerpColor(o,t,R.random_dec())),$.strokeWeight(v),drawBrokenLine($,S,k,S+y.x*p,k+y.y*p,getSunColor(1,0),getSunColor(1,1),5,5,!1))}}else if(3==e)for(let b of n){let P=b.x,z=b.y,W=z-R.random_num(100,500),C=R.random_num(3,25),F=.1*b.r,D=R.random_dec();$.fill(lerpColor(o,t,D)),$.circle(P,z,F),drawRadialGradient($,P,z,F,10*F,getSunColor(D,.5),getSunColor(D,0),20,2),$.stroke(lerpColor(o,t,R.random_dec())),$.strokeWeight(F),drawBrokenLine($,P,z,P,W,getSunColor(1,0),getSunColor(1,1),C,.5*C,!1)}else if(4==e){let H=halfWidth,M=sun_y;for(let T of(print("num stars = "+n.length),n)){let B=T.x,I=T.y,U=T.r,q=.5*U,G=2*dist(B,I,H,M),j=R.random_dec(),A=atan2(I-M,B-H);$.fill(lerpColor(o,t,j)),$.circle(B,I,U),drawRadialGradient($,B,I,U,10*U,getSunColor(j,.5),getSunColor(j,0),20,2),$.stroke(getSunColor(1,.2)),$.strokeWeight(q),$.arc(H,M,G,G,A,A+HALF_PI)}}else if(5==e)for(let E of n){let J=E.x,K=E.y,L=E.r;R.random_dec(),$.fill(getColor(0)),$.circle(J,K,L),drawRadialGradient($,J,K,L,10*L,getColor(0,.5),getColor(0,0),20,2)}$.noFill(),$.noStroke()}function drawStarFall($){let e=R.random_int(35,230),r=horizon_y-1500,o=myHeight-200,t=getSunColor(1),n=getSunColor(0);for(let l=0;l<e;l++){let a=$;R.random_bool(.5)&&(a=mg),map(l,0,e-1,0,1);let d=R.random_num(0,myWidth),_=R.random_num(r,o),m=_-R.random_num(100,500),i=R.random_num(3,25),u=3*pow(R.random_dec(),2)+1;a.noStroke(),a.fill(lerpColor(t,n,R.random_dec())),a.circle(d,_,u),drawRadialGradient(a,d,_,u,10*u,getSunColor(1,.5),getSunColor(0,0),20,2),a.stroke(lerpColor(t,n,R.random_dec())),a.strokeWeight(.1*u),drawBrokenLine(a,d,_,d,m,getSunColor(1,0),getSunColor(0,1),i,.5*i,!1)}mg.noStroke()}function drawSun($,e,r,o){$.noStroke();let t=halfWidth;if(0==SUN_TYPE);else if(1==SUN_TYPE||2==SUN_TYPE)drawRadialGradient($,t,e,0,r+r*(.5*o+.3)*15,getSunColor(1,.5),getSunColor(0,0),4,25),o>.5&&drawRadialGradient($,t,e,r,1.3*r,getSunColor(1),getSunColor(1,0),8,5),$.fill(getSunColor(1)),$.circle(t,e,r);else if(3==SUN_TYPE){let n=portals[0];n.x;let l=n.y,a=n.d,d=l-.5*a,_=sun_y;(n.y>.8*myHeight||n.d<.5*myWidth)&&(_=myHeight-d,a=min(.5*a,400)),R.random_bool(.5)&&(a=R.random_num(100,300)),drawGradientCircle(mg,t,e,r,getColor(.4),getColor(.3),.5)}$.noStroke()}function drawSunParticles($,e,r,o){let t=Math.sign(R.random_dec()-.5),n=getColor(.2),l=int(2*o);for(let a=0;a<l;a++){map(a,0,l-1,0,1);let d=R.random_num(0,TWO_PI),_=e+cos(d)*o,m=r+sin(d)*o;map(m,r-o,r+o,0,1);let i=atan2(m-r,_-e)+HALF_PI*t,u=R.random_num(-.001,.001),s=R.random_num(-.0001,1e-4),f=R.random_num(-.00001,1e-5),c=R.random_num(1.5,2.5),x=_,w=m,h=500*pow(R.random_dec(),11)+7;for(let S=0;S<h;S++){let k=map(S,0,h-1,0,1);_+=cos(i)*c,m+=sin(i)*c,$.stroke(n),$.strokeWeight(2*(1-k)),$.point(_,m),s+=f,u+=s,i+=u,x=_,w=m}let y=R.random_num(1,3);drawRadialGradient($,_,m,y,10*y,getColor(.2,.5),getColor(.2,0),20,2),$.fill(getColor(.2)),$.circle(_,m,y)}$.noStroke()}function drawDistantClouds($){let e=getColor(1),r=getColor(.85);cloudGlow&&(e=getSunColor(1),r=getColor(.85)),cloudiness>.5?drawStormClouds($,e,r):cloudiness>.2&&drawFlatClouds($,e,r)}function drawStormClouds($,e,r){$.noStroke();let o=int(map(cloudiness,.5,1,2,4));for(let t=0;t<o;t++){let n=map(t,0,o,0,1,!0),l=lerpColor(e,r,n),a=R.random_num(0,500),d=map(n,0,1,.5*myWidth,.7*myWidth),_=halfWidth,m=horizon_y-2*d+.8*d*n,i=[];for(let u=0;u<225;u++){let s=(1-map(u,0,224,0,1))*PI,f=cos(s),c=sin(s),x=_+f*d,w=m+c*d,h=getNoise(x,w+d,.002),S=getNoise(x,w+d+a,.005)*h,k=getNoise(x,w+d+2*a,.01),y=300*h+480*S+150*k;x=_+f*(d+y),w=m+c*(d+y);let p=R.random_num(40,80);R.random_bool(.045)&&(p=R.random_num(110,200)),i.push({x:x,y:w,r:p})}$.fill(l),$.beginShape(),$.vertex(-100,m);for(let g=0;g<225;g++){let v=i[g];$.vertex(v.x,v.y)}$.vertex(myWidth+100,m),$.vertex(myWidth+100,myHeight),$.vertex(-100,myHeight),$.endShape(),$.fill(l);for(let b=0;b<i.length;b++){let P=i[b];$.circle(P.x,P.y,P.r)}}$.noStroke()}function drawFlatClouds($,e,r){$.noStroke();let o=int(map(cloudiness,.2,.5,2,4));for(let t=0;t<o;t++){let n=map(t,0,o,0,1,!0),l=lerpColor(e,r,n),a=R.random_num(-400,0),d=map(n,0,1,horizon_y-350,horizon_y-100),_=R.random_num(1800,2400),m=int(map(_,300,800,50,100)),i=[],u=0;for(let s=0;s<m;s++){let f=map(s,0,m-1,0,1),c=sin(f*PI+n),x=a+f*_,w=d,h=.75*getNoise(x+500*n,w,.01)+.25;w-=c*h*_*.25,i.push({x:x,y:w,n:h}),u=w}$.fill(l),$.beginShape(),$.vertex(0,u);for(let S=0;S<m;S++){let k=i[S];$.vertex(k.x,k.y)}$.vertex(myWidth,u),$.vertex(myWidth,myHeight),$.vertex(0,myHeight),$.endShape(),shuffle(i,!0);for(let y=0;y<i.length;y++){let p=i[y],g=R.random_num(20,150)*p.n;p.n>.7&&R.random_bool(.1)&&(g*=2),$.fill(l),$.circle(p.x,p.y,g)}}$.noStroke()}function drawClouds($,e,r,o){if(cloudiness>.05){let t=R.random_int(6*cloudiness,14*cloudiness),n=horizon_y+e-50,l=horizon_y+e+50;for(let a=0;a<t;a++){let d=R.random_num(-100,myWidth+100),_=R.random_num(n,l),m=R.random_num(100,300)*R.random_num(r,2*r),i=m/6,u=d-m/2,s=d+m/2,f=int(m/9),c=[];$.noStroke(),$.fill(o),$.beginShape();for(let x=0;x<f;x++){let w=map(x,0,f-1,0,1),h=lerp(u,s,w),S=1-(.5*cos(w*TWO_PI)+.5),k=lerp(_,_-(i+R.random_num(-i/3,i/3)),S),y=createVector(h,k);$.vertex(h,k),append(c,y)}$.vertex(s+R.random_num(10,20),_+2),$.vertex(s+R.random_num(30,50),_+5),$.vertex(u-R.random_num(30,50),_+5),$.endShape();for(let p=1;p<f-1;p++){let g=map(p,0,f-1,0,1),v=.7*sin(g*PI)+.3,b=c[p-1],P=c[p],z=c[p+1],W=b.x-P.x,C=z.x-P.x,F=b.y-P.y,D=z.y-P.y,H=atan2(F,W),M=atan2(D,C),T=(.75*pow(R.random_dec(),2)+.25)*(m/10+20)*v;R.random_bool(.1)&&(T*=1.5),P.y<_-.3*T?($.fill(o),$.circle(P.x,P.y,T)):($.fill(o),$.arc(P.x,P.y+.5,T,T,H,M))}$.stroke(o),$.strokeWeight(1),drawBrokenLine($,u+R.random_num(-250,0),_+4,s+R.random_num(0,150),_+4,o,o,50,5,!1),drawBrokenLine($,u+R.random_num(-50,50),_+8,s+R.random_num(-50,50),_+8,o,o,50,5,!1),drawBrokenLine($,u+R.random_num(-50,50),_+10,s+R.random_num(-50,50),_+10,o,o,50,5,!1)}}$.noStroke()}function drawDistantPeaks($,e,r,o,t){let n=R.random_int(3,4),l=.1*r;for(let a=0;a<n;a++){let d=map(a,0,n-1,0,1),_=R.random_int(3,5),m=[],i=horizon_y+e+50*d,u=i-R.random_num(r,2*r)*(1-.5*d);for(let s=0;s<_;s++){let f;if(0==s)f=R.random_num(-300,-50);else if(s==_-1)f=myWidth+R.random_num(50,300);else do f=R.random_num(200*s,(s+1)*350);while(m.some($=>100>abs($.x-f)));let c=R.random_num(i,u);m.push({x:f,y:c})}m.sort(($,e)=>$.x-e.x);let x=[],w=lerpColor(o,t,d);$.fill(w),$.noStroke(),$.beginShape();let h,S;for(let k=0;k<m.length-1;k++){let y=m[k].x,p=m[k].y,g=m[k+1].x,v=m[k+1].y,b=dist(y,p,g,v),P=b/5,z=r*(b/400);for(let W=0;W<=1;W+=1/P){let C=W*W,F=1-W,D=F*F;h=D*y+2*F*W*((2*y+g)/3)+C*g,S=D*p+2*F*W*((2*p+v)/3+z)+C*v,S+=getNoise(h,S,.04)*l,$.vertex(h,S),x.push({x:h,y:S})}}$.vertex(myWidth,S),$.vertex(myWidth,myHeight),$.vertex(0,myHeight),$.endShape(),drawGradientRect($,0,horizon_y-100,myWidth,horizon_y-200,getColor(1,.5*(1-d)),getColor(1,0),0,.5,4)}$.noStroke()}function drawDistantBarrenPeaks($,e,r,o,t){let n=R.random_int(3,5),l=.2*r;for(let a=0;a<n;a++){let d=map(a,0,n-1,0,1),_=R.random_int(3,5),m=[],i=horizon_y+e+50*d,u=i-R.random_num(r,2*r)*(1-.5*d),s=horizon_y+50*d;for(let f=0;f<_;f++){let c;if(0==f)c=R.random_num(-300,-50);else if(f==_-1)c=myWidth+R.random_num(50,300);else do c=R.random_num(200*f,(f+1)*350);while(m.some($=>100>abs($.x-c)));let x=R.random_num(i,u);m.push({x:c,y:x})}m.sort(($,e)=>$.x-e.x);let w=[],h=lerpColor(o,t,d);$.fill(h),$.noStroke(),$.beginShape();let S,k;for(let y=0;y<m.length-1;y++){let p=m[y].x,g=m[y].y,v=m[y+1].x,b=m[y+1].y,P=dist(p,g,v,b),z=P/15,W=r*(P/400);for(let C=0;C<=1;C+=1/z){let F=C*C,D=1-C,H=D*D;S=H*p+2*D*C*((2*p+v)/3)+F*v,k=H*g+2*D*C*((2*g+b)/3+W)+F*b,k+=getNoise(S,k,.04)*l,k=min(s,k),$.vertex(S,k),w.push({x:S,y:k})}}$.vertex(myWidth,k),$.vertex(myWidth,myHeight),$.vertex(0,myHeight),$.endShape(),drawGradientRect($,0,s,myWidth,u,getColor(1,.5*(1-d)),getColor(1,0),0,.5,4)}$.noStroke()}function drawHills($,e,r,o,t){$.noStroke();let n=R.random_int(3,6);for(let l=0;l<n;l++){let a=[],d=map(l,0,n-1,0,1),_=horizon_y+e+200*d+R.random_num(-50,50),m=l%2==0?-1:1;R.random_bool(.4)&&(m*=-1);let i=map(d,0,1,lerp(minDist,maxDist,.9),lerp(minDist,maxDist,.7)),u=fov/(fov+i),s=map(i,minDist,maxDist,1,0),f=lerpColor(o,t,d);$.fill(f),$.beginShape();for(let c=0;c<50;c++){let x=map(c,0,49,0,1),w=x*myWidth,h=(x-.5)*200*m*r;h+=33*sin(9*x+50*d),$.vertex(w,_+h);let S=map(d,0,1,n,2);for(let k=0;k<S;k++){let y=w+R.random_num(-30,30),p=_+h+R.random_num(5,15)*(l+1),g=u*map(d,0,1,.5,1);a.push({id:5,type:0,x:y,y:p,z:i,s:g,zper:s,cd:f})}}for(let v of($.vertex(myWidth,myHeight),$.vertex(0,myHeight),$.endShape(),a))drawTree($,v,v.cd,v.cd)}}function drawGround($){$.strokeWeight(4);let e=(myHeight-horizon_y)/3,r=myWidth/200;for(let o=0;o<200;o++){let t=map(o,0,199,0,1),n=map(t,0,1,0,myWidth),l=n+r;for(let a=0;a<e;a++){let d=map(a,0,e-1,0,1),_=map(d,0,1,horizon_y,myHeight),m=getZ(_),i=getLighting(n,_,m),u=lerpColor(getGroundColor(m),getSunColor(0),i);$.stroke(u),$.line(n,_,l,_)}}PORTAL_GLOW&&drawPath($),$.noStroke()}function drawPortal($,e){0==PORTAL_TYPE?drawCircleFilledPortal($,e):1==PORTAL_TYPE?(drawTriangleFilledPortal($,e),PORTAL_GLOW&&drawPortalUpwardDrips($,e)):2==PORTAL_TYPE?drawSquareFilledPortal($,e):3==PORTAL_TYPE?(drawPortalScreen($,e),drawPortalParticles($,e)):4==PORTAL_TYPE?(drawMagicPortal($,e,1),drawPortalParticles($,e)):5==PORTAL_TYPE?(drawPortalScreen($,e),drawMagicPortal($,e,.88),drawPortalParticles($,e)):6==PORTAL_TYPE?(drawTrianglePortal($,e),R.random_bool(.7)&&drawPortalUpwardDrips($,e)):7==PORTAL_TYPE&&drawHole($,e)}function drawCircleFilledPortal($,e){let r=e.x,o=e.y,t=e.z;e.w;let n=e.d,l=.5*n;o-=l;let a=getSunColor(0),d=getSunColor(1);PORTAL_GLOW?drawRadialGradient($,r,o,n-25,2*n,getSunColor(0,.6),getSunColor(0,0),14,25):(a=getGroundColor(t,.15),d=getGroundColor(t)),drawGradientCircle($,r,o,l,a,d,.5)}function drawTriangleFilledPortal($,e){$.strokeWeight(1),e.id;let r=e.x,o=e.y,t=e.z,n=e.d,l=getSunColor(0),a=getSunColor(1);PORTAL_GLOW||(l=getGroundColor(t),a=getGroundColor(t,.15));let d=n,_=d/34,m=.5*_,i=r-.5*d,u=r,s=o,f=o-.866*d;for(let c=0;c<34;c++){let x=map(c,0,34,0,1),w=lerp(i,u,x),h=w+m,S=lerp(s,f,x),k=S-.866*_,y=lerpColor(l,a,x);$.fill(y),$.stroke(y),$.beginShape(),$.vertex(w,S),$.vertex(h,k),$.vertex(myWidth-h,k),$.vertex(myWidth-w,S),$.endShape(CLOSE)}$.noStroke()}function drawSquareFilledPortal($,e){let r=e.x,o=e.y,t=e.z,n=e.d,l=r-.5*n,a=r+.5*n;lerp(l,a,.3);let d=myHeight-o,_=getSunColor(0),m=getSunColor(1);PORTAL_GLOW||(_=getGroundColor(t),m=getGroundColor(t,.15)),drawGradientRect($,l,o,a,d,_,m,0,2,2)}function drawCubePortal($,e){let r=e.x,o=e.y;e.z;let t=e.d,n=.5*t,l=r-n,a=r+n,d=o,_=d-t,m=l+50,i=a-50,u=d-5,s=_+65;$.stroke(getSunColor(0)),$.strokeWeight(2),$.line(l,d,a,d),$.line(l,d,l,_),$.line(l,_,a,_),$.line(a,d,a,_),$.line(m,u,i,u),$.line(m,u,m,s),$.line(m,s,i,s),$.line(i,u,i,s),$.line(l,d,m,u),$.line(a,d,i,u),$.line(l,_,m,s),$.line(a,_,i,s)}function drawBasicPortal($,e){let r=getSunColor(0),o=getSunColor(1);$.strokeCap(SQUARE),$.strokeWeight(1);let t=e.x,n=e.y;e.z;let l=e.d,a=e.w,d=.5*l,_=d-a,m=_-a*R.random_num(.1,.2);n-=d;let i,u=4*(2*R.random_int(11,17)),s=[],f=[],c=[],x=.6*PI;for(let w=0;w<u;w++){let h=map(w,0,u,x,TWO_PI+.4*PI),S=cos(h),k=sin(h);s.push({x:t+S*d,y:n+k*d,t:h}),f.push({x:t+S*_,y:n+k*_,t:h}),c.push({x:t+S*m,y:n+k*m,t:h})}for(let y=0;y<s.length-1;y++){let p=y,g=y+1,v=s[p],b=s[g],P=f[g],z=f[p],W=map((b.y+P.y)*.5,n+_,n-_,0,1),C=lerpColor(r,o,W);$.stroke(C),$.fill(C),$.beginShape(),$.vertex(v.x,v.y),$.vertex(b.x,b.y),$.vertex(P.x,P.y),$.vertex(z.x,z.y),$.endShape()}for(let F=0;F<f.length-1;F++){let D=F,H=F+1,M=f[D],T=f[H],B=c[H],I=c[D],U=map((T.y+B.y)*.5,n+_,n-_,0,1),q=lerpColor(o,r,U);$.stroke(q),$.fill(q),$.beginShape(),$.vertex(M.x,M.y),$.vertex(T.x,T.y),$.vertex(B.x,B.y),$.vertex(I.x,I.y),$.endShape()}$.noStroke()}function drawMagicPortal($,e,r){$.noFill();let o=e.x,t=e.y,n=e.z,l=e.d;e.w;let a=.5*l;t-=a,a*=r;let d=map(n,minDist,maxDist,1,0),_=pow(d,5),m=[],i=[],u=[R.random_int(2,4),R.random_int(2,6),R.random_int(4,8),180],s=[R.random_bool(.5),R.random_bool(.5),R.random_bool(.5),!1];for(let f=0;f<3;f++){let c=map(f,0,2,0,1,!0),x=pow(c,5),w=map(c,0,1,30,.5)*_,h=getSunColor(x,x);$.strokeWeight(w);for(let S=0;S<u.length;S++){let k=drawPolygon($,u[S],o,t,a,h,s[S]);m.push(k)}}for(let y=0;y<m.length;y++){let p=m[y];for(let g=0;g<150;g++){let v=getPointOnPolygon(p,R.random_dec());i.push(v)}}for(let b=0;b<i.length;b++)for(let P=0;P<1;P++){let z=i[b],W=pow(R.random_num(0,1),15),C=pow(R.random_num(0,1),15);W*=R.random_bool(.5)?-1:1,C*=R.random_bool(.5)?-1:1;let F=z.x+25*W,D=z.y+25*C;$.stroke(getSunColor(R.random_num(0,.3))),$.strokeWeight(R.random_num(1,2)*d),$.point(F,D)}$.noStroke()}function drawTrianglePortal($,e){let r=getSunColor(0),o=getSunColor(1),t=e.x,n=e.y;e.z;let l=e.d;e.w;let a=l,d=.5*a,_=a/20,m=.5*_,i=t-d,u=t,s=t+d,f=n,c=n-.866*a;for(let x=0;x<20;x++){let w=map(x,0,20,0,1),h=lerp(i,s,w),S=h+m,k=h+_,y=S+_,p=f,g=p-.866*_;$.fill(r),$.strokeWeight(1),$.stroke(r),abs(S-halfWidth)>.15*a&&($.beginShape(),$.vertex(h,p),$.vertex(S,g),$.vertex(k,p),$.endShape(CLOSE)),abs(k-halfWidth)>.15*a+.5*_&&x<19&&($.beginShape(),$.vertex(S,g),$.vertex(k,p),$.vertex(y,g),$.endShape(CLOSE))}for(let v=1;v<20;v++){let b=map(v,0,20,0,1),P=lerp(i,u,b),z=P+m,W=P+_,C=z+_,F=lerp(f,c,b),D=F-.866*_,H=lerpColor(r,o,b);$.fill(H),$.strokeWeight(1),$.stroke(H),$.beginShape(),$.vertex(P,F),$.vertex(z,D),$.vertex(W,F),$.endShape(CLOSE),v<19&&($.beginShape(),$.vertex(z,D),$.vertex(W,F),$.vertex(C,D),$.endShape(CLOSE)),P=myWidth-P,z=myWidth-z,W=myWidth-W,C=myWidth-C,v<19&&($.beginShape(),$.vertex(W,F),$.vertex(z,D),$.vertex(P,F),$.endShape(CLOSE)),v<18&&($.beginShape(),$.vertex(C,D),$.vertex(W,F),$.vertex(z,D),$.endShape(CLOSE))}}function drawHole($,e){let r=e.x,o=e.y,t=3*e.d,n=.5*t,l=.125*t,a=getGroundColor(e.z),d=getGroundColor(e.z,-.25),_=r-t/2,m=r+t/2;for(let i=_;i<=m;i++){let u=sqrt(1-sq((i-r)/n))*(l/2),s=o-u,f=o+u,c=lerpColor(a,d,pow(1-abs(r-i)/n,.5));$.stroke(c),$.line(i,s,i,f)}}function drawPortalParticles($,e){let r=e.x,o=e.y;e.z;let t=map(e.z,nearestPortalZ,maxDist,1,.25),n=e.d,l=.5*n;e.w,o-=l;let a=Math.sign(R.random_dec()-.5),d=int(n);for(let _=0;_<d;_++){map(_,0,d-1,0,1);let m=R.random_num(0,TWO_PI),i=r+cos(m)*l,u=o+sin(m)*l,s=map(u,o-l,o+l,0,1),f=atan2(u-o,i-r)+HALF_PI*a,c=R.random_num(-.001,.001),x=R.random_num(-.0001,1e-4),w=R.random_num(-.00001,1e-5),h=R.random_num(1.5,2.5),S=i,k=u,y=500*pow(R.random_dec(),11)+7;for(let p=0;p<y;p++){let g=map(p,0,y-1,0,1);if(i+=cos(f)*h,(u+=sin(f)*h)<e.y){let v=lerpColor(getSunColor(.5),getSunColor(1),s),b=lerpColor(v,getSunColor(0,0),g);$.stroke(b),$.strokeWeight(2*t*(1-g)),$.point(i,u)}x+=w,c+=x,f+=c,S=i,k=u}let P=R.random_num(1,3);drawRadialGradient($,i,u,P,10*P,getSunColor(1,.5),getSunColor(0,0),20,2),$.fill(getSunColor(1)),$.circle(i,u,P)}$.noStroke()}function drawPortalScreen($,e){if(0==e.id){let r=e.x,o=e.y;e.z;let t=map(e.z,nearestPortalZ,maxDist,1,.25),n=e.d,l=e.w,a=.5*n;o-=a-l+10,a-=.5*l;let d=9*t,_=getSunColor(1,.4),m=getSunColor(0,0),i=d*sqrt(3)*.5;for(let u=-a;u<a;u+=i){let s=map(u,a,-a,0,1),f=floor(u/i)%2*d/2;for(let c=-a+f;c<a;c+=d){let x=c+r,w=u+o,h=dist(x,w,r,o);if(h<=a){let S=map(h,a,.75*a,0,1,!0),k=s*sqrt(S),y=lerpColor(m,_,k);$.fill(y),$.circle(x,w,10*s),$.fill(getSunColor(1,k)),$.circle(x,w,2*s)}}}}}function drawPortalUpwardDrips($,e){let r=getSunColor(1),o=getSunColor(0);PORTAL_GLOW||(r=getColor(.33),o=getColor(0)),R.random_int(5,25);let t=R.random_int(150,200),n=e.x,l=e.y,a=e.d;for(let d=0;d<t;d++){map(d,0,t-1,0,1);let _=R.random_num(n-.5*a,n+.5*a),m=R.random_num(l,-300),i=min(l,m+R.random_num(100,500)),u=R.random_num(3,25),s=3*pow(R.random_dec(),2)+1;$.noStroke(),$.fill(lerpColor(r,o,R.random_dec())),$.circle(_,m,s),drawRadialGradient($,_,m,s,10*s,getSunColor(1,.5),getSunColor(0,0),20,2),$.stroke(lerpColor(r,o,R.random_dec())),$.strokeWeight(.3*s),drawBrokenLine($,_,m,_,i,getSunColor(1,0),getSunColor(0,1),u,.5*u,!1)}$.noStroke()}function preload(){bg=createGraphics(myWidth,myHeight),mg=createGraphics(myWidth,myHeight),bg.noStroke(),mg.noStroke(),windowResized()}function windowResized(){dim=windowWidth<windowHeight?windowWidth:windowHeight,resizeCanvas(windowWidth,windowHeight);let $=myWidth/myHeight;width/height<$?(drawWidth=width,drawHeight=width/$):(drawHeight=height,drawWidth=height*$)}function keyTyped(){"s"==key?saveImage():"S"==key?SAVEFRAMES=!SAVEFRAMES:"d"==key||"r"==key&&reset()}function saveImage(){let $=createGraphics(myWidth,myHeight);$.image(bg,0,0),$.image(mg,0,0),save($,currentHash,"png")}function setupFeatures(){loadPalettes(),PALETTE=R.random_int(0,numPalettes-1);let $=R.random_dec();MEMORY_TYPE=$<.3?0:$<.7?1:2;let e=R.random_dec();PORTAL_GLOW=!((PORTAL_TYPE=e<.15?0:e<.3?1:e<.4?2:e<.6?3:e<.7?4:e<.75?5:e<.98?6:7)<=2)||!!R.random_bool(.8),7==PORTAL_TYPE&&(PORTAL_GLOW=!1);let r=R.random_dec();PATH_TYPE=r<.2?0:r<.8?1:2;let o=R.random_dec();SUN_TYPE=o<.1?0:o<.7?1:o<.95?2:3;let t=R.random_dec();STAR_TYPE=t<.3?0:t<.5?1:t<.75?2:t<.88?3:t<.95?4:5,(1==PORTAL_TYPE||6==PORTAL_TYPE)&&(STAR_TYPE=0),PORTAL_TYPE<=2&&(SUN_TYPE=0),0==MEMORY_TYPE&&(SUN_TYPE=R.random_bool(.5)?0:3,STAR_TYPE=0),MIDGROUND_COPSE=R.random_bool(.7),MIDGROUND_HILLS=R.random_bool(.4),MIDGROUND_MEGALITHS=R.random_bool(.1),MIDGROUND_SPIRES=R.random_bool(.1),0==MEMORY_TYPE&&(MIDGROUND_HILLS=!1),FORGETTING_TREES=R.random_bool(.2),MIDGROUND_HILLS?FORGETTING_TREES=!1:MIDGROUND_SPIRES=!1,13==PALETTE&&(MIDGROUND_HILLS=!0),haziness=R.random_num(.5,1),cloudiness=R.random_dec(),cloudGlow=R.random_bool(.1),skyGlow=R.random_bool(.1),createColors(PALETTE),grassChance=R.random_num(.3,.7),spikyChance=R.random_num(.1,.4),rockChance=R.random_num(.2,.5),flowerChance=R.random_num(.05,.1);let n=[grassChance,spikyChance,rockChance,flowerChance],l=n.reduce(($,e)=>$+e,0),a=n.map($=>$/l),d=0;for(let _=0;_<a.length;_++)d+=a[_],cumulativeChances[_]=d;GROUND=R.random_num(.25,.45),fov=R.random_num(70,90),maxDist=2500,minDist=-fov,eyeHeight=R.random_num(900,1400),horizon_y=R.random_num(.65*myHeight,.75*myHeight),nearestPortalZ=R.random_num(300,500),sun_y=R.random_num(0,.45*myHeight),sun_size=R.random_num(100,350),2==SUN_TYPE&&(sun_size=R.random_num(800,1200)),xnoff=R.random_num(50,300),ynoff=R.random_num(50,300),print("palette type = "+PALETTE+" "+PALETTES[PALETTE]),print("memory type = "+MEMORY_TYPE+" "+MEMORY_TYPES[MEMORY_TYPE]),print("portal type = "+PORTAL_TYPE+" "+PORTAL_TYPES[PORTAL_TYPE]),print("portal glow = "+PORTAL_GLOW),print("sun type = "+SUN_TYPE+" "+SUN_TYPES[SUN_TYPE]),print("star type = "+STAR_TYPE+" "+STAR_TYPES[STAR_TYPE]),print("copse = "+MIDGROUND_COPSE),print("hills = "+MIDGROUND_HILLS),print("megaliths = "+MIDGROUND_MEGALITHS),print("spires = "+MIDGROUND_SPIRES),print("forgetting = "+FORGETTING_TREES),print("cloudiness = "+cloudiness)}function reset(){print("Recollection"),print(tokenData.hash),print("------------------------------------------------------------------------------"),R=new Random,noiseDetail(5,.3),noiseSeed(R.random_dec()),randomSeed(R.random_dec()),strokeCap(SQUARE),colorMode(RGB,1),pixelDensity(2),smooth(),saveFrame=!1,currentFrame=0,buffer=createCanvas(windowWidth,windowHeight),bg.clear(),mg.clear(),bg.background(0,0,0,0),mg.background(0,0,0,0),bg.rectMode(CORNERS),mg.rectMode(CORNERS),cs=[],sunCs=[],pathPts=[],things=[],portals=[],setupFeatures()}function setup(){windowResized(),reset()}function draw(){if(background(0),61==currentFrame){let $=performance.now();if(createPath(),createThings(15e3),2==SUN_TYPE){let e=R.random_dec();e<.3?sun_y=portals[0].y-.5*portals[0].d:e<.6&&(sun_y=myHeight-(portals[0].y-.5*portals[0].d))}else if(3==SUN_TYPE){let r=portals[0];r.x;let o=r.y,t=r.d;(r.y>.8*myHeight||r.d<.5*myWidth)&&(sun_y=myHeight-(o-.5*t),sun_size=min(.5*t,400)),R.random_bool(.5)&&(sun_size=R.random_num(150,300))}let n=performance.now();console.log("stage 1: "+(n-$)+" milliseconds.")}else if(62==currentFrame){let l=performance.now();MEMORY_TYPE>0&&drawSky(bg),drawStars(bg,STAR_TYPE),MIDGROUND_MEGALITHS&&R.random_bool(.25)&&drawBgArch(bg,getColor(.85),getColor(1),1.5),drawSun(bg,sun_y,sun_size,haziness),MEMORY_TYPE>0&&drawDistantClouds(bg);let a=performance.now();console.log("stage 2: "+(a-l)+" milliseconds.")}else if(63==currentFrame){let d=performance.now();if(MIDGROUND_MEGALITHS&&R.random_bool(.25)&&drawBgArch(bg,getColor(.75),getColor(.95),1.25),0==MEMORY_TYPE)bg.background(getColor(GROUND)),drawGradientRect(bg,0,0,myWidth,horizon_y,getColor(GROUND+.15),getColor(GROUND),0,3,5);else if(1==MEMORY_TYPE){let _=MIDGROUND_HILLS?-300:0,m=MIDGROUND_HILLS?getColor(.62):getColor(GROUND);drawDistantBarrenPeaks(bg,-320+_,205,getColor(.72),getColor(.68)),drawClouds(bg,-200+_,.5,getColor(.75)),drawDistantBarrenPeaks(bg,-220+_,155,getColor(.66),m),drawClouds(bg,-250+_,.35,getColor(.64)),MIDGROUND_HILLS&&drawHills(bg,-330,R.random_num(.5,1.2),getColor(.6),getColor(GROUND))}else if(2==MEMORY_TYPE){let i=MIDGROUND_HILLS?-300:0,u=MIDGROUND_HILLS?getColor(.62):getColor(GROUND);drawClouds(bg,-280+i,.5,getColor(.8)),drawDistantPeaks(bg,-250+i,100,getColor(.72),getColor(.68)),drawClouds(bg,-220+i,.35,getColor(.75)),drawDistantPeaks(bg,-200+i,50,getColor(.66),u),MIDGROUND_HILLS&&drawHills(bg,-380,R.random_num(.5,1.2),getColor(.6),getColor(GROUND))}drawGround(bg),drawThings(mg),MIDGROUND_SPIRES&&drawWires(bg),3==STAR_TYPE&&drawStarFall(mg);let s=performance.now();console.log("stage 3: "+(s-d)+" milliseconds.")}currentFrame>63&&(image(bg,0,0,drawWidth,drawHeight),image(mg,0,0,drawWidth,drawHeight),noLoop()),SAVEFRAMES&&currentFrame>=100&&(saveImage(),reset()),currentFrame++}
let SAVEFRAMES=!1,myWidth=1152,myHeight=1600,halfWidth=myWidth/2,halfHeight=myHeight/2,drawWidth,drawHeight,currentFrame=0,currentHash="",buffer,bg,mg,fov,maxDist,minDist,eyeHeight,horizon_y,pathPts=[],things=[],portals=[],spireTips=[],numPalettes,palette_id,palettes=[],sunPalettes=[],cs=[],sunCs=[],cumulativeChances=[],GROUND,PALETTE,PALETTES=["Teal Rust","Crimson Sun","Brown/Barren","Deep Purple","Red Moon","Faded Nature","Slate Salmon","Grayscale","Sepia","Sharp Verdant","Peach Slate","Worn Viridescence","Mars/Dusk","White Void","Red Contrast","Blue Contrast","Sunset","Slate Ice"],SUN_TYPE,SUN_TYPES=["ABSENT","EXPECTED","EXAGGERATED","BLACK"],STAR_TYPE,STAR_TYPES=["OBSCURED","NIGHT SKY","SHOOTING STARS","FALLING STARS","LAPSED","MISSING"],PORTAL_TYPE,PORTAL_TYPES=["FULL CIRCLE","FULL TRIANGLE","FULL DOORWAY","CIRCULAR INTERFACE","MYSTICAL CIRCLE","COMPLEX PORTAL","PORTAL TRIANGLE","MISSING"],PORTAL_GLOW,PORTAL_GLOWS=["INVITING","STURDY"],nearestPortalZ,PATH_TYPE,PATH_TYPES=["OVERGROWN","MEANDERING","DIRECT"],MEMORY_TYPE,MEMORY_TYPES=["CREEPING FOG","PARTIAL RECOLLECTION","CONNECTED"],MIDGROUND_COPSE,MIDGROUND_HILLS,MIDGROUND_MEGALITHS,MIDGROUND_SPIRES,FORGETTING_TREES,FORGETTING_SPIRES,sun_size,sun_y,eclipse,haziness,cloudiness,cloudGlow,skyGlow,rockChance,grassChance,spikyChance,flowerChance,pixelDensityOrig,xnoff,ynoff;function genTokenData($){let e={},t="0x";for(var r=0;r<64;r++)t+=Math.floor(16*Math.random()).toString(16);return e.hash=t,e.tokenId=(1e6*$).toString(),currentHash=t,e}class Random{constructor(){this.useA=!1;let $=function($){let e=parseInt($.substr(0,8),16),t=parseInt($.substr(8,8),16),r=parseInt($.substr(16,8),16),n=parseInt($.substr(24,8),16);return function(){r|=0;let $=((e|=0)+(t|=0)|0)+(n|=0)|0;return n=n+1|0,e=t^t>>>9,t=r+(r<<3)|0,r=(r=r<<21|r>>>11)+$|0,($>>>0)/4294967296}};this.prngA=new $(tokenData.hash.substr(2,32)),this.prngB=new $(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num($,e){return $+(e-$)*this.random_dec()}random_int($,e){return Math.floor(this.random_num($,e+1))}random_bool($){return this.random_dec()<$}random_choice($){return $[this.random_int(0,$.length-1)]}}function loadPalettes(){append(sunPalettes,[.56,.96,1,.63,1,1]),append(sunPalettes,[.84,.11,.13,1,.25,.05]),append(sunPalettes,[.97,.95,.65,1,.98,.75]),append(sunPalettes,[.98,.87,.8,1,1,1]),append(sunPalettes,[.77,.27,.2,1,.35,.2]),append(sunPalettes,[.95,.85,.75,1,1,.92]),append(sunPalettes,[.9,.72,.62,1,.88,.8]),append(sunPalettes,[.9,.9,.9,1,1,1]),append(sunPalettes,[.8,.67,.51,.98,.88,.73]),append(sunPalettes,[.99,.99,.64,1,1,1]),append(sunPalettes,[.85,.58,.46,.94,.84,.66]),append(sunPalettes,[.75,.86,.72,.95,.97,.82]),append(sunPalettes,[.98,.87,.7,1,.92,.78]),append(sunPalettes,[1,1,1,1,1,1]),append(sunPalettes,[.85,0,0,1,0,0]),append(sunPalettes,[0,0,.85,0,0,1]),append(sunPalettes,[.97,.97,.78,1,1,.95]),append(sunPalettes,[.8,.92,.95,1,1,1]),append(palettes,[.16,.11,.05,.24,.16,.08,.4,.25,.14,.58,.35,.22]),append(palettes,[.01,.05,.11,.2,.06,.06,.45,.09,.09,.75,.16,.16]),append(palettes,[0,0,.08,.25,.12,.31,.55,.31,.27,.87,.72,.51]),append(palettes,[.04,.01,.03,.14,.04,.22,.31,.38,.4,.98,.83,.75]),append(palettes,[.02,.03,.05,.11,.12,.16,.22,.23,.28,.3,.31,.35]),append(palettes,[.05,.08,.12,.2,.25,.32,.3,.38,.48,.6,.55,.5]),append(palettes,[.04,.05,.1,.22,.28,.35,.35,.42,.52,.68,.62,.55]),append(palettes,[.11,.11,.11,.25,.25,.25,.44,.44,.44,.66,.66,.66]),append(palettes,[.3,.11,0,.47,.2,.04,.52,.4,.22,.8,.67,.51]),append(palettes,[.23,.15,.18,.25,.26,.55,.33,.74,.49,.85,.99,.78]),append(palettes,[.23,.15,.18,.2,.23,.26,.24,.28,.31,.5,.49,.42]),append(palettes,[.02,.16,.04,.26,.49,.28,.47,.67,.36,.57,.77,.66]),append(palettes,[.19,.14,.17,.42,.2,.16,.69,.32,.18,.89,.58,.32]),append(palettes,[.22,.22,.22,.65,.65,.65,.83,.83,.83,1,1,1]),append(palettes,[0,0,0,.05,.05,.25,.15,.2,.4,.2,.2,.8]),append(palettes,[0,0,0,.25,0,0,.4,0,0,.8,0,0]),append(palettes,[.14,.06,.3,.37,.07,.46,.82,.2,.46,.97,.5,.33]),append(palettes,[.07,.16,.19,.18,.32,.35,.27,.44,.55,.49,.68,.75]),numPalettes=palettes.length}function createColors($){let e=sunPalettes[$],t=palettes[$];cs=[];for(let r=0;r<4;r++){let n=3*r,o=t[n+0],l;append(cs,color(o,t[n+1],t[n+2]))}sunCs=[];for(let a=0;a<2;a++){let i=3*a,_=e[i+0],d;append(sunCs,color(_,e[i+1],e[i+2]))}}function getSunColor($,e){let t=lerpColor(sunCs[0],sunCs[1],$);return void 0!==e?color(red(t),green(t),blue(t),e):t}function getGroundColor($,e){let t=GROUND;void 0!==e&&(t+=e);let r=getColor(t),n=getColor(t+.05),o=map($,maxDist,minDist,0,1,!0);return lerpColor(r,n,pow(o,8))}function getColor($,e){let t,r;for(let n=0;n<3;n++)if($<=(n+1)*.3334){t=map($,.3334*n,(n+1)*.3334,0,1),r=lerpColor(cs[n],cs[n+1],t);break}return void 0!==e?color(red(r),green(r),blue(r),e):r}function getRandomColor(){return color(R.random_dec(),R.random_dec(),R.random_dec())}function getNoise($,e,t){return map(noise($*t+xnoff,e*t+ynoff),0,1,0,1,!0)}function findIntersection($,e,t,r,n){return[$+(n-e)*(t-$)/(r-e),n]}function findCircleLineIntersection($,e,t,r){let n=Math.abs(r-e);if(n>t)return null;if(n===t)return[{x:$,y:r}];{let o=Math.sqrt(t*t-n*n);return[{x:$+o,y:r},{x:$-o,y:r}]}}function drawGradient($,e,t,r,n,o,l,a,i,_){let d=min(r,n),s=max(r,n);$.strokeWeight(i+_);for(let u=d;u<s;u+=i){let m=pow(map(u,d,s,0,1,!0),a);$.stroke(lerpColor(o,l,m)),$.line(e,u,t,u)}$.noStroke()}function drawGradientLine($,e,t,r,n,o,l,a){let i=dist(e,t,r,n)/20;$.strokeWeight(a);for(let _=0;_<i;_++){let d=map(_,0,i,0,1),s=lerp(e,r,d),u=lerp(t,n,d),m=lerpColor(o,l,d);$.stroke(m),$.line(s,u,s,u+20)}}function drawGradientRect($,e,t,r,n,o,l,a,i,_){let d=ceil(abs(r-e)/_);0==a&&(d=ceil(abs(n-t)/_));for(let s=0;s<d-1;s++){let u=map(s,0,d-1,0,1,!0),m=map(s+1,0,d-1,0,1,!0),f,h;0==a?(f=ceil(lerp(t,n,u)),h=ceil(lerp(t,n,m))):(f=ceil(lerp(e,r,u)),h=ceil(lerp(e,r,m)));let g=lerpColor(o,l,pow(u,i));$.fill(g),$.beginShape(),0==a?($.vertex(e,f),$.vertex(e,h),$.vertex(r,h),$.vertex(r,f)):($.vertex(f,t),$.vertex(h,t),$.vertex(h,n),$.vertex(f,n)),$.endShape()}}function drawGradientCircle($,e,t,r,n,o,l){$.strokeWeight(1.5);let a=r*r;for(let i=-r;i<=r;i++){let _=int(t)+i,d=map(i,-r,r,0,1),s=lerpColor(n,o,d);$.stroke(s);let u=sqrt(a-i*i);$.line(e-u,_,e+u,_)}$.noStroke()}function drawRadialGradient($,e,t,r,n,o,l,a,i){$.noFill(),$.strokeWeight(i);let _,d,s,u;r<=n?(_=r,d=n,s=o,u=l,a=1/a):(_=n,d=r,s=l,u=o);for(let m=_;m<d;m+=i){let f=pow(map(m,_,d,0,1),a);$.stroke(lerpColor(s,u,f)),$.circle(e,t,m)}$.noStroke()}function drawEllipseGradient($,e,t,r,n,o,l,a,i,_){$.noStroke();for(let d=n;d>=r;d-=_){let s=pow(map(d,r,n,0,1),i);$.fill(lerpColor(l,a,s)),$.ellipse(e,t,d,d/o)}}function drawBrokenLine($,e,t,r,n,o,l,a,i,_,d){let s=dist(e,t,r,n),u=atan2(n-t,r-e),m=e,f=t;for(;dist(m,f,r,n)>a;){let h=R.random_num(.001*a,a),g=dist(m,f,r,n)/s,c=m+cos(u)*h,p=f+sin(u)*h;if(h<dist(m,f,r,n)){let x=lerpColor(o,l,g);_&&$.strokeWeight(d*sin(g*PI)),$.stroke(x),$.line(m,f,c,p)}let S=R.random_num(i/2,i);m+=cos(u)*(h+S),f+=sin(u)*(h+S)}(m!==r||f!==n)&&$.line(m,f,r,n)}function drawArc($,e,t,r,n,o,l,a){$.beginShape();for(let i=0;i<=a;i++){let _=lerp(o,l,i/a),d=e+n*cos(_),s=t+n*sin(_);$.vertex(d,s)}for(let u=a;u>=0;u--){let m=lerp(o,l,u/a),f=e+r*cos(m),h=t+r*sin(m);$.vertex(f,h)}$.endShape(CLOSE)}function drawPolygon($,e,t,r,n,o,l){let a=[],i=TWO_PI/e,_=-HALF_PI;l&&(_+=i/2);let d=t+cos(_-i)*n,s=r+sin(_-i)*n;for(let u=0;u<e;u++){let m=t+cos(_)*n,f=r+sin(_)*n;drawBrokenLine($,m,f,d,s,o,o,50,10,!1,1),a.push({x:m,y:f}),_+=i,d=m,s=f}return a}function getPointOnPolygon($,e){let t=-1;if(-1===t){t=0;for(let r=0;r<$.length;r++)t+=dist($[r].x,$[r].y,$[(r+1)%$.length].x,$[(r+1)%$.length].y)}let n=t*e,o=0;for(let l=0;l<$.length;l++){let a=dist($[l].x,$[l].y,$[(l+1)%$.length].x,$[(l+1)%$.length].y);if(o+a>=n){let i=(n-o)/a,_;return{x:$[l].x+i*($[(l+1)%$.length].x-$[l].x),y:$[l].y+i*($[(l+1)%$.length].y-$[l].y)}}o+=a}return null}function getLighting($,e,t){let r=0;for(let n of portals){let o=n.x;n.y;let l=n.z,a=n.d,i=dist($,4*t,o,4*l),_=map(i,50,1400,3.5*a,1*a,!0),d=pow(map(i,.1*_,_,1,0,!0),3);r+=d}return r=constrain(r,0,1),4==PORTAL_TYPE&&(r*=.5),PORTAL_GLOW||(r=0),r}function getZ($){return(eyeHeight*fov+horizon_y*fov-$*fov)/($-horizon_y)}function getY($,e){return eyeHeight*(fov/(fov+e))+horizon_y}function easeInOutSine($,e,t,r){return-t/2*(cos(PI*$/r)-1)+e}function createPath(){let $=R.random_num(0,13);for(let e=0;e<1e4;e++){let t=map(e,0,9999,0,1),r=map(sqrt(t),0,1,maxDist,minDist),n=map(r,maxDist,minDist,0,1),o=fov/(fov+r),l=eyeHeight*o+horizon_y,a=(650*sin(.01*r+$)+200*getNoise(n,l,.005))*o*n+halfWidth,i=abs(nearestPortalZ-r),_=map(i,0,200,0,1,!0);_=easeInOutSine(_,0,1,1),a=lerp(halfWidth,a,_);let d=o*R.random_num(20,40);2==PATH_TYPE&&(a=halfWidth),pathPts.push({x:a,y:l,z:r,w:d,zper:n*o})}}function getPath($){let e=0,t=abs(pathPts[0].y-$);for(let r=1;r<pathPts.length;r++){let n=abs(pathPts[r].y-$);if(n>t)break;t=n,e=r}return pathPts[e]}function drawPath($){if(0!=PATH_TYPE){let e=portals[portals.length-1].y,t=myHeight;$.noStroke();for(let r=0;r<200;r++){let n=map(r,0,199,0,1),o=map(n,0,1,e,t),l=getPath(o),a=l.x,i=l.z,_=l.w,d=l.zper,s=getGroundColor(i),u=portals[0].z;s=lerpColor(getSunColor(0,.3),s,d*d);let m=map(abs(i-u),0,600,2.5,0);drawBrokenLine($,a-7*_,o,a+7*_,o,s,s,15,3,!0,m),$.noStroke()}$.noStroke()}}function getId(){let $=R.random_dec();for(let e=0;e<cumulativeChances.length;e++)if($<cumulativeChances[e])return e+1;return 1}function createThings($){for(let e=0;e<$;e++){let t=getId(),r=pow(R.random_num(.25,1),.5),n=map(r,0,1,maxDist,minDist);r=pow(r,6);let o=fov/(fov+n),l=-100;for(;l<0||l>myWidth;)l=R.random_num(-15e3,15e3)*o+halfWidth;let a=getY(l,n);things.push({id:t,type:0,x:l,y:a,z:n,s:o,zper:r})}{let i=1;PORTAL_TYPE>=3&&PORTAL_TYPE<7&&(i=R.random_bool(.02)?2:1);let _=[nearestPortalZ,nearestPortalZ+500];for(let d=0;d<i;d++){let s=halfWidth,u=_[d],m=getY(s,u),f=map(u,200,1e3,R.random_num(350,1e3),50);7==PORTAL_TYPE&&(f=350);let h=f*R.random_num(.02,.05);things.push({id:0,type:PORTAL_TYPE,x:s,y:m,z:u,d:f,w:h}),portals.push({id:d,type:PORTAL_TYPE,x:s,y:m,z:u,d:f,w:h})}}if(MIDGROUND_COPSE){let g=R.random_int(150,355),c=lerp(minDist,maxDist,.7),p=lerp(minDist,maxDist,.4),x=R.random_num(-300,200);for(let S=0;S<g;S++){let P=R.random_dec(),y=map(P,0,1,c,p);P=pow(P,6);let T=fov/(fov+y),C=-1e3;for(;C<x||C>myWidth-x;)C=R.random_num(-15e3,15e3)*T+halfWidth;let G=getY(C,y);.4>getNoise(C,3*y,.003)&&things.push({id:5,type:0,x:C,y:G,z:y,s:T,zper:P})}}if(MIDGROUND_MEGALITHS){let E=R.random_int(3,5),v=150,O=1200;for(let w=0;w<E;w++){let D=map(w,0,E-1,0,1),L=map(D,0,1,v,O);D=pow(D,6);let k=fov/(fov+L),A=halfWidth,z=getY(A,L);things.push({id:6,type:0,x:A,y:z,z:L,s:k,zper:D})}}if(MIDGROUND_SPIRES){let N=R.random_int(6,14);R.random_bool(.25)&&(N*=3);let W=lerp(minDist,maxDist,.7),I=lerp(minDist,maxDist,.3);for(let b=0;b<N;b++){let Y=map(b,0,N-1,0,1),U=map(Y,0,1,W,I);Y=pow(Y,6);let M=fov/(fov+U),V=R.random_num(-250,myWidth+250),H=getY(V,U);things.push({id:7,type:0,x:V,y:H,z:U,s:M,zper:Y})}}PATH_TYPE>0&&(things=things.filter($=>{let e=!0,t=$.id,r=getPath($.y),n=abs(r.x-$.x);return t>0&&t<=4?(n<6*r.w&&(e=!1),2==t&&n<14.5*r.w&&(e=!1),2==t&&.35>getNoise($.x,3*$.z,.003)&&e&&(e=!1)):5==t&&n<6*r.w&&(e=!1),e}));let F=getY(halfWidth,nearestPortalZ);7==PORTAL_TYPE&&(things=things.filter($=>{let e=!0,t=$.id;return dist($.x,7*$.y,halfWidth,7*F)<.35*myWidth&&0!=t&&(e=!1),e})),things.sort(($,e)=>e.z-$.z)}function drawThings($){for(let e of things){let t=e.id;0==t?drawPortal($,e):1==t?drawGrass($,e):2==t?drawSpikyPlant($,e):3==t?drawRock($,e):4==t?drawFlower($,e):5==t?drawTree($,e):6==t?drawMegalith($,e):7==t&&drawSpire($,e)}}function drawGrass($,e){let t=e.x,r=e.y,n=e.z,o=e.s,l=e.zper,a=getLighting(t,r,n),i=R.random_num(70,105),_=i;R.random_bool(.02)&&(i*=R.random_num(1.4,2.8),_*=R.random_num(1.4,2.8));let d=.25*sin(a*a*PI);i*=d+o,_*=d+o;let s=getGroundColor(n),u=getColor(GROUND),m=getColor(GROUND+R.random_num(.05,.13)),f=lerpColor(s,u,l),h=lerpColor(s,m,l);f=lerpColor(f,getSunColor(0),.85*a),h=lerpColor(h,getSunColor(R.random_dec()),a);let g=max(7,int(.1*i));$.fill(h),$.beginShape(),$.vertex(t-.5*i,r);for(let c=0;c<g;c++){let p=map(c,0,g-1,0,1),x=sin(p*PI),S=map(p,0,1,t-.5*i,t+.5*i),P=map(p,0,1,t-i,t+i),y=r-x*i*.25,T=r-_*(.5*x+.5),C=lerp(y,T,R.random_dec()),G=R.random_num(-.2,.2)*i;$.quadraticVertex(P+G,C,P,T),$.quadraticVertex(P+G,C,S,y)}$.vertex(t+.5*i,r),$.endShape(CLOSE),r+=.15*i,$.fill(f),$.beginShape(),$.vertex(t-.5*i,r);for(let E=0;E<g;E++){let v=map(E,0,g-1,0,1),O=sin(v*PI),w=map(v,0,1,t-.5*i,t+.5*i),D=map(v,0,1,t-.8*i,t+.8*i),L=r-O*i*.25,k=r-_*(.5*O+.5)*.6,A=lerp(L,k,R.random_dec()),z=R.random_num(-.2,.2)*i;$.quadraticVertex(D+z,A,D,k),$.quadraticVertex(D+z,A,w,L)}$.vertex(t+.5*i,r),$.endShape(CLOSE),$.noStroke()}function drawBlade($,e,t,r,n,o){let l=r*(.5*o+.5);R.random_bool(.05)&&(l*=2.5);let a=(n-.5)*65+R.random_num(-(.5*r),.5*r),i=.5*l,_=R.random_num(15,25)*n,d=t+3*o+R.random_num(-10,10)*o;$.vertex(e,d),$.quadraticVertex(e,t-i,e+1.5*a,t-l),$.quadraticVertex(e,t-i,e+_,t)}function drawSpikyPlant($,e){let t=e.x,r=e.y,n=e.z,o=e.s,l=e.zper,a=getLighting(t,r,n),i=R.random_num(20,40),_=i;R.random_bool(.02)&&(i*=1.1,_*=1.4);let d=r-.5*_,s=getGroundColor(n),u=lerpColor(s,getColor(GROUND+.04),l),m=lerpColor(s,getColor(GROUND+.08),l);lerpColor(s,u,l),lerpColor(s,m,l),$.noStroke();let f=R.random_int(5,9);for(let h=0;h<5;h++){let g=map(h,0,4,0,1,!0),c=h%2*(TWO_PI/(2*f)),p=map(g,0,1,i,.1*i,!0),x=lerpColor(u,m,g);x=lerpColor(x,getSunColor(0),a*R.random_num(.6,1));for(let S=0;S<f;S++){let P=map(S,0,f-1,0,1,!0),y=map(P,0,1,.65*PI,2.35*PI)+c+R.random_num(-.2,.2,!0),T=cos(y),C=sin(y),G=t+T*i,E=d+C*p,v=R.random_num(25,35)*o;h<1&&($.stroke(getColor(GROUND+.1,.2)),$.strokeWeight(l)),$.fill(x),$.beginShape(),$.vertex(t,r),$.bezierVertex(t-C*v,r+T*v,G,E,G,E),$.bezierVertex(G,E,t+C*v,r-T*v,t,r),$.endShape()}}$.noStroke()}function drawRock($,e){let t=e.x,r=e.y,n=e.z,o=e.s;t+=map(getNoise(t,n,.01),0,1,-200*o,600*o);let l=e.zper,a=getLighting(t,r,n),i=50*pow(R.random_dec(),2)+5,_=i*R.random_num(.7,1.6);R.random_bool(.005)&&(i*=R.random_num(1.5,2.5),_*=R.random_num(1.5,2.5)),i*=o,_*=o;let d=getGroundColor(n),s=d,u=getColor(GROUND+R.random_num(.2,.25)),m=getColor(GROUND+.15),f=getColor(GROUND-.05),h=lerpColor(s,u,l),g=lerpColor(s,m,l),c=lerpColor(s,f,l);h=lerpColor(h,getSunColor(0),.75*a),g=lerpColor(g,getSunColor(0),.5*a),c=lerpColor(c,g,a);let p=35,x=[];for(let S=0;S<p;S++)if(R.random_bool(.75)){let P=map(S,0,p-1,0,1),y=sin(P*PI),T=map(P,0,1,HALF_PI,TWO_PI+HALF_PI),C=cos(T),G=.5*sin(T)-.5,E=t+C*i*R.random_num(.9,1.1),v=r+G*_*R.random_num(.9,1.1)*y;x.push({x:E,y:v})}p=x.length,$.fill(getColor(.1,.2)),$.beginShape();for(let O=0;O<p;O++){let w=x[O],D=w.x,L=w.y;O>2&&O<p-2&&(L+=(e.y-L)*1.5),$.vertex(D,L)}$.endShape(),$.fill(g),$.beginShape();for(let k=0;k<p;k++){let A=x[k],z=A.x,N=A.y;$.vertex(z,N)}$.endShape(),$.fill(h),$.beginShape();for(let W=8;W<p-8;W++){map(W,0,p-1,0,1);let I=x[W],b=I.x,Y=I.y;$.vertex(b,Y)}$.endShape(),$.fill(c),$.beginShape();for(let U=0;U<5;U++){map(U,0,p-1,0,1);let M=x[U],V=M.x,H=M.y;$.vertex(V,H)}for(let F=p-5;F<p;F++){map(F,0,p-1,0,1);let B=x[F],q=B.x,Z=B.y;$.vertex(q,Z)}$.endShape(),$.noStroke()}function drawFlower($,e){drawDaisy($,e)}function drawDaisy($,e){let t=e.x,r=e.y,n=e.z,o=e.s,l=e.zper,a=getLighting(t,r,n),i=R.random_num(25,35),_=R.random_num(55,85);R.random_bool(.01)&&(i*=1.3,_*=3);let d=.5*a;i*=d+o,_*=d+o;let s=0;for(let u of portals){let m=dist(t,6*n,u.x,6*u.z);s=max(s,m)}let f=map(s,0,2e3,1,0,!0);if(R.random_dec()<f){let h=getGroundColor(n),g=getColor(1);h=lerpColor(h,getColor(.7),a),g=lerpColor(g,getSunColor(1),a),PORTAL_GLOW||(g=lerpColor(getGroundColor(n),getColor(.6),a));let c=R.random_int(1,5);for(let p=0;p<c;p++){let x=t+R.random_num(-50,50)*l,S=r+R.random_num(-44,44)*l,P=i*R.random_num(.75,1.25),y=_*R.random_num(.75,1.25),T=.5*R.random_num(-P,P),C=x+T,G=S-y;$.noFill(),$.stroke(color(red(h),green(h),blue(h),.3)),$.strokeWeight(.05*P),$.beginShape(),$.vertex(x,S),$.bezierVertex(x,S,x-T,lerp(S,G,.5),C,G),$.endShape(),$.noStroke(),$.fill(g);let E=P*R.random_num(.5,.8),v=.25*E,O=R.random_num(.8,1),w=R.random_num(.4,.8),D=TWO_PI/11;for(let L=0;L<11;L++)drawPetal($,C,G,D*L,E,v,O,w)}}$.noStroke()}function drawPetal($,e,t,r,n,o,l,a){let i=cos(r)*l,_=sin(r)*a,d=e+i*o*l,s=t+_*o*a,u=t+_*n*a-o*R.random_num(.2,1),m=.7*n,f=PI/15,h=e+cos(r-f)*m*l,g=t+sin(r-f)*m*a,c=e+cos(r+f)*m*l,p=t+sin(r+f)*m*a;$.beginShape(),$.curveVertex(d,s),$.curveVertex(d,s),$.curveVertex(h,g),$.curveVertex(e+i*n*l,u),$.curveVertex(c,p),$.curveVertex(d,s),$.curveVertex(d,s),$.endShape()}function drawTree($,e,t,r){R.random_bool(.05)?drawPineTree($,e.x,e.y,e.z,e.s*R.random_num(3e3,5500),-HALF_PI,0,R.random_int(25,33),t,r):drawFurTree($,e,t,r)}function drawFurTree($,e,t,r){let n=e.x,o=e.y,l=e.z,a=e.s,i=map(e.zper,0,1,3450,6650)*R.random_num(.8,1.2);R.random_bool(.02)&&(i*=R.random_num(1.2,1.4));let _=.25*i;_*=a,i*=a;let d=getGroundColor(l),s=getGroundColor(l,.07);void 0!==t&&(d=t,s=r);let u=.1*_,m=.2*i,f=R.random_num(.7,.8),h=R.random_int(13,19),g=o,c=m*(1-pow(f,h))/(1-f);$.fill(d),$.beginShape(),$.vertex(n-.5*u,o),$.vertex(n-.05*u,o-c),$.vertex(n+.05*u,o-c),$.vertex(n+.5*u,o),$.endShape();for(let p=0;p<h;p++){let x=map(p,0,h,0,1),S=g-m;for(let P=0;P<8;P++){let y=map(P,0,7,0,1),T=map(cos(y*PI),-1,1,0,1),C=map(T,0,1,n-_,n+_),G=map(T,0,1,n+.2*_,n-.2*_),E=lerp(C,G,.5),v=lerp(C,E,.5),O=map(R.random_dec(),0,1,S-.4*m,S+.4*m),w=map(R.random_dec(),0,1,S-1*_,S-1.5*_),D=map(R.random_dec(),0,1,S+.1*_,S-.2*_),L=lerp(O,w,.25),k=lerp(O,w,.25);$.fill(lerpColor(d,s,x)),$.beginShape(),$.vertex(C,O),$.vertex(E,L),$.vertex(v,k),$.vertex(G,w),$.vertex(G,D),$.endShape()}m*=f,_*=.75,g=S}if(FORGETTING_TREES&&R.random_bool(.5)){$.strokeWeight(1),drawBrokenLine($,n,g,n,g-2*i,getColor(.2,0),getGroundColor(l,.07),30,10),$.noStroke();let A=R.random_int(0,60);for(let z=0;z<A;z++){let N=n+.5*R.random_num(-_,_),W=map(pow(R.random_dec(),3),0,1,g-.05*i,g-.5*i),I=map(pow(R.random_dec(),3),0,1,1,5);$.fill(getGroundColor(l,.07)),$.circle(N,W,I)}}$.noStroke()}function drawPineTree($,e,t,r,n,o,l,a,i,_){if(l>3)return;let d=l%2==1?a/4:a;l>=2&&(n*=3);let s=cos(o),u=sin(o),m=e+s*n,f=t+u*n,h=.02*n+.5;getColor(GROUND);let g=getGroundColor(r),c=getGroundColor(r,.07);void 0!==i&&(g=i,c=_),$.fill(g),$.triangle(e+u*h,t-s*h,m,f,e-u*h,t+s*h);for(let p=0;p<d;p++){let x=pow(map(p,0,d-1,0,1),.618),S=map(x,0,1,lerp(e,m,.2),m),P=map(x,0,1,lerp(t,f,.2),f),y=p%2==0?R.random_num(2,2.5):R.random_num(-2.5,-2);l>=1&&(y*=.2),R.random_bool(.9)&&drawPineTree($,S,P,r,n*R.random_num(.05,.3)*(1-x),o+y,l+1,d/2,i,_)}}function drawMegalith($,e){let t=e.x,r=e.y,n=e.z,o=e.s,l=e.zper,a=R.random_num(1e4,2e4)*o,i=5e4*o,_=getGroundColor(n,.01),d=t-a*map(l,0,1,.55,.65),s=t+a*map(l,0,1,.55,.65);$.strokeWeight(1);for(let u=0;u<49;u++){let m=map(u,0,49,0,1),f=map(u+1,0,49,0,1),h=map(m,0,1,r,r-i),g=map(f,0,1,r,r-i),c=lerpColor(_,getGroundColor(n+.05),pow(m,.25));$.fill(c),$.stroke(c),$.rect(d,h,d-.25*a,g),$.rect(s,h,s+.25*a,g)}$.noStroke()}function drawSpire($,e){let t=e.x,r=e.y,n=e.z,o=e.s,l=e.zper,a=40*o,i=a*R.random_num(80,110),_=r,d=r-i,s=getGroundColor(n),u=getGroundColor(n,.05);$.strokeWeight(2*l);let m=i/75;for(let f=0;f<75;f++){let h=map(f,0,74,0,1),g=t-a,c=t+a,p=map(h,0,1,_,d),x=lerpColor(s,u,h*h);$.fill(x),$.stroke(x),$.rect(g,p,c,p-m)}$.noStroke();{let S=450*o,P=R.random_num(0,TWO_PI),y=cos(P)*S,T=sin(P)*S*.2;spireTips.push({x:t,y:d,z:n,t:P});let C=t-y,G=t+y,E=d-T,v=d+T,O=87*o,w=R.random_int(1,2);for(let D=0;D<w;D++)map(D,0,w-1,0,1),$.fill(u),$.beginShape(),$.vertex(C,E),$.vertex(G,v),$.vertex(G,v+O),$.vertex(C,E+O),$.endShape(),E+=3*O,v+=3*O}$.noStroke()}function drawWires($){$.noFill(),$.stroke(getColor(.44)),$.strokeWeight(.5);let e=R.random_int(10,50),t=spireTips.length;for(let r=0;r<e;r++){map(r,0,e-1,0,1);let n=spireTips[R.random_int(0,t-1)],o=spireTips[R.random_int(0,t-1)];if(n!=o){let l=lerp(n.x,o.x,.15),a=lerp(n.x,o.x,.85);if(R.random_bool(.5)){let i=n.t,_=o.t,d=20*cos(i),s=4*sin(i),u=20*cos(_),m=4*sin(_),f=R.random_num(100,200);$.bezier(n.x+d,n.y+s,l+d,n.y+s+f,a+u,o.y+m+f,o.x+u,o.y+m),$.bezier(n.x-d,n.y-s,l-d,n.y-s+f,a-u,o.y-m+f,o.x-u,o.y-m)}}else{let h=n.x+150,g=horizon_y,c=lerp(n.x,h,.15),p=lerp(n.x,h,.85);$.bezier(n.x,n.y,c,n.y+150,p,g,h,g)}}}function drawBgArch($,e,t,r){let n=portals[0],o=n.x,l=n.y,a=n.d,i=.5*n.d*r,_=e,d=t;if(skyGlow&&(_=getSunColor(0),d=getSunColor(.4)),1==PORTAL_TYPE||6==PORTAL_TYPE){let s=o-1.5*a,u=o+1.5*a,m=l;$.fill(_),$.triangle(s,m,lerp(s,u,.5),m-2.598*a,u,m)}else drawGradientRect($,o-i,l+i,o+i,-100,_,d,0,.25,2)}function drawPalette($){$.noStroke(),$.fill(getSunColor(0)),$.rect(0,0,.5*myWidth,10),$.fill(getSunColor(1)),$.rect(.5*myWidth,0,myWidth,10),$.fill(getColor(0)),$.rect(0,10,.25*myWidth,20),$.fill(getColor(.33)),$.rect(.25*myWidth,10,.5*myWidth,20),$.fill(getColor(.67)),$.rect(.5*myWidth,10,.75*myWidth,20),$.fill(getColor(1)),$.rect(.75*myWidth,10,1*myWidth,20)}
It is curious how our memories can mislead. I vividly recall a childhood trek up Mt. Fuji with my parents through a foggy bamboo forest, and the image of my dad buying a walking stick from an older vendor. But as my mom later clarified, the adventure actually took place in a Tokyo park –– I’ve never even visited Fuji-san. Contemplating this blend of the real and the imagined has led me to create generative vistas whose clarity is eroded by the passing of time. The landscapes in Recollection are understated and familiar: rolling hills, distant mountains, and sporadic clusters of trees or forests. There is a path through grass and stone –– sometimes clear but, at other times, overgrown and obscure. Many of these paths culminate at a portal, its purpose enigmatic. It is pure mystery, both inviting and unsettling. It is an obscuring void, a memory half-recalled. Recollection is a meditation on the mysteries of the mind, and a tribute to the quest for understanding. It stands not only as a beacon of hope for those grappling with the disintegration of memory, but also a testament to the enduring pursuit of clarity in the midst of obscurity. While some details may fade with time, the essence — the emotions, the lessons, the significance — has the potential to regenerate through reflection, conversation, and creative expression. Recollection is part of the reGEN initiative for Alzheimer’s research. For many, this cause is deeply personal and, I believe, it is no exaggeration to say that almost everyone has witnessed the effects of Alzheimer’s, be it within their own family or through friends. This project not only creates funding but also plays a pivotal role in amplifying awareness about Alzheimer’s disease. The opportunity to merge the joy of artistic expression with a mission that has tangible, real-world implications is profoundly inspiring.
cd = mix( cd, cg0 * planetPer, planetEdge );\n cd += pb * cg1 * planetEdge * 0.2 * planetRadPer;\n\n float dp = max( 0.0, dot( vec3( normalize( dirToSun ), -u_renderPer * 15.0 ), planetN ) * rimGlow );\n cd += dp * distPer * planetEdge * 0.75;\n cd += smoothstep( -planetRad * 0.025, 0.0, planetDist ) * 0.2 * planetEdge * u_atmos;\n cd += rimGlow * 0.1 * planetEdge;\n cd += smoothstep( -8.0, 1.0, planetDist ) * 0.2 * planetEdge;\n }\n \n // landscape\n if( u_environmentId > 0 ){\n float reflectMask = pow( sin( uv.x * PI ), 21.0 );\n reflectMask += pow( sin( uv.x * PI ), 5.0 ) * 0.2;\n float gl = u_groundLevel;\n float skyMask = smoothstep( gl, gl + haze*0.04, uv.y );\n float seaMask = 1.0 - skyMask;\n\n float pnh1 = texture( u_noiseClouds, vec2( uv.x * 0.1, uv.y * 2.0 ) ).w * 0.5;\n float pnh2 = texture( u_noiseClouds, vec2( uv.x * 0.03, uv.y * 2.0 ) ).w * 0.5;\n float wispy0 = texture( u_noiseClouds, vec2( uv.x * 0.05, uv.y * 0.5 ) ).x;\n float wispy1 = texture( u_noiseClouds, vec2( uv.x * 0.1, uv.y * 1.5 ) ).x;\n\n float seaGrad = smoothstep( 0.0, gl, uv.y );\n\n if( u_environmentId == 1 ){ // ocean\n float nn = cn0 * 0.004 + cn0 * 0.002 + cn2 * 0.001 + 0.005;\n float gl0 = gl + nn - sin( uv.x * PI + 0.75 ) * 0.015;\n float lm = smoothstep( gl0, gl0 + haze*0.1, uv.y );\n float cloudyMask = cloudy * skyMask;\n\n cd *= skyMask;\n cd += ( pow( smoothstep( gl + ( cloudy + 1.0 ), gl, uv.y ), 3.0 ) ) * wispy0 * 0.3 * skyMask; // horizon glow\n cd += sin( smoothstep( gl + 0.2, gl - 0.2, uv.y ) * PI ) * cloudyMask * wispy1;\n cd += sin( smoothstep( gl-0.1, gl+0.3, uv.y ) * PI ) * cloudyMask * cn1 * 0.15;\n cd += sin( smoothstep( gl-0.1, gl+0.6, uv.y ) * PI ) * cloudyMask * cn0 * 0.3;\n cd += seaMask * 0.02; // sea base color\n cd += seaGrad * 0.1 * seaMask; // sea noisy gradient to horizon\n cd += ( pow( smoothstep( gl + haze, gl, uv.y ), 4.0 ) ) * haze * skyMask; // horizon glow\n cd += ( pow( smoothstep( gl + haze * 2.0, gl, uv.y ), 2.0 ) ) * max( u_cloudiness, 0.2 ) * sqrt( reflectMask ) * skyMask; // horizon glow\n cd += pow( 1.0 - abs( uv.y - gl ), 23.0 ) * 0.1;\n \n cd += pnh1 * pnh2 * reflectMask * seaMask * seaGrad * 0.3; // reflection\n cd += reflectMask * seaMask * 0.45 + pnh2 * smoothstep( gl * 0.3, gl, uv.y ) * seaMask * 0.3; // sugimoto\n cd -= sin( smoothstep( gl + 0.02, gl - 0.05, uv.y ) * PI ) * wispy1 * 0.2 * seaMask * u_cloudiness; // darker waters\n \n if( u_cloudiness > 0.2 ){\n float clouds0 = cn2 * sin( smoothstep( gl + 0.02 + cn1 * 0.05, gl + ( cn0 * 0.05 + cn2 * 0.05 ), uv.y + cn2 * 0.01 ) * PI );\n float clouds1 = cn0 * sin( smoothstep( gl + 0.02 + cn1 * 0.06, gl + ( cn0 * 0.2 + cn2 * 0.1 ) * cn0 + 0.05, uv.y + cn2 * 0.003 ) * PI );\n float clouds2 = cn0 * sin( smoothstep( gl + 0.02 + cn0 * 0.03, gl + ( cn0 * 0.3 + cn2 * 0.2 ) * cn0 + 0.1, uv.y + cn2 * 0.001 ) * PI );\n float cFinal = clouds0 * cn0 * 0.4 + clouds1 * cn1 * 1.4 + clouds2 * 0.35;\n cd += cFinal * u_cloudiness * cn0;\n }\n\n } else if( u_environmentId == 2 ){ // hills\n cd += pow( smoothstep( 0.9, gl, uv.y ), 1.0 ) * 0.1; // horizon glow\n cd += smoothstep( gl + max( u_cityHaze, 0.1 ) * 3.0, gl, uv.y ) * 0.2;\n float origCd = cd;\n int numHills = 4;\n for( int i=0; i<numHills; i++ ){\n float per = float(i) / float( numHills - 1 );\n float nn = ( cos( sin( uv.x * ( 6.0 + per * 3.0 ) + per * 4.95 + cn0 * 0.7 + u_rf0 * 52.0 ) )/( PI * 0.35 ) ) * 0.05;\n nn += sin( uv.x * ( 5.0 - per * 1.0 ) + per * 5.7 + ( cn0 + cn1 + cn2 * 0.5 ) * 0.5 + u_rf1 * 11.0 ) * 0.1;\n float gl0 = gl + nn * ( 1.0 - per * 0.7 ) - per * 0.05;\n float lm = smoothstep( gl0, gl0+0.0025, uv.y );\n cd = mix( origCd, cd, lm );\n cd -= ( 1.0 - lm ) * ( 0.1 + reflectMask * 0.03 ) * ( per * 0.5 );\n }\n }\n }\n \n // thick clouds\n cd -= ( cn0 * 0.5 - cn1 * 0.3 ) * cloudy;\n float rf0 = u_rf0 * 0.5 + 0.25;\n float cgrad = smoothstep( rf0 - cn0 * 0.25 + uv.x * 0.2, rf0 + cn0 * 0.25 + uv.x * 0.2, uv.y ) * u_cloudiness;\n cd -= ( cn0 * 0.5 - cn1 * 0.3 ) * cgrad;\n\n // fg light pollution\n cd += ( 1.0 - uv.y + cn2 * 0.02 ) * ( haze + 0.05 ) * 0.3;\n \n if( u_bailyBeads == 1 ){\n cd += beadsCd * 0.15;\n }\n \n cd *= 0.0865;\n\n color.xyz = vec3( cd );\n}\n"),attributes:{position:{data:Ie,size:2},uv:{data:Me,size:2}},count:3}),Ce.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat})},Oe=(n,e)=>{Ce.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Ce.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,oe.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Gn.fb.read.targetTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE3),n.bindTexture(n.TEXTURE_2D,xe.fb.read.targetTexture),n.activeTexture(n.TEXTURE4),n.bindTexture(n.TEXTURE_2D,Pe.fb.read.targetTexture),n.activeTexture(n.TEXTURE5),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),Ce.renderer.bindUniform("u_sky",0),Ce.renderer.bindUniform("u_pointCloud",1),Ce.renderer.bindUniform("u_sunTex",2),Ce.renderer.bindUniform("u_planetsTex",3),Ce.renderer.bindUniform("u_beadsTex",4),Ce.renderer.bindUniform("u_noiseClouds",5),Ce.renderer.bindUniform("u_sunPos",an.sunPos),Ce.renderer.bindUniform("u_sunRad",an.sunRad),Ce.renderer.bindUniform("u_sunRadPer",Be),Ce.renderer.bindUniform("u_numPlanets",an.numPlanets),Ce.renderer.bindUniform("u_bailyBeads",an.bailyBeads),Ce.renderer.bindUniform("u_environmentId",an.environmentId),Ce.renderer.bindUniform("u_groundLevel",an.groundLevel),Ce.renderer.bindUniform("u_cityHaze",an.cityHaze),Ce.renderer.bindUniform("u_cloudiness",an.cloudiness),Ce.renderer.bindUniform("u_flareIntensity",an.flareIntensity),Ce.renderer.bindUniform("u_renderPer",e),Ce.renderer.bindUniform("u_rf0",an.rf0),Ce.renderer.bindUniform("u_rf1",an.rf1),Ce.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),Ce.renderer.bindUniform("u_res",[an.height,an.height]),Ce.renderer.bindUniform("u_atmos",an.atmos),Ce.renderer.bindUniform("u_multi",[an.coronaMulti,an.surfaceMulti,an.coronaGlowMulti]),Ce.renderer.render(an.height,an.height),Ce.fb.swap()};const Xe=new Float32Array([-1,-1,3,-1,-1,3]),ke=new Float32Array([0,0,2,0,0,2]),Ne={},Ge=e=>{Ne.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform sampler2D u_framebuffer;\nuniform sampler2D u_scene;\n\nuniform vec2 u_res;\nuniform vec2 u_invRes;\nuniform int u_isRendering;\nuniform float u_renderPer;\nuniform int u_renderFrame;\nuniform float u_rf0;\nuniform float u_rf1;\n\nfloat off = 0.990;\nfloat off2 = 0.005;\n\nvec4 blur( float off, float multi ) {\n vec4 col = vec4( 0. );\n for(float x = -off; x <= off; x++) {\n for(float y = -off; y <= off; y++) {\n col += texture( u_framebuffer, v_uv+vec2(x,y)*u_invRes );\n }\n }\n col /= multi;\n return col;\n}\n\nvoid main() {\n vec2 fc = gl_FragCoord.xy;\n vec2 uv = fc / u_res;\n\n vec4 frag = texture( u_scene, uv );\n \tvec4 prev = texture( u_framebuffer, uv );\n\tfloat decay = 0.1;\n\n if( u_isRendering == 1 ){\n if( u_renderPer > 0.0 ){\n if( u_renderPer < 0.3 ) prev = blur( 1.0, 9.0 );\n\n float multi = 0.1;\n color = prev * ( off + u_renderPer * off2 ) + frag * multi;\n color = clamp( color, vec4( 0.0 ), vec4( 1.0 ) );\n if( u_renderPer > 0.999 ){\n color = prev;\n }\n } else { // LIVE VIEW\n color = prev * decay + frag;\n }\n } else {\n color = prev * decay + frag;\n }\n color = clamp( color, vec4( 0.0 ), vec4( 1.0 ) );\n}"),attributes:{position:{data:Xe,size:2},uv:{data:ke,size:2}},count:3}),Ne.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat})},Ve=(n,e,r,t)=>{Ne.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Ne.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Ne.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Ce.fb.read.targetTexture),Ne.renderer.bindUniform("u_framebuffer",0),Ne.renderer.bindUniform("u_scene",1),Ne.renderer.bindUniform("u_renderPer",r),Ne.renderer.bindUniform("u_isRendering",t),Ne.renderer.bindUniform("u_renderFrame",e),Ne.renderer.bindUniform("u_res",[an.height,an.height]),Ne.renderer.bindUniform("u_invRes",[1/an.height,1/an.height]),Ne.renderer.bindUniform("u_rf0",an.rf0),Ne.renderer.bindUniform("u_rf1",an.rf1),Ne.renderer.render(an.height,an.height),Ne.fb.swap()};const qe=new Float32Array([-1,-1,3,-1,-1,3]),He=new Float32Array([0,0,2,0,0,2]),Ye={},We=e=>{Ye.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform sampler2D u_trails;\nuniform sampler2D u_noiseClouds;\nuniform sampler2D u_forces;\n\nuniform int u_borderId;\nuniform float u_borderWidth;\nuniform float u_borderCornerRad;\nuniform float u_damage;\nuniform float u_cloudiness;\nuniform int u_tint;\nuniform vec2 u_res;\nuniform float u_renderPer;\n\n#define PI 3.14159265\n#define TAU 6.28318530718\n\nconst vec3 cd0 = vec3( 0.05, 0.02, 0.15 );\nconst vec3 cd1 = vec3( 0.5, 0.4, 0.8 );\nconst vec3 cd2 = vec3( 1.0, 0.7, 0.7 );\nconst vec3 cd3 = vec3( 1.0, 1.0, 0.9 );\nconst vec3 cd4 = vec3( 1.0, 1.0, 1.0 );\n\nfloat random( vec2 st ){\n return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);\n}\n\nfloat hash11(float p){\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n}\n\nvec3 bc( vec3 v, float b, float c ){\n return (v - 0.5) * c + 0.5 + b;\n}\n\nvec3 gamma( vec3 v, float p ){\n return vec3(pow(abs(v.r), p),pow(abs(v.g), p),pow(abs(v.b), p));\n}\n\nvec3 quintColor( vec3 c0, vec3 c1, vec3 c2, vec3 c3, vec3 c4, float per ){\n vec3 c = c0;\n if( per < 0.25 ){\n c = mix( c0, c1, per * 4.0 );\n } else if( per < 0.5 ){\n c = mix( c1, c2, ( per - 0.25 ) * 4.0 );\n } else if( per < 0.75 ){\n c = mix( c2, c3, ( per - 0.5 ) * 4.0 );\n } else {\n c = mix( c3, c4, ( per - 0.75 ) * 4.0 );\n }\n return c;\n}\n\nvec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ){\n return a + b*cos( TAU*(c*t+d) );\n}\n\nfloat sdCircle( vec2 p, float r ){\n return length(p) - r;\n}\n\nfloat sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ){\n r.xy = (p.x>0.0)?r.xy : r.zw;\n r.x = (p.y>0.0)?r.x : r.y;\n vec2 q = abs(p)-b+r.x;\n return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x;\n}\n\nvoid main() {\n \n vec2 frag = gl_FragCoord.xy;\n float ar = u_res.x/u_res.y;\n float ar2 = ( 1.0 - ar ) * 0.5;\n vec2 uv = frag / u_res;\n uv.x = uv.x * ar + ar2;\n vec2 fragCoord = frag + vec2( u_res.y * ar2, 0.0 );\n\n // GET NOISE CLOUDS\n vec4 clouds = texture( u_noiseClouds, uv );\n float cn0 = clouds.x;\n float cn1 = clouds.y;\n float cn2 = clouds.z;\n float cn3 = clouds.w;\n\n // set initial color\n color.xyz = vec3( 0.0 );\n \n // main image\n color += texture( u_trails, uv );\n color.xyz = vec3( max( color.x, max( color.y, color.z ) ) );\n \n // aging\n float dmg = u_damage * 0.5;\n\n // borders\n vec2 bp = (2.0*frag-u_res)/u_res.y;\n vec2 bp2 = (vec2( 2.0, ar*2.0 )*frag-u_res*vec2( 1.0, ar))/u_res.x;\n float br = u_borderId == 0 ? 0.0 : u_borderCornerRad;\n vec2 bs = vec2( ar - u_borderWidth, 1.0 - u_borderWidth );\n float borderSdf = sdRoundedBox( bp, bs, vec4( br ) );\n float b0 = smoothstep( -0.002, 0.0, borderSdf );\n float b1 = smoothstep( -0.01, 0.0, borderSdf );\n float b2 = smoothstep( -0.03, 0.0, borderSdf );\n float b3 = smoothstep( -0.1, 0.0, borderSdf );\n float b4 = smoothstep( -0.2, 0.0, borderSdf );\n float vign = sdCircle( bp2, 0.75 );\n float borderShadow = smoothstep( 0.9, 0.0, vign );\n float vignBlend = smoothstep( 0.66, -0.2, vign );\n \n if( u_borderId > 0 ){\n // aged discoloring\n color.xyz = mix( color.xyz, vec3( cos( color.xyz * PI * 2.0 ) ), dmg ); // color cycles with higher dmg\n float edgeDark = ( b4 * 0.1 + b3 * cn0 * 0.3 - b3 * cn1 * 0.3 + b2 * cn2 * 0.3 - b3 * cn2 * 0.15 );\n color.xyz *= 1.0 - edgeDark;\n\n // more clouds\n color.xyz -= cn0 * u_cloudiness * 0.2;\n\n // final noise and bgcolor\n color.xyz = clamp( color.xyz, 0.0, 1.0 );\n color.xyz = color.xyz * 0.8 + 0.1;\n float fn0 = ( random( ( fragCoord + vec2( 52.5, 77.8 ) ) * 0.01 ) ) * 0.025;\n color.xyz += fn0;\n\n color.xyz = clamp( color.xyz, 0.0, 1.0 );\n color.xyz *= vec3( borderShadow - b3 * 0.1 - b2 * 0.1 ); // final vignette\n\n if( u_borderId == 2 ){ // color edges\n float bMix = mix( b2, b3, dmg * 2.0 );\n float edge = clamp( 1.0 - bMix\n + cn0 * 0.5\n - sin( cn0 * 14.0 ) * 0.1\n - sin( cn3 * 7.0 + cn2 * 3.0 ) * 0.1\n - hash11( frag.x * frag.y ) * 0.1\n - b4 * 0.2\n + cn0 * 0.35\n + cn1 * 0.25, 0.0, 1.0 );\n color.xyz += ( 1.0 - edge ) * 0.2;\n float edgePer = clamp( pow( edge, 2.0 ), 0.0, 1.0 );\n vec3 stain = quintColor( cd0, cd1, cd2, cd3, cd4, pow( fract( edgePer * 2.0 ), 0.5 ) );\n color.xyz *= mix( stain, cd4, edgePer );\n }\n\n float innerb0 = smoothstep( -0.005, -0.002, borderSdf );\n color.xyz -= vec3( innerb0 * 0.05 );\n color.xyz = mix( vec3( 0.02 ), color.xyz, 1.0 - b0 );\n } else {\n if( u_tint != 9 )\n color.xyz *= ( vignBlend * 0.5 + 0.5 );\n }\n\n float b = max( color.x, max( color.y, color.z ) );\n \n // tinting\n int tint = u_tint;\n if( tint == 0 ){\n color.xyz = max( color.xyz, vec3( 0.05 ) );\n color.xyz = bc( color.xyz, 0.0, 1.1 );\n color.xyz = gamma( color.xyz, 1.5 );\n\n } else if( tint == 1 ){\n color.xyz = bc( color.xyz, 0.025, 1.1 );\n color.xyz = mix( color.xyz - vec3( 0.1, 0.15, 0.2 ), color.xyz * vec3( 1.0, 1.0, 0.9 ), vignBlend );\n color.xyz *= quintColor( cd2, cd2, cd3, cd3, cd4, b );\n\n } else if( tint == 2 ){\n vec3 nc = palette( b * 0.6 + 0.4, vec3( 0.5 ), vec3( 0.5 ), vec3( 0.9, 0.95, 1.0 ), vec3( 0.05, 0.07, 0.15 ) );\n color.xyz = mix( pow( nc, vec3( 1.5 ) ), vec3( b ), b );\n\n } else if( tint == 3 ){\n color.xyz = bc( color.xyz, 0.02, 0.9 );\n color.xyz = gamma( color.xyz, 1.2 );\n color.xyz = mix( color.xyz - vec3( 0.05, 0.1, 0.1 ), color.xyz * vec3( 1.0, 1.0, 0.95 ), vignBlend );\n color.xyz *= quintColor( cd1, cd1, cd2, cd3, cd4, b );\n\n } else if( tint == 4 ){\n color.xyz = vec3( pow( b, 1.5 ), 0.0, 0.0 );\n\n } else if( tint == 5 ){\n color.xyz = quintColor( cd0, cd1, cd2, cd3, cd4, b * b );\n\n } else if( tint == 6 ){\n color.xyz = quintColor( vec3( 0.05, 0.02, 0.01 ), vec3( 0.3, 0.05, 0.025 ), vec3( 0.6, 0.3, 0.1 ), vec3( 1.0, 0.7, 0.3 ), vec3( 1.0, 1.0, 0.7 ), b );\n\n } else if( tint == 7 ){\n color.xyz = palette( b, vec3( 0.5 ), vec3( 0.5 ), vec3( 1.0 ), vec3( 0.9, 1.0, 0.22 ) );\n\n } else if( tint == 8 ){\n color.xyz = vec3( 1.0 ) - color.xyz;\n color.xyz = bc( color.xyz, 0.15, 1.1 );\n\n }\n color.xyz *= u_renderPer;\n}\n"),attributes:{position:{data:qe,size:2},uv:{data:He,size:2}},count:3})},Ke=(n,e,r)=>{Ye.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,null),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Ne.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,zn.fb.read.targetTexture),Ye.renderer.bindUniform("u_trails",0),Ye.renderer.bindUniform("u_noiseClouds",1),Ye.renderer.bindUniform("u_forces",2),Ye.renderer.bindUniform("u_borderId",an.borderId),Ye.renderer.bindUniform("u_borderWidth",an.borderWidth),Ye.renderer.bindUniform("u_borderCornerRad",an.borderCornerRad),Ye.renderer.bindUniform("u_damage",an.damage),Ye.renderer.bindUniform("u_cloudiness",an.cloudiness),Ye.renderer.bindUniform("u_tint",an.tintId),Ye.renderer.bindUniform("u_res",[n.canvas.width,n.canvas.height]),Ye.renderer.bindUniform("u_renderPer",Math.sqrt(e)),Ye.renderer.render()},je=(n,e)=>{const r=n.canvas.toDataURL("image/png",1).replace("image/png","image/octet-stream"),t=document.createElement("a");t.download="image_"+e+".png",t.href=r,t.click()};const Je=new Float32Array([-1,-1,3,-1,-1,3]),Qe=new Float32Array([0,0,2,0,0,2]),Ze={},$e=(n,e,r)=>{Ze.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,null),Ze.renderer.bindUniform("u_preloadPer",e),Ze.renderer.bindUniform("u_prerenderPer",r),Ze.renderer.bindUniform("u_res",[n.canvas.width,n.canvas.height]),Ze.renderer.render()};console.log(tokenData.tokenId+" "+tokenData.hash);const nr=document.createElement("canvas"),er=nr.getContext("webgl2",{premultipliedAlpha:!1,alpha:!1,preserveDrawingBuffer:!0});function rr(n,e,r,t,o){return t+(o-t)*(n-e)/(r-e)}const tr=(n,e,r)=>Math.min(Math.max(n,e),r);let or=168+an.exposureFrames,ar=0,ir=0,sr=0,dr=0;document.addEventListener("keydown",(function(n){let e=n.key;"s"==e?je(er,tokenData.hash):"0"==e?dr=0:"1"==e?dr=1:"2"==e?dr=2:"3"==e?dr=3:"4"==e?dr=4:"5"==e&&(dr=5)}),!1);const ur=er.getExtension("EXT_color_buffer_float");er.getExtension("OES_texture_float_linear"),er.getExtension("EXT_float_blend");const fr=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document;(an.hasFloat=!!ur)&&!fr?(an.fbType=er.FLOAT,an.fbFormat=er.RGBA32F):(an.fbType=er.HALF_FLOAT,an.fbFormat=er.RGBA16F),document.body.appendChild(nr);const cr=()=>{nr.width=1836,nr.height=2400,nr.style.maxWidth="100%",nr.style.maxHeight="100%"};window.addEventListener("resize",cr);const lr=e=>{requestAnimationFrame(lr);let r=tr(rr(sr,0,16,0,1),0,1),t=tr(rr(sr,17,167,0,1),0,1),o=tr(rr(sr,168,or,0,1),0,1);var a;0==sr?(a=er,Ze.renderer=s(a,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform float u_preloadPer;\nuniform float u_prerenderPer;\nuniform vec2 u_res;\n\n#define PI 3.14159265\n#define TAU 6.28318\n#define HPI 3.141592/2.0\nvoid main() {\n \n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n\n float pl = u_preloadPer;\n float pr = min( u_prerenderPer * 1.25, 1.0 );\n float pout = max( ( u_prerenderPer * 1.25 ) - 1.0, 0.0 ) * 4.0;\n float fadeIn = clamp( pl * 5.0 - 0.2, 0.0, 1.0 );\n float fadeOut = 1.0 - pout;\n vec4 bg = vec4( 0.0, 0.0, 0.0, 1.0 );\n color.xyz = vec3( 0.0 );\n\n float r = 50.0;\n vec2 c = u_res/2.0;\n vec2 p = c + vec2( 0.0, ( 1.0 - pr ) * r * 2.2 );\n float d0 = distance( frag, c );\n float d1 = distance( frag, p );\n vec2 dir = normalize( c - frag );\n float angle = atan( dir.y, dir.x );\n float anglePer = fract( ( angle + PI ) / TAU - 0.25 );\n\n float loader = smoothstep( r*pl, r*pl-2.0, d0 ) * fadeIn;\n loader += sin( smoothstep( r - 1.0, r + 5.0, d0 ) * PI ) * pl * 0.5;\n\n loader += pow( smoothstep( r*(pr*35.0), 0.0, d0 ), 25.0 ) * pow( pr, 5.0 ) * 0.3; // outer glow\n loader += smoothstep( r + ( sin( angle * 42.0 + u_prerenderPer * 10.0 ) * 0.5 + 0.5 ) * 30.0 * sin( pout * PI ) + 2.0, r, d0 ) * pow( pl, 55.0 );\n loader = min( loader, 1.0 );\n loader -= smoothstep( r+1.0, r-1.0, d1 );\n loader = max( loader, 0.0 );\n loader += smoothstep( r, r-2.0, d1 ) * 0.25 * pow( pr, 11.0 );\n loader *= fadeOut;\n\n color.xyz += vec3( loader );\n}\n"),attributes:{position:{data:Je,size:2},uv:{data:Qe,size:2}},count:3})):1==sr?An(er):2==sr?ne(er):3==sr?ae(er):4==sr?Xn(er):5==sr?he(er):6==sr?Se(er):7==sr?Mn(er):8==sr?(Cn(er),ee(er),ie(er),Pn(er),kn(er),ye(er),De(er)):9==sr?qn(er):10==sr?_n(er):11==sr?gn(er):12==sr?Le(er):13==sr?Ge(er):14==sr&&We(er),t<.999?$e(er,r,t):(1==ar?ir++:o=0,o<.999&&(Yn(er,o),pn(er),xn(er),Oe(er,o),Ve(er,ir,o,ar)),Ke(er,o)),sr++,168==sr&&(ar=1)};requestAnimationFrame(lr),cr();
e.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,zn.fb.read.targetTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),On.renderer.bindUniform("u_framebuffer",0),On.renderer.bindUniform("u_forces",1),On.renderer.bindUniform("u_noiseClouds",2),On.renderer.bindUniform("u_sunPos",an.sunPos),On.renderer.bindUniform("u_sunRad",an.sunRad),On.renderer.bindUniform("u_res",[On.fb.width,On.fb.height]),On.renderer.bindUniform("u_rf0",an.rf0),On.renderer.bindUniform("u_rf1",an.rf1),On.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),On.renderer.render(On.fb.width,On.fb.height),On.fb.swap()},Nn=c(),Gn={},Vn=1/an.mapSize,qn=e=>{const r=an.numParticles,t=new Float32Array(2*r),o=new Float32Array(2*r),a=new Float32Array(4*r);for(let n=0;n<2*r;n+=2){let e=Nn.random_num(-Math.PI,Math.PI),r=Math.pow(Nn.random_dec(),.25)*an.sunRad;t[n]=an.sunPos[0]+Math.cos(e)*r,t[n+1]=an.sunPos[1]+Math.sin(e)*r,o[n]=2*Nn.random_dec()-1+1e-4,o[n+1]=2*Nn.random_dec()-1+1e-4,a[2*n]=5*Nn.random_dec(),a[2*n+1]=20*Nn.random_dec()+3,a[2*n+2]=Nn.random_dec(),a[2*n+3]=.1*Math.pow(Nn.random_num(.2,1),5)}Gn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nlayout(location=0) in vec2 a_position;\nlayout(location=1) in vec2 a_velocity;\nlayout(location=2) in vec4 a_extras;\n\nout vec2 v_position;\nout vec2 v_velocity;\nout vec4 v_extras;\nout vec3 v_color;\n\nuniform sampler2D u_particlemap;\nuniform sampler2D u_dvmap;\nuniform sampler2D u_sunTex;\nuniform sampler2D u_forceTex;\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\n\nuniform float u_renderPer;\nuniform vec2 u_res;\n\nuniform float u_frame;\nuniform float u_haziness;\nuniform float u_activity;\nuniform float u_intensity;\nuniform float u_flareIntensity;\nuniform float u_rand;\nuniform vec2 u_invRes;\nuniform float u_rf0;\nuniform float u_rf1;\n\nconst float dt = 0.0002;\nfloat u_speedMin = 0.01;\n\n#define PI 3.14159265359\n#define TAU 6.28318530718\n\nvec3 getNormal( vec4 sdf ){\n float x = dot( vec2( 1.0, 0.0 ), sdf.yz );\n float y = dot( vec2( 0.0, 1.0 ), sdf.yz );\n float z = 1.0 - ( sdf.w - abs( sdf.x ) )/sdf.w;\n vec3 n = normalize( vec3( sqrt( abs( x ) ) * sign( x ) * ( 1.0 - z ), sqrt( abs( y ) ) * sign( y ) * ( 1.0 - z ), z ) );\n return n;\n}\n\n// Grab from https://www.shadertoy.com/view/4djSRW\n#define MOD3 vec3(.1031,.11369,.13787)\nfloat hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\nvec2 hash22(vec2 p) {\n\tvec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));\n p3 += dot(p3, p3.yzx+33.33);\n return fract((p3.xx+p3.yz)*p3.zy);\n}\n\nvec4 derivative( vec4 state, inout float density, inout float densityMult, inout vec4 sunData, in float speedMax ){\n vec2 uv = state.xy;\n\n vec4 dv = texture( u_dvmap, uv );\n density = dv.x;\n vec2 avgVelocity = dv.zw / max( density, 1.0 );\n\n float sunDist = sunData.x;\n vec2 sunGrad = normalize( sunData.yz );\n float sunGradMag = ( 1.0 / ( sunDist ) );\n\n vec4 forceData = texture( u_forceTex, uv );\n float forceDist = forceData.z;\n vec2 forceGrad = normalize( forceData.xy );\n float forceGradMag = ( 1.0 / ( forceDist ) );\n\n vec3 normal = getNormal( sunData );\n\n vec4 extras = a_extras;\n float agePer = extras.x/extras.y;\n float rf0 = extras.z;\n\n float dm = smoothstep( 100.0, 1200.0, u_sunRad ) * 0.2 + 0.05;\n float sv1 = sin( forceGrad.y * 15.7 * sin( forceGrad.x * ( ( mix( u_rf0, rf0, u_renderPer * u_renderPer ) + 0.2 ) * 25.0 ) ) );\n float sv2 = sin( forceGrad.y * ( u_rf1 + 0.5 ) * 3.3 );\n vec2 vel0 = forceGrad * forceGradMag * ( sv1 ) * u_intensity * u_sunRad;\n vec2 vel1 = sunGrad * sunGradMag * u_intensity * u_sunRad * 0.1;\n vec2 customVel = mix( vel0 + vel1 * 0.25, -vel1 * 0.15, agePer ) * u_flareIntensity;\n\n float attract = 0.06 * dm;\n float repel = 0.12 * dm;\n float align = 0.5 * dm;\n float leading = 0.5;\n densityMult = 0.1 * dm;\n\n vec2 xy = state.xy + leading * dt * state.zw;\n\n vec3 dvm = texture( u_dvmap, xy ).xzw;\n xy = state.xy + dt * 2.0 * leading * dvm.yz / dvm.x;\n\n float dE = texture( u_dvmap, state.xy + vec2( u_invRes.x, 0 ) ).x;\n float dW = texture( u_dvmap, state.xy + vec2( -u_invRes.x, 0 ) ).x;\n float dN = texture( u_dvmap, state.xy + vec2( 0, u_invRes.y ) ).x;\n float dS = texture( u_dvmap, state.xy + vec2( 0, -u_invRes.y ) ).x;\n vec2 densityGrad = vec2( dE - dW, dN - dS ) / u_invRes;\n\n vec4 avgPosValues = texture( u_particlemap, xy );\n float density1= texture( u_dvmap, xy ).x;\n\n vec2 avgPos = vec2(\n state.x < 0.5 ? avgPosValues.x : avgPosValues.z,\n state.y < 0.5 ? avgPosValues.y : avgPosValues.w\n ) / max( density1, 1e-8 );\n\n // The magic numbers!\n float repulsion = 1.4 * repel;\n float follow = 5000.0 * align;\n float cohesion = 1700000.0 * attract;\n float velEnforce = 100.0 * ( 1.5 - u_activity );\n\n float vmag = length( state.zw );\n \n vec2 randLoc = state.xy * 1. + u_rand * 100.0;\n vec2 rand = hash22(randLoc) - .5;\n\n vec2 v = customVel + 10000.0 * rand * ( 0.3 + u_haziness * 0.5 );\n return vec4( state.zw, v );\n}\n\nvoid main() {\n // get extras\n vec4 extras = a_extras;\n float age = extras.x;\n float life = extras.y;\n float rf0 = extras.z;\n\n float densityMult = 0.01;\n float density = 0.0;\n float speedMax = smoothstep( 50.0, 1000.0, u_sunRad ) * 15.0;\n vec4 state = vec4( a_position / u_res, a_velocity );\n \n vec4 sunData = texture( u_sunTex, state.xy );\n state += dt * derivative( state, density, densityMult, sunData, speedMax );\n vec2 uv = state.xy;\n vec2 pos = state.xy * u_res;\n vec2 vel = state.zw;\n\n // limit speed\n float speed = length( vel );\n float maxSpeed = speedMax * ( smoothstep( 100.0, 500.0, u_sunRad ) * 0.8 + 0.2 ) + rf0 * 10.0;\n if( speed > maxSpeed ){\n vel = normalize( vel ) * maxSpeed;\n } else if( speed < u_speedMin ){\n vel = normalize( vel ) * u_speedMin;\n }\n \n int oob = 0;\n float b = 0.0;\n if( pos.y < b || pos.y > u_res.y - b ) oob = 1;\n if( pos.x < b || pos.x > u_res.x - b ) oob = 1;\n if( age < 0.0 || age > life ) oob = 1;\n if( sunData.x < 0.0 ) oob = 1;\n\n if( oob == 1 ){\n float angle = hash12( pos * 0.01 ) * 0.5 + hash12( pos * 0.05 ) * 0.5 * TAU * 5.0;\n float radius = u_sunRad + u_sunRad * ( rf0 * 0.015 );\n vec2 dir = vec2( cos( angle ), sin( angle ) );\n vec2 newPos = u_sunPos + dir * radius;\n pos = newPos;\n vel = dir * 0.001;\n }\n\n v_position = pos;\n v_velocity = vel * 0.9975;\n\n if( u_frame < 5.0 ) {\n v_velocity = a_velocity;\n }\n \n vec2 position = a_position / u_res * 2.0 - 1.0;\n v_extras = a_extras;\n if( oob == 1 ){\n v_extras.x = 0.0;\n }\n v_extras.x += 0.0333;\n\n vec2 velDir = normalize( v_velocity.xy );\n float angle = atan( velDir.y, velDir.x );\n v_color = vec3( 1.0 );\n\n float fadeOut = u_renderPer;\n float ps = max( extras.w, 0.1 ) * u_flareIntensity * fadeOut;\n\n gl_PointSize = max( 1.0, ps );\n gl_Position = vec4( position, 0.0, 1.0 );\n}"),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec3 v_color;\nout vec4 color;\n\nuniform float u_renderPer;\n\nvoid main() {\n vec2 uv = gl_PointCoord.xy - .5;\n color = vec4( v_color, 1.0 );\n}"),attributes:{a_extras:{data:a,size:4}},transformFeedbacks:{a_position:{data:t,size:2,usage:e.STREAM_COPY,varying:"v_position"},a_velocity:{data:o,size:2,usage:e.STREAM_COPY,varying:"v_velocity"},a_extras:{data:a,size:4,usage:e.STREAM_COPY,varying:"v_extras"}},count:r,mode:e.POINTS}),Gn.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat,singular:!0})};let Hn=0;const Yn=(n,e)=>{Gn.renderer.bindVAOs(),Gn.renderer.bindTransformFeedbacks(),n.bindFramebuffer(n.FRAMEBUFFER,Gn.fb.read.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,vn.blurTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,bn.blurTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE3),n.bindTexture(n.TEXTURE_2D,zn.fb.read.targetTexture),Gn.renderer.bindUniform("u_particlemap",0),Gn.renderer.bindUniform("u_dvmap",1),Gn.renderer.bindUniform("u_sunTex",2),Gn.renderer.bindUniform("u_forceTex",3),Gn.renderer.bindUniform("u_frame",Hn++),Gn.renderer.bindUniform("u_renderPer",e),Gn.renderer.bindUniform("u_rand",Nn.random_dec()),Gn.renderer.bindUniform("u_invRes",[Vn,Vn]),Gn.renderer.bindUniform("u_res",[Gn.fb.width,Gn.fb.height]),Gn.renderer.bindUniform("u_sunPos",an.sunPos),Gn.renderer.bindUniform("u_sunRad",an.sunRad),Gn.renderer.bindUniform("u_haziness",an.cloudiness+an.cityHaze),Gn.renderer.bindUniform("u_activity",an.solarActivity),Gn.renderer.bindUniform("u_intensity",an.solarIntensity),Gn.renderer.bindUniform("u_flareIntensity",an.flareIntensity),Gn.renderer.bindUniform("u_rf0",an.rf0),Gn.renderer.bindUniform("u_rf1",an.rf1),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.MAX),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),Gn.renderer.render(Gn.fb.width,Gn.fb.height),n.disable(n.BLEND),Gn.fb.swap()};const Wn=c(),Kn=new Float32Array([-1,-1,3,-1,-1,3]),jn=new Float32Array([0,0,2,0,0,2]),Jn={},Qn=new Float32Array(4*(an.numStars*an.numStars)).fill(0);let Zn=an.height,$n=an.height;for(let n=0;n<an.numStars*an.numStars;n++){const e=4*n;let r=Wn.random_num(0,Zn),t=Wn.random_num(0,$n);an.environmentId>0&&(t=Wn.random_num(an.groundLevel*$n,$n)),Qn[e]=r,Qn[e+1]=t,Qn[e+2]=5*Math.pow(Wn.random_dec(),12)+.5,Qn[e+3]=0}const ne=e=>{Jn.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D u_starsTex;\nuniform int u_res;\nuniform float u_invRes;\n\nout vec4 color;\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b ){\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n float myRadius = 100000.0;\n\n\tfloat dres \t\t= u_invRes * 0.5;\n \tfor( int x=0; x<u_res; x++ ){\n\t\tfloat xp = float( x ) * u_invRes + dres;\n\t\tfor( int y=0; y<u_res; y++ ){\n\t\t\tfloat yp \t\t= float( y ) * u_invRes + dres;\n\n\t\t\tvec2 uv\t\t = vec2( xp, yp );\n\t\t\tvec4 data \t\t= texture( u_starsTex, uv, 0.0 );\n\t\t\tvec2 p \t\t = data.xy;\n\t\t\tfloat r\t\t = data.z; \n\t\t\t\n\t\t\tvec2 dir \t\t= gl_FragCoord.xy - p;\n\t\t\tvec3 sdg = sdgCircle( dir, r );\n float dist\t\t= length( dir );\n\n mySdg = sdgMin( sdg, mySdg );\n mySdg.yz = normalize( mySdg.yz );\n\n if( dist < r ){\n myRadius = r;\n }\n\t\t}\n\t}\n\n vec4 sdfData = vec4( mySdg, myRadius );\n\n color = sdfData;\n}"),attributes:{position:{data:Kn,size:2},uv:{data:jn,size:2}},count:3}),Jn.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat,tiling:e.REPEAT}),Jn.starsTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,Jn.starsTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,an.numStars,an.numStars,0,e.RGBA,e.FLOAT,Qn),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)},ee=n=>{Jn.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Jn.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Jn.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Jn.starsTexture),Jn.renderer.bindUniform("u_framebuffer",0),Jn.renderer.bindUniform("u_starsTex",1),Jn.renderer.bindUniform("u_res",an.numStars),Jn.renderer.bindUniform("u_invRes",1/parseFloat(an.numStars)),Jn.renderer.render(Jn.fb.width,Jn.fb.height),Jn.fb.swap()};const re=new Float32Array([-1,-1,3,-1,-1,3]),te=new Float32Array([0,0,2,0,0,2]),oe={},ae=e=>{oe.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_res;\nuniform sampler2D u_stars;\n\nuniform float u_cityHaze;\nuniform float u_rf0;\nuniform float u_rf1;\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n vec4 data = texture( u_stars, uv );\n float sd = data.x;\n float sr = data.w;\n color.xyz = vec3( ( 1.0 - uv.y ) * u_cityHaze * 0.2 );\n color.xyz += vec3( smoothstep( 0.0, -sr, sd ) * 0.3 );\n}\n"),attributes:{position:{data:re,size:2},uv:{data:te,size:2}},count:3}),oe.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat})},ie=n=>{oe.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,oe.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,oe.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Jn.fb.read.targetTexture),oe.renderer.bindUniform("u_framebuffer",0),oe.renderer.bindUniform("u_stars",1),oe.renderer.bindUniform("u_res",[an.height,an.height]),oe.renderer.bindUniform("u_cityHaze",an.cityHaze),oe.renderer.bindUniform("u_rf0",an.rf0),oe.renderer.bindUniform("u_rf1",an.rf1),oe.renderer.render(oe.fb.width,oe.fb.height),oe.fb.swap()};const se=c(),de=new Float32Array([-1,-1,3,-1,-1,3]),ue=new Float32Array([0,0,2,0,0,2]);let fe=an.numPlanets,ce=an.eventId,le=an.compId,me=an.sunPos[0],ve=an.sunPos[1],_e=an.sunRad,pe=an.sunSign,be=an.height,ge="const vec3 planets["+fe+"] = vec3["+fe+"](";const xe={},he=e=>{for(let n=0;n<fe;n++){let e=be/2+.01,r=be/2,t=100*Math.pow(se.random_dec(),4)+5;if(0==ce)r=-1e4;else if(1==ce)0==n?(r=ve,t=1.02*_e):(r=ve+se.random_num(1*_e,8*_e)*Math.sign(se.random_dec()-.5),t=_e*(.1*Math.pow(se.random_dec(),6)+.05));else if(2==ce)if(7==le)t=se.random_num(200,300);else if(0==n){let n=se.random_num(.3*_e,.5*_e)*Math.sign(se.random_dec()-.5)*2;r=ve+n,t=_e}else r=ve+se.random_num(_e,5*_e)*Math.sign(se.random_dec()-.5),t=_e*se.random_num(.03,.1);else 3==ce?0==n?(r=ve,t=_e*se.random_num(.5,.8)):(r=ve+se.random_num(_e,5*_e)*Math.sign(se.random_dec()-.5),t=_e*se.random_num(.03,.1)):4==ce?(t=_e*(.25*Math.pow(se.random_dec(),6)+.005)*3,0==n?se.random_bool(.5)?(t=se.random_num(.05*_e,.2*_e),r=ve+(_e-t)*Math.sign(se.random_dec()-.5)):(t=se.random_num(.025*_e,.2*_e),r=ve+(_e+t+se.random_num(-100,100))*Math.sign(se.random_dec()-.5)):r=ve+se.random_num(1*_e,8*_e)*Math.sign(se.random_dec()-.5)):5==ce&&(4==le?(r=ve-se.random_num(.3*_e,3*_e)*pe,t=se.random_num(5,20)):5==le?(e=me-se.random_num(.5*_e,2*_e)*pe,t=se.random_num(2,10)):6==le?(r=ve+se.random_num(.5*-_e,.5*_e),t=_e*(.1*Math.pow(se.random_dec(),6)+.01)):(r=ve+se.random_num(1*_e,16*_e)*Math.sign(se.random_dec()-.5),n>0&&(t=_e*(.1*Math.pow(se.random_dec(),6)+.05))));ce>0&&((r<.1*be||r>.9*be)&&(r=se.random_num(.2*be,.8*be)),(e<.2*be||e>.8*be)&&(e=se.random_num(.3*be,.7*be))),ge+="vec3("+e+","+r+","+t+")",ge+=n<fe-1?", ":");"}xe.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform int u_numPlanets;\n\nout vec4 color;\n\n#define PI 3.14159265359\n#define TAU 6.28318530718\n\n%%planets%%\n\nvec3 sdgCircle( in vec2 p, in float r ) \n{\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b )\n{\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n \tfloat myDist \t= 100000.0;\n vec2 myGrad = vec2( 0.0, 0.0 );\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n float myRadius = 1.0;\n\n for( int i=0; i<u_numPlanets; i++ ){\n vec3 planet = planets[i];\n vec2 p = planet.xy;\n float r = planet.z;\n vec2 dir = gl_FragCoord.xy - p;\n vec3 sdg = sdgCircle( dir, r );\n float dist = length( dir );\n mySdg = sdgMin( sdg, mySdg );\n\n if( dist < r ){\n myRadius = r;\n }\n }\n\n vec4 sdfData = vec4( mySdg.x, mySdg.yz, myRadius );\n\n color = sdfData;\n}").replace("%%planets%%",ge),attributes:{position:{data:de,size:2},uv:{data:ue,size:2}},count:3}),xe.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat})},ye=n=>{xe.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,xe.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,xe.fb.read.targetTexture),xe.renderer.bindUniform("u_framebuffer",0),xe.renderer.bindUniform("u_numPlanets",fe),xe.renderer.bindUniform("u_numBeads",55),xe.renderer.bindUniform("u_res",[xe.fb.width,xe.fb.height]),xe.renderer.render(xe.fb.width,xe.fb.height),xe.fb.swap()};const Te=c(),Ee=new Float32Array([-1,-1,3,-1,-1,3]),Re=new Float32Array([0,0,2,0,0,2]);let Ue=an.sunPos[0],Fe=an.sunPos[1],we=an.sunRad,ze=parseInt(we/2);0==an.bailyBeads&&(ze=1);let Ae="const vec3 beads["+ze+"] = vec3["+ze+"](";const Pe={},Se=e=>{let r=Te.random_num(0,6.283),t=5*Math.pow(Te.random_dec(),2)+1.5;for(let n=0;n<ze;n++){let e=(1-Math.pow(Te.random_dec(),.5))*Math.sign(Te.random_dec()-.5)*t,o=Math.sin(r+e)*we*1.02,a=Math.cos(r+e)*we*1.02,i=Ue+a,s=Fe+o,d=we*(.02*Math.pow(Te.random_dec(),3)+.002);Ae+="vec3("+i+","+s+","+d+")",Ae+=n<ze-1?", ":");"}Pe.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform int u_numBeads;\n\nout vec4 color;\n\n%%beads%%\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b ){\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n \tfloat myDist = 100000.0;\n vec2 myGrad = vec2( 0.0, 0.0 );\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n float myRadius = 1.0;\n\n for( int i=0; i<u_numBeads; i++ ){\n vec3 bead = beads[i];\n vec2 p = bead.xy;\n float r = bead.z;\n vec2 dir = gl_FragCoord.xy - p;\n vec3 sdg = sdgCircle( dir, r );\n float dist = length( dir );\n mySdg = sdgMin( sdg, mySdg );\n\n if( dist < r ){\n myRadius = r;\n }\n }\n\n vec4 sdfData = vec4( mySdg.x, mySdg.yz, myRadius );\n\n color = sdfData;\n}").replace("%%beads%%",Ae),attributes:{position:{data:Ee,size:2},uv:{data:Re,size:2}},count:3}),Pe.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat})},De=n=>{Pe.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Pe.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Pe.fb.read.targetTexture),Pe.renderer.bindUniform("u_framebuffer",0),Pe.renderer.bindUniform("u_numBeads",ze),Pe.renderer.bindUniform("u_res",[Pe.fb.width,Pe.fb.height]),Pe.renderer.render(Pe.fb.width,Pe.fb.height),Pe.fb.swap()},Ie=new Float32Array([-1,-1,3,-1,-1,3]),Me=new Float32Array([0,0,2,0,0,2]),Ce={};let Be=Math.min(Math.max(an.sunRad-50,0)/1100,1);const Le=e=>{Ce.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_res;\nuniform float u_renderPer;\n\nuniform sampler2D u_pointCloud;\nuniform sampler2D u_sunTex;\nuniform sampler2D u_planetsTex;\nuniform sampler2D u_beadsTex;\nuniform sampler2D u_sky;\nuniform sampler2D u_noiseClouds;\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\nuniform float u_sunRadPer;\nuniform int u_bailyBeads;\nuniform float u_cityHaze;\nuniform float u_cloudiness;\nuniform float u_flareIntensity;\nuniform int u_environmentId;\nuniform float u_groundLevel;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform float u_atmos;\nuniform vec3 u_multi;\n\n#define PI 3.14159265\n#define TAU 6.28318530718\n\nvec3 getNormal( vec4 sdf ){\n float x = dot( vec2( 1.0, 0.0 ), sdf.yz );\n float y = dot( vec2( 0.0, 1.0 ), sdf.yz );\n float z = 1.0 - ( sdf.w - abs( sdf.x ) )/sdf.w;\n vec3 n = normalize( vec3( x * ( 1.0 - z ), y * ( 1.0 - z ), z ) );\n return n;\n}\n\nfloat linear( in float minVal, in float maxVal, in float val ){\n float v = clamp( ( val - minVal ) / ( maxVal - minVal ), 0.0, 1.0 );\n return v;\n}\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n\n float haze = u_cityHaze;\n float cloudy = u_cloudiness * 0.5;\n\n vec4 sunData = texture( u_sunTex, uv );\n float sd = sunData.x;\n float surf = sunData.w;\n float sr = u_sunRad;\n float sunRadPer = u_sunRadPer; // small sun = 0.0, huge sun = 1.0;\n float sunSide = smoothstep( -0.001, 0.001, sd );\n\n // GET SKY\n float skyTex = texture( u_sky, uv ).x;\n\n // GET PLANETS TEX\n vec4 planets = texture( u_planetsTex, uv );\n float planetDist = planets.x;\n float planetRad = planets.w;\n vec3 planetN = getNormal( planets );\n float planetRadPer = smoothstep( 5.0, 800.0, planetRad ) * 0.8 + 0.2;\n\n // GET NOISE CLOUDS\n vec4 clouds = texture( u_noiseClouds, uv );\n float cn0 = clouds.x;\n float cn1 = clouds.y;\n float cn2 = clouds.z;\n float cn3 = clouds.w; \n\n // set initial color\n float cd = skyTex * smoothstep( 0.0, 1.0, sd );\n cd -= clouds.x * u_cloudiness * 0.2;\n \n // SUN PARTICLES\n float particles = min( texture( u_pointCloud, uv ).x, 1.0 );\n cd += particles * 0.5 + pow( particles, 10.0 ) * cn1 * sunRadPer * 2.0;\n cd = clamp( cd, 0.0, 1.0 );\n\n // SUN SURFACE\n float sdPer = 1.0 - ( -sd / sr );\n float sun = surf;\n sun += pow( sdPer, 2.0 ) * 0.125;\n sun += pow( sdPer, 15.0 ) * 0.35 * sunRadPer; // brighten sun edge at high radii\n sun += u_cloudiness * 0.25 + u_flareIntensity * 0.05;\n sun = mix( sun, cd, sunSide );\n\n // SUN CORONA\n float cg0 = linear( sr * 5.0, -sr * 0.5, sd );\n float cg1 = linear( sr * 0.5, -sr * 0.5, sd );\n float cg2 = linear( max( cn1, cn2 ) * sr * 0.07, 0.0, sd );\n float ss0 = 1.0 - linear( 0.0, sr * 18.0, sd );\n float ss1 = 1.0 - linear( 0.0, sr * 5.0, sd );\n float ss2 = 1.0 - linear( 0.0, sr * 0.4, sd );\n float ss3 = 1.0 - linear( 0.0, sr * 0.1, sd );\n float corona = ss0 * ss0 * 0.35 + 0.1;\n corona += ss1 * ss1 * 0.15;\n corona += ss2 * ss2 * 0.15;\n corona += ss3 * ss3 * 0.15;\n corona += pow( ss3 * ss3 * cn1 * cn2 * 2.0, 2.0 );\n corona += cg2 * ( 1.0 - sunRadPer ) * 0.25;\n corona += smoothstep( cn3 * cn2 * sr * 0.1, -sr * 0.025, sd ) * sunRadPer * 0.2;\n\n // RENDER SUN AND CORONA\n cd += sun * u_multi.y * ( 1.0 - sunSide ) + corona * u_multi.z * sunSide;\n\n \n // Baily's Beads\n float beadsCd = 0.0;\n if( u_bailyBeads == 1 ){\n vec4 beads = texture( u_beadsTex, uv );\n float beadDist = beads.x;\n float beadRad = beads.w;\n beadsCd = pow( smoothstep( beadRad * 6.0, -beadRad, beadDist ), 15.0 ) * 2.0;\n cd += beadsCd;\n }\n \n // render planets\n {\n float distPer = smoothstep( sr * -0.15, sr * 0.15, sd );\n vec2 dirToSun = u_sunPos - frag;\n float distToSun = length( vec2( dirToSun ) );\n float planetPer = smoothstep( 800.0, 50.0, planetDist ) * 0.25 * ( 1.0 - planetRadPer ) + 0.1;\n float rimGlow = smoothstep( sr * 20.0, 0.0, distToSun + sr );\n float planetEdge = smoothstep( 1.0, -4.0, planetDist );\n float pc = smoothstep( -planetRad, planetRad * 0.05, planetDist );\n float pb = pow( pc, 2.0 ) * 0.2;\n pb += pow( pc, 4.0 ) * 0.2;\n pb += pow( pc, 11.0 ) * 0.3;\n
function n(n){return n&&n.__esModule?n.default:n}const e=(n,e,r)=>{const t=n.createShader(r);if(n.shaderSource(t,e),n.compileShader(t),!n.getShaderParameter(t,n.COMPILE_STATUS)){const e=n.getShaderInfoLog(t);throw new Error(e)}return t},r=(n,r,t,o)=>{const a=e(n,r,n.VERTEX_SHADER),i=e(n,t,n.FRAGMENT_SHADER),s=n.createProgram();if(n.attachShader(s,a),n.attachShader(s,i),o){const e=[];for(let n in o)e.push(o[n].varying);n.transformFeedbackVaryings(s,e,n.SEPARATE_ATTRIBS)}if(n.linkProgram(s),!n.getProgramParameter(s,n.LINK_STATUS)){const e=n.getProgramInfoLog(s);throw new Error(e)}return s},t=(n,e)=>{const r=n.getProgramParameter(e,n.ACTIVE_UNIFORMS),t={};for(let o=0;o<r;o++){const{name:r,type:a}=n.getActiveUniform(e,o);t[r]={location:n.getUniformLocation(e,r),type:a}}return t},o=(n,e,r=n.STATIC_DRAW,t=n.ARRAY_BUFFER)=>{const o=n.createBuffer();return n.bindBuffer(t,o),n.bufferData(t,e,r),o},a=(n,e,r)=>{if(!r)return null;const t=n.createVertexArray(),a=Object.keys(r);n.bindVertexArray(t);for(let t=0;t<a.length;t++){let{size:i=1,type:s=n.FLOAT,normalize:d=!1,stride:u=0,offset:f=0,buffer:c,data:l,usage:m=n.STATIC_DRAW,buffertype:v=n.ARRAY_BUFFER}=r[a[t]];l&&!c&&(c=o(n,l,m,v)),n.bindAttribLocation(e,t,a[t]),n.enableVertexAttribArray(t),n.bindBuffer(n.ARRAY_BUFFER,c),n.vertexAttribPointer(t,i,s,d,u,f)}return t},i=(n,e,r)=>{if(!r)return null;const t=[n.createVertexArray(),n.createVertexArray()],a=[n.createTransformFeedback(),n.createTransformFeedback()],i=[],s=Object.keys(r);return t.forEach(((t,d)=>{n.bindVertexArray(t);const u=[],f={};for(let t=0;t<s.length;t++){let{size:a=1,type:i=n.FLOAT,normalize:d=!1,stride:c=0,offset:l=0,buffer:m,data:v,usage:_=n.STATIC_DRAW,buffertype:p=n.ARRAY_BUFFER}=r[s[t]];v&&!m&&(m=o(n,v,_,p)),f[s[t]]={i:t,buffer:m},n.bindAttribLocation(e,t,s[t]),n.enableVertexAttribArray(t),n.bindBuffer(n.ARRAY_BUFFER,m),n.vertexAttribPointer(t,a,i,d,c,l),u.push(m)}n.bindBuffer(n.ARRAY_BUFFER,null),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,a[d]),u.forEach(((e,r)=>{n.bindBufferBase(n.TRANSFORM_FEEDBACK_BUFFER,r,e)})),n.bindVertexArray(null),i.push(f)})),{vaos:t,tfbs:a,tfbBuffers:i}},s=(n,{vert:e,frag:o,attributes:s,transformFeedbacks:d,count:u,offset:f=0,mode:c=n.TRIANGLES}={})=>{const l=r(n,e,o,d),m=t(n,l),v=a(n,l,s),_=i(n,l,d);let p=0;return{uniforms:m,bindUniform(e,r){if(void 0===r)return;if(!m[e])return;const{type:t,location:o}=m[e];switch(t){case 5126:return r instanceof Array?n.uniform1fv(o,r):("number"==typeof r&&n.uniform1f(o,r),null);case 35664:return n.uniform2fv(o,r);case 35665:return n.uniform3fv(o,r);case 35666:return n.uniform4fv(o,r);case 35670:case 5124:case 35678:case 35680:return r.length?n.uniform1iv(o,r):n.uniform1i(o,r);case 35671:case 35667:return n.uniform2iv(o,r);case 35672:case 35668:return n.uniform3iv(o,r);case 35673:case 35669:return n.uniform4iv(o,r);case 35674:return n.uniformMatrix2fv(o,!1,r);case 35675:return n.uniformMatrix3fv(o,!1,r);case 35676:if(null===r)return;return n.uniformMatrix4fv(o,!1,r)}},bindVAOs(){n.useProgram(l),v&&n.bindVertexArray(v)},bindTransformFeedbacks(){if(!_)return;const e=(p+1)%2,r=_.vaos[p],t=_.tfbs[e],o=_.tfbBuffers[e];this.readTFB=r,this.writeTFB=_.vaos[e],n.bindVertexArray(r),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,t);for(let e in o){const r=o[e];n.bindBufferBase(n.TRANSFORM_FEEDBACK_BUFFER,r.i,r.buffer)}p=e},render(e,r){n.viewport(0,0,e||n.canvas.width,r||n.canvas.height),_&&n.beginTransformFeedback(c),n.drawArrays(c,f,u),_&&n.endTransformFeedback()}}},d=(n,{width:e,height:r,tiling:t=n.CLAMP_TO_EDGE,type:o=n.UNSIGNED_BYTE,format:a=n.RGBA,internalFormat:i=n.RGBA,data:s=null,singular:d=!1,minFilter:u=n.LINEAR,magFilter:f=u,mips:c=!1}={})=>{const l=({w:d=e,h:l=r}={})=>{const m=n.createTexture();n.bindTexture(n.TEXTURE_2D,m),n.texImage2D(n.TEXTURE_2D,0,i,d,l,0,a,o,s),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,u),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,f),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,t),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,t);const v=n.createFramebuffer();return n.bindFramebuffer(n.FRAMEBUFFER,v),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,m,0),c&&n.generateMipmap(n.TEXTURE_2D),{fb:v,targetTexture:m}};return{width:e,height:r,read:l({w:e,h:r}),write:d?null:l({w:e,h:r}),resize(n,e){this.width=n,this.height=e,this.read=l({w:n,h:e}),this.write=l({w:n,h:e})},swap(){if(d)return;const n=this.read;this.read=this.write,this.write=n}}};class u{constructor(n){this.useA=!1;let e=function(n){let e=parseInt(n.substr(0,8),16),r=parseInt(n.substr(8,8),16),t=parseInt(n.substr(16,8),16),o=parseInt(n.substr(24,8),16);return function(){e|=0,r|=0,t|=0,o|=0;let n=(e+r|0)+o|0;return o=o+1|0,e=r^r>>>9,r=t+(t<<3)|0,t=t<<21|t>>>11,t=t+n|0,(n>>>0)/4294967296}};this.prngA=new e(n.hash.substr(2,32)),this.prngB=new e(n.hash.substr(34,32));for(let n=0;n<1e6;n+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(n,e){return n+(e-n)*this.random_dec()}random_int(n,e){return Math.floor(this.random_num(n,e+1))}random_bool(n){return this.random_dec()<n}random_choice(n){return n[this.random_int(0,n.length-1)]}}let f;function c(n){return n||(n=tokenData),f instanceof u||(f=new u(n)),f}const l=c();let m=parseInt(1836),v=parseInt(2400),_=[l.random_num(-500,500),l.random_num(-500,500)],p=0,b=l.random_dec();p=b<.9?0:b<.97?1:2;let g=0,x=l.random_dec();g=x<.05?0:x<.35?1:x<.55?2:x<.62?3:x<.9?4:5;let h=0,y=l.random_dec();h=y<.2?0:y<.4?1:y<.6?2:y<.8?3:y<.9?4:y<.92?5:y<.98?6:7,p>0&&(h=l.random_int(0,3)),4==h?g=l.random_int(4,5):5==h?g=5:6==h&&(g=l.random_int(3,5));let T=v/2,E=v/2,R=50,U=Math.sign(l.random_dec()-.5),F=Math.sqrt(l.random_num(.85,1.5));0==g&&(F=2);let w=7e3*F+8e3,z=1;if(0==h)R=l.random_num(100,150);else if(1==h)R=l.random_num(250,450);else if(2==h)R=l.random_num(100,150),E+=l.random_num(200,400);else if(3==h)R=l.random_num(250,450),E+=l.random_num(200,400);else if(4==h)R=l.random_num(1200,1800),E+=l.random_num(1250,1500)*U;else if(5==h)R=l.random_num(2500,4400),T+=l.random_num(.99*R,1.1*R)*U;else if(6==h)R=l.random_num(600,1e3);else if(7==h){R=4e3;let n=l.random_num(0,6.28318),e=l.random_num(.95*R,1.05*R);T+=Math.cos(n)*e,E+=Math.sin(n)*e,g=2}let A=[T,E];p>0&&(R=l.random_num(70,100));0==g&&(z=3.5);let P=parseInt(R/12),S=8*P,D=parseInt(l.random_int(P+15*F,S+50*F)/5+5);4!=h&&5!=h||(D=l.random_int(50,80)),7==h&&(D=200);let I=parseInt(R/20*F)+2,M=parseInt(R/10*F)+4,C=Math.min(40,l.random_int(I,M)),B=[1,1,1,2,5,6],L=l.random_int(1,B[g]);5==g&&(L=l.random_int(2,B[g]));let O=1==g?1:0,X=0;7==h&&(X=1),6==h&&(X=.5);let k=0,N=l.random_dec();k=N<.5?0:N<.85?1:2;let G=l.random_num(.005,.015),V=.2*Math.pow(l.random_dec(),3)+.05,q=l.random_num(.15,.25),H=.3*Math.pow(l.random_dec(),3)+.025,Y=.5*Math.pow(l.random_dec(),2),W=Math.pow(2,l.random_int(2,4));W=parseInt(W*(1-Y)*(1-H));let K=l.random_int(1840,1890),j=.3*Math.pow(1-(parseFloat(K)-1840)/50,5),J=0,Q=l.random_dec();J=Q<.18?0:Q<.36?1:Q<.48?2:Q<.6?3:Q<.68?4:Q<.78?5:Q<.93?6:Q<.96?7:8,J>=7&&(k=0),0==h||2==h?8==J&&(J=l.random_int(0,7)):7==h&&(J=l.random_int(4,6)),p>0&&(J=l.random_int(0,5));let Z=l.random_num(.8,1.1);5==h&&(Z=Math.min(Z,.95)),h>=4&&(Z=Math.max(Z,1));let $=parseInt(150*Z),nn=[.2,.8,.2,.8,1.5,1.5,1.25,1.25];1==g&&(nn=[1.2,1.2,1.2,1.2,1.5,1.5,1,1.25]);let en=nn[h],rn=[1.4,1.2,1.4,1.2,.92,.92,1.1,.9][h],tn=[.9,1,.8,1,1,1,1,1][h],on=["Solar Flare","Total Eclipse","Partial Eclipse","Annular Eclipse","Transit","Alignment"][g];7==h&&(on="Transit");const an={width:m,height:v,nOff:_,mapSize:1024,mapScale:32,numParticles:3e5,compId:h,eventId:g,sunPos:A,sunRad:R,sunSign:U,solarActivity:F,solarIntensity:w,flareIntensity:z,atmos:X,numForces:D,numSpots:C,numStars:W,numPlanets:L,bailyBeads:O,borderId:k,borderWidth:G,borderCornerRad:V,damage:j,cityHaze:H,cloudiness:Y,environmentId:p,groundLevel:q,exposure:Z,exposureFrames:$,tintId:J,rf0:l.random_dec(),rf1:l.random_dec(),coronaMulti:en,surfaceMulti:rn,coronaGlowMulti:tn};var sn;sn="#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 position;\nin vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = uv;\n gl_Position = vec4( position * 2.0 - 1.0, 0, 1 );\n}";const dn=new Float32Array([-1,-1,3,-1,-1,3]),un=new Float32Array([0,0,2,0,0,2]),fn=1/an.mapSize,cn=e=>{const r={};return r.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_inverseResolution;\nuniform vec2 u_direction;\nuniform vec2 u_resolution;\nuniform sampler2D u_buffer;\n\nvec4 blur(sampler2D image, vec2 uv, vec2 inverseResolution, vec2 direction) {\n vec4 color = vec4(0.0);\n vec2 off1 = vec2(1.411764705882353) * direction;\n vec2 off2 = vec2(3.2941176470588234) * direction;\n vec2 off3 = vec2(5.176470588235294) * direction;\n color += texture(image, uv) * 0.1964825501511404;\n color += texture(image, uv + (off1 * inverseResolution)) * 0.2969069646728344;\n color += texture(image, uv - (off1 * inverseResolution)) * 0.2969069646728344;\n color += texture(image, uv + (off2 * inverseResolution)) * 0.09447039785044732;\n color += texture(image, uv - (off2 * inverseResolution)) * 0.09447039785044732;\n color += texture(image, uv + (off3 * inverseResolution)) * 0.010381362401148057;\n color += texture(image, uv - (off3 * inverseResolution)) * 0.010381362401148057;\n return color;\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution;\n color = blur(u_buffer, uv, u_inverseResolution, u_direction);\n}"),attributes:{position:{data:dn,size:2},uv:{data:un,size:2}},count:3}),r.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:an.fbType,internalFormat:an.fbFormat}),r},ln=(n,e,r,t,o,a)=>{e.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,e.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,r),e.renderer.bindUniform("u_buffer",0),e.renderer.bindUniform("u_direction",t),e.renderer.bindUniform("u_inverseResolution",[fn,fn]),e.renderer.bindUniform("u_resolution",[o,a]),e.renderer.render(o,a),e.fb.swap()},mn=(n,e,r,t,o)=>(ln(n,r,e,[1,0],t,o),ln(n,r,r.fb.read.targetTexture,[0,1],t,o),r.fb.read.targetTexture),vn={},_n=e=>{const r=an.numParticles;vn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nin vec2 a_position;\nin vec2 a_velocity;\n\nuniform vec2 u_screensize;\n\nout vec2 state;\n\nvoid main() {\n gl_PointSize = 1.;\n state = a_position / u_screensize;\n gl_Position = vec4( state * 2. - 1., 0., 1.);\n}"),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nin vec2 state;\n\nuniform float u_scale;\n\nout vec4 color;\n\nvoid main() {\n color = vec4( fract( state + 0.25 ) - 0.25, fract( state - 0.25 ) + 0.25 ) * u_scale;\n}"),count:r,mode:e.POINTS}),vn.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:an.fbType,internalFormat:an.fbFormat,singular:!0}),vn.blur=cn(e)};const pn=n=>{vn.renderer.bindVAOs(),n.bindVertexArray(Gn.renderer.readTFB),n.bindFramebuffer(n.FRAMEBUFFER,vn.fb.read.fb),vn.renderer.bindUniform("u_screensize",[an.height,an.height]),vn.renderer.bindUniform("u_scale",an.mapScale),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),vn.renderer.render(an.mapSize,an.mapSize),n.disable(n.BLEND),vn.fb.swap(),vn.blurTexture=mn(n,vn.fb.read.targetTexture,vn.blur,an.mapSize,an.mapSize)};const bn={},gn=e=>{const r=an.numParticles;bn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nlayout(location=0) in vec2 a_position;\nlayout(location=1) in vec2 a_velocity;\n\nuniform vec2 u_screensize;\n\nout vec2 state;\nout vec2 statedv;\n\nvoid main() {\n gl_PointSize = 1.;\n state = a_position / u_screensize;\n statedv = a_velocity;\n gl_Position = vec4( a_position / u_screensize * 2. - 1., 0., 1. );\n}"),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nin vec2 state;\nin vec2 statedv;\n\nuniform float u_scale;\n\nout vec4 color;\n\nvoid main() {\n color = vec4(1, 0, clamp(statedv, -1e4, 1e4)) * u_scale;\n}"),count:r,mode:e.POINTS}),bn.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:an.fbType,internalFormat:an.fbFormat,singular:!0}),bn.blur=cn(e)};const xn=n=>{bn.renderer.bindVAOs(),n.bindVertexArray(Gn.renderer.readTFB),n.bindFramebuffer(n.FRAMEBUFFER,bn.fb.read.fb),bn.renderer.bindUniform("u_screensize",[an.height,an.height]),bn.renderer.bindUniform("u_scale",an.mapScale),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),bn.renderer.render(an.mapSize,an.mapSize),n.disable(n.BLEND),bn.fb.swap(),bn.blurTexture=mn(n,bn.fb.read.targetTexture,bn.blur,an.mapSize,an.mapSize)};const hn=c(),yn=new Float32Array([-1,-1,3,-1,-1,3]),Tn=new Float32Array([0,0,2,0,0,2]);let En=an.numSpots,Rn=an.sunPos[0],Un=an.sunPos[1],Fn=an.sunRad,wn="const vec4 spots["+En+"] = vec4["+En+"](";const zn={},An=e=>{let r,t;for(let n=0;n<En;n++){let e=Un+1*hn.random_num(-Fn,Fn),o=hn.random_num(.05,.8)*Fn;hn.random_bool(.5)&&(o=-o);let a=Rn+o,i=Math.pow(hn.random_dec(),3)*Fn*.7+6,s=hn.random_num(-4,4);n%2==1&&(e=t+hn.random_num(-50,50),a=r+hn.random_num(-20,20)),r=a,t=e,wn+="vec4("+a+","+e+","+i+","+s+")",wn+=n<En-1?", ":");"}zn.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\nprecision highp int;\n#define GLSLIFY 1\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\nuniform int u_numForces;\nuniform int u_numSpots;\n\nuniform vec2 u_res;\nuniform int u_eventId;\nuniform vec2 u_nOff;\n\nout vec4 color;\n\n#define PI 3.1415926\n#define TAU 6.2831853\n\n%%sunspots%%\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nfloat smin( float a, float b, float k ){\n float res = exp2( -k*a ) + exp2( -k*b );\n return -log2( res )/k;\n}\n\nvec3 sdgSmoothMin( in vec3 a, in vec3 b, in float k ){\n float h = max(k-abs(a.x-b.x),0.0);\n float m = 0.25*h*h/k;\n float n = 0.50* h/k;\n return vec3( min(a.x, b.x) - m, \n mix(a.yz, b.yz, (a.x<b.x)?n:1.0-n) );\n}\n\nfloat getHaversine( vec2 p0, vec2 p1 ){\n vec2 c = u_sunPos;\n float sr = u_sunRad;\n float d0 = distance( c, p0 );\n float d1 = distance( c, p1 );\n float r0 = clamp( d0/sr, 0.0, 1.0 );\n float r1 = clamp( d1/sr, 0.0, 1.0 );\n\n r0 = pow( 1.0 - r0, 0.25 ) * sr * 2.0;\n r1 = pow( 1.0 - r1, 0.25 ) * sr * 2.0;\n\n vec3 ps0 = vec3( p0, r0 );\n vec3 ps1 = vec3( p1, r1 );\n\n float hd = distance( ps0, ps1 );\n return hd;\n}\n\n// Hash without Sine\n// MIT License...\n// Copyright (c)2014 David Hoskins.\n\n#define OCTAVES 8\n#define UI0 1597334673U\n#define UI1 3812015801U\n#define UI2 uvec2(UI0, UI1)\n#define UIF (1.0 / float(0xffffffffU))\nfloat hash12(vec2 p){\n\tuvec2 q = uvec2(ivec2(p)) * UI2;\n\tuint n = (q.x ^ q.y) * UI0;\n\treturn float(n) * UIF;\n}\n\n/*float hash12( vec2 p ){\n\tvec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}*/\n\nvec4 getForceData( vec2 p, float sr ){\n vec2 c = u_sunPos;\n float t = hash12( p ) * TAU;\n float r = sr - hash12( p + u_nOff ) * sr * 0.05;\n float x = c.x + cos( t ) * r;\n float y = c.y + sin( t ) * r;\n float f = hash12( p * vec2( 155.0 ) + u_nOff ) - 0.5;\n\n return vec4( x, y, hash12( p + vec2( 2.3, 5.6 ) ), f );\n}\n\nvoid main() {\n vec2 dirToSun = u_sunPos - gl_FragCoord.xy;\n vec3 sunSdg = sdgCircle( dirToSun, u_sunRad );\n float sunDist = sunSdg.x;\n\n float myDist = 1000000.0;\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n\tvec2 myVel = vec2( 0.0, 0.0 );\n\tfloat myF = 0.0;\n float myR = 0.0;\n\tvec2 p0 = gl_FragCoord.xy;\n\n if( sunDist > 0.0 ){\n for( int i=0; i<u_numForces; i++ ){\n float u = hash12( vec2( float( i ) * 3.3 + 11.4, 0.5 ) );\n float v = hash12( vec2( float( i ) * 5.5 + 17.5, 0.5 ) );\n vec4 forceData = getForceData( vec2( u, v ) * 100.0, u_sunRad );\n vec2 p1 = forceData.xy;\n float r = forceData.z;\n float f = forceData.w;\n\n vec2 dir \t\t= p0 - p1;\n float dist \t\t= length( dir );\n vec2 dirNorm = normalize( dir );\n float distSq = dist * dist;\n float invDistSq = 1.0 / ( distSq + r );\n\n myVel += dirNorm * invDistSq * 5000.0 * f;\n\n if( dist < myDist ){\n myDist = dist;\n myF = f;\n }\n }\n } else {\n for( int i=0; i<u_numSpots; i++ ){\n vec4 spot = spots[i];\n vec2 p1 = spot.xy;\n float r = spot.z;\n float f = spot.w;\n\n vec2 dir \t\t= p0 - p1;\n float dist = getHaversine( p0, p1 );\n vec3 sdg = sdgCircle( dir, r );\n vec2 dirNorm = normalize( dir );\n float distSq = dist * dist;\n float invDistSq = 1.0 / ( distSq + r );\n sdg.x = dist;\n mySdg = sdgSmoothMin( sdg, mySdg, u_sunRad * 0.05 );\n myF = smin( myF, f, 35.0 ) * sign( f );\n myR = smin( myR, r, 35.0 );\n myVel += dirNorm * invDistSq * 500.0 * f;\n }\n myDist = mySdg.x;\n }\n \n \tcolor = vec4( myVel.x, myVel.y, myDist, myF );\n}").replace("%%sunspots%%",wn),attributes:{position:{data:yn,size:2},uv:{data:Tn,size:2}},count:3}),zn.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat,tiling:e.REPEAT})},Pn=n=>{zn.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,zn.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,zn.fb.read.targetTexture),zn.renderer.bindUniform("u_framebuffer",0),zn.renderer.bindUniform("u_sunPos",an.sunPos),zn.renderer.bindUniform("u_sunRad",an.sunRad),zn.renderer.bindUniform("u_numForces",an.numForces),zn.renderer.bindUniform("u_numSpots",an.numSpots),zn.renderer.bindUniform("u_res",[zn.fb.width,zn.fb.height]),zn.renderer.bindUniform("u_eventId",an.eventId),zn.renderer.bindUniform("u_nOff",an.nOff),zn.renderer.render(zn.fb.width,zn.fb.height),zn.fb.swap()};const Sn=new Float32Array([-1,-1,3,-1,-1,3]),Dn=new Float32Array([0,0,2,0,0,2]),In={},Mn=e=>{In.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\nprecision highp int;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform vec2 u_ruv;\n\nout vec4 color;\n\n#define PI 3.14159\n#define TAU 6.28318\n\n#define OCTAVES 8\n#define UI0 1597334673U\n#define UI1 3812015801U\n#define UI2 uvec2(UI0, UI1)\n#define UIF (1.0 / float(0xffffffffU))\nfloat hash12(vec2 p){\n\tuvec2 q = uvec2(ivec2(p)) * UI2;\n\tuint n = (q.x ^ q.y) * UI0;\n\treturn float(n) * UIF;\n}\n\nfloat hermite(float t)\n{\n return t*t*(3.0-2.0*t);\n}\n\nfloat noise(vec2 co, float frequency)\n{\n vec2 v = vec2(co.x * frequency, co.y * frequency);\n\n float ix1 = floor(v.x);\n float iy1 = floor(v.y);\n float ix2 = floor(v.x + 1.0);\n float iy2 = floor(v.y + 1.0);\n\n float fx = hermite(fract(v.x));\n float fy = hermite(fract(v.y));\n\n float fade1 = mix(hash12(vec2(ix1, iy1)), hash12(vec2(ix2, iy1)), fx);\n float fade2 = mix(hash12(vec2(ix1, iy2)), hash12(vec2(ix2, iy2)), fx);\n\n return mix(fade1, fade2, fy);\n}\n\nfloat pnoise(vec2 co, float freq, int steps, float persistence)\n{\n float value = 0.0;\n float ampl = 1.0;\n float sum = 0.0;\n for(int i=0 ; i<steps ; i++)\n {\n sum += ampl;\n value += noise(co, freq) * ampl;\n freq *= 2.0;\n ampl *= persistence;\n }\n return value / sum;\n}\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n vec2 off = vec2( u_rf0, u_rf1 );\n float c0 = pnoise( uv + off * 1.0, 3.0, OCTAVES, 0.6 );\n float c1 = pnoise( uv + off * 2.0, 8.0, OCTAVES, 0.6 );\n float c2 = pnoise( uv + off * 3.0, 20.0, OCTAVES, 0.6 );\n float c3 = pnoise( uv + off * 4.0, 100.0, OCTAVES, 0.6 );\n vec4 clouds = vec4( c0, c1, c2, c3 );\n color = clouds;\n}"),attributes:{position:{data:Sn,size:2},uv:{data:Dn,size:2}},count:3}),In.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat,tiling:e.REPEAT})},Cn=n=>{In.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,In.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),In.renderer.bindUniform("u_framebuffer",0),In.renderer.bindUniform("u_res",[In.fb.width,In.fb.height]),In.renderer.bindUniform("u_rf0",an.rf0),In.renderer.bindUniform("u_rf1",an.rf1),In.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),In.renderer.render(In.fb.width,In.fb.height),In.fb.swap()},Bn=new Float32Array([-1,-1,3,-1,-1,3]),Ln=new Float32Array([0,0,2,0,0,2]),On={},Xn=e=>{On.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D u_forces;\nuniform sampler2D u_noiseClouds;\n\nuniform vec2 u_res;\nuniform float u_sunRad;\nuniform vec2 u_sunPos;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform vec2 u_ruv;\n\nuniform float u_time;\nout vec4 color;\n\nconst float PI = 3.141592;\n\nvec3 sdgCircle( in vec2 p, in float r ){\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_res;\n\n vec2 dirToSun = gl_FragCoord.xy - u_sunPos;\n vec3 sdg = sdgCircle( dirToSun, u_sunRad );\n\n float dist = sdg.x / u_sunRad;\n vec2 sp = uv - ( u_sunPos / u_res );\n\tfloat f = abs( 1.0 - ( pow( abs( dist ), 0.2 ) ) ) + 1.0;\n float srf = 0.0;\n\n float sr = u_sunRad;\n\n if( dist <= 0.0 ){\n vec4 spots = texture( u_forces, uv );\n vec2 sg = spots.xy;\n vec2 sgp = vec2( spots.y, -spots.x );\n float sd = spots.z;\n float sa = atan( sg.y, sg.x );\n float sm = smoothstep( 600.0, 50.0, u_sunRad ) * 0.4 + 0.1;\n\n vec2 suv;\n \t\tsuv.x = ( sp.x ) * f + 0.5;\n \t\tsuv.y = ( sp.y ) * f + 0.5;\n\n vec4 ccd = texture( u_noiseClouds, ( ( suv - 0.5 ) * 0.9 + 0.5 ) + sg * 0.01 );\n float c0 = ccd.x - 0.2;\n float c1 = ccd.y - 0.2;\n float c2 = ccd.z - 0.2;\n float c3 = ccd.w - 0.2;\n\n vec4 cnd = texture( u_noiseClouds, suv + vec2( c0, c1 ) + sg * 0.05 * sin( sa * 15.0 ) );\n float n0 = cnd.x - 0.25;\n float n1 = cnd.y - 0.25;\n float n2 = cnd.z - 0.25;\n float n3 = cnd.w - 0.25;\n\n float prox = smoothstep( sr * 0.02 * n1 + sr * 0.03 * n2, sr * 0.001, sd + 15.0 + c2 * 3.0 );\n float prox2 = smoothstep( sr * 0.2 * n1 + sr * 0.17 * n2 + n0, sr * 0.01, sd + 12.0 + c1 * 8.0 );\n float dark = smoothstep( 0.0, ( n2 + n1 ) * sr * 0.01 * n1, sd + 10.0 + c0 * 13.0 );\n dark -= ( sin( sa * sr * 0.03 ) * 0.5 + 0.5 ) * prox * n2 * 6.0;\n dark = max( 0.1, dark );\n\n srf = ( c0 + c1 + c2 + c3 ) * 0.1 + ( sin( c3 * c2 * 250.0 ) * 0.2 + 0.2 ); // complex base layer\n srf *= ( n0 + n1 + n2 + n3 ); // complex base layer\n srf *= sin( ( 1.0 - c3 ) * 115.0 ) * 0.2 + 0.8;\n srf -= pow( prox2, 25.0 ) * n2;\n srf += pow( prox2, 100.0 ) * n3 * c3 * 6.0;\n float noisy = sin( srf * 5.0 ) * 0.5 + 0.5;\n srf = mix( srf, noisy, n3 ) + 0.2;\n srf = srf * 0.45 + 0.55;\n srf = clamp( srf, 0.0, 1.0 );\n }\n\n color = vec4( sdg, srf );\n}"),attributes:{position:{data:Bn,size:2},uv:{data:Ln,size:2}},count:3}),On.fb=d(e,{width:an.height,height:an.height,type:an.fbType,internalFormat:an.fbFormat,tiling:e.REPEAT})},kn=(n,e)=>{On.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,On.fb.writ
Solar Transits is a procedural exploration of the origins of astrophotography. Each image in this series depicts a randomly generated astronomical event but viewed through the lens of mid-to-late 19th century image capture techniques. The collection features a variety of rare alignments of stars, planets and moons, and are rendered in the spirit of the daguerreotype. In June of 2012, I took a trip to Minneapolis to speak at the Eyeo Festival. Venus was going to transit while I was there. I was curious. I had not seen a transit before. At 5:09 pm on June 5th, a nearly imperceptible black circle began its march across the sun. Were it not a predicted mathematical certainty, it is doubtful anyone would have noticed. For six minutes, the light from the sun was 0.087% dimmer. It is a significant thing to see an object silhouetted against the sun. We are so accustom to seeing our perfect circle of pure light that we can't help but to celebrate the occasions where something blocks the view. I still feel a little more excitement when a slight shadow shoots across the landscape on a cloudless day, the source being an extremely rare transit of a commercial jet liner. Exponentially more rare is the planetary transit. When Venus hangs on the horizon, glowing against the night sky, it is all too easy to think it another star. Only when it is viewed in silhouette can its position in our universe be fully appreciated: orbitally locked like us, and forever drawing it's path around the sun. That tiny black circle effected me in a big way. The scale of the cosmos shifted into perspective. That doesn’t happen often. I was incredibly moved. It was an experience I will never forget. This project is an homage to that strange once-in-a-lifetime event. As it turns out, I was very lucky to have seen it at all. In the time since my birth in 1972, a Venus transit has only happened twice. The 1st time was in 2004 but I lived in a part of the world where it was not visible. The 2nd time was in 2012. Unless I live to be 145 years old, there won’t be a 3rd time. There are a couple silver linings: the Great American solar eclipse is on April 8 2024, and Mercury will transit in 2032. The first 10 sales will have the option to purchase their output in the form of a framed daguerreotype.
Solar Transits is a procedural exploration of the origins of astrophotography. Each image in this series depicts a randomly generated astronomical event but viewed through the lens of mid-to-late 19th century image capture techniques. The collection features a variety of rare alignments of stars, planets and moons, and are rendered in the spirit of the daguerreotype. In June of 2012, I took a trip to Minneapolis to speak at the Eyeo Festival. Venus was going to transit while I was there. I was curious. I had not seen a transit before. At 5:09 pm on June 5th, a nearly imperceptible black circle began its march across the sun. Were it not a predicted mathematical certainty, it is doubtful anyone would have noticed. For six minutes, the light from the sun was 0.087% dimmer. It is a significant thing to see an object silhouetted against the sun. We are so accustom to seeing our perfect circle of pure light that we can't help but to celebrate the occasions where something blocks the view. I still feel a little more excitement when a slight shadow shoots across the landscape on a cloudless day, the source being an extremely rare transit of a commercial jet liner. Exponentially more rare is the planetary transit. When Venus hangs on the horizon, glowing against the night sky, it is all too easy to think it another star. Only when it is viewed in silhouette can its position in our universe be fully appreciated: orbitally locked like us, and forever drawing it's path around the sun. That tiny black circle effected me in a big way. The scale of the cosmos shifted into perspective. That doesn’t happen often. I was incredibly moved. It was an experience I will never forget. This project is an homage to that strange once-in-a-lifetime event. As it turns out, I was very lucky to have seen it at all. In the time since my birth in 1972, a Venus transit has only happened twice. The 1st time was in 2004 but I lived in a part of the world where it was not visible. The 2nd time was in 2012. Unless I live to be 145 years old, there won’t be a 3rd time. There are a couple silver linings: the Great American solar eclipse is on April 8 2024, and Mercury will transit in 2032. The first 10 sales will have the option to receive their output in the form of a framed daguerreotype.
Solar Transits: The Lost Daguerreotypes is a procedural exploration of the origins of astrophotography. Each image in this series depicts a randomly generated astronomical event but viewed through the lens of mid-to-late 19th century image capture techniques. The collection features a variety of rare alignments of stars, planets and moons, and are rendered in the spirit of the daguerreotype. In June of 2012, I took a trip to Minneapolis to speak at the Eyeo Festival. Venus was going to transit while I was there. I was curious. I had not seen a transit before. At 5:09 pm on June 5th, a nearly imperceptible black circle began its march across the sun. Were it not a predicted mathematical certainty, it is doubtful anyone would have noticed. For six minutes, the light from the sun was 0.087% dimmer. It is a significant thing to see an object silhouetted against the sun. We are so accustom to seeing our perfect circle of pure light that we can't help but to celebrate the occasions where something blocks the view. I still feel a little more excitement when a slight shadow shoots across the landscape on a cloudless day, the source being an extremely rare transit of a commercial jet liner. Exponentially more rare is the planetary transit. When Venus hangs on the horizon, glowing against the night sky, it is all too easy to think it another star. Only when it is viewed in silhouette can its position in our universe be fully appreciated: orbitally locked like us, and forever drawing it's path around the sun. That tiny black circle effected me in a big way. The scale of the cosmos shifted into perspective. That doesn’t happen often. I was incredibly moved. It was an experience I will never forget. This project is an homage to that strange once-in-a-lifetime event. As it turns out, I was very lucky to have seen it at all. In the time since my birth in 1972, a Venus transit has only happened twice. The 1st time was in 2004 but I lived in a part of the world where it was not visible. The 2nd time was in 2012. Unless I live to be 145 years old, there won’t be a 3rd time. There are a couple silver linings: the Great American solar eclipse is on April 8 2024, and Mercury will transit in 2032. The first 10 sales will have the option to receive their output in the form of a framed daguerreotype.
Solar Transits: The Lost Daguerreotypes is a procedural exploration of the origins of astrophotography. Each image in this series depicts a randomly generated astronomical event but viewed through the lens of mid-to-late 19th century image capture techniques. The collection features a variety of rare alignments of stars, planets and moons, and are rendered in the spirit of the daguerreotype. In June of 2012, I took a trip to Minneapolis to speak at the Eyeo Festival. Venus was going to transit while I was there. I was curious. I had not seen a transit before. At 5:09 pm on June 5th, a nearly imperceptible black circle began its march across the sun. Were it not a predicted mathematical certainty, it is doubtful anyone would have noticed. For six minutes, the light from the sun was 0.087% dimmer. It is a significant thing to see an object silhouetted against the sun. We are so accustom to seeing our perfect circle of pure light that we can't help but to celebrate the occasions where something blocks the view. I still feel a little more excitement when a slight shadow shoots across the landscape on a cloudless day, the source being an extremely rare transit of a commercial jet liner. Exponentially more rare is the planetary transit. When Venus hangs on the horizon, glowing against the night sky, it is all too easy to think it another star. Only when it is viewed in silhouette can its position in our universe be fully appreciated: orbitally locked like us, and forever drawing it's path around the sun. That tiny black circle effected me in a big way. The scale of the cosmos shifted into perspective. That doesn’t happen often. I was incredibly moved. It was an experience I will never forget. This project is an homage to that strange once-in-a-lifetime event. As it turns out, I was very lucky to have seen it at all. In the time since my birth in 1972, a Venus transit has only happened twice. The 1st time was in 2004 but I lived in a part of the world where it was not visible. The 2nd time was in 2012. Unless I live to be 145 years old, there won’t be a 3rd time. There are a couple silver linings: the Great American solar eclipse is on April 8 2024, and Mercury will transit in 2032. The first 10 sales will receive their output in the form of a framed daguerreotype.
nessContrast( color.xyz, 0.02, 0.9 );\n color.xyz = gamma( color.xyz, 1.2 );\n color.xyz = mix( color.xyz - vec3( 0.05, 0.1, 0.1 ), color.xyz * vec3( 1.0, 1.0, 0.95 ), vignBlend );\n color.xyz *= quintColor( cd1, cd1, cd2, cd3, cd4, bright );\n\n } else if( tint == 4 ){\n color.xyz = vec3( pow( bright, 1.5 ), 0.0, 0.0 );\n\n } else if( tint == 5 ){\n color.xyz = vec3( bright, bright, ( bright ) * 0.8 + 0.2 ) * quintColor( cd0, cd1, cd2, cd2, cd4, bright );\n color.xyz = mix( color.xyz, vec3( bright ), bright );\n\n } else if( tint == 6 ){\n float br = bright - 0.1;\n color.xyz = vec3( pow( br, 1.0 ), pow( br, 2.0 ), pow( br, 4.0 ) );\n\n } else if( tint == 7 ){\n color.xyz = palette( bright, vec3( 0.5 ), vec3( 0.5 ), vec3( 1.0 ), vec3( 0.9, 1.0, 0.22 ) );\n //color.xyz = mix( vec3( bright ), color.xyz, sin( 2550.0 * ( 1.0 - bright ) ) * 0.5 + 0.5 );\n\n } else if( tint == 8 ){\n color.xyz = vec3( 1.0 ) - color.xyz;\n color.xyz = brightnessContrast( color.xyz, 0.15, 1.1 );\n\n }\n color.xyz *= u_renderPer;\n}\n"),attributes:{position:{data:qe,size:2},uv:{data:Ye,size:2}},count:3})},Ke=(n,e,r)=>{He.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,null),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Ge.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),He.renderer.bindUniform("u_trails",0),He.renderer.bindUniform("u_noiseClouds",1),He.renderer.bindUniform("u_borderId",an.borderId),He.renderer.bindUniform("u_borderWidth",an.borderWidth),He.renderer.bindUniform("u_borderCornerRad",an.borderCornerRad),He.renderer.bindUniform("u_damage",an.damage),He.renderer.bindUniform("u_cloudiness",an.cloudiness),He.renderer.bindUniform("u_tint",an.tintId),He.renderer.bindUniform("u_res",[n.canvas.width,n.canvas.height]),He.renderer.bindUniform("u_renderPer",Math.sqrt(e)),He.renderer.render()},je=(n,e)=>{const r=n.canvas.toDataURL("image/png",1).replace("image/png","image/octet-stream"),t=document.createElement("a");t.download="image_"+e+".png",t.href=r,t.click()};const Je=new Float32Array([-1,-1,3,-1,-1,3]),Qe=new Float32Array([0,0,2,0,0,2]),Ze={},$e=(n,e,r)=>{Ze.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,null),Ze.renderer.bindUniform("u_preloadPer",e),Ze.renderer.bindUniform("u_prerenderPer",r),Ze.renderer.bindUniform("u_res",[n.canvas.width,n.canvas.height]),Ze.renderer.render()};console.log(tokenData.tokenId+" "+tokenData.hash);const nr=document.createElement("canvas"),er=nr.getContext("webgl2",{premultipliedAlpha:!1,alpha:!1,preserveDrawingBuffer:!0});function rr(n,e,r,t,o){return t+(o-t)*(n-e)/(r-e)}const tr=(n,e,r)=>Math.min(Math.max(n,e),r);let or=138+an.exposureFrames,ar=0,ir=0,sr=0,dr=0;document.addEventListener("keydown",(function(n){let e=n.key;"s"==e?je(er,tokenData.hash):"0"==e?dr=0:"1"==e?dr=1:"2"==e?dr=2:"3"==e?dr=3:"4"==e?dr=4:"5"==e&&(dr=5)}),!1),er.getExtension("EXT_color_buffer_float"),er.getExtension("OES_texture_float_linear"),er.getExtension("EXT_float_blend"),document.body.appendChild(nr);const ur=()=>{nr.width=1836,nr.height=2400,nr.style.maxWidth="100%",nr.style.maxHeight="100%"};window.addEventListener("resize",ur);const fr=e=>{requestAnimationFrame(fr);let r=tr(rr(sr,0,16,0,1),0,1),t=tr(rr(sr,17,137,0,1),0,1),o=tr(rr(sr,138,or,0,1),0,1);var a;0==sr?(a=er,Ze.renderer=s(a,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform float u_preloadPer;\nuniform float u_prerenderPer;\nuniform vec2 u_res;\n\n#define PI 3.14159265\n#define TAU 6.28318\n#define HPI 3.141592/2.0\nvoid main() {\n \n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n\n float pl = u_preloadPer;\n float pr = min( u_prerenderPer * 1.25, 1.0 );\n float pout = max( ( u_prerenderPer * 1.25 ) - 1.0, 0.0 ) * 4.0;\n float fadeIn = clamp( pl * 5.0 - 0.2, 0.0, 1.0 );\n float fadeOut = 1.0 - pout;\n vec4 bg = vec4( 0.0, 0.0, 0.0, 1.0 );\n color.xyz = vec3( 0.0 );\n\n float r = 50.0;\n vec2 c = u_res/2.0;\n vec2 p = c + vec2( 0.0, ( 1.0 - pr ) * r * 2.2 );\n float d0 = distance( frag, c );\n float d1 = distance( frag, p );\n vec2 dir = normalize( c - frag );\n float angle = atan( dir.y, dir.x );\n float anglePer = fract( ( angle + PI ) / TAU - 0.25 );\n\n float loader = smoothstep( r*pl, r*pl-2.0, d0 ) * fadeIn;\n loader += sin( smoothstep( r - 1.0, r + 5.0, d0 ) * PI ) * pl * 0.5;\n\n loader += pow( smoothstep( r*(pr*35.0), 0.0, d0 ), 25.0 ) * pow( pr, 5.0 ) * 0.3; // outer glow\n loader += smoothstep( r + ( sin( angle * 50.0 ) * 0.5 + 0.5 ) * 50.0 * sin( pout * PI ) + 2.0, r, d0 ) * pow( pl, 55.0 );\n loader = min( loader, 1.0 );\n loader -= smoothstep( r+1.0, r-1.0, d1 );\n loader = max( loader, 0.0 );\n loader += smoothstep( r, r-2.0, d1 ) * 0.25 * pow( pr, 11.0 );\n loader *= fadeOut;\n\n color.xyz += vec3( loader );\n}\n"),attributes:{position:{data:Je,size:2},uv:{data:Qe,size:2}},count:3})):1==sr?zn(er):2==sr?ne(er):3==sr?ae(er):4==sr?Xn(er):5==sr?xe(er):6==sr?Se(er):7==sr?Mn(er):8==sr?(Bn(er),ee(er),ie(er),Pn(er),kn(er),ye(er),De(er)):9==sr?qn(er):10==sr?_n(er):11==sr?gn(er):12==sr?Le(er):13==sr?Ne(er):14==sr&&We(er),t<.999?$e(er,r,t):(1==ar?ir++:o=0,o<.999&&(Hn(er,o),pn(er),hn(er),Oe(er,o),Ve(er,ir,o,ar)),Ke(er,o)),sr++,138==sr&&(ar=1)};requestAnimationFrame(fr),ur();
0.05 ) * 0.3;\n \n if( u_bailyBeads == 1 ){\n cd += beadsCd * 0.15;\n }\n \n cd *= 0.1;\n\n color.xyz = vec3( cd );\n}\n"),attributes:{position:{data:Ie,size:2},uv:{data:Me,size:2}},count:3}),Be.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F})},Oe=(n,e)=>{Be.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Be.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,oe.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Nn.fb.read.targetTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE3),n.bindTexture(n.TEXTURE_2D,he.fb.read.targetTexture),n.activeTexture(n.TEXTURE4),n.bindTexture(n.TEXTURE_2D,Pe.fb.read.targetTexture),n.activeTexture(n.TEXTURE5),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),Be.renderer.bindUniform("u_sky",0),Be.renderer.bindUniform("u_pointCloud",1),Be.renderer.bindUniform("u_sunTex",2),Be.renderer.bindUniform("u_planetsTex",3),Be.renderer.bindUniform("u_beadsTex",4),Be.renderer.bindUniform("u_noiseClouds",5),Be.renderer.bindUniform("u_sunPos",an.sunPos),Be.renderer.bindUniform("u_sunRad",an.sunRad),Be.renderer.bindUniform("u_sunRadPer",Ce),Be.renderer.bindUniform("u_numPlanets",an.numPlanets),Be.renderer.bindUniform("u_bailyBeads",an.bailyBeads),Be.renderer.bindUniform("u_environmentId",an.environmentId),Be.renderer.bindUniform("u_groundLevel",an.groundLevel),Be.renderer.bindUniform("u_cityHaze",an.cityHaze),Be.renderer.bindUniform("u_cloudiness",an.cloudiness),Be.renderer.bindUniform("u_flareIntensity",an.flareIntensity),Be.renderer.bindUniform("u_renderPer",e),Be.renderer.bindUniform("u_rf0",an.rf0),Be.renderer.bindUniform("u_rf1",an.rf1),Be.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),Be.renderer.bindUniform("u_res",[an.height,an.height]),Be.renderer.bindUniform("u_atmos",an.atmos),Be.renderer.bindUniform("u_multi",[an.coronaMulti,an.surfaceMulti,an.coronaGlowMulti]),Be.renderer.render(an.height,an.height),Be.fb.swap()};const Xe=new Float32Array([-1,-1,3,-1,-1,3]),ke=new Float32Array([0,0,2,0,0,2]),Ge={},Ne=e=>{Ge.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform sampler2D u_framebuffer;\nuniform sampler2D u_scene;\n\nuniform vec2 u_res;\nuniform vec2 u_invRes;\nuniform int u_isRendering;\nuniform float u_renderPer;\nuniform int u_renderFrame;\nuniform float u_rf0;\nuniform float u_rf1;\n\nfloat off = 0.990;\nfloat off2 = 0.005;\n\nvec4 blur( float off, float multi ) {\n vec4 col = vec4( 0. );\n for(float x = -off; x <= off; x++) {\n for(float y = -off; y <= off; y++) {\n col += texture( u_framebuffer, v_uv+vec2(x,y)*u_invRes );\n }\n }\n col /= multi;\n return col;\n}\n\nvoid main() {\n vec2 fc = gl_FragCoord.xy;\n vec2 uv = fc / u_res;\n\n vec4 frag = texture( u_scene, uv );\n \tvec4 prev = texture( u_framebuffer, uv );\n\tfloat decay = 0.1;\n\n if( u_isRendering == 1 ){\n if( u_renderPer > 0.0 ){\n if( u_renderPer < 0.3 ) prev = blur( 1.0, 9.0 );\n\n float multi = 0.1;\n color = prev * ( off + u_renderPer * off2 ) + frag * multi;\n color = clamp( color, vec4( 0.0 ), vec4( 1.0 ) );\n if( u_renderPer > 0.999 ){\n color = prev;\n }\n } else { // LIVE VIEW\n color = prev * decay + frag;\n }\n } else {\n color = prev * decay + frag;\n }\n color = clamp( color, vec4( 0.0 ), vec4( 1.0 ) );\n}"),attributes:{position:{data:Xe,size:2},uv:{data:ke,size:2}},count:3}),Ge.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F})},Ve=(n,e,r,t)=>{Ge.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Ge.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Ge.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Be.fb.read.targetTexture),Ge.renderer.bindUniform("u_framebuffer",0),Ge.renderer.bindUniform("u_scene",1),Ge.renderer.bindUniform("u_renderPer",r),Ge.renderer.bindUniform("u_isRendering",t),Ge.renderer.bindUniform("u_renderFrame",e),Ge.renderer.bindUniform("u_res",[an.height,an.height]),Ge.renderer.bindUniform("u_invRes",[1/an.height,1/an.height]),Ge.renderer.bindUniform("u_rf0",an.rf0),Ge.renderer.bindUniform("u_rf1",an.rf1),Ge.renderer.render(an.height,an.height),Ge.fb.swap()};const qe=new Float32Array([-1,-1,3,-1,-1,3]),Ye=new Float32Array([0,0,2,0,0,2]),He={},We=e=>{He.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform sampler2D u_trails;\nuniform sampler2D u_noiseClouds;\n\nuniform int u_borderId;\nuniform float u_borderWidth;\nuniform float u_borderCornerRad;\nuniform float u_damage;\nuniform float u_cloudiness;\nuniform int u_tint;\nuniform vec2 u_res;\nuniform float u_renderPer;\n\n#define PI 3.14159265\n#define TAU 6.28318530718\n\nconst vec3 cd0 = vec3( 0.6, 0.95, 1.0 );\nconst vec3 cd1 = vec3( 0.5, 0.4, 0.8 );\nconst vec3 cd2 = vec3( 1.0, 0.7, 0.7 );\nconst vec3 cd3 = vec3( 1.0, 1.0, 0.9 );\nconst vec3 cd4 = vec3( 1.0, 1.0, 1.0 );\n\nfloat random( vec2 st ){\n return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);\n}\n\nfloat hash11(float p){\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n}\n\nvec3 brightnessContrast( vec3 v, float b, float c ){\n return (v - 0.5) * c + 0.5 + b;\n}\n\nvec3 gamma( vec3 v, float p ){\n return vec3(pow(abs(v.r), p),pow(abs(v.g), p),pow(abs(v.b), p));\n}\n\nvec3 quintColor( vec3 c0, vec3 c1, vec3 c2, vec3 c3, vec3 c4, float per ){\n vec3 c = c0;\n if( per < 0.25 ){\n c = mix( c0, c1, per * 4.0 );\n } else if( per < 0.5 ){\n c = mix( c1, c2, ( per - 0.25 ) * 4.0 );\n } else if( per < 0.75 ){\n c = mix( c2, c3, ( per - 0.5 ) * 4.0 );\n } else {\n c = mix( c3, c4, ( per - 0.75 ) * 4.0 );\n }\n return c;\n}\n\nvec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ){\n return a + b*cos( TAU*(c*t+d) );\n}\n\nfloat sdCircle( vec2 p, float r ){\n return length(p) - r;\n}\n\nfloat sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ){\n r.xy = (p.x>0.0)?r.xy : r.zw;\n r.x = (p.y>0.0)?r.x : r.y;\n vec2 q = abs(p)-b+r.x;\n return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x;\n}\n\nvoid main() {\n \n vec2 frag = gl_FragCoord.xy;\n float ar = u_res.x/u_res.y;\n float ar2 = ( 1.0 - ar ) * 0.5;\n vec2 uv = frag / u_res;\n uv.x = uv.x * ar + ar2;\n vec2 fragCoord = frag + vec2( u_res.y * ar2, 0.0 );\n\n // GET NOISE CLOUDS\n vec4 clouds = texture( u_noiseClouds, uv );\n float cn0 = clouds.x;\n float cn1 = clouds.y;\n float cn2 = clouds.z;\n float cn3 = clouds.w;\n\n // set initial color\n color.xyz = vec3( 0.0 );\n \n // main image\n color += texture( u_trails, uv );\n color.xyz = vec3( max( color.x, max( color.y, color.z ) ) );\n \n // aging\n float dmg = u_damage * 0.5;\n\n // borders\n vec2 bp = (2.0*frag-u_res)/u_res.y;\n vec2 bp2 = (vec2( 2.0, ar*2.0 )*frag-u_res*vec2( 1.0, ar))/u_res.x;\n float br = u_borderId == 0 ? 0.0 : u_borderCornerRad;\n vec2 bs = vec2( ar - u_borderWidth, 1.0 - u_borderWidth );\n float borderSdf = sdRoundedBox( bp, bs, vec4( br ) );\n float b0 = smoothstep( -0.002, 0.0, borderSdf );\n float b1 = smoothstep( -0.01, 0.0, borderSdf );\n float b2 = smoothstep( -0.03, 0.0, borderSdf );\n float b3 = smoothstep( -0.1, 0.0, borderSdf );\n float b4 = smoothstep( -0.2, 0.0, borderSdf );\n float vign = sdCircle( bp2, 0.75 );\n float borderShadow = smoothstep( 0.9, 0.0, vign );\n float vignBlend = smoothstep( 0.66, -0.2, vign );\n \n if( u_borderId > 0 ){\n // aged discoloring\n color.xyz = mix( color.xyz, vec3( cos( color.xyz * PI * 2.0 ) ), dmg ); // color cycles with higher dmg\n float edgeDark = ( b4 * 0.1 + b3 * cn0 * 0.3 - b3 * cn1 * 0.3 + b2 * cn2 * 0.3 - b3 * cn2 * 0.15 );\n color.xyz *= 1.0 - edgeDark;\n\n // more clouds\n color.xyz -= cn0 * u_cloudiness * 0.2;\n\n // final noise and bgcolor\n color.xyz = clamp( color.xyz, 0.0, 1.0 );\n color.xyz = color.xyz * 0.8 + 0.1;\n float fn0 = ( random( ( fragCoord + vec2( 52.5, 77.8 ) ) * 0.01 ) ) * 0.025;\n color.xyz += fn0;\n\n color.xyz = clamp( color.xyz, 0.0, 1.0 );\n color.xyz *= vec3( borderShadow - b3 * 0.1 - b2 * 0.1 ); // final vignette\n\n if( u_borderId == 2 ){ // color edges\n float bMix = mix( b2, b3, dmg * 4.0 );\n float edge = clamp( 1.0 - bMix\n + cn0 * 0.5\n - sin( cn0 * 14.0 ) * 0.1\n - sin( cn3 * 7.0 + cn2 * 3.0 ) * 0.1\n - hash11( frag.x * frag.y ) * 0.1\n - b1 * 0.2\n + cn0 * 0.35\n + cn1 * 0.25, 0.0, 1.0 );\n color.xyz += ( 1.0 - edge ) * 0.2;\n float edgePer = clamp( pow( edge, 2.0 ), 0.0, 1.0 );\n vec3 stain = quintColor( cd0, cd1, cd2, cd3, cd4, pow( fract( edgePer * 2.0 ), 0.5 ) );\n color.xyz *= mix( stain, cd4, edgePer );\n }\n\n float innerb0 = smoothstep( -0.005, -0.002, borderSdf );\n color.xyz -= vec3( innerb0 * 0.05 );\n color.xyz = mix( vec3( 0.02 ), color.xyz, 1.0 - b0 );\n } else {\n if( u_tint != 9 )\n color.xyz *= ( vignBlend * 0.5 + 0.5 );\n }\n\n float bright = max( color.x, max( color.y, color.z ) );\n \n // tinting\n int tint = u_tint;\n if( tint == 0 ){\n color.xyz = max( color.xyz, vec3( 0.05 ) );\n color.xyz = brightnessContrast( color.xyz, 0.0, 1.1 );\n color.xyz = gamma( color.xyz, 1.3 );\n\n } else if( tint == 1 ){\n color.xyz = brightnessContrast( color.xyz, 0.025, 1.1 );\n color.xyz = mix( color.xyz - vec3( 0.1, 0.15, 0.2 ), color.xyz * vec3( 1.0, 1.0, 0.9 ), vignBlend );\n color.xyz *= quintColor( cd2, cd2, cd3, cd3, cd4, bright );\n\n } else if( tint == 2 ){\n vec3 nc = palette( bright * 0.6 + 0.4, vec3( 0.5 ), vec3( 0.5 ), vec3( 0.9, 0.95, 1.0 ), vec3( 0.05, 0.07, 0.15 ) );\n color.xyz = mix( pow( nc, vec3( 1.5 ) ), vec3( bright ), bright );\n\n } else if( tint == 3 ){\n color.xyz = bright
c3( 100000.0, 0.0, 0.0 ); \n float myRadius = 1.0;\n\n for( int i=0; i<u_numBeads; i++ ){\n vec3 bead = beads[i];\n vec2 p = bead.xy;\n float r = bead.z;\n vec2 dir = gl_FragCoord.xy - p;\n vec3 sdg = sdgCircle( dir, r );\n float dist = length( dir );\n mySdg = sdgMin( sdg, mySdg );\n\n if( dist < r ){\n myRadius = r;\n }\n }\n\n vec4 sdfData = vec4( mySdg.x, mySdg.yz, myRadius );\n\n color = sdfData;\n}").replace("%%beads%%",ze),attributes:{position:{data:Ee,size:2},uv:{data:Re,size:2}},count:3}),Pe.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F})},De=n=>{Pe.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Pe.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Pe.fb.read.targetTexture),Pe.renderer.bindUniform("u_framebuffer",0),Pe.renderer.bindUniform("u_numBeads",Ae),Pe.renderer.bindUniform("u_res",[Pe.fb.width,Pe.fb.height]),Pe.renderer.render(Pe.fb.width,Pe.fb.height),Pe.fb.swap()},Ie=new Float32Array([-1,-1,3,-1,-1,3]),Me=new Float32Array([0,0,2,0,0,2]),Be={};let Ce=Math.min(Math.max(an.sunRad-50,0)/1500,1);const Le=e=>{Be.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_res;\nuniform float u_renderPer;\n\nuniform sampler2D u_pointCloud;\nuniform sampler2D u_sunTex;\nuniform sampler2D u_planetsTex;\nuniform sampler2D u_beadsTex;\nuniform sampler2D u_sky;\nuniform sampler2D u_noiseClouds;\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\nuniform float u_sunRadPer;\nuniform int u_bailyBeads;\nuniform float u_cityHaze;\nuniform float u_cloudiness;\nuniform float u_flareIntensity;\nuniform int u_environmentId;\nuniform float u_groundLevel;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform float u_atmos;\nuniform vec3 u_multi;\n\n#define PI 3.14159265\n#define TAU 6.28318530718\n\nvec3 getNormal( vec4 sdf ){\n float x = dot( vec2( 1.0, 0.0 ), sdf.yz );\n float y = dot( vec2( 0.0, 1.0 ), sdf.yz );\n float z = 1.0 - ( sdf.w - abs( sdf.x ) )/sdf.w;\n vec3 n = normalize( vec3( x * ( 1.0 - z ), y * ( 1.0 - z ), z ) );\n return n;\n}\n\nfloat linear( in float minVal, in float maxVal, in float val ){\n float v = clamp( ( val - minVal ) / ( maxVal - minVal ), 0.0, 1.0 );\n return v;\n}\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n\n float haze = u_cityHaze;\n float cloudy = u_cloudiness * 0.5;\n\n vec4 sunData = texture( u_sunTex, uv );\n float sd = sunData.x;\n float surf = sunData.w;\n float sr = u_sunRad;\n float sunRadPer = u_sunRadPer; // small sun = 0.0, huge sun = 1.0;\n float sunSide = smoothstep( -0.001, 0.001, sd );\n\n // GET SKY\n float skyTex = texture( u_sky, uv ).x;\n\n // GET PLANETS TEX\n vec4 planets = texture( u_planetsTex, uv );\n float planetDist = planets.x;\n float planetRad = planets.w;\n vec3 planetN = getNormal( planets );\n float planetRadPer = smoothstep( 5.0, 800.0, planetRad ) * 0.8 + 0.2;\n\n // GET NOISE CLOUDS\n vec4 clouds = texture( u_noiseClouds, uv );\n float cn0 = clouds.x;\n float cn1 = clouds.y;\n float cn2 = clouds.z;\n float cn3 = clouds.w; \n\n // set initial color\n float cd = skyTex * smoothstep( 0.0, 1.0, sd );\n cd -= clouds.x * u_cloudiness * 0.2;\n \n // SUN PARTICLES\n float particles = min( texture( u_pointCloud, uv ).x, 1.0 ) * 0.9;\n cd += particles * 0.1 + pow( particles, 10.0 ) * 2.0 * cn2;\n cd = clamp( cd, 0.0, 1.0 );\n\n // SUN SURFACE\n float sdPer = 1.0 - ( -sd / sr );\n float sun = surf;\n sun += pow( sdPer, 2.0 ) * 0.1;\n sun += pow( sdPer, 15.0 ) * 0.35 * sunRadPer; // brighten sun edge at high radii\n sun += u_cloudiness * 0.25 + u_flareIntensity * 0.05;\n sun = mix( sun, cd, sunSide );\n\n // SUN CORONA\n float cg0 = linear( sr * 5.0, -sr * 0.5, sd );\n float cg1 = linear( sr * 0.5, -sr * 0.5, sd );\n float cg2 = linear( max( cn1, cn2 ) * sr * 0.07, 0.0, sd );\n float ss0 = 1.0 - linear( 0.0, sr * 18.0, sd );\n float ss1 = 1.0 - linear( 0.0, sr * 5.0, sd );\n float ss2 = 1.0 - linear( 0.0, sr * 0.4, sd );\n float ss3 = 1.0 - linear( 0.0, sr * 0.01, sd );\n float corona = ss0 * ss0 * 0.35 + 0.1;\n corona += ss1 * ss1 * 0.15;\n corona += ss2 * ss2 * 0.15;\n corona += ss3 * ss3 * 0.15;\n corona += pow( ss3 * ss3 * cn1 * cn2 * 2.0, 2.0 );\n corona += cg2 * ( 1.0 - sunRadPer ) * 0.25;\n corona += smoothstep( cn3 * cn2 * sr * 0.1, -sr * 0.025, sd ) * sunRadPer * 0.8;\n\n // RENDER SUN AND CORONA\n cd += sun * u_multi.y * ( 1.0 - sunSide ) + corona * u_multi.z * sunSide;\n\n \n // Baily's Beads\n float beadsCd = 0.0;\n if( u_bailyBeads == 1 ){\n vec4 beads = texture( u_beadsTex, uv );\n float beadDist = beads.x;\n float beadRad = beads.w;\n beadsCd = pow( smoothstep( beadRad * 6.0, -beadRad, beadDist ), 15.0 ) * 2.0;\n cd += beadsCd;\n }\n \n // render planets\n {\n float distPer = smoothstep( sr * -0.15, sr * 0.15, sd );\n vec2 dirToSun = u_sunPos - frag;\n float distToSun = length( vec2( dirToSun ) );\n float planetPer = smoothstep( 800.0, 50.0, planetDist ) * 0.25 * ( 1.0 - planetRadPer ) + 0.1;\n float rimGlow = smoothstep( sr * 20.0, 0.0, distToSun + sr );\n float planetEdge = smoothstep( 1.0, -4.0, planetDist );\n float pc = smoothstep( -planetRad, planetRad * 0.05, planetDist );\n float pb = pow( pc, 2.0 ) * 0.2;\n pb += pow( pc, 4.0 ) * 0.2;\n pb += pow( pc, 11.0 ) * 0.3;\n cd = mix( cd, cg0 * planetPer, planetEdge );\n cd += pb * cg1 * planetEdge * 0.2 * planetRadPer;\n\n float dp = max( 0.0, dot( vec3( normalize( dirToSun ), -u_renderPer * 15.0 ), planetN ) * rimGlow );\n cd += dp * distPer * planetEdge * 0.75;\n cd += smoothstep( -planetRad * 0.025, 0.0, planetDist ) * 0.2 * planetEdge * u_atmos;\n cd += rimGlow * 0.1 * planetEdge;\n cd += smoothstep( -8.0, 1.0, planetDist ) * 0.2 * planetEdge;\n }\n \n // landscape\n if( u_environmentId > 0 ){\n float reflectMask = pow( sin( uv.x * PI ), 21.0 );\n reflectMask += pow( sin( uv.x * PI ), 5.0 ) * 0.2;\n float gl = u_groundLevel;\n float skyMask = smoothstep( gl, gl + haze*0.04, uv.y );\n float seaMask = 1.0 - skyMask;\n\n float pnh1 = texture( u_noiseClouds, vec2( uv.x * 0.1, uv.y * 2.0 ) ).w * 0.5;\n float pnh2 = texture( u_noiseClouds, vec2( uv.x * 0.03, uv.y * 2.0 ) ).w * 0.5;\n float wispy0 = texture( u_noiseClouds, vec2( uv.x * 0.05, uv.y * 0.5 ) ).x;\n float wispy1 = texture( u_noiseClouds, vec2( uv.x * 0.1, uv.y * 1.5 ) ).x;\n\n float seaGrad = smoothstep( 0.0, gl, uv.y );\n\n if( u_environmentId == 1 ){ // ocean\n float nn = cn0 * 0.004 + cn0 * 0.002 + cn2 * 0.001 + 0.005;\n float gl0 = gl + nn - sin( uv.x * PI + 0.75 ) * 0.015;\n float lm = smoothstep( gl0, gl0 + haze*0.1, uv.y );\n float cloudyMask = cloudy * skyMask;\n\n cd *= skyMask;\n cd += ( pow( smoothstep( gl + ( cloudy + 1.0 ), gl, uv.y ), 3.0 ) ) * wispy0 * 0.3 * skyMask; // horizon glow\n cd += sin( smoothstep( gl + 0.2, gl - 0.2, uv.y ) * PI ) * cloudyMask * wispy1;\n cd += sin( smoothstep( gl-0.1, gl+0.3, uv.y ) * PI ) * cloudyMask * cn1 * 0.15;\n cd += sin( smoothstep( gl-0.1, gl+0.6, uv.y ) * PI ) * cloudyMask * cn0 * 0.3;\n cd += seaMask * 0.02; // sea base color\n cd += seaGrad * 0.1 * seaMask; // sea noisy gradient to horizon\n cd += ( pow( smoothstep( gl + haze, gl, uv.y ), 4.0 ) ) * haze * skyMask; // horizon glow\n cd += ( pow( smoothstep( gl + haze * 2.0, gl, uv.y ), 2.0 ) ) * max( u_cloudiness, 0.2 ) * sqrt( reflectMask ) * skyMask; // horizon glow\n cd += pow( 1.0 - abs( uv.y - gl ), 23.0 ) * 0.1;\n \n cd += pnh1 * pnh2 * reflectMask * seaMask * seaGrad * 0.3; // reflection\n cd += reflectMask * seaMask * 0.45 + pnh2 * smoothstep( gl * 0.3, gl, uv.y ) * seaMask * 0.3; // sugimoto\n cd -= sin( smoothstep( gl + 0.02, gl - 0.05, uv.y ) * PI ) * wispy1 * 0.2 * seaMask * u_cloudiness; // darker waters\n \n if( u_cloudiness > 0.2 ){\n float clouds0 = cn2 * sin( smoothstep( gl + 0.02 + cn1 * 0.05, gl + ( cn0 * 0.05 + cn2 * 0.05 ), uv.y + cn2 * 0.01 ) * PI );\n float clouds1 = cn0 * sin( smoothstep( gl + 0.02 + cn1 * 0.06, gl + ( cn0 * 0.2 + cn2 * 0.1 ) * cn0 + 0.05, uv.y + cn2 * 0.003 ) * PI );\n float clouds2 = cn0 * sin( smoothstep( gl + 0.02 + cn0 * 0.03, gl + ( cn0 * 0.3 + cn2 * 0.2 ) * cn0 + 0.1, uv.y + cn2 * 0.001 ) * PI );\n float cFinal = clouds0 * cn0 * 0.4 + clouds1 * cn1 * 1.4 + clouds2 * 0.35;\n cd += cFinal * u_cloudiness * cn0;\n }\n\n } else if( u_environmentId == 2 ){ // hills\n cd += pow( smoothstep( 0.9, gl, uv.y ), 1.0 ) * 0.1; // horizon glow\n cd += smoothstep( gl + max( u_cityHaze, 0.1 ) * 3.0, gl, uv.y ) * 0.2;\n float origCd = cd;\n int numHills = 4;\n for( int i=0; i<numHills; i++ ){\n float per = float(i) / float( numHills - 1 );\n float nn = ( cos( sin( uv.x * ( 16.0 + per * 3.0 ) + per * 4.95 + cn0 * 0.7 + u_rf0 * 52.0 ) )/( PI * 0.35 ) ) * 0.03;\n nn += sin( uv.x * ( 5.0 - per * 1.0 ) + per * 5.7 + ( cn0 + cn1 + cn2 * 0.5 ) * 0.5 + u_rf1 * 22.0 ) * 0.05;\n float gl0 = gl + nn * ( 1.0 - per * 0.7 ) - per * 0.05;\n float lm = smoothstep( gl0, gl0+0.0025, uv.y );\n cd = mix( origCd, cd, lm );\n cd -= ( 1.0 - lm ) * ( 0.1 + reflectMask * 0.03 ) * ( per * 0.5 );\n }\n }\n }\n \n // thick clouds\n cd -= ( cn0 * 0.5 - cn1 * 0.3 ) * cloudy;\n float rf0 = u_rf0 * 0.5 + 0.25;\n float cgrad = smoothstep( rf0 - cn0 * 0.25 + uv.x * 0.2, rf0 + cn0 * 0.25 + uv.x * 0.2, uv.y ) * u_cloudiness;\n cd -= ( cn0 * 0.5 - cn1 * 0.3 ) * cgrad;\n\n // fg light pollution\n cd += ( 1.0 - uv.y + cn2 * 0.02 ) * ( haze +
ec4( position, 0.0, 1.0 );\n}"),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec3 v_color;\nout vec4 color;\n\nvoid main() {\n vec2 uv = gl_PointCoord.xy - .5;\n color = vec4( v_color, 1.0 );\n}"),attributes:{a_extras:{data:a,size:4}},transformFeedbacks:{a_position:{data:t,size:2,usage:e.STREAM_COPY,varying:"v_position"},a_velocity:{data:o,size:2,usage:e.STREAM_COPY,varying:"v_velocity"},a_extras:{data:a,size:4,usage:e.STREAM_COPY,varying:"v_extras"}},count:r,mode:e.POINTS}),Nn.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F,singular:!0})};let Yn=0;const Hn=(n,e)=>{Nn.renderer.bindVAOs(),Nn.renderer.bindTransformFeedbacks(),n.bindFramebuffer(n.FRAMEBUFFER,Nn.fb.read.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,vn.blurTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,bn.blurTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE3),n.bindTexture(n.TEXTURE_2D,An.fb.read.targetTexture),Nn.renderer.bindUniform("u_particlemap",0),Nn.renderer.bindUniform("u_dvmap",1),Nn.renderer.bindUniform("u_sunTex",2),Nn.renderer.bindUniform("u_forceTex",3),Nn.renderer.bindUniform("u_frame",Yn++),Nn.renderer.bindUniform("u_renderPer",e),Nn.renderer.bindUniform("u_rand",Gn.random_dec()),Nn.renderer.bindUniform("u_invRes",[Vn,Vn]),Nn.renderer.bindUniform("u_res",[Nn.fb.width,Nn.fb.height]),Nn.renderer.bindUniform("u_sunPos",an.sunPos),Nn.renderer.bindUniform("u_sunRad",an.sunRad),Nn.renderer.bindUniform("u_haziness",an.cloudiness+an.cityHaze),Nn.renderer.bindUniform("u_activity",an.solarActivity),Nn.renderer.bindUniform("u_intensity",an.solarIntensity),Nn.renderer.bindUniform("u_flareIntensity",an.flareIntensity),Nn.renderer.bindUniform("u_rf0",an.rf0),Nn.renderer.bindUniform("u_rf1",an.rf1),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.MAX),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),Nn.renderer.render(Nn.fb.width,Nn.fb.height),n.disable(n.BLEND),Nn.fb.swap()};const Wn=c(),Kn=new Float32Array([-1,-1,3,-1,-1,3]),jn=new Float32Array([0,0,2,0,0,2]),Jn={},Qn=new Float32Array(4*(an.numStars*an.numStars)).fill(0);let Zn=an.height,$n=an.height;for(let n=0;n<an.numStars*an.numStars;n++){const e=4*n;let r=Wn.random_num(0,Zn),t=Wn.random_num(0,$n);Qn[e]=r,Qn[e+1]=t,Qn[e+2]=2*Math.pow(Wn.random_dec(),12)+.25,Qn[e+3]=0}const ne=e=>{Jn.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D u_starsTex;\nuniform int u_res;\nuniform float u_invRes;\n\nout vec4 color;\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b ){\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n float myRadius = 100000.0;\n\n\tfloat dres \t\t= u_invRes * 0.5;\n \tfor( int x=0; x<u_res; x++ ){\n\t\tfloat xp = float( x ) * u_invRes + dres;\n\t\tfor( int y=0; y<u_res; y++ ){\n\t\t\tfloat yp \t\t= float( y ) * u_invRes + dres;\n\n\t\t\tvec2 uv\t\t = vec2( xp, yp );\n\t\t\tvec4 data \t\t= texture( u_starsTex, uv, 0.0 );\n\t\t\tvec2 p \t\t = data.xy;\n\t\t\tfloat r\t\t = data.z; \n\t\t\t\n\t\t\tvec2 dir \t\t= gl_FragCoord.xy - p;\n\t\t\tvec3 sdg = sdgCircle( dir, r );\n float dist\t\t= length( dir );\n\n mySdg = sdgMin( sdg, mySdg );\n mySdg.yz = normalize( mySdg.yz );\n\n if( dist < r ){\n myRadius = r;\n }\n\t\t}\n\t}\n\n vec4 sdfData = vec4( mySdg, myRadius );\n\n color = sdfData;\n}"),attributes:{position:{data:Kn,size:2},uv:{data:jn,size:2}},count:3}),Jn.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F,tiling:e.REPEAT}),Jn.starsTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,Jn.starsTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,an.numStars,an.numStars,0,e.RGBA,e.FLOAT,Qn),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)},ee=n=>{Jn.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,Jn.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,Jn.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Jn.starsTexture),Jn.renderer.bindUniform("u_framebuffer",0),Jn.renderer.bindUniform("u_starsTex",1),Jn.renderer.bindUniform("u_res",an.numStars),Jn.renderer.bindUniform("u_invRes",1/parseFloat(an.numStars)),Jn.renderer.render(Jn.fb.width,Jn.fb.height),Jn.fb.swap()};const re=new Float32Array([-1,-1,3,-1,-1,3]),te=new Float32Array([0,0,2,0,0,2]),oe={},ae=e=>{oe.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_res;\nuniform sampler2D u_stars;\n\nuniform float u_cityHaze;\nuniform float u_rf0;\nuniform float u_rf1;\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n vec4 data = texture( u_stars, uv );\n float sd = data.x;\n float sr = data.w;\n color.xyz = vec3( ( 1.0 - uv.y ) * u_cityHaze * 0.2 );\n color.xyz += vec3( smoothstep( 0.0, -sr, sd ) );\n}\n"),attributes:{position:{data:re,size:2},uv:{data:te,size:2}},count:3}),oe.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F})},ie=n=>{oe.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,oe.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,oe.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,Jn.fb.read.targetTexture),oe.renderer.bindUniform("u_framebuffer",0),oe.renderer.bindUniform("u_stars",1),oe.renderer.bindUniform("u_res",[an.height,an.height]),oe.renderer.bindUniform("u_cityHaze",an.cityHaze),oe.renderer.bindUniform("u_rf0",an.rf0),oe.renderer.bindUniform("u_rf1",an.rf1),oe.renderer.render(oe.fb.width,oe.fb.height),oe.fb.swap()};const se=c(),de=new Float32Array([-1,-1,3,-1,-1,3]),ue=new Float32Array([0,0,2,0,0,2]);let fe=an.numPlanets,ce=an.eventId,le=an.compId,me=an.sunPos[0],ve=an.sunPos[1],_e=an.sunRad,pe=an.sunSign,be=an.height,ge="const vec3 planets["+fe+"] = vec3["+fe+"](";const he={},xe=e=>{for(let n=0;n<fe;n++){let e=be/2+.01,r=be/2,t=100*Math.pow(se.random_dec(),4)+5;if(0==ce)r=-1e4;else if(1==ce)0==n?(r=ve,t=1.02*_e):(r=ve+se.random_num(1*_e,8*_e)*Math.sign(se.random_dec()-.5),t=_e*(.1*Math.pow(se.random_dec(),6)+.05));else if(2==ce)if(7==le)t=se.random_num(200,300);else if(0==n){let n=se.random_num(.3*_e,.5*_e)*Math.sign(se.random_dec()-.5)*2;r=ve+n,t=_e}else r=ve+se.random_num(_e,5*_e)*Math.sign(se.random_dec()-.5),t=_e*se.random_num(.03,.1);else 3==ce?0==n?(r=ve,t=_e*se.random_num(.5,.8)):(r=ve+se.random_num(_e,5*_e)*Math.sign(se.random_dec()-.5),t=_e*se.random_num(.03,.1)):4==ce?(t=_e*(.25*Math.pow(se.random_dec(),6)+.005)*3,0==n?se.random_bool(.5)?(t=se.random_num(.05*_e,.2*_e),r=ve+(_e-t)*Math.sign(se.random_dec()-.5)):(t=se.random_num(.025*_e,.2*_e),r=ve+(_e+t+se.random_num(-100,100))*Math.sign(se.random_dec()-.5)):r=ve+se.random_num(1*_e,8*_e)*Math.sign(se.random_dec()-.5)):5==ce&&(4==le?(r=ve-se.random_num(.3*_e,3*_e)*pe,t=se.random_num(5,20)):5==le?(e=me-se.random_num(.5*_e,2*_e)*pe,t=se.random_num(2,10)):6==le?(r=ve+se.random_num(.5*-_e,.5*_e),t=_e*(.1*Math.pow(se.random_dec(),6)+.01)):(r=ve+se.random_num(1*_e,16*_e)*Math.sign(se.random_dec()-.5),n>0&&(t=_e*(.1*Math.pow(se.random_dec(),6)+.05))));ce>0&&((r<.1*be||r>.9*be)&&(r=se.random_num(.2*be,.8*be)),(e<.2*be||e>.8*be)&&(e=se.random_num(.3*be,.7*be))),ge+="vec3("+e+","+r+","+t+")",ge+=n<fe-1?", ":");"}console.log(ge),he.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform int u_numPlanets;\n\nout vec4 color;\n\n#define PI 3.14159265359\n#define TAU 6.28318530718\n\n%%planets%%\n\nvec3 sdgCircle( in vec2 p, in float r ) \n{\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b )\n{\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n \tfloat myDist \t= 100000.0;\n vec2 myGrad = vec2( 0.0, 0.0 );\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n float myRadius = 1.0;\n\n for( int i=0; i<u_numPlanets; i++ ){\n vec3 planet = planets[i];\n vec2 p = planet.xy;\n float r = planet.z;\n vec2 dir = gl_FragCoord.xy - p;\n vec3 sdg = sdgCircle( dir, r );\n float dist = length( dir );\n mySdg = sdgMin( sdg, mySdg );\n\n if( dist < r ){\n myRadius = r;\n }\n }\n\n vec4 sdfData = vec4( mySdg.x, mySdg.yz, myRadius );\n\n color = sdfData;\n}").replace("%%planets%%",ge),attributes:{position:{data:de,size:2},uv:{data:ue,size:2}},count:3}),he.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F})},ye=n=>{he.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,he.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,he.fb.read.targetTexture),he.renderer.bindUniform("u_framebuffer",0),he.renderer.bindUniform("u_numPlanets",fe),he.renderer.bindUniform("u_numBeads",55),he.renderer.bindUniform("u_res",[he.fb.width,he.fb.height]),he.renderer.render(he.fb.width,he.fb.height),he.fb.swap()};const Te=c(),Ee=new Float32Array([-1,-1,3,-1,-1,3]),Re=new Float32Array([0,0,2,0,0,2]);let Fe=an.sunPos[0],Ue=an.sunPos[1],we=an.sunRad,Ae=parseInt(we/2);0==an.bailyBeads&&(Ae=1);let ze="const vec3 beads["+Ae+"] = vec3["+Ae+"](";const Pe={},Se=e=>{let r=Te.random_num(0,6.283),t=5*Math.pow(Te.random_dec(),2)+1.5;for(let n=0;n<Ae;n++){let e=(1-Math.pow(Te.random_dec(),.5))*Math.sign(Te.random_dec()-.5)*t,o=Math.sin(r+e)*we*1.02,a=Math.cos(r+e)*we*1.02,i=Fe+a,s=Ue+o,d=we*(.02*Math.pow(Te.random_dec(),3)+.002);ze+="vec3("+i+","+s+","+d+")",ze+=n<Ae-1?", ":");"}Pe.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform int u_numBeads;\n\nout vec4 color;\n\n%%beads%%\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvec3 sdgMin( in vec3 a, in vec3 b ){\n return (a.x<b.x)?a:b;\n}\n\nvoid main() {\n \tfloat myDist = 100000.0;\n vec2 myGrad = vec2( 0.0, 0.0 );\n vec3 mySdg = ve
orm float u_time;\nout vec4 color;\n\nconst float PI = 3.141592;\n\nvec3 sdgCircle( in vec2 p, in float r ){\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_res;\n\n vec2 dirToSun = gl_FragCoord.xy - u_sunPos;\n vec3 sdg = sdgCircle( dirToSun, u_sunRad );\n\n float dist = sdg.x / u_sunRad;\n vec2 sp = uv - ( u_sunPos / u_res );\n\tfloat f = abs( 1.0 - ( pow( abs( dist ), 0.2 ) ) ) + 1.0;\n float srf = 0.0;\n\n float sr = u_sunRad;\n\n if( dist <= 0.0 ){\n vec4 spots = texture( u_forces, uv );\n vec2 sg = spots.xy;\n vec2 sgp = vec2( spots.y, -spots.x );\n float sd = spots.z;\n float sa = atan( sg.y, sg.x );\n float sm = smoothstep( 600.0, 50.0, u_sunRad ) * 0.4 + 0.1;\n\n vec2 suv;\n \t\tsuv.x = ( sp.x ) * f + 0.5;\n \t\tsuv.y = ( sp.y ) * f + 0.5;\n\n vec4 ccd = texture( u_noiseClouds, ( ( suv - 0.5 ) * 0.9 + 0.5 ) + sg * 0.01 );\n float c0 = ccd.x - 0.2;\n float c1 = ccd.y - 0.2;\n float c2 = ccd.z - 0.2;\n float c3 = ccd.w - 0.2;\n\n vec4 cnd = texture( u_noiseClouds, suv + vec2( c0, c1 ) + sg * 0.05 * sin( sa * 15.0 ) );\n float n0 = cnd.x - 0.25;\n float n1 = cnd.y - 0.25;\n float n2 = cnd.z - 0.25;\n float n3 = cnd.w - 0.25;\n\n float prox = smoothstep( sr * 0.02 * n1 + sr * 0.03 * n2, sr * 0.001, sd + 15.0 + c2 * 3.0 );\n float prox2 = smoothstep( sr * 0.2 * n1 + sr * 0.17 * n2 + n0, sr * 0.01, sd + 12.0 + c1 * 8.0 );\n float dark = smoothstep( 0.0, ( n2 + n1 ) * sr * 0.01 * n1, sd + 10.0 + c0 * 13.0 );\n dark -= ( sin( sa * sr * 0.03 ) * 0.5 + 0.5 ) * prox * n2 * 6.0;\n dark = max( 0.1, dark );\n\n srf = c0 * 0.2 + c1 * 0.1 + c2 * 0.1 + c3 * 0.1 + ( sin( c3 * c2 * 150.0 ) * 0.1 + 0.1 ); // complex base layer\n srf *= ( n0 + n1 + n2 + n3 ); // complex base layer\n srf *= 1.3;\n srf *= 1.0 - clamp( prox2 * c0 * c1 * c2 * 15.0, 0.0, 1.0 ); // spot darkening\n srf *= sin( ( 1.0 - c3 ) * 25.0 ) * 0.4 + 0.7;\n srf *= ( 1.0 - n3 ) * 0.3 + 0.7;\n srf += pow( prox2, 13.0 ) * n1 * n2 * n3 * 5.0; // spot lightening\n srf = abs( srf - 0.25 ) + 0.25;\n float noisy = sin( srf * 20.0 ) * 0.5 + 0.5;\n srf = mix( srf, noisy, n3 - n2 ) + 0.1;\n srf = clamp( srf + 0.2, 0.0, 1.0 );\n }\n\n color = vec4( sdg, srf );\n}"),attributes:{position:{data:Cn,size:2},uv:{data:Ln,size:2}},count:3}),On.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F,tiling:e.REPEAT})},kn=(n,e)=>{On.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,On.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,On.fb.read.targetTexture),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,An.fb.read.targetTexture),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),On.renderer.bindUniform("u_framebuffer",0),On.renderer.bindUniform("u_forces",1),On.renderer.bindUniform("u_noiseClouds",2),On.renderer.bindUniform("u_sunPos",an.sunPos),On.renderer.bindUniform("u_sunRad",an.sunRad),On.renderer.bindUniform("u_res",[On.fb.width,On.fb.height]),On.renderer.bindUniform("u_rf0",an.rf0),On.renderer.bindUniform("u_rf1",an.rf1),On.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),On.renderer.render(On.fb.width,On.fb.height),On.fb.swap()},Gn=c(),Nn={},Vn=1/an.mapSize,qn=e=>{const r=an.numParticles,t=new Float32Array(2*r),o=new Float32Array(2*r),a=new Float32Array(4*r);for(let n=0;n<2*r;n+=2){let e=Gn.random_num(-Math.PI,Math.PI),r=Math.pow(Gn.random_dec(),.25)*an.sunRad;t[n]=an.sunPos[0]+Math.cos(e)*r,t[n+1]=an.sunPos[1]+Math.sin(e)*r,o[n]=2*Gn.random_dec()-1+1e-4,o[n+1]=2*Gn.random_dec()-1+1e-4,a[2*n]=5*Gn.random_dec(),a[2*n+1]=5*Gn.random_dec()+5,a[2*n+2]=Gn.random_dec(),a[2*n+3]=.1*Math.pow(Gn.random_num(.2,1),5)}Nn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nlayout(location=0) in vec2 a_position;\nlayout(location=1) in vec2 a_velocity;\nlayout(location=2) in vec4 a_extras;\n\nout vec2 v_position;\nout vec2 v_velocity;\nout vec4 v_extras;\nout vec3 v_color;\n\nuniform sampler2D u_particlemap;\nuniform sampler2D u_dvmap;\nuniform sampler2D u_sunTex;\nuniform sampler2D u_forceTex;\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\n\nuniform float u_renderPer;\nuniform vec2 u_res;\n\nuniform float u_frame;\nuniform float u_haziness;\nuniform float u_activity;\nuniform float u_intensity;\nuniform float u_flareIntensity;\nuniform float u_rand;\nuniform vec2 u_invRes;\nuniform float u_rf0;\nuniform float u_rf1;\n\nconst float dt = 0.0002;\nfloat u_speedMin = 0.01;\n\n#define PI 3.14159265359\n#define TAU 6.28318530718\n\nvec3 getNormal( vec4 sdf ){\n float x = dot( vec2( 1.0, 0.0 ), sdf.yz );\n float y = dot( vec2( 0.0, 1.0 ), sdf.yz );\n float z = 1.0 - ( sdf.w - abs( sdf.x ) )/sdf.w;\n vec3 n = normalize( vec3( sqrt( abs( x ) ) * sign( x ) * ( 1.0 - z ), sqrt( abs( y ) ) * sign( y ) * ( 1.0 - z ), z ) );\n return n;\n}\n\n// Grab from https://www.shadertoy.com/view/4djSRW\n#define MOD3 vec3(.1031,.11369,.13787)\nfloat hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\nvec2 hash22(vec2 p) {\n\tvec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));\n p3 += dot(p3, p3.yzx+33.33);\n return fract((p3.xx+p3.yz)*p3.zy);\n}\n\nvec4 derivative( vec4 state, inout float density, inout float densityMult, inout vec4 sunData, in float speedMax ){\n vec2 uv = state.xy;\n\n vec4 dv = texture( u_dvmap, uv );\n density = dv.x;\n vec2 avgVelocity = dv.zw / max( density, 1.0 );\n\n float sunDist = sunData.x;\n vec2 sunGrad = normalize( sunData.yz );\n float sunGradMag = ( 1.0 / ( sunDist ) );\n\n vec4 forceData = texture( u_forceTex, uv );\n float forceDist = forceData.z;\n vec2 forceGrad = normalize( forceData.xy );\n float forceGradMag = ( 1.0 / ( forceDist ) );\n\n vec3 normal = getNormal( sunData );\n\n vec4 extras = a_extras;\n float agePer = extras.x/extras.y;\n float rf0 = extras.z;\n\n float dm = smoothstep( 100.0, 1200.0, u_sunRad ) * 0.2 + 0.05;\n float sv1 = sin( forceGrad.y * 15.7 * sin( forceGrad.x * ( ( mix( u_rf0, rf0, u_renderPer * u_renderPer ) + 0.2 ) * 25.0 ) ) );\n float sv2 = sin( forceGrad.y * ( u_rf1 + 0.5 ) * 3.3 );\n vec2 vel0 = forceGrad * forceGradMag * ( sv1 * sv2 ) * u_intensity * u_sunRad;\n vec2 vel1 = sunGrad * sunGradMag * u_intensity * u_sunRad * 0.1;\n vec2 customVel = mix( vel0 + vel1 * 0.25, -vel1 * 0.5, agePer ) * u_flareIntensity;\n\n float attract = 0.06 * dm;\n float repel = 0.12 * dm;\n float align = 0.5 * dm;\n float leading = 0.5;\n densityMult = 0.1 * dm;\n\n vec2 xy = state.xy + leading * dt * state.zw;\n\n vec3 dvm = texture( u_dvmap, xy ).xzw;\n xy = state.xy + dt * 2.0 * leading * dvm.yz / dvm.x;\n\n float dE = texture( u_dvmap, state.xy + vec2( u_invRes.x, 0 ) ).x;\n float dW = texture( u_dvmap, state.xy + vec2( -u_invRes.x, 0 ) ).x;\n float dN = texture( u_dvmap, state.xy + vec2( 0, u_invRes.y ) ).x;\n float dS = texture( u_dvmap, state.xy + vec2( 0, -u_invRes.y ) ).x;\n vec2 densityGrad = vec2( dE - dW, dN - dS ) / u_invRes;\n\n vec4 avgPosValues = texture( u_particlemap, xy );\n float density1= texture( u_dvmap, xy ).x;\n\n vec2 avgPos = vec2(\n state.x < 0.5 ? avgPosValues.x : avgPosValues.z,\n state.y < 0.5 ? avgPosValues.y : avgPosValues.w\n ) / max( density1, 1e-8 );\n\n // The magic numbers!\n float repulsion = 1.4 * repel;\n float follow = 5000.0 * align;\n float cohesion = 1700000.0 * attract;\n float velEnforce = 100.0 * ( 1.5 - u_activity );\n\n float vmag = length( state.zw );\n \n vec2 randLoc = state.xy * 1. + u_rand * 100.0;\n vec2 rand = hash22(randLoc) - .5;\n\n vec2 v = customVel;\n - densityGrad * repulsion\n + ( avgVelocity - state.zw ) * follow\n + ( avgPos - state.xy ) * cohesion / max( 0.01, leading )\n + state.zw * ( speedMax - vmag ) * velEnforce\n + 20000.0 * rand * ( 0.3 + u_haziness * 0.5 );\n\n return vec4( state.zw, v );\n}\n\nvoid main() {\n // get extras\n vec4 extras = a_extras;\n float age = extras.x;\n float life = extras.y;\n float rf0 = extras.z;\n\n float densityMult = 0.01;\n float density = 0.0;\n float speedMax = smoothstep( 50.0, 1000.0, u_sunRad ) * 15.0;\n vec4 state = vec4( a_position / u_res, a_velocity );\n \n vec4 sunData = texture( u_sunTex, state.xy );\n state += dt * derivative( state, density, densityMult, sunData, speedMax );\n vec2 uv = state.xy;\n vec2 pos = state.xy * u_res;\n vec2 vel = state.zw;\n\n // limit speed\n float speed = length( vel );\n float maxSpeed = speedMax * ( smoothstep( 100.0, 500.0, u_sunRad ) * 0.8 + 0.2 ) + rf0 * 10.0;\n if( speed > maxSpeed ){\n vel = normalize( vel ) * maxSpeed;\n } else if( speed < u_speedMin ){\n vel = normalize( vel ) * u_speedMin;\n }\n \n int oob = 0;\n float b = 0.0;\n if( pos.y < b || pos.y > u_res.y - b ) oob = 1;\n if( pos.x < b || pos.x > u_res.x - b ) oob = 1;\n if( age < 0.0 || age > life ) oob = 1;\n if( sunData.x < 0.0 ) oob = 1;\n\n if( oob == 1 ){\n float angle = hash12( pos * 0.01 ) * 0.5 + hash12( pos * 0.05 ) * 0.5 * TAU * 5.0;\n float radius = u_sunRad + u_sunRad * ( rf0 * 0.015 );\n vec2 dir = vec2( cos( angle ), sin( angle ) );\n vec2 newPos = u_sunPos + dir * radius;\n pos = newPos;\n vel = dir * 0.001;\n }\n\n v_position = pos;\n v_velocity = vel * 0.9975;\n\n if( u_frame < 5.0 ) {\n v_velocity = a_velocity;\n }\n \n vec2 position = a_position / u_res * 2.0 - 1.0;\n v_extras = a_extras;\n if( oob == 1 ){\n v_extras.x = 0.0;\n }\n v_extras.x += 0.0333;\n\n vec2 velDir = normalize( v_velocity.xy );\n float angle = atan( velDir.y, velDir.x );\n v_color = vec3( 1.0 );\n\n float fadeOut = pow( u_renderPer, 0.5 );\n float ps = max( extras.w, 0.1 ) * u_flareIntensity * fadeOut;\n\n gl_PointSize = ps;\n gl_Position = v
highp float;\n#define GLSLIFY 1\n\nin vec2 state;\n\nuniform float u_scale;\n\nout vec4 color;\n\nvoid main() {\n color = vec4( fract( state + 0.25 ) - 0.25, fract( state - 0.25 ) + 0.25 ) * u_scale;\n}"),count:r,mode:e.POINTS}),vn.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:e.FLOAT,internalFormat:e.RGBA32F,singular:!0}),vn.blur=cn(e)};const pn=n=>{vn.renderer.bindVAOs(),n.bindVertexArray(Nn.renderer.readTFB),n.bindFramebuffer(n.FRAMEBUFFER,vn.fb.read.fb),vn.renderer.bindUniform("u_screensize",[an.height,an.height]),vn.renderer.bindUniform("u_scale",an.mapScale),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),vn.renderer.render(an.mapSize,an.mapSize),n.disable(n.BLEND),vn.fb.swap(),vn.blurTexture=mn(n,vn.fb.read.targetTexture,vn.blur,an.mapSize,an.mapSize)};const bn={},gn=e=>{const r=an.numParticles;bn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nlayout(location=0) in vec2 a_position;\nlayout(location=1) in vec2 a_velocity;\n\nuniform vec2 u_screensize;\n\nout vec2 state;\nout vec2 statedv;\n\nvoid main() {\n gl_PointSize = 1.;\n state = a_position / u_screensize;\n statedv = a_velocity;\n gl_Position = vec4( a_position / u_screensize * 2. - 1., 0., 1. );\n}"),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nin vec2 state;\nin vec2 statedv;\n\nuniform float u_scale;\n\nout vec4 color;\n\nvoid main() {\n color = vec4(1, 0, clamp(statedv, -1e4, 1e4)) * u_scale;\n}"),count:r,mode:e.POINTS}),bn.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:e.FLOAT,internalFormat:e.RGBA32F,singular:!0}),bn.blur=cn(e)};const hn=n=>{bn.renderer.bindVAOs(),n.bindVertexArray(Nn.renderer.readTFB),n.bindFramebuffer(n.FRAMEBUFFER,bn.fb.read.fb),bn.renderer.bindUniform("u_screensize",[an.height,an.height]),bn.renderer.bindUniform("u_scale",an.mapScale),n.clear(n.DEPTH_BUFFER_BIT),n.clear(n.DEPTH_BUFFER_BIT|n.COLOR_BUFFER_BIT),n.enable(n.BLEND),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE),bn.renderer.render(an.mapSize,an.mapSize),n.disable(n.BLEND),bn.fb.swap(),bn.blurTexture=mn(n,bn.fb.read.targetTexture,bn.blur,an.mapSize,an.mapSize)};const xn=c(),yn=new Float32Array([-1,-1,3,-1,-1,3]),Tn=new Float32Array([0,0,2,0,0,2]);let En=an.numSpots,Rn=an.sunPos[0],Fn=an.sunPos[1],Un=an.sunRad,wn="const vec4 spots["+En+"] = vec4["+En+"](";const An={},zn=e=>{let r,t;for(let n=0;n<En;n++){let e=Fn+1*xn.random_num(-Un,Un),o=xn.random_num(.05,.8)*Un;xn.random_bool(.5)&&(o=-o);let a=Rn+o,i=Math.pow(xn.random_dec(),3)*Un*.7+6,s=xn.random_num(-4,4);n%2==1&&(e=t+xn.random_num(-50,50),a=r+xn.random_num(-20,20)),r=a,t=e,wn+="vec4("+a+","+e+","+i+","+s+")",wn+=n<En-1?", ":");"}An.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_sunPos;\nuniform float u_sunRad;\nuniform int u_numForces;\nuniform int u_numSpots;\n\nuniform vec2 u_res;\nuniform int u_eventId;\nuniform vec2 u_nOff;\n\nout vec4 color;\n\n#define PI 3.1415926\n#define TAU 6.2831853\n\n%%sunspots%%\n\nvec3 sdgCircle( in vec2 p, in float r ) {\n float d = length(p);\n return vec3( d-r, p/d );\n}\n\nfloat smin( float a, float b, float k ){\n float res = exp2( -k*a ) + exp2( -k*b );\n return -log2( res )/k;\n}\n\nvec3 sdgSmoothMin( in vec3 a, in vec3 b, in float k ){\n float h = max(k-abs(a.x-b.x),0.0);\n float m = 0.25*h*h/k;\n float n = 0.50* h/k;\n return vec3( min(a.x, b.x) - m, \n mix(a.yz, b.yz, (a.x<b.x)?n:1.0-n) );\n}\n\nfloat getHaversine( vec2 p0, vec2 p1 ){\n vec2 c = u_sunPos;\n float sr = u_sunRad;\n float d0 = distance( c, p0 );\n float d1 = distance( c, p1 );\n float r0 = clamp( d0/sr, 0.0, 1.0 );\n float r1 = clamp( d1/sr, 0.0, 1.0 );\n\n r0 = pow( 1.0 - r0, 0.25 ) * sr * 2.0;\n r1 = pow( 1.0 - r1, 0.25 ) * sr * 2.0;\n\n vec3 ps0 = vec3( p0, r0 );\n vec3 ps1 = vec3( p1, r1 );\n\n float hd = distance( ps0, ps1 );\n return hd;\n}\n\n// Hash without Sine\n// MIT License...\n// Copyright (c)2014 David Hoskins.\n\nfloat hash12( vec2 p ){\n\tvec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\nvec4 getForceData( vec2 p, float sr ){\n vec2 c = u_sunPos;\n float t = hash12( p ) * TAU;\n float r = sr - hash12( p + u_nOff ) * sr * 0.05;\n float x = c.x + cos( t ) * r;\n float y = c.y + sin( t ) * r;\n float f = hash12( p * vec2( 155.0 ) + u_nOff ) - 0.5;\n\n return vec4( x, y, hash12( p + vec2( 2.3, 5.6 ) ), f );\n}\n\nvoid main() {\n vec2 dirToSun = u_sunPos - gl_FragCoord.xy;\n vec3 sunSdg = sdgCircle( dirToSun, u_sunRad );\n float sunDist = sunSdg.x;\n\n float myDist = 1000000.0;\n vec3 mySdg = vec3( 100000.0, 0.0, 0.0 ); \n\tvec2 myVel = vec2( 0.0, 0.0 );\n\tfloat myF = 0.0;\n float myR = 0.0;\n\tvec2 p0 = gl_FragCoord.xy;\n\n if( sunDist > 0.0 ){\n for( int i=0; i<u_numForces; i++ ){\n float u = hash12( vec2( float( i ) * 3.3 + 11.4, 0.5 ) );\n float v = hash12( vec2( float( i ) * 5.5 + 17.5, 0.5 ) );\n vec4 forceData = getForceData( vec2( u, v ) * 100.0, u_sunRad );\n vec2 p1 = forceData.xy;\n float r = forceData.z;\n float f = forceData.w;\n\n vec2 dir \t\t= p0 - p1;\n float dist \t\t= length( dir );\n vec2 dirNorm = normalize( dir );\n float distSq = dist * dist;\n float invDistSq = 1.0 / ( distSq + r );\n\n myVel += dirNorm * invDistSq * 5000.0 * f;\n\n if( dist < myDist ){\n myDist = dist;\n myF = f;\n }\n }\n } else {\n for( int i=0; i<u_numSpots; i++ ){\n vec4 spot = spots[i];\n vec2 p1 = spot.xy;\n float r = spot.z;\n float f = spot.w;\n\n vec2 dir \t\t= p0 - p1;\n float dist = getHaversine( p0, p1 );\n vec3 sdg = sdgCircle( dir, r );\n vec2 dirNorm = normalize( dir );\n float distSq = dist * dist;\n float invDistSq = 1.0 / ( distSq + r );\n sdg.x = dist;\n mySdg = sdgSmoothMin( sdg, mySdg, u_sunRad * 0.05 );\n myF = smin( myF, f, 35.0 ) * sign( f );\n myR = smin( myR, r, 35.0 );\n myVel += dirNorm * invDistSq * 500.0 * f;\n }\n myDist = mySdg.x;\n }\n \n \tcolor = vec4( myVel.x, myVel.y, myDist, myF );\n}").replace("%%sunspots%%",wn),attributes:{position:{data:yn,size:2},uv:{data:Tn,size:2}},count:3}),An.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA32F,tiling:e.REPEAT})},Pn=n=>{An.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,An.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,An.fb.read.targetTexture),An.renderer.bindUniform("u_framebuffer",0),An.renderer.bindUniform("u_sunPos",an.sunPos),An.renderer.bindUniform("u_sunRad",an.sunRad),An.renderer.bindUniform("u_numForces",an.numForces),An.renderer.bindUniform("u_numSpots",an.numSpots),An.renderer.bindUniform("u_res",[An.fb.width,An.fb.height]),An.renderer.bindUniform("u_eventId",an.eventId),An.renderer.bindUniform("u_nOff",an.nOff),An.renderer.render(An.fb.width,An.fb.height),An.fb.swap()};const Sn=new Float32Array([-1,-1,3,-1,-1,3]),Dn=new Float32Array([0,0,2,0,0,2]),In={},Mn=e=>{In.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform vec2 u_res;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform vec2 u_ruv;\n\nout vec4 color;\n\n#define PI 3.14159\n#define TAU 6.28318\n\n#define OCTAVES 8\n#define UI0 1597334673U\n#define UI1 3812015801U\n#define UI2 uvec2(UI0, UI1)\n#define UIF (1.0 / float(0xffffffffU))\nfloat hash12(vec2 p){\n\tuvec2 q = uvec2(ivec2(p)) * UI2;\n\tuint n = (q.x ^ q.y) * UI0;\n\treturn float(n) * UIF;\n}\n\nfloat hermite(float t)\n{\n return t*t*(3.0-2.0*t);\n}\n\nfloat noise(vec2 co, float frequency)\n{\n vec2 v = vec2(co.x * frequency, co.y * frequency);\n\n float ix1 = floor(v.x);\n float iy1 = floor(v.y);\n float ix2 = floor(v.x + 1.0);\n float iy2 = floor(v.y + 1.0);\n\n float fx = hermite(fract(v.x));\n float fy = hermite(fract(v.y));\n\n float fade1 = mix(hash12(vec2(ix1, iy1)), hash12(vec2(ix2, iy1)), fx);\n float fade2 = mix(hash12(vec2(ix1, iy2)), hash12(vec2(ix2, iy2)), fx);\n\n return mix(fade1, fade2, fy);\n}\n\nfloat pnoise(vec2 co, float freq, int steps, float persistence)\n{\n float value = 0.0;\n float ampl = 1.0;\n float sum = 0.0;\n for(int i=0 ; i<steps ; i++)\n {\n sum += ampl;\n value += noise(co, freq) * ampl;\n freq *= 2.0;\n ampl *= persistence;\n }\n return value / sum;\n}\n\nvoid main() {\n vec2 frag = gl_FragCoord.xy;\n vec2 uv = frag / u_res;\n vec2 off = vec2( u_rf0, u_rf1 );\n float c0 = pnoise( uv + off * 1.0, 3.0, OCTAVES, 0.6 );\n float c1 = pnoise( uv + off * 2.0, 8.0, OCTAVES, 0.6 );\n float c2 = pnoise( uv + off * 3.0, 20.0, OCTAVES, 0.6 );\n float c3 = pnoise( uv + off * 4.0, 100.0, OCTAVES, 0.6 );\n vec4 clouds = vec4( c0, c1, c2, c3 );\n color = clouds;\n}"),attributes:{position:{data:Sn,size:2},uv:{data:Dn,size:2}},count:3}),In.fb=d(e,{width:an.height,height:an.height,type:e.FLOAT,internalFormat:e.RGBA16F,tiling:e.REPEAT})},Bn=n=>{In.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,In.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,In.fb.read.targetTexture),In.renderer.bindUniform("u_framebuffer",0),In.renderer.bindUniform("u_res",[In.fb.width,In.fb.height]),In.renderer.bindUniform("u_rf0",an.rf0),In.renderer.bindUniform("u_rf1",an.rf1),In.renderer.bindUniform("u_ruv",[123.45*an.rf0,123.45*an.rf1]),In.renderer.render(In.fb.width,In.fb.height),In.fb.swap()},Cn=new Float32Array([-1,-1,3,-1,-1,3]),Ln=new Float32Array([0,0,2,0,0,2]),On={},Xn=e=>{On.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\n\nuniform sampler2D u_forces;\nuniform sampler2D u_noiseClouds;\n\nuniform vec2 u_res;\nuniform float u_sunRad;\nuniform vec2 u_sunPos;\nuniform float u_rf0;\nuniform float u_rf1;\nuniform vec2 u_ruv;\n\nunif
function n(n){return n&&n.__esModule?n.default:n}const e=(n,e,r)=>{const t=n.createShader(r);if(n.shaderSource(t,e),n.compileShader(t),!n.getShaderParameter(t,n.COMPILE_STATUS)){const e=n.getShaderInfoLog(t);throw new Error(e)}return t},r=(n,r,t,o)=>{const a=e(n,r,n.VERTEX_SHADER),i=e(n,t,n.FRAGMENT_SHADER),s=n.createProgram();if(n.attachShader(s,a),n.attachShader(s,i),o){const e=[];for(let n in o)e.push(o[n].varying);n.transformFeedbackVaryings(s,e,n.SEPARATE_ATTRIBS)}if(n.linkProgram(s),!n.getProgramParameter(s,n.LINK_STATUS)){const e=n.getProgramInfoLog(s);throw new Error(e)}return s},t=(n,e)=>{const r=n.getProgramParameter(e,n.ACTIVE_UNIFORMS),t={};for(let o=0;o<r;o++){const{name:r,type:a}=n.getActiveUniform(e,o);t[r]={location:n.getUniformLocation(e,r),type:a}}return t},o=(n,e,r=n.STATIC_DRAW,t=n.ARRAY_BUFFER)=>{const o=n.createBuffer();return n.bindBuffer(t,o),n.bufferData(t,e,r),o},a=(n,e,r)=>{if(!r)return null;const t=n.createVertexArray(),a=Object.keys(r);n.bindVertexArray(t);for(let t=0;t<a.length;t++){let{size:i=1,type:s=n.FLOAT,normalize:d=!1,stride:u=0,offset:f=0,buffer:c,data:l,usage:m=n.STATIC_DRAW,buffertype:v=n.ARRAY_BUFFER}=r[a[t]];l&&!c&&(c=o(n,l,m,v)),n.bindAttribLocation(e,t,a[t]),n.enableVertexAttribArray(t),n.bindBuffer(n.ARRAY_BUFFER,c),n.vertexAttribPointer(t,i,s,d,u,f)}return t},i=(n,e,r)=>{if(!r)return null;const t=[n.createVertexArray(),n.createVertexArray()],a=[n.createTransformFeedback(),n.createTransformFeedback()],i=[],s=Object.keys(r);return t.forEach(((t,d)=>{n.bindVertexArray(t);const u=[],f={};for(let t=0;t<s.length;t++){let{size:a=1,type:i=n.FLOAT,normalize:d=!1,stride:c=0,offset:l=0,buffer:m,data:v,usage:_=n.STATIC_DRAW,buffertype:p=n.ARRAY_BUFFER}=r[s[t]];v&&!m&&(m=o(n,v,_,p)),f[s[t]]={i:t,buffer:m},n.bindAttribLocation(e,t,s[t]),n.enableVertexAttribArray(t),n.bindBuffer(n.ARRAY_BUFFER,m),n.vertexAttribPointer(t,a,i,d,c,l),u.push(m)}n.bindBuffer(n.ARRAY_BUFFER,null),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,a[d]),u.forEach(((e,r)=>{n.bindBufferBase(n.TRANSFORM_FEEDBACK_BUFFER,r,e)})),n.bindVertexArray(null),i.push(f)})),{vaos:t,tfbs:a,tfbBuffers:i}},s=(n,{vert:e,frag:o,attributes:s,transformFeedbacks:d,count:u,offset:f=0,mode:c=n.TRIANGLES}={})=>{const l=r(n,e,o,d),m=t(n,l),v=a(n,l,s),_=i(n,l,d);let p=0;return{uniforms:m,bindUniform(e,r){if(void 0===r)return;if(!m[e])return;const{type:t,location:o}=m[e];switch(t){case 5126:return r instanceof Array?n.uniform1fv(o,r):("number"==typeof r&&n.uniform1f(o,r),null);case 35664:return n.uniform2fv(o,r);case 35665:return n.uniform3fv(o,r);case 35666:return n.uniform4fv(o,r);case 35670:case 5124:case 35678:case 35680:return r.length?n.uniform1iv(o,r):n.uniform1i(o,r);case 35671:case 35667:return n.uniform2iv(o,r);case 35672:case 35668:return n.uniform3iv(o,r);case 35673:case 35669:return n.uniform4iv(o,r);case 35674:return n.uniformMatrix2fv(o,!1,r);case 35675:return n.uniformMatrix3fv(o,!1,r);case 35676:if(null===r)return;return n.uniformMatrix4fv(o,!1,r)}},bindVAOs(){n.useProgram(l),v&&n.bindVertexArray(v)},bindTransformFeedbacks(){if(!_)return;const e=(p+1)%2,r=_.vaos[p],t=_.tfbs[e],o=_.tfbBuffers[e];this.readTFB=r,this.writeTFB=_.vaos[e],n.bindVertexArray(r),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,t);for(let e in o){const r=o[e];n.bindBufferBase(n.TRANSFORM_FEEDBACK_BUFFER,r.i,r.buffer)}p=e},render(e,r){n.viewport(0,0,e||n.canvas.width,r||n.canvas.height),_&&n.beginTransformFeedback(c),n.drawArrays(c,f,u),_&&n.endTransformFeedback()}}},d=(n,{width:e,height:r,tiling:t=n.CLAMP_TO_EDGE,type:o=n.UNSIGNED_BYTE,format:a=n.RGBA,internalFormat:i=n.RGBA,data:s=null,singular:d=!1,minFilter:u=n.LINEAR,magFilter:f=u,mips:c=!1}={})=>{const l=({w:d=e,h:l=r}={})=>{const m=n.createTexture();n.bindTexture(n.TEXTURE_2D,m),n.texImage2D(n.TEXTURE_2D,0,i,d,l,0,a,o,s),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,u),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,f),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,t),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,t);const v=n.createFramebuffer();return n.bindFramebuffer(n.FRAMEBUFFER,v),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,m,0),c&&n.generateMipmap(n.TEXTURE_2D),{fb:v,targetTexture:m}};return{width:e,height:r,read:l({w:e,h:r}),write:d?null:l({w:e,h:r}),resize(n,e){this.width=n,this.height=e,this.read=l({w:n,h:e}),this.write=l({w:n,h:e})},swap(){if(d)return;const n=this.read;this.read=this.write,this.write=n}}};class u{constructor(n){this.useA=!1;let e=function(n){let e=parseInt(n.substr(0,8),16),r=parseInt(n.substr(8,8),16),t=parseInt(n.substr(16,8),16),o=parseInt(n.substr(24,8),16);return function(){e|=0,r|=0,t|=0,o|=0;let n=(e+r|0)+o|0;return o=o+1|0,e=r^r>>>9,r=t+(t<<3)|0,t=t<<21|t>>>11,t=t+n|0,(n>>>0)/4294967296}};this.prngA=new e(n.hash.substr(2,32)),this.prngB=new e(n.hash.substr(34,32));for(let n=0;n<1e6;n+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(n,e){return n+(e-n)*this.random_dec()}random_int(n,e){return Math.floor(this.random_num(n,e+1))}random_bool(n){return this.random_dec()<n}random_choice(n){return n[this.random_int(0,n.length-1)]}}let f;function c(n){return n||(n=tokenData),f instanceof u||(f=new u(n)),f}const l=c();let m=parseInt(1835),v=parseInt(2400),_=[l.random_num(-500,500),l.random_num(-500,500)],p=0,b=l.random_dec();p=b<.9?0:b<.97?1:2;let g=0,h=l.random_dec();g=h<.05?0:h<.35?1:h<.55?2:h<.62?3:h<.9?4:5,p>0&&(g=l.random_int(1,2));let x=0,y=l.random_dec();x=y<.2?0:y<.4?1:y<.6?2:y<.8?3:y<.9?4:y<.92?5:y<.98?6:7,p>0&&(x=2*l.random_int(0,1)),4==x?g=l.random_int(4,5):5==x?g=5:6==x&&(g=l.random_int(3,5));let T=v/2,E=v/2,R=50,F=Math.sign(l.random_dec()-.5),U=Math.sqrt(l.random_num(.85,1.5));0==g&&(U=2);let w=7e3*U+8e3,A=1;if(0==x)R=l.random_num(100,150);else if(1==x)R=l.random_num(220,350);else if(2==x)R=l.random_num(100,150),E+=l.random_num(200,400);else if(3==x)R=l.random_num(220,350),E+=l.random_num(200,400);else if(4==x)R=l.random_num(800,1800),E+=l.random_num(1250,1500)*F;else if(5==x)R=l.random_num(1500,2400),T+=l.random_num(.99*R,1.1*R)*F;else if(6==x)R=l.random_num(600,1e3);else if(7==x){R=4e3;let n=l.random_num(0,6.28318),e=l.random_num(.95*R,1.05*R);T+=Math.cos(n)*e,E+=Math.sin(n)*e,g=2}let z=[T,E];p>0&&(R=l.random_num(70,100));0==g&&(A=3.5);let P=parseInt(R/12),S=8*P,D=parseInt(l.random_int(P+15*U,S+50*U)/4+5);4!=x&&5!=x||(D=l.random_int(50,80)),7==x&&(D=200);let I=parseInt(R/20*U)+2,M=parseInt(R/10*U)+4,B=Math.min(40,l.random_int(I,M)),C=[1,1,1,2,2,6],L=l.random_int(1,C[g]);5==g&&(L=l.random_int(2,C[g]));let O=1==g?1:0,X=0;7==x&&(X=1),6==x&&(X=.5);let k=0,G=l.random_dec();k=G<.6?0:G<.85?1:2;let N=l.random_num(.005,.015),V=.2*Math.pow(l.random_dec(),3)+.05,q=l.random_num(.15,.25),Y=.3*Math.pow(l.random_dec(),3)+.025,H=.5*Math.pow(l.random_dec(),2),W=Math.pow(2,l.random_int(2,4));W=parseInt(W*(1-H)*(1-Y));let K=l.random_int(1840,1890),j=.3*Math.pow(1-(parseFloat(K)-1840)/50,5),J=0,Q=l.random_dec();J=Q<.18?0:Q<.36?1:Q<.48?2:Q<.6?3:Q<.68?4:Q<.78?5:Q<.93?6:Q<.96?7:8,J>=7&&(k=0),0==x||2==x?8==J&&(J=l.random_int(0,7)):7==x&&(J=l.random_int(4,6)),p>0&&(J=l.random_int(0,5));let Z=l.random_num(.8,1.1);5==x&&(Z=Math.min(Z,.95));let $=parseInt(150*Z),nn=[.2,.8,.2,.8,1.5,1.5,1.25,1.25];1==g&&(nn=[1.2,1.2,1.2,1.2,1.5,1.5,1,1.25]);let en=nn[x],rn=[1.4,1.2,1.4,1.2,.92,.92,1.1,.9][x],tn=[.9,1,.8,1,1,1,1,1][x],on=["Solar Flare","Total Eclipse","Partial Eclipse","Annular Eclipse","Transit","Alignment"][g];7==x&&(on="Transit");const an={width:m,height:v,nOff:_,mapSize:1024,mapScale:32,numParticles:2e5,compId:x,eventId:g,sunPos:z,sunRad:R,sunSign:F,solarActivity:U,solarIntensity:w,flareIntensity:A,atmos:X,numForces:D,numSpots:B,numStars:W,numPlanets:L,bailyBeads:O,borderId:k,borderWidth:N,borderCornerRad:V,damage:j,cityHaze:Y,cloudiness:H,environmentId:p,groundLevel:q,exposure:Z,exposureFrames:$,tintId:J,rf0:l.random_dec(),rf1:l.random_dec(),coronaMulti:en,surfaceMulti:rn,coronaGlowMulti:tn};var sn;sn="#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 position;\nin vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = uv;\n gl_Position = vec4( position, 0, 1 );\n}";const dn=new Float32Array([-1,-1,3,-1,-1,3]),un=new Float32Array([0,0,2,0,0,2]),fn=1/an.mapSize,cn=e=>{const r={};return r.renderer=s(e,{vert:n(sn),frag:n("#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nin vec2 v_uv;\nout vec4 color;\n\nuniform vec2 u_inverseResolution;\nuniform vec2 u_direction;\nuniform vec2 u_resolution;\nuniform sampler2D u_buffer;\n\nvec4 blur(sampler2D image, vec2 uv, vec2 inverseResolution, vec2 direction) {\n vec4 color = vec4(0.0);\n vec2 off1 = vec2(1.411764705882353) * direction;\n vec2 off2 = vec2(3.2941176470588234) * direction;\n vec2 off3 = vec2(5.176470588235294) * direction;\n color += texture(image, uv) * 0.1964825501511404;\n color += texture(image, uv + (off1 * inverseResolution)) * 0.2969069646728344;\n color += texture(image, uv - (off1 * inverseResolution)) * 0.2969069646728344;\n color += texture(image, uv + (off2 * inverseResolution)) * 0.09447039785044732;\n color += texture(image, uv - (off2 * inverseResolution)) * 0.09447039785044732;\n color += texture(image, uv + (off3 * inverseResolution)) * 0.010381362401148057;\n color += texture(image, uv - (off3 * inverseResolution)) * 0.010381362401148057;\n return color;\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / u_resolution;\n color = blur(u_buffer, uv, u_inverseResolution, u_direction);\n}"),attributes:{position:{data:dn,size:2},uv:{data:un,size:2}},count:3}),r.fb=d(e,{width:an.mapSize,height:an.mapSize,tiling:e.REPEAT,type:e.FLOAT,internalFormat:e.RGBA32F}),r},ln=(n,e,r,t,o,a)=>{e.renderer.bindVAOs(),n.bindFramebuffer(n.FRAMEBUFFER,e.fb.write.fb),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,r),e.renderer.bindUniform("u_buffer",0),e.renderer.bindUniform("u_direction",t),e.renderer.bindUniform("u_inverseResolution",[fn,fn]),e.renderer.bindUniform("u_resolution",[o,a]),e.renderer.render(o,a),e.fb.swap()},mn=(n,e,r,t,o)=>(ln(n,r,e,[1,0],t,o),ln(n,r,r.fb.read.targetTexture,[0,1],t,o),r.fb.read.targetTexture),vn={},_n=e=>{const r=an.numParticles;vn.renderer=s(e,{vert:n("#version 300 es\n#define GLSLIFY 1\n\nin vec2 a_position;\nin vec2 a_velocity;\n\nuniform vec2 u_screensize;\n\nout vec2 state;\n\nvoid main() {\n gl_PointSize = 1.;\n state = a_position / u_screensize;\n gl_Position = vec4( state * 2. - 1., 0., 1.);\n}"),frag:n("#version 300 es\nprecision
Solar Transits: The Lost Daguerreotypes is a procedural exploration of the origins of astrophotography. Each image in this series depicts a randomly generated astronomical event but viewed through the lens of mid-to-late 19th century image capture techniques. The collection features a variety of rare alignments of stars, planets and moons, and are rendered in the spirit of the daguerreotype. In June of 2012, I took a trip to Minneapolis to speak at the Eyeo Festival. Venus was going to transit while I was there. I was curious. I had not seen a transit before. At 5:09 pm on June 5th, a nearly imperceptible black circle began its march across the sun. Were it not a predicted mathematical certainty, it is doubtful anyone would have noticed. For six minutes, the light from the sun was 0.087% dimmer. It is a significant thing to see an object silhouetted against the sun. We are so accustom to seeing our perfect circle of pure light that we can't help but to celebrate the occasions where something blocks the view. I still feel a little more excitement when a slight shadow shoots across the landscape on a cloudless day, the source being an extremely rare transit of a commercial jet liner. Exponentially more rare is the planetary transit. When Venus hangs on the horizon, glowing against the night sky, it is all too easy to think it another star. Only when it is viewed in silhouette can its position in our universe be fully appreciated: orbitally locked like us, and forever drawing it's path around the sun. That tiny black circle effected me in a big way. The scale of the cosmos shifted into perspective. That doesn’t happen often. I was incredibly moved. It was an experience I will never forget. This project is an homage to that strange once-in-a-lifetime event. As it turns out, I was very lucky to have seen it at all. In the time since my birth in 1972, a Venus transit has only happened twice. The 1st time was in 2004 but I lived in a part of the world where it was not visible. The 2nd time was in 2012. Unless I live to be 145 years old, there won’t be a 3rd time. There are a couple silver linings: the Great American solar eclipse is on April 8 2024, and Mercury will transit in 2032. The first 10 purchases (above 4 Eth) will receive their output in the form of a framed daguerreotype.
class ParticleSystem{constructor(){this.particles=[],this.forces=[],this.forcePairPs=[]}initForces(){let e=R.random_dec();e*=e;let r=int(lerp(8,35,e)),a=0,t=R.random_num(250,300);for(let e=0;e<r;e++){let r=R.random_dec(),o=R.random_num(50,t),i=R.random_num(0,6.283),s=cos(i)*o+MYHALF,p=sin(i)*o+.425*MYSIZE,n=createVector(s,p),d=0,m=0,c=!1;r<.1&&a<3&&0==SOURCE_ID?(d=15,m=0,c=!0,a++):r<.25?(d=R.random_num(-5,-1.5),m=0,0):r<.35?(d=R.random_num(.5,23),m=R.random_num(-8,8),0):(d=R.random_num(-.25,.25),m=R.random_num(1,55),R.random_bool(.5)&&(m=-m),0);let l=map(n.x,0,MYSIZE,-SCENESCALE,SCENESCALE),E=map(n.y,0,MYSIZE,-SCENESCALE,SCENESCALE),S=createVector(l,E),g=createVector(-l,E);this.addForce(e,S,d,m,c,!1),this.addForce(e+1,g,d,-m,c,!1)}if(0==a&&1!=SOURCE_ID)for(let e=0;e<1;e++){let e=R.random_num(0,.4*SCENESCALE),r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,s=!0;this.addForce(0,a,o,i,s,!1),this.addForce(0,t,o,-i,s,!1)}if(1==SOURCE_ID){let e=0,r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,s=!0;this.addForce(0,a,o,i,s,!1),this.addForce(0,t,o,-i,s,!1)}else if(2==SOURCE_ID)for(let e=0;e<2;e++){let e=R.random_num(.6*-SCENESCALE,.6*SCENESCALE),r=R.random_num(.4*-SCENESCALE,.6*SCENESCALE),a=createVector(e,r),t=(createVector(-e,r),2),o=0,i=!0;this.addForce(0,a,t,o,i,!1)}let o=R.random_num(.65,.75);2==SOURCE_ID&&(o=R.random_num(.9,1));for(let e=0;e<14;e++){let r=map(e,0,14,.5*PI+PI/28,1.5*PI+PI/28),a=R.random_num(.95,1.1),t=cos(r)*SCENESCALE*o*a,i=sin(r)*SCENESCALE*o*a,s=createVector(t,i),p=createVector(-t,i),n=R.random_num(14,18),d=0;this.addForce(e,s,n,d,!1,!0),this.addForce(e+1,p,n,-d,!1,!0)}this.setupForceLines()}setupForceLines(){for(let e=0;e<this.forces.length;e+=2){let r=this.forces[e],a=this.forces[e+1];if(!r.isBoundary){let e=r.pos,t=a.pos,o=map(e.x,-SCENESCALE,SCENESCALE,0,MYSIZE),i=map(e.y,-SCENESCALE,SCENESCALE,0,MYSIZE),s=map(t.x,-SCENESCALE,SCENESCALE,0,MYSIZE),p=map(t.y,-SCENESCALE,SCENESCALE,0,MYSIZE);e=createVector(o,i),t=createVector(s,p),append(this.forcePairPs,e),append(this.forcePairPs,t)}}}update(){let e=R.random_dec();for(let r=0;r<this.forces.length-1;r+=2){let a=this.forces[r+0],t=this.forces[r+1];if(frameMarkTrigger)if(a.isEmitter)a.isEmitter=!1,t.isEmitter=!1;else{let r=!1;a.force<-4&&!a.isBoundary&&(r=!0);let o=R.random_num(-6,6),i=R.random_num(-15,15);if(r&&(o=R.random_num(2,6)),a.updateForce(o,i,r),t.updateForce(o,-i,r),a.isBoundary){let r=map(e,0,1,.65,1.15);a.pos.x=a.origPos.x*r,a.pos.y=a.origPos.y*r,t.pos.x=t.origPos.x*r,t.pos.y=t.origPos.y*r}else if(R.random_bool(.7)){R.random_dec();let e=R.random_num(50,400),r=R.random_num(0,6.283),o=cos(r)*e+MYHALF,i=sin(r)*e+.425*MYSIZE,s=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),p=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE);1==SOURCE_ID&&(s=0),a.pos.x=s,a.pos.y=p,2==SOURCE_ID&&(s=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),p=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE)),t.pos.x=-s,t.pos.y=p}else 1==SOURCE_ID&&r&&(a.pos.x=0,t.pos.x=0)}if(this.particles.length<4e3){if(a.isEmitter)for(let e=0;e<3;e++){let e=new Particle(a.pos);append(this.particles,e)}if(t.isEmitter)for(let e=0;e<3;e++){let e=new Particle(t.pos);append(this.particles,e)}}a.update(),t.update()}for(let e=0;e<this.particles.length;e++){let r=this.particles[e];r.update(this.forces),r.dead&&this.particles.splice(e,1)}}draw(e){e.stroke(color(255,255,255)),e.strokeWeight(.5),e.noFill();for(let r=0;r<this.forces.length;r++){this.forces[r].draw(e)}}drawToPaper(){for(let e=0;e<this.particles.length;e++){let r=this.particles[e],a=r.renderx,t=r.rendery,o=r.renderxo,i=r.renderyo,s=(r.radius,r.dp),p=r.ftd,n=r.std;if(r.age>.01){let e=r.speedLerp*map(frameMarkPer,0,1,15,4);if(e+=3*cos(r.totalDist*SURFACE_VAR),e=max(e,1),e*=1-r.agePer,myFrameCount>=frameMark1&&myFrameCount<frameMark2?e*=.45:myFrameCount>=frameMark2&&(e*=.25),0==r.context){let s=lerpColor(cs[2],cs[1],map(r.totalDist,0,40,0,1,!0));drawDragLine(a,t,o,i,paperBg,cs[1],e*r.augRadius*3.5,r.age),drawDragLine(a,t,o,i,paperMg,s,e*r.augRadius*3,r.age),r.cd=s}else if(1==r.context){let s=sin(.02*pow(n+1,2)),p=cs[1],d=cs[2],m=lerpColor(d,p,s);r.cd=m,drawDragLine(a,t,o,i,paperMg,p,e*r.augRadius*2,r.age),drawDragLine(a,t,o,i,paperFg,m,e*r.augRadius*1.75,r.age)}else if(2==r.context){let s=map(r.age,0,30,1,0,!0),p=lerpColor(cs[2],cs[3],s);r.cd=p,drawDragLine(a,t,o,i,paperFg,p,e*r.augRadius*1.4,r.age)}else if(3==r.context){let p=max(s,0),n=getColor(.5*p+.5);n=lerpColor(n,cs[3],.6),r.cd=n,drawDragLine(a,t,o,i,paperFg,n,e*r.augRadius*1.4,r.age)}else if(4==r.context){let n=map(r.totalDist,0,50,.5,1),d=getColor(n),m=d,c=max(p,0,5,0,1);drawDragLine(a,t,o,i,paperFg,d,e*r.augRadius*1.5,r.age),1==OUTLOOK_ID&&(m=lerpColor(d,getIrriColor(fract(8*s)),(.6*s+.4)*c),drawDragLine(a,t,o,i,paperTg,m,e*r.augRadius*.5,r.age)),r.cd=m}else if(5==r.context){let e=pow(r.agePer,.25),s=cs[4],p=color(red(s),green(s),blue(s),80);r.cd=p,drawDragLine(a,t,o,i,paperTg,p,pow(1-r.agePer,4)*e,r.age)}}}}drawStaticToPaper(){paperBg.noStroke(),paperMg.noStroke(),paperFg.noStroke(),paperTg.noStroke();SCENESCALE;let e=paperMg;e.fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.5)*a.radius*.02;drawStatic(a.renderx,a.rendery,t,e,5)}(e=paperTg).fill(csTrans[1]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.3)*a.radius*.1;drawStatic(a.renderx,a.rendery,t,e,3)}(e=paperFg).fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.2,o=t*t*a.radius;drawStreakedStatic(a.renderx,a.rendery,o,e,4)}if(3==SOURCE_ID){let e=paperFg;e.fill(csTrans[2]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.1,o=t*t*a.radius*.15;drawStreakedStatic(a.renderx,a.rendery,o,e,2)}(e=paperTg).fill(csTrans[3]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed,o=t*t*a.radius*.01;drawStatic(a.renderx,a.rendery,o,e,2)}e=paperFg;for(let r=0;r<this.particles.length;r++)if(R.random_bool(.125)){let a=this.particles[r],t=a.cd,o=a.speed+.2;e.fill(color(red(t),green(t),blue(t),80));let i=o*a.radius*5;drawSplatter(a.renderx,a.rendery,i,e,3)}}(e=paperFg).fill(cs[1]);for(let r=0;r<this.particles.length;r++)if(R.random_bool(.025)){let a=this.particles[r];if(2==a.context||5==a.context){let r=a.speed+.2,t=r*r*a.radius;drawSplatter(a.renderx,a.rendery,t,e,4)}}}addParticle(e){let r=new Particle(e);append(this.particles,r)}addForce(e,r,a,t,o,i){let s=new Force(e,r,a,t,o,i);append(this.forces,s)}}function reset(e){print("Latent Spirit "+tokenData.hash),print("Exposure summary #"+tokenData.tokenId),print("--------------------------------------------------------"),windowWidth<windowHeight?dim=windowWidth:dim=windowHeight,STROKESCALE=275e-6*MYSIZE,dimHalf=.5*dim,buffer=createCanvas(dim,dim),pixelDensity(e),myFrameCount=0,R=new Random,setupFeatures(),createColors(PALETTE_ID),rectMode(CORNERS),img=createGraphics(MYSIZE,MYSIZE),img.rectMode(CORNERS),paperBg=createGraphics(MYSIZE,MYSIZE),paperMg=createGraphics(MYSIZE,MYSIZE),paperFg=createGraphics(MYSIZE,MYSIZE),paperTg=createGraphics(MYSIZE,MYSIZE),paperBg.imageMode(CORNERS),paperMg.imageMode(CORNERS),paperFg.imageMode(CORNERS),paperTg.imageMode(CORNERS),paperBg.rectMode(CORNERS),paperMg.rectMode(CORNERS),paperFg.rectMode(CORNERS),paperTg.rectMode(CORNERS);let r=cs[0];paperBg.background(color(red(r),green(r),blue(r),255)),paperMg.background(255,255,255,0),paperFg.background(255,255,255,0),paperTg.background(255,255,255,0),papers=[],append(papers,paperBg),append(papers,paperMg),append(papers,paperFg),append(papers,paperTg),GRAVITY=R.random_num(.03,.06),R.random_bool(.5)&&(GRAVITY=-GRAVITY),frameMark1=R.random_int(350,500),frameMark2=frameMark1+R.random_int(300,470),totalFrames=frameMark2+R.random_int(300,400),frameMarkPer=0,frameMarkTrigger=!1,blurryBg=new BlurryBg,0==BG_ID||1==BG_ID?blurryBg.drawMain(papers[1]):2==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawAnarchic(papers[1],1)):3==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawConcentric(papers[2])):4==BG_ID&&(blurryBg.drawMain(papers[1]),blurryBg.drawSpiritual(papers[1])),rorschach=new Rorschach,rorschachTop=new Rorschach,pSystem=new ParticleSystem,pSystem.initForces()}function setup(){reset(2)}function setupFeatures(){let e=R.random_dec(),r=int(map(pow(e,1.5),0,1,0,15));PALETTE_ID=min(r,14),R.random_dec()<.075&&(PALETTE_ID=13);let a=R.random_dec();BG_ID=a<.1?0:a<.3?1:a<.85?2:a<.95?3:4;let t=R.random_dec();SOURCE_ID=t<.8?0:t<.95?1:t<.98?2:3,BASIS_ID=0,R.random_bool(.4)&&(BASIS_ID=1),BASIS_OCTAVES=2*R.random_int(4,8),OUTLOOK_ID=0,R.random_bool(.3)&&(OUTLOOK_ID=1),SURFACE_VAR=R.random_num(.3,.8),print("Your aura is "+AURAS[PALETTE_ID]+". "+ODDS[R.random_int(0,3)]+" you are "+MEANINGS[PALETTE_ID]+"."),print("The source of your energy is "+SOURCES[SOURCE_ID]+". "+BGS[BG_ID]+"."),print("You have a tendency to be "+BASIS_TYPES[BASIS_ID]+" which is expressed through your "+OUTLOOK_TYPES[OUTLOOK_ID]+"."),print(" "),print("Look at your latent spirit. Focus on its features. Find its source."),print("What do you see?")}function draw(){img.clear(),myFrameCount<=frameMark1?frameMarkPer=map(myFrameCount,0,frameMark1,0,1):myFrameCount<=frameMark2?frameMarkPer=map(myFrameCount,frameMark1,frameMark2,0,1):frameMarkPer=map(myFrameCount,frameMark2,totalFrames,0,1,!0),myFrameCount==frameMark1||myFrameCount==frameMark2?frameMarkTrigger=!0:frameMarkTrigger=!1,2==BG_ID&&myFrameCount==frameMark1&&blurryBg.drawAnarchic(papers[2],.35),myFrameCount<12&&1==BG_ID&&(rorschach.drawDarks(paperMg,1),rorschach.drawLights(paperFg,1),rorschachTop.drawDarks(paperMg,1.25),rorschachTop.drawLights(paperFg,1.25)),myFrameCount<totalFrames&&(pSystem.update(),pSystem.drawToPaper(),pSystem.drawStaticToPaper(),3==SOURCE_ID&&(myFrameCount==frameMark1?drawForceLines(pSystem.forcePairPs,cs[2]):myFrameCount==frameMark2&&drawForceLines(pSystem.forcePairPs,cs[4]))),push(),translate(dimHalf,dimHalf),FLIP_VERT&&(rotate(PI),scale(-1,1,1));for(let e=0;e<4;e++)image(papers[e],-dimHalf,-dimHalf,dim,dim);if(SHOW_FORCES&&(pSystem.draw(img),image(img,-dimHalf,-dimHalf,dim,dim)),pop(),DEBUG){let e=map(myFrameCount,0,totalFrames,0,.5*dim);noStroke(),fill(cs[0]),rect(dimHalf-e-1,0,dimHalf+e+1,3),fill(cs[3]),rect(dimHalf-e,1,dimHalf+e,2)}myFrameCount==totalFrames-1&&(DEBUG=!1),SAVE_PRINTRES&&myFrameCount==totalFrames&&(save(tokenData.hash+".png"),SAVE_PRINTRES=!1),myFrameCount++}
let dim,dimHalf,buffer,STROKESCALE,img,paperBg,paperMg,paperFg,paperTg,pSystem,blurryBg,rorschach,rorschachTop,BG_ID,SOURCE_ID,BASIS_ID,BASIS_OCTAVES,OUTLOOK_ID,SURFACE_VAR,myFrameCount,frameMark1,frameMark2,frameMarkPer,frameMarkTrigger,totalFrames,MYSIZE=1600,MYHALF=MYSIZE/2,SCENESCALE=100,GRAVITY=0,MINSPEED=.01,MAXSPEED=.75,papers=[],cs=[],csTrans=[],csIrri=[],AURAS=["pale yellow on deep blue","an intense green","an aggressive orange","bright deep red","soft green on a deep purple","grey and green with bright red","bright blue and pink","an intense yellow","peach orange and yellow","pale orange and dark teal","neon green in a grey void","powder blue","bright but lacking color","dark and lacking color","dark shadowy red"],MEANINGS=["filled with an impenetrable calm","enjoying growth and renewal","experiencing focused anger","full of fear, uncertainty and doubt","very calm and alert","very wise and energetic","introverted and highly compassionate","nurturing hope","an outgoing social creature","secure but sad","suspicious","eager and resourceful","aware but distant","sensing a foreboding future","confident and energetic"],BGS=["You are a blank slate","Your obstructions are indistinct","However, you have many deep obstructions","You are aligned","You carry a spirit with you"],SOURCES=["normal","very centered","unusual","surprisingly bright"],ODDS=["This usually means","This often means","This generally means","This can mean"],BASIS_TYPES=["disorganized","organized"],OUTLOOK_TYPES=["negativity","positivity"],FLIP_VERT=!1,SHOW_FORCES=!0,DEBUG=!1,SAVE_PRINTRES=!1;function genTokenData(e){let t={},r="0x";for(var s=0;s<64;s++)r+=Math.floor(16*Math.random()).toString(16);return t.hash=r,t.tokenId=(1e6*e).toString(),t}class Random{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),r=parseInt(e.substr(8,8),16),s=parseInt(e.substr(16,8),16),i=parseInt(e.substr(24,8),16);return function(){let e=((t|=0)+(r|=0)|0)+(i|=0)|0;return i=i+1|0,t=r^r>>>9,r=(s|=0)+(s<<3)|0,s=(s=s<<21|s>>>11)+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(e,t){return e+(t-e)*this.random_dec()}random_int(e,t){return Math.floor(this.random_num(e,t+1))}random_bool(e){return this.random_dec()<e}random_choice(e){return e[this.random_int(0,e.length-1)]}}function createColors(e){let t=[];append(t,[1,3,38,1,31,38,166,138,55,242,209,109,242,235,141]),append(t,[4,41,64,0,92,83,159,193,49,219,242,39,255,252,102]),append(t,[31,38,35,59,64,57,255,133,0,255,179,0,255,230,67]),append(t,[15,15,15,35,35,35,107,9,47,255,41,58,255,125,74]),append(t,[45,7,77,75,39,122,0,148,134,35,235,178,183,255,227]),append(t,[117,10,10,255,74,11,79,180,139,167,233,177,212,255,185]),append(t,[142,2,45,242,21,143,148,7,242,4,107,242,4,156,216]),append(t,[12,49,94,7,101,219,255,192,18,255,239,3,255,255,102]),append(t,[242,232,101,242,177,99,242,142,106,242,106,94,225,253,247]),append(t,[23,42,46,22,63,69,217,103,37,242,150,80,247,206,105]),append(t,[25,25,25,55,55,55,100,100,100,200,255,100,235,255,150]),append(t,[36,39,41,68,69,55,65,185,220,124,204,217,244,247,217]),append(t,[11,11,11,40,40,40,210,210,210,240,240,240,255,255,255]),append(t,[205,205,205,255,255,255,0,0,0,15,15,15,235,235,235]),append(t,[89,1,1,165,9,51,242,55,105,0,0,0,242,75,136]),cs=[],csTrans=[],csIrri=[];let r=t[e];for(let e=0;e<5;e++){let t=3*e,s=r[t+0],i=r[t+1],a=r[t+2],n=color(s,i,a),o=color(s,i,a,60);append(cs,n),append(csTrans,o)}for(let e=0;e<5;e++)append(csIrri,color(255,100,100)),append(csIrri,color(255,190,100)),append(csIrri,color(200,255,110)),append(csIrri,color(100,155,255)),append(csIrri,color(150,100,200))}function getColor(e){let t;if(e<.25){let r=map(e,0,.25,0,1);t=lerpColor(cs[0],cs[1],r)}else if(e<.5){let r=map(e,.25,.5,0,1);t=lerpColor(cs[1],cs[2],r)}else if(e<.75){let r=map(e,.5,.75,0,1);t=lerpColor(cs[2],cs[3],r)}else{let r=map(e,.75,1,0,1);t=lerpColor(cs[3],cs[4],r)}return t}function getIrriColor(e){let t;if(e<.2){let r=map(e,0,.2,0,1);t=lerpColor(csIrri[0],csIrri[1],r)}else if(e<.4){let r=map(e,.2,.4,0,1);t=lerpColor(csIrri[1],csIrri[2],r)}else if(e<.6){let r=map(e,.4,.6,0,1);t=lerpColor(csIrri[2],csIrri[3],r)}else if(e<.8){let r=map(e,.6,.8,0,1);t=lerpColor(csIrri[3],csIrri[4],r)}else{let r=map(e,.8,1,0,1);t=lerpColor(csIrri[4],csIrri[0],r)}return t}function drawDragLine(e,t,r,s,i,a,n,o){i.stroke(a),i.strokeWeight(n),i.line(e,t,r,s)}function drawStatic(e,t,r,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(r)),a=R.random_num(-PI,PI),n=sin(a),o=e+cos(a)*i,h=t+n*i;s.circle(o,h,STROKESCALE)}}function drawSplatter(e,t,r,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,130*sqrt(r)),a=R.random_num(-PI,PI),n=sin(a),o=e+cos(a)*i,h=t+n*i,l=1*pow(.9*R.random_dec(),3)+.05;s.circle(o,h,l)}}function drawStreakedStatic(e,t,r,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(r)),a=R.random_num(-PI,PI),n=sin(a),o=e+cos(a)*i,h=t+n*i*.25;s.circle(o,h,STROKESCALE)}}function keyTyped(){"d"==key&&(DEBUG=!DEBUG),"r"==key||("s"==key?(reset(6),SAVE_PRINTRES=!0):"v"==key?FLIP_VERT=!FLIP_VERT:"f"==key&&(SHOW_FORCES=!SHOW_FORCES))}function drawForceLines(e,t){if(e.length>1)for(let r=0;r<e.length;r+=2){let s=e[r],i=e[r+1],a=R.random_int(0,3),n=paperBg;1==a?n=paperMg:2==a?n=paperFg:3==a&&(n=paperTg),n.stroke(t),n.strokeWeight(2),n.fill(cs[0]),n.line(s.x,s.y,i.x,i.y),n.circle(s.x,s.y,4),n.circle(i.x,i.y,4)}}class BlurryBg{constructor(){}drawMain(e){e.noStroke();let t=1.375*MYSIZE,r=MYHALF,s=MYHALF-55;for(let i=0;i<200;i++){let a=map(i,0,129,0,1,!0),n=lerpColor(cs[0],cs[1],a);e.fill(n),e.circle(r,s,t),s-=.002*(t*=.995)}}drawAnarchic(e,t){e.noStroke();let r=MYHALF;for(let s=0;s<10;s++){let s=R.random_num(100,650)*t;R.random_bool(.6)?e.fill(cs[1]):(e.fill(cs[3]),s*=1.5);let i=R.random_num(MYHALF-350,MYHALF+260);e.circle(r,i,s)}}drawSpiritual(e){let t=MYSIZE*R.random_num(.45,.8),r=MYHALF,s=MYHALF-150;e.noStroke(),e.fill(cs[2]),e.circle(r,s,t)}drawConcentric(e){let t=e,r=.95*MYSIZE,s=MYHALF,i=MYHALF-300;for(let e=0;e<7;e++){let a=map(e,0,7,.1,.9);(t=0==e?paperBg:1==e?paperBg:2==e?paperMg:3==e?paperMg:paperFg).noStroke(),t.fill(getColor(a)),t.circle(s,i,r),r-=170,i+=55}}}class Rorschach{constructor(){this.numDark=R.random_int(5,11),this.numLight=R.random_int(5,11),this.darks=[],this.lights=[];for(let e=0;e<this.numDark;e++){let e=R.random_num(-400,400),t=R.random_num(-200,150),r=R.random_num(100,500),s=createVector(e,t,r);append(this.darks,s)}for(let e=0;e<this.numLight;e++){let e=R.random_num(-420,420),t=R.random_num(-200,150);e*=map(t,-300,250,1,.5);let r=R.random_num(170,330),s=createVector(e,t,r);append(this.lights,s)}}drawDarks(e,t){let r=cs[0];e.fill(color(red(r),green(r),blue(r),4)),e.noStroke();for(let r=0;r<this.numDark;r++){let s=this.darks[r],i=s.x*t,a=s.y*t,n=s.z*t;e.circle(MYHALF+i,MYHALF+a,n),e.circle(MYHALF-i,MYHALF+a,n),s.z*=.975}}drawLights(e,t){let r=cs[1];e.fill(color(red(r),green(r),blue(r),4)),e.noStroke();for(let r=0;r<this.numLight;r++){let s=this.lights[r],i=s.x*t,a=s.y*t,n=s.z*t;e.circle(MYHALF+i,MYHALF+a,n),e.circle(MYHALF-i,MYHALF+a,n),s.z*=.985}}}class Force{constructor(e,t,r,s,i,a){this.id=e,this.pos=t.copy(),this.origPos=t.copy(),this.force=2*r,this.rotForce=2*s,this.isEmitter=i,this.isBoundary=a,this.radius=5,this.age=0,this.isEmitter&&(this.cd=color(255,255,0),this.radius=15)}updateForce(e,t,r){this.force=e,this.rotForce=t,this.isEmitter=r}update(){this.age+=1}draw(e){if(!this.isBoundary&&this.radius>6){let t=SCENESCALE,r=map(this.pos.x,-t,t,0,MYSIZE),s=map(this.pos.y,-t,t,0,MYSIZE),i=min(abs(this.pos.x),this.radius);e.noStroke();for(let t=0;t<5;t++)e.fill(cs[t]),e.circle(r,s,i),i*=.8}}drawToPaper(e){if(e.fill(color(0,0,0,25)),e.noStroke(),!this.isBoundary){let t=SCENESCALE,r=map(1.08*this.pos.x,-t,t,0,MYSIZE),s=map(1.08*this.pos.y,-t,t,0,MYSIZE),i=15*this.radius;for(let t=0;t<25;t++)e.circle(r,s,i),i*=.95}}}class Particle{constructor(e){this.context=Math.min(int(map(frameMarkPer,0,1,0,6)),5),this.x=e.x,this.y=e.y,this.px=e.x,this.py=e.y;let t=R.random_num(-PI,PI);if(this.context>=2&&1==BASIS_ID){let e=map(t,-PI,PI,0,1);e=int(e*BASIS_OCTAVES)/float(BASIS_OCTAVES),t=e=map(e,0,1,-PI,PI)}this.speed=R.random_num(1,2.1),this.vx=Math.cos(t)*this.speed,this.vy=Math.sin(t)*this.speed,this.px+=.05*this.vx,this.py+=.05*this.vy,this.x+=.1*this.vx,this.y+=.1*this.vy,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderxo=map(this.px,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderyo=map(this.py,-SCENESCALE,SCENESCALE,0,MYSIZE),this.ax=0,this.ay=0,this.speedLerp=this.speed,this.cd=color(0,0,0),this.radius=R.random_num(.3,3),this.mass=R.random_num(.8,1.2),this.augRadius=this.radius,this.dp=0,this.ftd=0,this.std=0,this.totalDist=0,this.decay=R.random_num(.95,.975),this.age=0,this.agePer=0,this.life=300,this.dead=!1}update(e){this.px=this.x,this.py=this.y,this.ftd=0,this.std=0;for(let t=0;t<e.length;t++){let r=e[t],s=this.x-r.pos.x,i=this.y-r.pos.y,a=createVector(s,i),n=a.mag(),o=n*n,h=1/o;a=a.normalize();let l=createVector(a.y,-a.x);l=p5.Vector.mult(l,h*r.rotForce*this.mass),a=p5.Vector.mult(a,h*r.force*this.mass),this.ax+=a.x+l.x,this.ay+=a.y+l.y,o<.5&&!r.isEmitter&&(this.dead=!0,r.radius+=.025),r.isEmitter&&(this.ftd+=n,this.std+=sin(10*n))}this.ay+=map(myFrameCount,0,75,GRAVITY,.01,!0),this.vx+=this.ax,this.vy+=this.ay;let t=createVector(this.vx,this.vy),r=t.copy().normalize();this.speed=t.mag(),this.speed>MAXSPEED?(t=p5.Vector.mult(r,MAXSPEED),this.speed=MAXSPEED):this.speed<MINSPEED&&(t=p5.Vector.mult(r,MINSPEED),this.speed=MINSPEED),this.vx=t.x,this.vy=t.y,this.dp=p5.Vector.dot(r,createVector(0,1)),this.dp=map(this.dp,-1,1,0,1),this.totalDist+=this.vx*this.vx+this.vy*this.vy,this.x+=this.vx,this.y+=this.vy,this.vx*=this.decay,this.vy*=this.decay,this.speed=this.vx*this.vx+this.vy*this.vy,this.ax=0,this.ay=0,this.age+=1,this.agePer=this.age/this.life,this.radius*=.99,this.augRadius=this.radius*map(cos(.25*this.totalDist),-1,1,.3,1),this.speedLerp-=.15*(this.speedLerp-this.speed),this.renderxo=this.renderx,this.renderyo=this.rendery,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),(abs(this.x)>1.1*SCENESCALE||abs(this.y)>1.1*SCENESCALE)&&(this.dead=!0),this.age>this.life&&(this.dead=!0)}}
class ParticleSystem{constructor(){this.particles=[],this.forces=[],this.forcePairPs=[]}initForces(){let e=R.random_dec();e*=e;let r=int(lerp(8,35,e)),a=0,t=R.random_num(250,300);for(let e=0;e<r;e++){let r=R.random_dec(),o=R.random_num(50,t),i=R.random_num(0,6.283),p=cos(i)*o+MYHALF,s=sin(i)*o+.425*MYSIZE,d=createVector(p,s),n=0,m=0,c=!1;r<.1&&a<3&&0==SOURCE_ID?(n=15,m=0,c=!0,a++):r<.25?(n=R.random_num(-5,-1.5),m=0,0):r<.35?(n=R.random_num(.5,23),m=R.random_num(-8,8),0):(n=R.random_num(-.25,.25),m=R.random_num(1,55),R.random_bool(.5)&&(m=-m),0);let l=map(d.x,0,MYSIZE,-SCENESCALE,SCENESCALE),E=map(d.y,0,MYSIZE,-SCENESCALE,SCENESCALE),S=createVector(l,E),g=createVector(-l,E);this.addForce(e,S,n,m,c,!1),this.addForce(e+1,g,n,-m,c,!1)}if(0==a&&1!=SOURCE_ID)for(let e=0;e<1;e++){let e=R.random_num(0,.4*SCENESCALE),r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,p=!0;this.addForce(0,a,o,i,p,!1),this.addForce(0,t,o,-i,p,!1)}if(1==SOURCE_ID){let e=0,r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,p=!0;this.addForce(0,a,o,i,p,!1),this.addForce(0,t,o,-i,p,!1)}else if(2==SOURCE_ID)for(let e=0;e<2;e++){let e=R.random_num(.6*-SCENESCALE,.6*SCENESCALE),r=R.random_num(.4*-SCENESCALE,.6*SCENESCALE),a=createVector(e,r),t=(createVector(-e,r),2),o=0,i=!0;this.addForce(0,a,t,o,i,!1)}let o=R.random_num(.65,.75);2==SOURCE_ID&&(o=R.random_num(.9,1));for(let e=0;e<14;e++){let r=map(e,0,14,.5*PI+PI/28,1.5*PI+PI/28),a=R.random_num(.95,1.1),t=cos(r)*SCENESCALE*o*a,i=sin(r)*SCENESCALE*o*a,p=createVector(t,i),s=createVector(-t,i),d=R.random_num(14,18),n=0;this.addForce(e,p,d,n,!1,!0),this.addForce(e+1,s,d,-n,!1,!0)}this.setupForceLines()}setupForceLines(){for(let e=0;e<this.forces.length;e+=2){let r=this.forces[e],a=this.forces[e+1];if(!r.isBoundary){let e=r.pos,t=a.pos,o=map(e.x,-SCENESCALE,SCENESCALE,0,MYSIZE),i=map(e.y,-SCENESCALE,SCENESCALE,0,MYSIZE),p=map(t.x,-SCENESCALE,SCENESCALE,0,MYSIZE),s=map(t.y,-SCENESCALE,SCENESCALE,0,MYSIZE);e=createVector(o,i),t=createVector(p,s),append(this.forcePairPs,e),append(this.forcePairPs,t)}}}update(){let e=R.random_dec();for(let r=0;r<this.forces.length-1;r+=2){let a=this.forces[r+0],t=this.forces[r+1];if(frameMarkTrigger)if(a.isEmitter)a.isEmitter=!1,t.isEmitter=!1;else{let r=!1;a.force<-4&&!a.isBoundary&&(r=!0);let o=R.random_num(-6,6),i=R.random_num(-15,15);if(r&&(o=R.random_num(2,6)),a.updateForce(o,i,r),t.updateForce(o,-i,r),a.isBoundary){let r=map(e,0,1,.65,1.15);a.pos.x=a.origPos.x*r,a.pos.y=a.origPos.y*r,t.pos.x=t.origPos.x*r,t.pos.y=t.origPos.y*r}else if(R.random_bool(.7)){R.random_dec();let e=R.random_num(50,400),r=R.random_num(0,6.283),o=cos(r)*e+MYHALF,i=sin(r)*e+.425*MYSIZE,p=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),s=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE);1==SOURCE_ID&&(p=0),a.pos.x=p,a.pos.y=s,2==SOURCE_ID&&(p=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),s=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE)),t.pos.x=-p,t.pos.y=s}else 1==SOURCE_ID&&r&&(a.pos.x=0,t.pos.x=0)}if(this.particles.length<4e3){if(a.isEmitter)for(let e=0;e<3;e++){let e=new Particle(a.pos);append(this.particles,e)}if(t.isEmitter)for(let e=0;e<3;e++){let e=new Particle(t.pos);append(this.particles,e)}}a.update(),t.update()}for(let e=0;e<this.particles.length;e++){let r=this.particles[e];r.update(this.forces),r.dead&&this.particles.splice(e,1)}}draw(e){e.stroke(color(255,255,255)),e.strokeWeight(.5),e.noFill();for(let r=0;r<this.forces.length;r++){this.forces[r].draw(e)}}drawToPaper(){for(let e=0;e<this.particles.length;e++){let r=this.particles[e],a=r.renderx,t=r.rendery,o=r.renderxo,i=r.renderyo,p=(r.radius,r.dp),s=r.ftd,d=r.std;if(r.age>.01){let e=r.speedLerp*map(frameMarkPer,0,1,15,4);if(e+=3*cos(r.totalDist*SURFACE_VAR),e=max(e,1),e*=1-r.agePer,myFrameCount>=frameMark1&&myFrameCount<frameMark2?e*=.45:myFrameCount>=frameMark2&&(e*=.25),0==r.context){let p=lerpColor(cs[2],cs[1],map(r.totalDist,0,40,0,1,!0));drawDragLine(a,t,o,i,paperBg,cs[1],e*r.augRadius*3.5,r.age),drawDragLine(a,t,o,i,paperMg,p,e*r.augRadius*3,r.age),r.cd=p}else if(1==r.context){let p=sin(.02*pow(d+1,2)),s=cs[1],n=cs[2],m=lerpColor(n,s,p);r.cd=m,drawDragLine(a,t,o,i,paperMg,s,e*r.augRadius*2,r.age),drawDragLine(a,t,o,i,paperFg,m,e*r.augRadius*1.75,r.age)}else if(2==r.context){let p=map(r.age,0,30,1,0,!0),s=lerpColor(cs[2],cs[3],p);r.cd=s,drawDragLine(a,t,o,i,paperFg,s,e*r.augRadius*1.4,r.age)}else if(3==r.context){let s=max(p,0),d=getColor(.5*s+.5);d=lerpColor(d,cs[3],.6),r.cd=d,drawDragLine(a,t,o,i,paperFg,d,e*r.augRadius*1.4,r.age)}else if(4==r.context){let d=map(r.totalDist,0,50,.5,1),n=getColor(d),m=n,c=max(s,0,5,0,1);drawDragLine(a,t,o,i,paperFg,n,e*r.augRadius*1.5,r.age),1==OUTLOOK_ID&&(m=lerpColor(n,getIrriColor(fract(8*p)),(.6*p+.4)*c),drawDragLine(a,t,o,i,paperTg,m,e*r.augRadius*.5,r.age)),r.cd=m}else if(5==r.context){let e=pow(r.agePer,.25),p=cs[4],s=color(red(p),green(p),blue(p),80);r.cd=s,drawDragLine(a,t,o,i,paperTg,s,pow(1-r.agePer,4)*e,r.age)}}}}drawStaticToPaper(){paperBg.noStroke(),paperMg.noStroke(),paperFg.noStroke(),paperTg.noStroke();SCENESCALE;let e=paperMg;e.fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.5)*a.radius*.02;drawStatic(a.renderx,a.rendery,t,e,5)}(e=paperTg).fill(csTrans[1]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.3)*a.radius*.1;drawStatic(a.renderx,a.rendery,t,e,3)}(e=paperFg).fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.2,o=t*t*a.radius;drawStreakedStatic(a.renderx,a.rendery,o,e,4)}if(3==SOURCE_ID){let e=paperFg;e.fill(csTrans[2]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.1,o=t*t*a.radius*.15;drawStreakedStatic(a.renderx,a.rendery,o,e,2)}(e=paperTg).fill(csTrans[3]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed,o=t*t*a.radius*.01;drawStatic(a.renderx,a.rendery,o,e,2)}e=paperFg;for(let r=0;r<this.particles.length;r++)if(R.random_bool(.125)){let a=this.particles[r],t=a.cd,o=a.speed+.2;e.fill(color(red(t),green(t),blue(t),80));let i=o*a.radius*5;drawSplatter(a.renderx,a.rendery,i,e,3)}}(e=paperFg).fill(cs[1]);for(let r=0;r<this.particles.length;r++)if(R.random_bool(.025)){let a=this.particles[r];if(2==a.context||5==a.context){let r=a.speed+.2,t=r*r*a.radius;drawSplatter(a.renderx,a.rendery,t,e,4)}}}addParticle(e){let r=new Particle(e);append(this.particles,r)}addForce(e,r,a,t,o,i){let p=new Force(e,r,a,t,o,i);append(this.forces,p)}}function reset(e){print(tokenData.hash),print(tokenData.tokenId),windowWidth<windowHeight?dim=windowWidth:dim=windowHeight,STROKESCALE=275e-6*MYSIZE,print("dim = "+dim),dimHalf=.5*dim,buffer=createCanvas(dim,dim),pixelDensity(e),myFrameCount=0,R=new Random,setupFeatures(),createColors(PALETTE_ID),rectMode(CORNERS),img=createGraphics(MYSIZE,MYSIZE),img.rectMode(CORNERS),paperBg=createGraphics(MYSIZE,MYSIZE),paperMg=createGraphics(MYSIZE,MYSIZE),paperFg=createGraphics(MYSIZE,MYSIZE),paperTg=createGraphics(MYSIZE,MYSIZE),paperBg.imageMode(CORNERS),paperMg.imageMode(CORNERS),paperFg.imageMode(CORNERS),paperTg.imageMode(CORNERS),paperBg.rectMode(CORNERS),paperMg.rectMode(CORNERS),paperFg.rectMode(CORNERS),paperTg.rectMode(CORNERS);let r=cs[0];paperBg.background(color(red(r),green(r),blue(r),255)),paperMg.background(255,255,255,0),paperFg.background(255,255,255,0),paperTg.background(255,255,255,0),papers=[],append(papers,paperBg),append(papers,paperMg),append(papers,paperFg),append(papers,paperTg),GRAVITY=R.random_num(.03,.06),R.random_bool(.5)&&(GRAVITY=-GRAVITY),frameMark1=R.random_int(350,500),frameMark2=frameMark1+R.random_int(300,470),totalFrames=frameMark2+R.random_int(300,400),frameMarkPer=0,frameMarkTrigger=!1,blurryBg=new BlurryBg,0==BG_ID||1==BG_ID?blurryBg.drawMain(papers[1]):2==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawAnarchic(papers[1],1)):3==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawConcentric(papers[2])):4==BG_ID&&(blurryBg.drawMain(papers[1]),blurryBg.drawSpiritual(papers[1])),rorschach=new Rorschach,rorschachTop=new Rorschach,pSystem=new ParticleSystem,pSystem.initForces()}function setup(){reset(2)}function setupFeatures(){let e=R.random_dec(),r=int(map(pow(e,1.5),0,1,0,15));PALETTE_ID=min(r,14),R.random_dec()<.075&&(PALETTE_ID=13);let a=R.random_dec();BG_ID=a<.1?0:a<.3?1:a<.85?2:a<.95?3:4;let t=R.random_dec();SOURCE_ID=t<.8?0:t<.95?1:t<.98?2:3,BASIS_ID=0,R.random_bool(.4)&&(BASIS_ID=1),BASIS_OCTAVES=2*R.random_int(4,8),OUTLOOK_ID=0,R.random_bool(.3)&&(OUTLOOK_ID=1),SURFACE_VAR=R.random_num(.3,.8),print("palette = "+PALETTES[PALETTE_ID]),print("obstruction = "+BG_TYPES[BG_ID]),print("source = "+SOURCE_TYPES[SOURCE_ID]),print("basis = "+BASIS_TYPES[BASIS_ID]),print("octaves = "+BASIS_OCTAVES),print("outlook = "+OUTLOOK_TYPES[OUTLOOK_ID]),print("surface var = "+SURFACE_VAR)}function draw(){img.clear(),myFrameCount<=frameMark1?frameMarkPer=map(myFrameCount,0,frameMark1,0,1):myFrameCount<=frameMark2?frameMarkPer=map(myFrameCount,frameMark1,frameMark2,0,1):frameMarkPer=map(myFrameCount,frameMark2,totalFrames,0,1,!0),myFrameCount==frameMark1||myFrameCount==frameMark2?frameMarkTrigger=!0:frameMarkTrigger=!1,2==BG_ID&&myFrameCount==frameMark1&&blurryBg.drawAnarchic(papers[2],.35),myFrameCount<12&&1==BG_ID&&(rorschach.drawDarks(paperMg,1),rorschach.drawLights(paperFg,1),rorschachTop.drawDarks(paperMg,1.25),rorschachTop.drawLights(paperFg,1.25)),myFrameCount<totalFrames&&(pSystem.update(),pSystem.drawToPaper(),pSystem.drawStaticToPaper(),3==SOURCE_ID&&(myFrameCount==frameMark1?drawForceLines(pSystem.forcePairPs,cs[2]):myFrameCount==frameMark2&&drawForceLines(pSystem.forcePairPs,cs[4]))),push(),translate(dimHalf,dimHalf),FLIP_VERT&&(rotate(PI),scale(-1,1,1));for(let e=0;e<4;e++)image(papers[e],-dimHalf,-dimHalf,dim,dim);if(SHOW_FORCES&&(pSystem.draw(img),image(img,-dimHalf,-dimHalf,dim,dim)),pop(),DEBUG){let e=map(myFrameCount,0,totalFrames,0,.5*dim);noStroke(),fill(cs[0]),rect(dimHalf-e-1,0,dimHalf+e+1,3),fill(cs[3]),rect(dimHalf-e,1,dimHalf+e,2)}myFrameCount==totalFrames-1&&(DEBUG=!1),SAVE_PRINTRES&&myFrameCount==totalFrames&&(save(tokenData.hash+".png"),SAVE_PRINTRES=!1),myFrameCount++}
let dim,dimHalf,buffer,STROKESCALE,img,paperBg,paperMg,paperFg,paperTg,pSystem,blurryBg,rorschach,rorschachTop,PALETTE_ID,BG_ID,SOURCE_ID,BASIS_ID,BASIS_OCTAVES,OUTLOOK_ID,SURFACE_VAR,myFrameCount,frameMark1,frameMark2,frameMarkPer,frameMarkTrigger,totalFrames,MYSIZE=1600,MYHALF=MYSIZE/2,SCENESCALE=100,GRAVITY=0,MINSPEED=.01,MAXSPEED=.75,papers=[],cs=[],csTrans=[],csIrri=[],PALETTES=["IMPENETRABLE_CALM","GROWTH_AND_RENEWAL","FOCUSED_ANGER","FEAR, UNCERTAINTY, AND DOUBT","CALM_BUT_ALERT","WISE_AND_ENERGETIC","INTROVERTED_AND_COMPASSIONATE","NURTURED_HOPE","SOCIAL_CREATURE","SECURE_BUT_SAD","SUSPICIOUS","EAGER AND RESOURCEFUL","AWARE_BUT_DISTANT","FOREBODING","CONFIDENT_ENERGY"],BG_TYPES=["TABULA RASA","PROJECTIVE","ANARCHIC","ALIGNED","SPIRITUAL"],SOURCE_TYPES=["NORMAL","CENTERED","PSYCHO-ANOMALOUS","ASCENDED"],BASIS_TYPES=["DISORGANIZED","ORGANIZED"],OUTLOOK_TYPES=["NEGATIVITY","POSITIVITY"],FLIP_VERT=!1,SHOW_FORCES=!0,DEBUG=!1,SAVE_PRINTRES=!1;function genTokenData(t){let r={},s="0x";for(var e=0;e<64;e++)s+=Math.floor(16*Math.random()).toString(16);return r.hash=s,r.tokenId=(1e6*t).toString(),r}class Random{constructor(){this.useA=!1;let t=function(t){let r=parseInt(t.substr(0,8),16),s=parseInt(t.substr(8,8),16),e=parseInt(t.substr(16,8),16),i=parseInt(t.substr(24,8),16);return function(){let t=((r|=0)+(s|=0)|0)+(i|=0)|0;return i=i+1|0,r=s^s>>>9,s=(e|=0)+(e<<3)|0,e=(e=e<<21|e>>>11)+t|0,(t>>>0)/4294967296}};this.prngA=new t(tokenData.hash.substr(2,32)),this.prngB=new t(tokenData.hash.substr(34,32));for(let t=0;t<1e6;t+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(t,r){return t+(r-t)*this.random_dec()}random_int(t,r){return Math.floor(this.random_num(t,r+1))}random_bool(t){return this.random_dec()<t}random_choice(t){return t[this.random_int(0,t.length-1)]}}function createColors(t){let r=[];append(r,[1,3,38,1,31,38,166,138,55,242,209,109,242,235,141]),append(r,[4,41,64,0,92,83,159,193,49,219,242,39,255,252,102]),append(r,[31,38,35,59,64,57,255,133,0,255,179,0,255,230,67]),append(r,[15,15,15,35,35,35,107,9,47,255,41,58,255,125,74]),append(r,[45,7,77,75,39,122,0,148,134,35,235,178,183,255,227]),append(r,[117,10,10,255,74,11,79,180,139,167,233,177,212,255,185]),append(r,[142,2,45,242,21,143,148,7,242,4,107,242,4,156,216]),append(r,[12,49,94,7,101,219,255,192,18,255,239,3,255,255,102]),append(r,[242,232,101,242,177,99,242,142,106,242,106,94,225,253,247]),append(r,[23,42,46,22,63,69,217,103,37,242,150,80,247,206,105]),append(r,[25,25,25,55,55,55,100,100,100,200,255,100,235,255,150]),append(r,[36,39,41,68,69,55,65,185,220,124,204,217,244,247,217]),append(r,[11,11,11,40,40,40,210,210,210,240,240,240,255,255,255]),append(r,[205,205,205,255,255,255,0,0,0,15,15,15,235,235,235]),append(r,[89,1,1,165,9,51,242,55,105,0,0,0,242,75,136]),cs=[],csTrans=[],csIrri=[];let s=r[t];for(let t=0;t<5;t++){let r=3*t,e=s[r+0],i=s[r+1],a=s[r+2],o=color(e,i,a),h=color(e,i,a,60);append(cs,o),append(csTrans,h)}for(let t=0;t<5;t++)append(csIrri,color(255,100,100)),append(csIrri,color(255,190,100)),append(csIrri,color(200,255,110)),append(csIrri,color(100,155,255)),append(csIrri,color(150,100,200))}function getColor(t){let r;if(t<.25){let s=map(t,0,.25,0,1);r=lerpColor(cs[0],cs[1],s)}else if(t<.5){let s=map(t,.25,.5,0,1);r=lerpColor(cs[1],cs[2],s)}else if(t<.75){let s=map(t,.5,.75,0,1);r=lerpColor(cs[2],cs[3],s)}else{let s=map(t,.75,1,0,1);r=lerpColor(cs[3],cs[4],s)}return r}function getIrriColor(t){let r;if(t<.2){let s=map(t,0,.2,0,1);r=lerpColor(csIrri[0],csIrri[1],s)}else if(t<.4){let s=map(t,.2,.4,0,1);r=lerpColor(csIrri[1],csIrri[2],s)}else if(t<.6){let s=map(t,.4,.6,0,1);r=lerpColor(csIrri[2],csIrri[3],s)}else if(t<.8){let s=map(t,.6,.8,0,1);r=lerpColor(csIrri[3],csIrri[4],s)}else{let s=map(t,.8,1,0,1);r=lerpColor(csIrri[4],csIrri[0],s)}return r}function drawDragLine(t,r,s,e,i,a,o,h){i.stroke(a),i.strokeWeight(o),i.line(t,r,s,e)}function drawStatic(t,r,s,e,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(s)),a=R.random_num(-PI,PI),o=sin(a),h=t+cos(a)*i,n=r+o*i;e.circle(h,n,STROKESCALE)}}function drawSplatter(t,r,s,e,i){for(let a=0;a<i;a++){let i=R.random_num(0,130*sqrt(s)),a=R.random_num(-PI,PI),o=sin(a),h=t+cos(a)*i,n=r+o*i,l=1*pow(.9*R.random_dec(),3)+.05;e.circle(h,n,l)}}function drawStreakedStatic(t,r,s,e,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(s)),a=R.random_num(-PI,PI),o=sin(a),h=t+cos(a)*i,n=r+o*i*.25;e.circle(h,n,STROKESCALE)}}function keyTyped(){"d"==key&&(DEBUG=!DEBUG),"r"==key||("s"==key?(reset(6),SAVE_PRINTRES=!0):"v"==key?FLIP_VERT=!FLIP_VERT:"f"==key&&(SHOW_FORCES=!SHOW_FORCES))}function drawForceLines(t,r){if(t.length>1)for(let s=0;s<t.length;s+=2){let e=t[s],i=t[s+1],a=R.random_int(0,3),o=paperBg;1==a?o=paperMg:2==a?o=paperFg:3==a&&(o=paperTg),o.stroke(r),o.strokeWeight(2),o.fill(cs[0]),o.line(e.x,e.y,i.x,i.y),o.circle(e.x,e.y,4),o.circle(i.x,i.y,4)}}class BlurryBg{constructor(){}drawMain(t){t.noStroke();let r=1.375*MYSIZE,s=MYHALF,e=MYHALF-55;for(let i=0;i<200;i++){let a=map(i,0,129,0,1,!0),o=lerpColor(cs[0],cs[1],a);t.fill(o),t.circle(s,e,r),e-=.002*(r*=.995)}}drawAnarchic(t,r){t.noStroke();let s=MYHALF;for(let e=0;e<10;e++){let e=R.random_num(100,650)*r;R.random_bool(.6)?t.fill(cs[1]):(t.fill(cs[3]),e*=1.5);let i=R.random_num(MYHALF-350,MYHALF+260);t.circle(s,i,e)}}drawSpiritual(t){let r=MYSIZE*R.random_num(.45,.8),s=MYHALF,e=MYHALF-150;t.noStroke(),t.fill(cs[2]),t.circle(s,e,r)}drawConcentric(t){let r=t,s=.95*MYSIZE,e=MYHALF,i=MYHALF-300;for(let t=0;t<7;t++){let a=map(t,0,7,.1,.9);(r=0==t?paperBg:1==t?paperBg:2==t?paperMg:3==t?paperMg:paperFg).noStroke(),r.fill(getColor(a)),r.circle(e,i,s),s-=170,i+=55}}}class Rorschach{constructor(){this.numDark=R.random_int(5,11),this.numLight=R.random_int(5,11),this.darks=[],this.lights=[];for(let t=0;t<this.numDark;t++){let t=R.random_num(-400,400),r=R.random_num(-200,150),s=R.random_num(100,500),e=createVector(t,r,s);append(this.darks,e)}for(let t=0;t<this.numLight;t++){let t=R.random_num(-420,420),r=R.random_num(-200,150);t*=map(r,-300,250,1,.5);let s=R.random_num(170,330),e=createVector(t,r,s);append(this.lights,e)}}drawDarks(t,r){let s=cs[0];t.fill(color(red(s),green(s),blue(s),4)),t.noStroke();for(let s=0;s<this.numDark;s++){let e=this.darks[s],i=e.x*r,a=e.y*r,o=e.z*r;t.circle(MYHALF+i,MYHALF+a,o),t.circle(MYHALF-i,MYHALF+a,o),e.z*=.975}}drawLights(t,r){let s=cs[1];t.fill(color(red(s),green(s),blue(s),4)),t.noStroke();for(let s=0;s<this.numLight;s++){let e=this.lights[s],i=e.x*r,a=e.y*r,o=e.z*r;t.circle(MYHALF+i,MYHALF+a,o),t.circle(MYHALF-i,MYHALF+a,o),e.z*=.985}}}class Force{constructor(t,r,s,e,i,a){this.id=t,this.pos=r.copy(),this.origPos=r.copy(),this.force=2*s,this.rotForce=2*e,this.isEmitter=i,this.isBoundary=a,this.radius=5,this.age=0,this.isEmitter&&(this.cd=color(255,255,0),this.radius=15)}updateForce(t,r,s){this.force=t,this.rotForce=r,this.isEmitter=s}update(){this.age+=1}draw(t){if(!this.isBoundary&&this.radius>6){let r=SCENESCALE,s=map(this.pos.x,-r,r,0,MYSIZE),e=map(this.pos.y,-r,r,0,MYSIZE),i=min(abs(this.pos.x),this.radius);t.noStroke();for(let r=0;r<5;r++)t.fill(cs[r]),t.circle(s,e,i),i*=.8}}drawToPaper(t){if(t.fill(color(0,0,0,25)),t.noStroke(),!this.isBoundary){let r=SCENESCALE,s=map(1.08*this.pos.x,-r,r,0,MYSIZE),e=map(1.08*this.pos.y,-r,r,0,MYSIZE),i=15*this.radius;for(let r=0;r<25;r++)t.circle(s,e,i),i*=.95}}}class Particle{constructor(t){this.context=Math.min(int(map(frameMarkPer,0,1,0,6)),5),this.x=t.x,this.y=t.y,this.px=t.x,this.py=t.y;let r=R.random_num(-PI,PI);if(this.context>=2&&1==BASIS_ID){let t=map(r,-PI,PI,0,1);t=int(t*BASIS_OCTAVES)/float(BASIS_OCTAVES),r=t=map(t,0,1,-PI,PI)}this.speed=R.random_num(1,2.1),this.vx=Math.cos(r)*this.speed,this.vy=Math.sin(r)*this.speed,this.px+=.05*this.vx,this.py+=.05*this.vy,this.x+=.1*this.vx,this.y+=.1*this.vy,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderxo=map(this.px,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderyo=map(this.py,-SCENESCALE,SCENESCALE,0,MYSIZE),this.ax=0,this.ay=0,this.speedLerp=this.speed,this.cd=color(0,0,0),this.radius=R.random_num(.3,3),this.mass=R.random_num(.8,1.2),this.augRadius=this.radius,this.dp=0,this.ftd=0,this.std=0,this.totalDist=0,this.decay=R.random_num(.95,.975),this.age=0,this.agePer=0,this.life=300,this.dead=!1}update(t){this.px=this.x,this.py=this.y,this.ftd=0,this.std=0;for(let r=0;r<t.length;r++){let s=t[r],e=this.x-s.pos.x,i=this.y-s.pos.y,a=createVector(e,i),o=a.mag(),h=o*o,n=1/h;a=a.normalize();let l=createVector(a.y,-a.x);l=p5.Vector.mult(l,n*s.rotForce*this.mass),a=p5.Vector.mult(a,n*s.force*this.mass),this.ax+=a.x+l.x,this.ay+=a.y+l.y,h<.5&&!s.isEmitter&&(this.dead=!0,s.radius+=.025),s.isEmitter&&(this.ftd+=o,this.std+=sin(10*o))}this.ay+=map(myFrameCount,0,75,GRAVITY,.01,!0),this.vx+=this.ax,this.vy+=this.ay;let r=createVector(this.vx,this.vy),s=r.copy().normalize();this.speed=r.mag(),this.speed>MAXSPEED?(r=p5.Vector.mult(s,MAXSPEED),this.speed=MAXSPEED):this.speed<MINSPEED&&(r=p5.Vector.mult(s,MINSPEED),this.speed=MINSPEED),this.vx=r.x,this.vy=r.y,this.dp=p5.Vector.dot(s,createVector(0,1)),this.dp=map(this.dp,-1,1,0,1),this.totalDist+=this.vx*this.vx+this.vy*this.vy,this.x+=this.vx,this.y+=this.vy,this.vx*=this.decay,this.vy*=this.decay,this.speed=this.vx*this.vx+this.vy*this.vy,this.ax=0,this.ay=0,this.age+=1,this.agePer=this.age/this.life,this.radius*=.99,this.augRadius=this.radius*map(cos(.25*this.totalDist),-1,1,.3,1),this.speedLerp-=.15*(this.speedLerp-this.speed),this.renderxo=this.renderx,this.renderyo=this.rendery,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),(abs(this.x)>1.1*SCENESCALE||abs(this.y)>1.1*SCENESCALE)&&(this.dead=!0),this.age>this.life&&(this.dead=!0)}}
class ParticleSystem{constructor(){this.particles=[],this.forces=[],this.forcePairPs=[]}initForces(){let e=R.random_dec();e*=e;let r=int(lerp(8,35,e)),a=0,t=R.random_num(250,300);for(let e=0;e<r;e++){let r=R.random_dec(),o=R.random_num(50,t),i=R.random_num(0,6.283),s=cos(i)*o+MYHALF,p=sin(i)*o+.425*MYSIZE,n=createVector(s,p),d=0,m=0,c=!1;r<.1&&a<3&&0==SOURCE_ID?(d=15,m=0,c=!0,a++):r<.25?(d=R.random_num(-5,-1.5),m=0,0):r<.35?(d=R.random_num(.5,23),m=R.random_num(-8,8),0):(d=R.random_num(-.25,.25),m=R.random_num(1,55),R.random_bool(.5)&&(m=-m),0);let l=map(n.x,0,MYSIZE,-SCENESCALE,SCENESCALE),E=map(n.y,0,MYSIZE,-SCENESCALE,SCENESCALE),S=createVector(l,E),g=createVector(-l,E);this.addForce(e,S,d,m,c,!1),this.addForce(e+1,g,d,-m,c,!1)}if(0==a&&1!=SOURCE_ID)for(let e=0;e<1;e++){let e=R.random_num(0,.4*SCENESCALE),r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,s=!0;this.addForce(0,a,o,i,s,!1),this.addForce(0,t,o,-i,s,!1)}if(1==SOURCE_ID){let e=0,r=R.random_num(0,.2*SCENESCALE),a=createVector(e,r),t=createVector(-e,r),o=2,i=0,s=!0;this.addForce(0,a,o,i,s,!1),this.addForce(0,t,o,-i,s,!1)}else if(2==SOURCE_ID)for(let e=0;e<2;e++){let e=R.random_num(.6*-SCENESCALE,.6*SCENESCALE),r=R.random_num(.4*-SCENESCALE,.6*SCENESCALE),a=createVector(e,r),t=(createVector(-e,r),2),o=0,i=!0;this.addForce(0,a,t,o,i,!1)}let o=R.random_num(.65,.75);2==SOURCE_ID&&(o=R.random_num(.9,1));for(let e=0;e<14;e++){let r=map(e,0,14,.5*PI+PI/28,1.5*PI+PI/28),a=R.random_num(.95,1.1),t=cos(r)*SCENESCALE*o*a,i=sin(r)*SCENESCALE*o*a,s=createVector(t,i),p=createVector(-t,i),n=R.random_num(14,18),d=0;this.addForce(e,s,n,d,!1,!0),this.addForce(e+1,p,n,-d,!1,!0)}this.setupForceLines()}setupForceLines(){for(let e=0;e<this.forces.length;e+=2){let r=this.forces[e],a=this.forces[e+1];if(!r.isBoundary){let e=r.pos,t=a.pos,o=map(e.x,-SCENESCALE,SCENESCALE,0,MYSIZE),i=map(e.y,-SCENESCALE,SCENESCALE,0,MYSIZE),s=map(t.x,-SCENESCALE,SCENESCALE,0,MYSIZE),p=map(t.y,-SCENESCALE,SCENESCALE,0,MYSIZE);e=createVector(o,i),t=createVector(s,p),append(this.forcePairPs,e),append(this.forcePairPs,t)}}}update(){let e=R.random_dec();for(let r=0;r<this.forces.length-1;r+=2){let a=this.forces[r+0],t=this.forces[r+1];if(frameMarkTrigger)if(a.isEmitter)a.isEmitter=!1,t.isEmitter=!1;else{let r=!1;a.force<-4&&!a.isBoundary&&(r=!0);let o=R.random_num(-6,6),i=R.random_num(-15,15);if(r&&(o=R.random_num(2,6)),a.updateForce(o,i,r),t.updateForce(o,-i,r),a.isBoundary){let r=map(e,0,1,.65,1.15);a.pos.x=a.origPos.x*r,a.pos.y=a.origPos.y*r,t.pos.x=t.origPos.x*r,t.pos.y=t.origPos.y*r}else if(R.random_bool(.7)){R.random_dec();let e=R.random_num(50,400),r=R.random_num(0,6.283),o=cos(r)*e+MYHALF,i=sin(r)*e+.425*MYSIZE,s=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),p=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE);a.pos.x=s,a.pos.y=p,2==SOURCE_ID&&(s=map(o,0,MYSIZE,-SCENESCALE,SCENESCALE),p=map(i,0,MYSIZE,-SCENESCALE,SCENESCALE)),t.pos.x=-s,t.pos.y=p}}if(this.particles.length<4e3){if(a.isEmitter)for(let e=0;e<3;e++){let e=new Particle(a.pos);append(this.particles,e)}if(t.isEmitter)for(let e=0;e<3;e++){let e=new Particle(t.pos);append(this.particles,e)}}a.update(),t.update()}for(let e=0;e<this.particles.length;e++){let r=this.particles[e];r.update(this.forces),r.dead&&this.particles.splice(e,1)}}draw(e){e.stroke(color(255,255,255)),e.strokeWeight(.5),e.noFill();for(let r=0;r<this.forces.length;r++){this.forces[r].draw(e)}}drawToPaper(){for(let e=0;e<this.particles.length;e++){let r=this.particles[e],a=r.renderx,t=r.rendery,o=r.renderxo,i=r.renderyo,s=(r.radius,0),p=0;for(let e=0;e<this.forces.length;e++){let a=this.forces[e];if(a.isEmitter){let e=a.pos.x,t=a.pos.y,o=dist(e,t,r.x,r.y);s+=o=sqrt(o),p+=sin(10*o)}}let n=createVector(a-o,i-t);n.normalize();let d=p5.Vector.dot(n,createVector(0,1));if(d=map(d,-1,1,0,1),r.age>.01){let e=r.speedLerp*map(frameMarkPer,0,1,15,4);if(e+=3*cos(r.totalDist*SURFACE_VAR),e=max(e,1),e*=1-r.agePer,myFrameCount>=frameMark1&&myFrameCount<frameMark2?e*=.45:myFrameCount>=frameMark2&&(e*=.25),0==r.context){let s=lerpColor(cs[2],cs[1],map(r.totalDist,0,40,0,1,!0));drawDragLine(a,t,o,i,paperBg,cs[1],e*r.augRadius*3.5,r.age),drawDragLine(a,t,o,i,paperMg,s,e*r.augRadius*3,r.age),r.cd=s}else if(1==r.context){let s=sin(.02*pow(p+1,2)),n=cs[1],d=cs[2],m=lerpColor(d,n,s);r.cd=m,drawDragLine(a,t,o,i,paperMg,n,e*r.augRadius*2,r.age),drawDragLine(a,t,o,i,paperFg,m,e*r.augRadius*1.75,r.age)}else if(2==r.context){let s=map(r.age,0,30,1,0,!0),p=lerpColor(cs[2],cs[3],s);r.cd=p,drawDragLine(a,t,o,i,paperFg,p,e*r.augRadius*1.4,r.age)}else if(3==r.context){let s=max(d,0),p=getColor(.5*s+.5);p=lerpColor(p,cs[3],.6),r.cd=p,drawDragLine(a,t,o,i,paperFg,p,e*r.augRadius*1.4,r.age)}else if(4==r.context){let p=map(r.totalDist,0,50,.5,1),n=getColor(p),m=n,c=max(s,0,5,0,1);drawDragLine(a,t,o,i,paperFg,n,e*r.augRadius*1.5,r.age),1==OUTLOOK_ID&&(m=lerpColor(n,getIrriColor(fract(8*d)),(.6*d+.4)*c),drawDragLine(a,t,o,i,paperTg,m,e*r.augRadius*.5,r.age)),r.cd=m}else if(5==r.context){let e=pow(r.agePer,.25),s=cs[4],p=color(red(s),green(s),blue(s),80);r.cd=p,drawDragLine(a,t,o,i,paperTg,p,pow(1-r.agePer,4)*e,r.age)}}}}drawStaticToPaper(){paperBg.noStroke(),paperMg.noStroke(),paperFg.noStroke(),paperTg.noStroke();SCENESCALE;let e=paperMg;e.fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.5)*a.radius*.02;drawStatic(a.renderx,a.rendery,t,e,6)}(e=paperTg).fill(csTrans[1]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=(a.speed+.3)*a.radius*.1;drawStatic(a.renderx,a.rendery,t,e,4)}(e=paperFg).fill(csTrans[0]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.2,o=t*t*a.radius;drawStreakedStatic(a.renderx,a.rendery,o,e,6)}if(3==SOURCE_ID){let e=paperFg;e.fill(csTrans[2]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed+.1,o=t*t*a.radius*.15;drawStreakedStatic(a.renderx,a.rendery,o,e,3)}(e=paperTg).fill(csTrans[3]);for(let r=0;r<this.particles.length;r++){let a=this.particles[r],t=a.speed,o=t*t*a.radius*.01;drawStatic(a.renderx,a.rendery,o,e,3)}e=paperFg;for(let r=0;r<this.particles.length;r++)if(R.random_bool(.125)){let a=this.particles[r],t=a.cd,o=a.speed+.2;e.fill(color(red(t),green(t),blue(t),80));let i=o*a.radius*5;drawSplatter(a.renderx,a.rendery,i,e,3)}}(e=paperFg).fill(cs[1]);for(let r=0;r<this.particles.length;r++)if(R.random_bool(.025)){let a=this.particles[r];if(2==a.context||5==a.context){let r=a.speed+.2,t=r*r*a.radius;drawSplatter(a.renderx,a.rendery,t,e,6)}}}addParticle(e){let r=new Particle(e);append(this.particles,r)}addForce(e,r,a,t,o,i){let s=new Force(e,r,a,t,o,i);append(this.forces,s)}}function reset(e){print("edit 015"),print(tokenData.hash),print(tokenData.tokenId),windowWidth<windowHeight?dim=windowWidth:dim=windowHeight,STROKESCALE=275e-6*MYSIZE,print("dim = "+dim),dimHalf=.5*dim,buffer=createCanvas(dim,dim),pixelDensity(e),myFrameCount=0,R=new Random,setupFeatures(),createColors(PALETTE_ID),rectMode(CORNERS),img=createGraphics(MYSIZE,MYSIZE),img.rectMode(CORNERS),paperBg=createGraphics(MYSIZE,MYSIZE),paperMg=createGraphics(MYSIZE,MYSIZE),paperFg=createGraphics(MYSIZE,MYSIZE),paperTg=createGraphics(MYSIZE,MYSIZE),paperBg.imageMode(CORNERS),paperMg.imageMode(CORNERS),paperFg.imageMode(CORNERS),paperTg.imageMode(CORNERS),paperBg.rectMode(CORNERS),paperMg.rectMode(CORNERS),paperFg.rectMode(CORNERS),paperTg.rectMode(CORNERS);let r=cs[0];paperBg.background(color(red(r),green(r),blue(r),255)),paperMg.background(255,255,255,0),paperFg.background(255,255,255,0),paperTg.background(255,255,255,0),papers=[],append(papers,paperBg),append(papers,paperMg),append(papers,paperFg),append(papers,paperTg),GRAVITY=R.random_num(.03,.06),R.random_bool(.5)&&(GRAVITY=-GRAVITY),frameMark1=R.random_int(350,500),frameMark2=frameMark1+R.random_int(300,470),totalFrames=frameMark2+R.random_int(300,400),frameMarkPer=0,frameMarkTrigger=!1,print("frameMark1 = "+frameMark1),print("frameMark2 = "+frameMark2),print("totalFrames = "+totalFrames),blurryBg=new BlurryBg,0==BG_ID||1==BG_ID?blurryBg.drawMain(papers[1]):2==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawAnarchic(papers[1],1)):3==BG_ID?(blurryBg.drawMain(papers[1]),blurryBg.drawConcentric(papers[2])):4==BG_ID&&(blurryBg.drawMain(papers[1]),blurryBg.drawSpiritual(papers[1])),rorschach=new Rorschach,rorschachTop=new Rorschach,pSystem=new ParticleSystem,pSystem.initForces()}function setup(){reset(2)}function setupFeatures(){let e=R.random_dec(),r=int(map(pow(e,1.5),0,1,0,15));PALETTE_ID=min(r,14),R.random_dec()<.15&&(PALETTE_ID=13);let a=R.random_dec();BG_ID=a<.1?0:a<.3?1:a<.85?2:a<.95?3:4;let t=R.random_dec();SOURCE_ID=t<.8?0:t<.95?1:t<.98?2:3,BASIS_ID=0,R.random_bool(.4)&&(BASIS_ID=1),BASIS_OCTAVES=2*R.random_int(4,8),OUTLOOK_ID=0,R.random_bool(.3)&&(OUTLOOK_ID=1),SURFACE_VAR=R.random_num(.3,.8),print("palette = "+PALETTES[PALETTE_ID]),print("obstruction = "+BG_TYPES[BG_ID]),print("source = "+SOURCE_TYPES[SOURCE_ID]),print("basis = "+BASIS_TYPES[BASIS_ID]),print("octaves = "+BASIS_OCTAVES),print("outlook = "+OUTLOOK_TYPES[OUTLOOK_ID]),print("surface var = "+SURFACE_VAR)}function draw(){img.clear(),myFrameCount<=frameMark1?frameMarkPer=map(myFrameCount,0,frameMark1,0,1):myFrameCount<=frameMark2?frameMarkPer=map(myFrameCount,frameMark1,frameMark2,0,1):frameMarkPer=map(myFrameCount,frameMark2,totalFrames,0,1,!0),myFrameCount==frameMark1||myFrameCount==frameMark2?frameMarkTrigger=!0:frameMarkTrigger=!1,2==BG_ID&&myFrameCount==frameMark1&&blurryBg.drawAnarchic(papers[2],.35),myFrameCount<12&&1==BG_ID&&(rorschach.drawDarks(paperMg,1),rorschach.drawLights(paperFg,1),rorschachTop.drawDarks(paperMg,1.25),rorschachTop.drawLights(paperFg,1.25)),myFrameCount<totalFrames&&(pSystem.update(),pSystem.drawToPaper(),pSystem.drawStaticToPaper(),3==SOURCE_ID&&(myFrameCount==frameMark1?drawForceLines(pSystem.forcePairPs,cs[2]):myFrameCount==frameMark2&&drawForceLines(pSystem.forcePairPs,cs[4]))),push(),translate(dimHalf,dimHalf),FLIP_VERT&&(rotate(PI),scale(-1,1,1));for(let e=0;e<4;e++)image(papers[e],-dimHalf,-dimHalf,dim,dim);if(SHOW_FORCES&&(pSystem.draw(img),image(img,-dimHalf,-dimHalf,dim,dim)),pop(),DEBUG){let e=map(myFrameCount,0,totalFrames,0,.5*dim);noStroke(),fill(cs[0]),rect(dimHalf-e-1,0,dimHalf+e+1,3),fill(cs[3]),rect(dimHalf-e,1,dimHalf+e,2)}myFrameCount==totalFrames-1&&(DEBUG=!1),SAVE_PRINTRES&&myFrameCount==totalFrames&&(save(tokenData.hash+".png"),SAVE_PRINTRES=!1),myFrameCount++}
let dim,dimHalf,buffer,STROKESCALE,img,paperBg,paperMg,paperFg,paperTg,pSystem,blurryBg,rorschach,rorschachTop,PALETTE_ID,BG_ID,SOURCE_ID,BASIS_ID,BASIS_OCTAVES,OUTLOOK_ID,SURFACE_VAR,myFrameCount,frameMark1,frameMark2,frameMarkPer,frameMarkTrigger,totalFrames,MYSIZE=1600,MYHALF=MYSIZE/2,SCENESCALE=100,GRAVITY=0,MINSPEED=.01,MAXSPEED=.75,papers=[],cs=[],csTrans=[],csIrri=[],PALETTES=["IMPENETRABLE_CALM","GROWTH_AND_RENEWAL","FOCUSED_ANGER","SOPHISTICATION","CALM_BUT_ALERT","WISE_AND_ENERGETIC","INTROVERTED_AND_COMPASSIONATE","NURTURED_HOPE","SOCIAL_CREATURE","SECURE_BUT_SAD","PESSIMISTIC","OPTIMISTIC","AWARE_BUT_DISTANT","FOREBODING","CONFIDENT_ENERGY"],BG_TYPES=["TABULA RASA","PROJECTIVE","ANARCHIC","ALIGNED","SPIRITUAL"],SOURCE_TYPES=["NORMAL","CENTERED","PSYCHO-ANOMALOUS","ASCENDED"],BASIS_TYPES=["DISORGANIZED","ORGANIZED"],OUTLOOK_TYPES=["NEGATIVITY","POSITIVITY"],FLIP_VERT=!1,SHOW_FORCES=!0,DEBUG=!1,SAVE_PRINTRES=!1;function genTokenData(t){let r={},e="0x";for(var s=0;s<64;s++)e+=Math.floor(16*Math.random()).toString(16);return r.hash=e,r.tokenId=(1e6*t).toString(),r}class Random{constructor(){this.useA=!1;let t=function(t){let r=parseInt(t.substr(0,8),16),e=parseInt(t.substr(8,8),16),s=parseInt(t.substr(16,8),16),i=parseInt(t.substr(24,8),16);return function(){let t=((r|=0)+(e|=0)|0)+(i|=0)|0;return i=i+1|0,r=e^e>>>9,e=(s|=0)+(s<<3)|0,s=(s=s<<21|s>>>11)+t|0,(t>>>0)/4294967296}};this.prngA=new t(tokenData.hash.substr(2,32)),this.prngB=new t(tokenData.hash.substr(34,32));for(let t=0;t<1e6;t+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(t,r){return t+(r-t)*this.random_dec()}random_int(t,r){return Math.floor(this.random_num(t,r+1))}random_bool(t){return this.random_dec()<t}random_choice(t){return t[this.random_int(0,t.length-1)]}}function createColors(t){let r=[];append(r,[1,3,38,1,31,38,166,138,55,242,209,109,242,235,141]),append(r,[4,41,64,0,92,83,159,193,49,219,242,39,255,252,102]),append(r,[31,38,35,59,64,57,255,133,0,255,179,0,255,230,67]),append(r,[15,15,15,35,35,35,107,9,47,255,41,58,255,125,74]),append(r,[45,7,77,75,39,122,0,148,134,35,235,178,183,255,227]),append(r,[117,10,10,255,74,11,79,180,139,167,233,177,212,255,185]),append(r,[142,2,45,242,21,143,148,7,242,4,107,242,4,156,216]),append(r,[12,49,94,7,101,219,255,192,18,255,239,3,255,255,102]),append(r,[242,232,101,242,177,99,242,142,106,242,106,94,225,253,247]),append(r,[23,42,46,22,63,69,217,103,37,242,150,80,247,206,105]),append(r,[25,25,25,55,55,55,100,100,100,200,255,100,235,255,150]),append(r,[36,39,41,68,69,55,65,185,220,124,204,217,244,247,217]),append(r,[11,11,11,40,40,40,210,210,210,240,240,240,255,255,255]),append(r,[205,205,205,255,255,255,0,0,0,15,15,15,235,235,235]),append(r,[89,1,1,165,9,51,242,55,105,0,0,0,242,75,136]),cs=[],csTrans=[],csIrri=[];let e=r[t];for(let t=0;t<5;t++){let r=3*t,s=e[r+0],i=e[r+1],a=e[r+2],o=color(s,i,a),n=color(s,i,a,60);append(cs,o),append(csTrans,n)}for(let t=0;t<5;t++)append(csIrri,color(255,100,100)),append(csIrri,color(255,190,100)),append(csIrri,color(200,255,110)),append(csIrri,color(100,155,255)),append(csIrri,color(150,100,200))}function getColor(t){let r;if(t<.25){let e=map(t,0,.25,0,1);r=lerpColor(cs[0],cs[1],e)}else if(t<.5){let e=map(t,.25,.5,0,1);r=lerpColor(cs[1],cs[2],e)}else if(t<.75){let e=map(t,.5,.75,0,1);r=lerpColor(cs[2],cs[3],e)}else{let e=map(t,.75,1,0,1);r=lerpColor(cs[3],cs[4],e)}return r}function getIrriColor(t){let r;if(t<.2){let e=map(t,0,.2,0,1);r=lerpColor(csIrri[0],csIrri[1],e)}else if(t<.4){let e=map(t,.2,.4,0,1);r=lerpColor(csIrri[1],csIrri[2],e)}else if(t<.6){let e=map(t,.4,.6,0,1);r=lerpColor(csIrri[2],csIrri[3],e)}else if(t<.8){let e=map(t,.6,.8,0,1);r=lerpColor(csIrri[3],csIrri[4],e)}else{let e=map(t,.8,1,0,1);r=lerpColor(csIrri[4],csIrri[0],e)}return r}function drawDragLine(t,r,e,s,i,a,o,n){i.stroke(a),i.strokeWeight(o),i.line(t,r,e,s)}function drawStatic(t,r,e,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(e)),a=R.random_num(-PI,PI),o=sin(a),n=t+cos(a)*i,h=r+o*i;s.circle(n,h,STROKESCALE)}}function drawSplatter(t,r,e,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,130*sqrt(e)),a=R.random_num(-PI,PI),o=sin(a),n=t+cos(a)*i,h=r+o*i,l=1*pow(.9*R.random_dec(),3)+.05;s.circle(n,h,l)}}function drawStreakedStatic(t,r,e,s,i){for(let a=0;a<i;a++){let i=R.random_num(0,750*sqrt(e)),a=R.random_num(-PI,PI),o=sin(a),n=t+cos(a)*i,h=r+o*i*.25;s.circle(n,h,STROKESCALE)}}function keyTyped(){"d"==key&&(DEBUG=!DEBUG),"r"==key||("s"==key?(reset(6),SAVE_PRINTRES=!0):"v"==key?FLIP_VERT=!FLIP_VERT:"f"==key&&(SHOW_FORCES=!SHOW_FORCES))}function drawForceLines(t,r){if(t.length>1)for(let e=0;e<t.length;e+=2){let s=t[e],i=t[e+1],a=R.random_int(0,3),o=paperBg;1==a?o=paperMg:2==a?o=paperFg:3==a&&(o=paperTg),o.stroke(r),o.strokeWeight(2),o.fill(cs[0]),o.line(s.x,s.y,i.x,i.y),o.circle(s.x,s.y,4),o.circle(i.x,i.y,4)}}class BlurryBg{constructor(){}drawMain(t){t.noStroke();let r=1.375*MYSIZE,e=MYHALF,s=MYHALF-55;for(let i=0;i<200;i++){let a=map(i,0,129,0,1,!0),o=lerpColor(cs[0],cs[1],a);t.fill(o),t.circle(e,s,r),s-=.002*(r*=.995)}}drawAnarchic(t,r){t.noStroke();let e=MYHALF;for(let s=0;s<10;s++){let s=R.random_num(100,650)*r;R.random_bool(.6)?t.fill(cs[1]):(t.fill(cs[3]),s*=1.5);let i=R.random_num(MYHALF-350,MYHALF+260);t.circle(e,i,s)}}drawSpiritual(t){let r=MYSIZE*R.random_num(.45,.8),e=MYHALF,s=MYHALF-150;t.noStroke(),t.fill(cs[2]),t.circle(e,s,r)}drawConcentric(t){let r=t,e=.8*MYSIZE,s=MYHALF,i=MYHALF-300;for(let t=0;t<7;t++){let a=map(t,0,7,.1,.9);(r=0==t?paperBg:1==t?paperBg:2==t?paperMg:3==t?paperMg:paperFg).noStroke(),r.fill(getColor(a)),r.circle(s,i,e),e-=170,i+=55}}}class Rorschach{constructor(){this.numDark=R.random_int(5,11),this.numLight=R.random_int(5,11),this.darks=[],this.lights=[];for(let t=0;t<this.numDark;t++){let t=R.random_num(-400,400),r=R.random_num(-200,150),e=R.random_num(100,500),s=createVector(t,r,e);append(this.darks,s)}for(let t=0;t<this.numLight;t++){let t=R.random_num(-420,420),r=R.random_num(-200,150);t*=map(r,-300,250,1,.5);let e=R.random_num(170,330),s=createVector(t,r,e);append(this.lights,s)}}drawDarks(t,r){let e=cs[0];t.fill(color(red(e),green(e),blue(e),4)),t.noStroke();for(let e=0;e<this.numDark;e++){let s=this.darks[e],i=s.x*r,a=s.y*r,o=s.z*r;t.circle(MYHALF+i,MYHALF+a,o),t.circle(MYHALF-i,MYHALF+a,o),s.z*=.975}}drawLights(t,r){let e=cs[1];t.fill(color(red(e),green(e),blue(e),4)),t.noStroke();for(let e=0;e<this.numLight;e++){let s=this.lights[e],i=s.x*r,a=s.y*r,o=s.z*r;t.circle(MYHALF+i,MYHALF+a,o),t.circle(MYHALF-i,MYHALF+a,o),s.z*=.985}}}class Force{constructor(t,r,e,s,i,a){this.id=t,this.pos=r.copy(),this.origPos=r.copy(),this.force=2*e,this.rotForce=2*s,this.isEmitter=i,this.isBoundary=a,this.radius=5,this.age=0,this.isEmitter&&(this.cd=color(255,255,0),this.radius=15)}updateForce(t,r,e){this.force=t,this.rotForce=r,this.isEmitter=e}update(){this.age+=1}draw(t){if(!this.isBoundary&&this.radius>6){let r=SCENESCALE,e=map(this.pos.x,-r,r,0,MYSIZE),s=map(this.pos.y,-r,r,0,MYSIZE),i=min(abs(this.pos.x),this.radius);t.noStroke();for(let r=0;r<5;r++)t.fill(cs[r]),t.circle(e,s,i),i*=.8}}drawToPaper(t){if(t.fill(color(0,0,0,25)),t.noStroke(),!this.isBoundary){let r=SCENESCALE,e=map(1.08*this.pos.x,-r,r,0,MYSIZE),s=map(1.08*this.pos.y,-r,r,0,MYSIZE),i=15*this.radius;for(let r=0;r<25;r++)t.circle(e,s,i),i*=.95}}}class Particle{constructor(t){this.context=Math.min(int(map(frameMarkPer,0,1,0,6)),5),this.x=t.x,this.y=t.y,this.px=t.x,this.py=t.y;let r=R.random_num(-PI,PI);if(this.context>=2&&1==BASIS_ID){let t=map(r,-PI,PI,0,1);t=int(t*BASIS_OCTAVES)/float(BASIS_OCTAVES),r=t=map(t,0,1,-PI,PI)}this.speed=R.random_num(1,2.1),this.vx=Math.cos(r)*this.speed,this.vy=Math.sin(r)*this.speed,this.px+=.05*this.vx,this.py+=.05*this.vy,this.x+=.1*this.vx,this.y+=.1*this.vy,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderxo=map(this.px,-SCENESCALE,SCENESCALE,0,MYSIZE),this.renderyo=map(this.py,-SCENESCALE,SCENESCALE,0,MYSIZE),this.ax=0,this.ay=0,this.speedLerp=this.speed,this.cd=color(0,0,0),this.radius=R.random_num(.3,3),this.mass=R.random_num(.8,1.2),this.augRadius=this.radius,this.totalDist=0,this.decay=R.random_num(.95,.975),this.age=0,this.agePer=0,this.life=300,this.dead=!1}update(t){this.px=this.x,this.py=this.y;for(let r=0;r<t.length;r++){let e=t[r],s=this.x-e.pos.x,i=this.y-e.pos.y,a=createVector(s,i),o=s*s+i*i,n=1/o;a=a.normalize();let h=createVector(a.y,-a.x);h=p5.Vector.mult(h,n*e.rotForce*this.mass),a=p5.Vector.mult(a,n*e.force*this.mass),this.ax+=a.x+h.x,this.ay+=a.y+h.y,o<.5&&!e.isEmitter&&(this.dead=!0,e.radius+=.025)}this.ay+=map(myFrameCount,0,75,GRAVITY,.01,!0),this.vx+=this.ax,this.vy+=this.ay;let r=createVector(this.vx,this.vy);if(this.speed=r.mag(),this.speed>MAXSPEED){let t=r.copy().normalize();r=p5.Vector.mult(t,MAXSPEED),this.speed=MAXSPEED}else if(this.speed<MINSPEED){let t=r.copy().normalize();r=p5.Vector.mult(t,MINSPEED),this.speed=MINSPEED}this.vx=r.x,this.vy=r.y,this.totalDist+=this.vx*this.vx+this.vy*this.vy,this.x+=this.vx,this.y+=this.vy,this.vx*=this.decay,this.vy*=this.decay,this.speed=this.vx*this.vx+this.vy*this.vy,this.ax=0,this.ay=0,this.age+=1,this.agePer=this.age/this.life,this.radius*=.99,this.augRadius=this.radius*map(cos(.25*this.totalDist),-1,1,.3,1),this.speedLerp-=.15*(this.speedLerp-this.speed),this.renderxo=this.renderx,this.renderyo=this.rendery,this.renderx=map(this.x,-SCENESCALE,SCENESCALE,0,MYSIZE),this.rendery=map(this.y,-SCENESCALE,SCENESCALE,0,MYSIZE),(abs(this.x)>1.1*SCENESCALE||abs(this.y)>1.1*SCENESCALE)&&(this.dead=!0),this.age>this.life&&(this.dead=!0)}}
🐺🐵🐶🐺🐱🦁🐯🦒🦊🐻🐰🐹🐭🐗🐷🐮🦝🐨🐼🐸 Rorschach meets Pareidolia. Spirit Animal meets Mood Ring. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- What will be revealed about who you are --- who you become. What do YOU see? 's' to re-render at print res 'f' to toggle force node positions 'v' to invert vertically 'd' to toggle progress bar
Ancient Courses is a generative experience that explores the aesthetics of meandering rivers and the settlements that form on their banks. The design is graphic and cartographic with bold color palettes rendered against map iconography and line sensibility. From the river banks, roads stretch across the landscape: sometimes a single access road, other times sprawling towns. The river meandering is simulated via a custom algorithm which closely models the real world process. Press 'r' to reset the simulation. Press 's' to save an image to disk. Press 'h' to re-run the simulation at print res. This is significantly slower than the default screen res version. The progress bar at the bottom of the screen shows how long before the print-res image is automatically saved to disk. A limited number of Ancient Courses mints will come with a Treasure Map feature. The owner can request a physical print (max one print per treasure map). Best viewed on Chrome, Firefox, or Safari.
Ancient Courses is a generative experience that explores the aesthetics of meandering rivers and the settlements that form on their banks. The design is graphic and cartographic with bold color palettes rendered against map iconography and line sensibility. From the river banks, roads stretch across the landscape: sometimes a single access road, other times sprawling towns. The river meandering is simulated via a custom algorithm which closely models the real world process. Press 'r' to reset the simulation. Press 's' to save an image to disk. Press 'h' to re-run the simulation at print res. This is significantly slower than the default screen res version. The progress bar at the bottom of the screen shows how long before the print-res image is automatically saved to disk. A limited number of Ancient Courses mints will come with a Treasure Map feature. The original purchaser will receive a physical print. Best viewed on Chrome, Firefox, or Safari.
let dim,hdim,buffer,R,nox,noy,bgColor,dkBgColor,ltBgColor,fgColor,dkFgColor,edgeColor,highlightColor,shadowColor,BIOME,COMP,CITY_TYPE,GRID_TYPE,LAND_TYPE,HISTORY_TYPE,HEAVY_SEASON_FREQ,COLOR_TYPE,HISTORY_CONTRAST,FIELD_SCALE,PLOT_TYPE,SQUARE_TYPE,PALETTE_ID,RENDER_TYPE,MEANDER_TYPE,LINE_TYPE,INVERTED,HAS_CONTOURS,HAS_POISSON,DRIFTER,TREASURE_MAP,HAS_BORDER,HAS_RAILROAD,borderWidth,treasurePos,MYSIZE=1200,SIMSIZE=600,SIMRATIO=MYSIZE/SIMSIZE,MYHALF=MYSIZE/2,cs=[],BIOMES=["FARMLAND","SWAMP","DESERT","ARCTIC","MOUNTAINS"],COMPS=["HORIZONTAL","VERTICAL","DIAGONAL","SINE WAVE","S-CURVE","DOUBLE"],CITY_TYPES=["REMOTE","HAMLET","SETTLEMENT","TOWN"],GRID_TYPES=["NO GRID","JUST DOTS","PLUSSES","DOTTED LINES"],LAND_TYPES=["DESERT","SWAMP","MIXED","SPARSE","ARCTIC","MOUNTAIN"],HISTORY_TYPES=["SEQUENTIAL","STACKS","SHORTSTACKS","RANDOMIZED"],COLOR_TYPES=["FADED","VIBRANT"],FIELD_SCALES=["CLOSE","MEDIUM","FAR"],PLOT_TYPES=["EMPTY","FULL","HALVED","HALF_QUARTERED","QUARTERED"],SQUARE_TYPES=["CLEAN","OVERGROWN","REMNANT","DIVIDED"],PALETTES=["Elevation","Warm Grays","Warm Autumn","Kirkjufell","Reynisfjara","Dry Spell","Lupine Fields","Purple Sand","Lava Fisk","Classic Map","Moss","Classic Fisk","Pale Fields","Landmannalaugar","Dried Slate","Color Shift","Ocean Desert","Pale Fisk","Dark Fisk","Near Buðir","Black/White"],RENDER_TYPES=["COLORFUL","MONOCHROME","BLACKWHITE"],MEANDER_TYPES=["REALISTIC","EXCESSIVE","CLOSE-UP"],LINE_TYPES=["NONE","HIGHLIGHTED","STROKED","SHORELINE"],tps=[];const EMPTY=0,FULL=1,HALVED=2,HALF_QUARTERED=3,QUARTERED=4,CLEAN=0,OVERGROWN=1,REMNANT=2,DIVIDED=3,FARMLAND=0,SWAMP=1,DESERT=2,ARCTIC=3,MOUNTAINS=4,REMOTE=0,RURAL=1,TOWN=2,TWIN_TOWNS=3,LAND_DESERT=0,LAND_SWAMP=1,LAND_MIXED=2,LAND_SPARSE=3,LAND_ARCTIC=4,LAND_MOUNTAIN=5,REALISTIC=0,EXCESSIVE=1,CLOSEUP=2,NONE=0,HIGHLIGHTED=1,STROKED=2,SEQUENTIAL=0,STACKS=1,SHORTSTACKS=2,RANDOMIZED=3;let riverBg,riverFg,river,riverDur,riverSpacing,riverSpeed,riverWidth,riverTanLerp,riverHistoryIter,riverCollSpacing,riverCollDistSqrd,riverHistoryCount,riverStartPos,riverEndPos,plotBg,plotsImg,plotGrowthSpeed,plotTypeThresh,plotStartFrame,rail,railStartFrame,landBg,poisson,poissonStartFrame,field,SUN_DIRECTION,mainSw,mainGapMin,mainGapMax,qTree,overlayFg,mainRand,plots=[],Q_MAX_GEN=7,qRects=[],qUpdated=!1,HALFPI=1.570796,TOTAL_DUR=2e3,myFrameCount=0,introAnim=0,introDur=60,riverStartFrame=350,riverFramePer=0,ITERATION=0,SHOW_DETAILS=!1,SAVE_IMAGE=!1,SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1;class Random{constructor(){this.useA=!1;let e=function(e){let r=parseInt(e.substr(0,8),16),t=parseInt(e.substr(8,8),16),o=parseInt(e.substr(16,8),16),n=parseInt(e.substr(24,8),16);return function(){let e=((r|=0)+(t|=0)|0)+(n|=0)|0;return n=n+1|0,r=t^t>>>9,t=(o|=0)+(o<<3)|0,o=(o=o<<21|o>>>11)+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}random_num(e,r){return e+(r-e)*this.random_dec()}random_int(e,r){return Math.floor(this.random_num(e,r+1))}random_bool(e){return this.random_dec()<e}random_choice(e){return e[this.random_int(0,e.length-1)]}}function createColors(e){let r=[];append(r,[35,92,92,44,158,158,158,248,238,255,254,204,242,130,90]),append(r,[166,164,165,64,63,62,242,236,233,217,167,150,191,105,105]),append(r,[89,73,54,242,214,179,217,168,126,94,8,11,181,56,56]),append(r,[186,203,217,109,150,166,21,56,64,92,115,63,159,171,135]),append(r,[94,113,138,8,30,38,49,78,89,213,217,199,193,87,80]),append(r,[166,158,143,217,208,193,166,130,99,140,72,48,124,165,157]),append(r,[146,153,110,252,255,235,223,230,188,131,95,153,214,188,230]),append(r,[237,199,183,238,226,220,186,178,181,18,60,105,172,59,97]),append(r,[69,133,140,160,217,217,217,197,137,191,151,101,217,43,4]),append(r,[134,154,166,242,220,194,242,163,94,38,30,23,191,162,136]),append(r,[16,69,79,80,98,102,129,130,116,163,171,120,202,224,119]),append(r,[147,184,177,247,210,198,226,114,91,255,248,197,128,143,106]),append(r,[230,244,242,184,216,205,168,126,52,242,212,126,255,239,205]),append(r,[122,159,191,156,193,216,114,101,37,216,204,145,165,41,41]),append(r,[215,215,217,104,120,140,166,143,73,191,165,132,115,101,85]),append(r,[191,107,130,37,65,89,128,151,166,197,209,217,242,236,145]),append(r,[59,102,140,87,115,140,33,49,64,140,104,45,255,218,158]),append(r,[223,173,137,115,103,88,186,201,189,237,222,199,222,122,108]),append(r,[30,73,89,217,152,95,242,214,189,166,69,33,115,34,16]),append(r,[225,223,242,180,185,217,1,40,64,191,160,4,140,117,3]),append(r,[20,20,20,70,70,70,120,120,120,150,150,150,225,225,225]),cs=[];let t=r[e];for(let e=0;e<5;e++){let r=3*e,o=255*pow(t[r+0]/255,1),n=255*pow(t[r+1]/255,1),i=255*pow(t[r+2]/255,1),l=color(int(o),int(n),int(i));brightness(l);append(cs,l)}colorMode(HSB,255);let o=[];for(let e=0;e<cs.length;e++){let r=cs[e],t=brightness(r);append(o,t)}let n=0;for(;n<cs.length;){for(let e=0;e<cs.length-n-1;e++){cs[e],cs[e+1];o[e]>o[e+1]&&(swap(cs,e,e+1),swap(o,e,e+1))}n++}colorMode(RGB,255)}function getColor(e){let r;if(e<.2){let t=map(e,0,.2,0,1);r=lerpColor(cs[0],cs[1],t)}else if(e<.4){let t=map(e,.2,.4,0,1);r=lerpColor(cs[1],cs[2],t)}else if(e<.6){let t=map(e,.4,.6,0,1);r=lerpColor(cs[2],cs[3],t)}else if(e<.8){let t=map(e,.6,.8,0,1);r=lerpColor(cs[3],cs[4],t)}else{let t=map(e,.8,1,0,1);r=lerpColor(cs[4],cs[0],t)}return r}function readColor(e,r,t){let o=4*(int(e)+int(r)*SIMSIZE),n=t.pixels[o+0],i=t.pixels[o+1],l=t.pixels[o+2];return color(n,i,l,255)}function writeColor(e,r,t,o){let n=4*(int(e)+int(r)*SIMSIZE);o.pixels[n+0]=red(t),o.pixels[n+1]=green(t),o.pixels[n+2]=blue(t),o.pixels[n+3]=255}function wrapTheta(e){let r=e;return r<0?r+=TWO_PI:r>TWO_PI&&(r-=TWO_PI),r}function swap(e,r,t){let o=e[r];e[r]=e[t],e[t]=o}function getNoise(e,r){return noise(e.x*r+nox,e.y*r+noy)}function resampleLine(e,r,t){let o=[];return append(o,e),append(o,r),o=resample(o,t)}function resample(e,r){let t=e.length,o=[],n=0;for(let r=0;r<e.length-1;r++){let t=e[r],i=e[r+1],l=p5.Vector.dist(t,i);n+=l,append(o,l)}let i=r,l=ceil(n/float(i));i=n/float(l);let a=0,E=0,p=[];append(p,createVector(e[0].x,e[0].y));for(let r=1;r<l;r++){let r=float(E),t=0;for(;r<=i;)r+=o[a],a++,t++;let n=a-1,l=1-(r-i)/o[n];E=r-i;let s=e[n],S=e[n+1],T=p5.Vector.lerp(s,S,l);T.x=Math.floor(1e7*T.x)/1e7,T.y=Math.floor(1e7*T.y)/1e7,append(p,T)}return append(p,e[t-1]),p}function smoothSubdiv(e){let r=e.length,t=[];for(let o=0;o<r-1;o++){let r,n=e[o],i=e[o+1];if(o>0){let t=e[o-1],l=(4*n.x+t.x+i.x)/6,a=(4*n.y+t.y+i.y)/6;r=createVector(l,a)}else r=n.copy();let l=r.copy(),a=p5.Vector.add(n,i);a.x*=.5,a.y*=.5,append(t,l),append(t,a)}return append(t,e[r-1]),t}function calcCoordFrame(e){let r=e.length,t=[],o=createVector(0,0);for(let n=0;n<r;n++){if(0==n){let r=e[n],t=e[n+1];o=p5.Vector.sub(t,r).normalize()}else if(n==r-1){let r=e[n-1],t=e[n];o=p5.Vector.sub(t,r).normalize()}else{let r=e[n-1],t=e[n],i=e[n+1],l=p5.Vector.sub(t,r),a=p5.Vector.sub(i,t);o=p5.Vector.lerp(l,a,.5).normalize()}append(t,createVector(o.x,o.y)),append(t,createVector(o.y,-o.x))}return t}function calcFlowBitangent(e,r){let t,o=e.length,n=[];for(let i=0;i<o;i++){let l=(i+1)%o,a=e[i].normalize(),E=e[l].normalize();t=r[i].copy();let p=createVector(a.x,a.y,0),s=createVector(E.x,E.y,0);p5.Vector.cross(p,s).z<0&&(t=createVector(-t.x,-t.y));let S=p5.Vector.dot(p,s),T=sqrt(1-S)*riverSpeed;t=createVector(t.x*T,t.y*T),append(n,t)}return n}function distanceToRiver(e){let r=river.getPs(),t=1e3;for(let o=0;o<r.length;o+=3){let n=r[o],i=p5.Vector.dist(n,e);i<t&&(t=i)}return t}function drawRiver(e,r,t,o,n,i){riverStartPos=e[0].copy(),riverEndPos=e[e.length-1].copy();let l=riverHistoryCount%5;HISTORY_TYPE==STACKS?l=int(.2*riverHistoryCount)%5:HISTORY_TYPE==SHORTSTACKS?l=int(.4*riverHistoryCount)%5:HISTORY_TYPE==RANDOMIZED&&(l=R.random_int(0,4));let a=cs[l],E=o,p=createVector(0,0),s=createVector(.75*-SUN_DIRECTION.x,.75*-SUN_DIRECTION.y),S=createVector(.75*SUN_DIRECTION.x,.75*SUN_DIRECTION.y),T=!1;LINE_TYPE==STROKED&&(T=!0);let d=buildRiverGeo(e,r,t,o,n);if(myFrameCount%riverHistoryIter==0&&myFrameCount<=riverDur){let i=lerpColor(bgColor,a,riverFramePer*HISTORY_CONTRAST),l=lerpColor(i,color(0,0,0),.25);if(LINE_TYPE==HIGHLIGHTED&&drawRiverGeo(d,s,1,riverBg,l,T,E,shadowColor,n),R.random_dec()<HEAVY_SEASON_FREQ&&(i=fgColor),drawRiverGeo(d,S,1,riverBg,highlightColor,T,E,shadowColor,n),drawRiverGeo(d,p,1,riverBg,i,T,E,l,n),MEANDER_TYPE==CLOSEUP){let i=buildRiverGeo(e,r,t,.875*o,n),a=buildRiverGeo(e,r,t,1*o,n);drawDottedRiverLine(i,.4*E,riverBg,l),drawDottedRiverLine(a,.4*E,riverBg,l)}}if(myFrameCount<=riverDur&&(LINE_TYPE==HIGHLIGHTED&&drawRiverGeo(d,s,1,riverFg,shadowColor,!1,E,color(0),n),drawRiverGeo(d,p,1,riverFg,fgColor,T,3*mainSw,dkFgColor,n)),myFrameCount==riverDur&&3==LINE_TYPE)for(let i=0;i<20;i++){let l=map(i,0,19,0,1),a=buildRiverGeo(e,r,t,o*(13*pow(l,3)+1),n),p=255*(1-l),s=color(red(fgColor),green(fgColor),blue(fgColor),p);drawDottedRiverLine(a,.3*E,riverBg,s)}if(MEANDER_TYPE==CLOSEUP&&myFrameCount==riverDur){riverFg.strokeCap(SQUARE);let i=buildRiverGeo(e,r,t,.875*o,n);drawDottedRiverLine(i,.6*E,riverFg,shadowColor);let l=buildRiverGeo(e,r,t,1*o,n);drawDottedRiverLine(l,.3*E,riverFg,shadowColor)}}function drawRiverBanks(e){let r=[],t=int(map(mainRand,0,1,3,15)),o=resample(e,1);for(let e=0;e<o.length;e++){let n=o[e];.5*(getNoise(n,.04)+getNoise(n,.01))<.3&&R.random_bool(.5)&&(n.x+=R.random_num(-t,t),n.y+=R.random_num(-t,t),n.x=int(n.x/t)*t,n.y=int(n.y/t)*t,append(r,n))}for(let e=0;e<r.length;e++){let o=r[e],n=distanceToRiver(o),i=map(n,0,150,.25*t,.01*t,!0);riverBg.stroke(edgeColor),riverBg.strokeWeight(mainSw*i*2.5),riverBg.stroke(cs[R.random_int(0,4)]),riverBg.line(o.x-i,o.y-i,o.x+i,o.y+i),riverBg.line(o.x+i,o.y-i,o.x-i,o.y+i)}}function buildRiverGeo(e,r,t,o,n){let i,l=createVector(0,0),a=e.length,E=[],p=[];for(let s=0;s<a;s++){let S=e[s],T=r[s],d=t[s].mag(),R=riverWidth;if(n||(R+=.5*d),i=map(getNoise(S,.01),0,1,.15*R,.9*R)*o,n){let e=map(s,0,a-1,0,1);i*=.9*pow(Math.sin(e*PI),.5)+.1}append(E,i),l=createVector(S.x+T.x*i,S.y+T.y*i),append(p,l)}for(let t=a-1;t>=0;t--){map(t,0,a-1,0,1);let o=e[t],n=r[t];i=E[t],l=createVector(o.x-n.x*i,o.y-n.y*i),append(p,l)}return p=smoothSubdiv(p=smoothSubdiv(p))}
function drawRiverGeo(e,t,r,i,s,o,n,a,l){i.beginShape(),o?(i.stroke(a),i.strokeWeight(.5*n)):i.noStroke(),i.fill(s);let h=e.length;for(let s=0;s<h;s++){let o=e[s].x,n=e[s].y;o=(o-MYHALF)*r+MYHALF,n=(n-MYHALF)*r+MYHALF,0==s&&i.curveVertex(o+t.x,n+t.y),i.curveVertex(o+t.x,n+t.y)}i.endShape(CLOSE),l||5!=COMP||(i.stroke(s),i.strokeWeight(riverWidth*introAnim*.9),i.noFill(),i.line(riverStartPos.x,riverStartPos.y,riverEndPos.x,riverEndPos.y))}function drawScreenOverlay(e,t,r,i){e.stroke(t),e.strokeWeight(i);for(let t=0;t<MYSIZE;t+=r)e.line(0,t,MYSIZE,t)}function drawDottedRiverLine(e,t,r,i){r.stroke(i),r.strokeWeight(t),r.noFill();let s=resample(e,1);for(let e=0;e<s.length-1;e++)if(e%4<=1){let t=s[e],i=s[e+1];r.line(t.x,t.y,i.x,i.y)}}function distanceToRiver(e){let t=river.getPs(),r=2e3;for(let i=0;i<t.length;i+=3){let s=t[i],o=p5.Vector.dist(s,e);o<r&&(r=o)}return r}function drawBuilding(e,t,r,i,s,o){let n=map(pow(R.random_dec(),2),0,1,2,6),a=map(pow(R.random_dec(),2),0,1,2,6),l=3;R.random_bool(.01)&&(n*=3,a*=3,l*=2);let h=.6*i,c=.6*-r;R.random_bool(.5)&&(h=.6*-i,c=.6*r);let d=createVector(e+h*l,t+c*l),p=createVector(d.x+h*a,d.y+c*a),x=createVector(p.x+r*n,p.y+i*n),y=createVector(d.x+r*n,d.y+i*n);o.beginShape(),o.fill(s),o.noStroke(),o.vertex(d.x,d.y),o.vertex(p.x,p.y),o.vertex(x.x,x.y),o.vertex(y.x,y.y),o.endShape()}function createPlotNetwork(e,t){let r=350;0==CITY_TYPE?r=0:1==CITY_TYPE?r=5:2==CITY_TYPE&&(r=50);let i=e.length,s=R.random_num(-.4,.4);for(let o=0;o<r;o++){let r=R.random_int(50,i-50);1==CITY_TYPE?r=R.random_int(int(i/2)-10,int(i/2)+10):2==CITY_TYPE?(r=R.random_int(int(i/2)-20,int(i/2)+20),5==COMP&&(r=R.random_int(int(i/4)-10,int(i/4)+10))):3==CITY_TYPE&&(r=R.random_bool(.5)?R.random_int(int(.3*i)-10,int(.3*i)+10):R.random_int(int(.7*i)-10,int(.7*i)+10));let o=e[r].x,n=e[r].y,a=t[r].x,l=t[r].y,h=atan2(l,a);if(R.random_bool(.5)&&(h+=PI),BIOME==DESERT){let e=R.random_int(0,3);h=0+HALFPI*float(e)+s}addPlot(o/2,n/2,h,color(0),0)}}function addPlot(e,t,r,i,s){let o=wrapTheta(r),n=new Plot(e,t,o,i,s);plots.push(n)}function makeGrid(e,t){let r=R.random_int(8,50);2==GRID_TYPE&&(r=R.random_int(12,16));let i=r,s=1.5;if(3==GRID_TYPE&&(s=65),t.noFill(),t.stroke(fgColor),t.strokeWeight(.25*mainSw),3!=GRID_TYPE)for(let e=0;e<r;e++){let o=map(e,0,r-1,0,MYSIZE),n=map(e+1,0,r-1,0,MYSIZE);for(let e=0;e<i;e++){let r=map(e,0,i-1,0,MYSIZE),a=map(e+1,0,i-1,0,MYSIZE);1==GRID_TYPE&&(t.circle(o,r,1),t.circle(o,r,.5)),2==GRID_TYPE&&(t.line(o,r+.4*s,o,r+2*s),t.line(o+.4*s,r,o+2*s,r),t.line(o,a-.4*s,o,a-2*s),t.line(n-.4*s,r,n-2*s,r))}}else{for(let e=0;e<r;e++){let i=map(e,0,r-1,0,MYSIZE),s=createVector(i,0),o=createVector(i,MYSIZE),n=[];append(n,s),append(n,o),n=resample(n,3);for(let e=0;e<n.length-1;e+=2){let r=n[e],i=n[e+1];t.line(r.x,r.y,i.x,i.y)}}for(let e=0;e<i;e++){let r=map(e,0,i-1,0,MYSIZE),s=createVector(0,r),o=createVector(MYSIZE,r),n=[];append(n,s),append(n,o),n=resample(n,3);for(let e=0;e<n.length-1;e+=2){let r=n[e],i=n[e+1];t.line(r.x,r.y,i.x,i.y)}}}}function makeTreasure(){let e=river.getPs(),t=e[R.random_int(max(e.length/2-20,1),min(e.length/2+20,e.length-2))],r=[];append(r,t.copy()),append(r,treasurePos.copy()),r=resample(r,50);for(let e=1;e<r.length-1;e++)r[e].x+=125*getNoise(r[e],.03),r[e].y+=125*getNoise(r[e],.03);return r=smoothSubdiv(r),r=resample(r,5)}function xMarksTheSpot(e){let t=treasurePos.x,r=treasurePos.y;e.stroke(edgeColor),e.strokeWeight(2.25),e.strokeCap(SQUARE),e.line(t-3,r-3,t+3,r+3),e.line(t+3,r-3,t-3,r+3)}function outOfBounds(e,t){let r=!1;return e<=2&&(r=!0),t<=2&&(r=!0),e>=SIMSIZE-3&&(r=!0),t>=SIMSIZE-3&&(r=!0),r}function getPlotType(){let e=R.random_dec(),t=0;return t=e<.1?0:e<.5?1:e<.7?2:e<.8?3:4}class RectPlot{constructor(e,t,r,i){this.p0=createVector(e,t),this.p1=createVector(r,i),this.x0=this.p0.x,this.y0=this.p0.y,this.x1=this.p1.x,this.y1=this.p1.y,this.center=p5.Vector.lerp(this.p0,this.p1,.5),this.w=r-e,this.h=i-t,this.density=0,this.innerDensity=0,this.radius=this.w/2-.01*this.w*2,this.rect=new Rectangle(this.center.x,this.center.y,this.w/2,this.h/2)}setDensity(e){this.density=e}split(e){let t=[];for(let r=0;r<e;r++){let i=map(r,0,e,this.x0,this.x1),s=map(r+1,0,e,this.x0,this.x1),o=new RectPlot(i,this.y0,s,this.y1);append(t,o)}return t}draw(e,t,r){let i=getColor(R.random_dec());e.noStroke(),e.fill(red(i),green(i),blue(i),R.random_int(20,100)),e.rect(this.x0,this.y0,this.w,this.h),this.drawDottedLine(e,i,createVector(this.x0,this.y0),createVector(this.x1,this.y0)),this.drawDottedLine(e,i,createVector(this.x1,this.y0),createVector(this.x1,this.y1)),this.drawDottedLine(e,i,createVector(this.x1,this.y1),createVector(this.x0,this.y1)),this.drawDottedLine(e,i,createVector(this.x0,this.y1),createVector(this.x0,this.y0)),R.random_bool(.75)&&this.drawDottedFill(e,i,this.rect)}drawDottedLine(e,t,r,i){let s=p5.Vector.sub(i,r);s.normalize();let o=createVector(-s.y,s.x);e.stroke(t),e.strokeWeight(.5*mainSw);let n=[];append(n,r),append(n,i);let a=resample(n,1),l=1.5;for(let t=0;t<a.length-1;t++)if(t%3==0){let r=a[t],i=a[t+1];e.line(r.x+o.x*l,r.y+o.y*l,i.x+o.x*l,i.y+o.y*l)}e.stroke(0,0,0,50),e.line(r.x,r.y,i.x,i.y)}drawDottedFill(e,t,r){let i=createVector(r.x-r.w,r.y-r.h),s=createVector(r.x-r.w,r.y+r.h),o=createVector(r.x+r.w,r.y-r.h),n=[];append(n,i),append(n,s),e.stroke(t),e.strokeWeight(.5*mainSw);let a=resample(n,1);for(let t=1;t<a.length-1;t+=2){let r=a[t],i=createVector(o.x,r.y),s=[];append(s,r),append(s,i);let n=resample(s,.5);for(let t=0;t<n.length-1;t++)if(t%3==0){let r=n[t],i=n[t+1];e.line(r.x,r.y,i.x,i.y)}}}}class Point{constructor(e,t){this.x=e,this.y=t,this.p=createVector(e,t)}}class Line{constructor(e,t,r,i){this.x0=e,this.y0=t,this.x1=r,this.y1=i,this.p0=createVector(e,t),this.p1=createVector(r,i),this.d=p5.Vector.dist(this.p0,this.p1)}}class Rectangle{constructor(e,t,r,i){this.x=e,this.y=t,this.w=r,this.h=i}contains(e){return e.x>=this.x-this.w&&e.x<this.x+this.w&&e.y>=this.y-this.h&&e.y<this.y+this.h}}class Contours{constructor(){this.field=[],this.res=7,this.cols=1+MYSIZE/this.res,this.rows=1+MYSIZE/this.res;for(let e=0;e<this.cols;e++){let e=[];for(let t=0;t<this.rows;t++)e.push(0);this.field.push(e)}}getXYDist(e,t,r){let i=createVector(e,t),s=111111;for(let e=0;e<r.length;e++){let t=r[e],o=p5.Vector.sub(t,i).mag();o<s&&(s=o)}return s}solve(e){let t=7,r=7,i=1.4;BIOME==FARMLAND||BIOME==DESERT?(t=5,r=5,i=1.4):BIOME==MOUNTAINS&&(t=15,r=15,i=.225);for(let s=0;s<this.cols;s++){let o=map(s,0,this.cols-1,0,t),n=map(s,0,this.cols-1,0,MYSIZE);for(let t=0;t<this.rows;t++){let a=map(t,0,this.rows-1,0,r),l=map(t,0,this.rows-1,0,MYSIZE),h=this.getXYDist(n,l,e);this.field[s][t]=float(h/1e3+noise(o+123.45,a+456.78)*i)}}}drawLine(e,t,r){let i=p5.Vector.sub(t,r),s=i.mag();i.normalize(),e.line(t.x,t.y,t.x-i.x*s*.5,t.y-i.y*s*.5)}draw(e){let t=this.res,r=.25;BIOME==MOUNTAINS?r=.05:BIOME!=FARMLAND&&BIOME!=DESERT||(r=.25);for(let i=-1;i<1.25;i+=r){e.stroke(edgeColor),e.strokeWeight(map(i,-1,1.25,.1,.25));for(let r=0;r<this.cols-1;r++)for(let s=0;s<this.rows-1;s++){let o=this.field[r][s]-i,n=this.field[r+1][s]-i,a=this.field[r+1][s+1]-i,l=this.field[r][s+1]-i,h=r*t,c=s*t,d=createVector(h+t*o/(o-n),c),p=createVector(h+t,c+t*n/(n-a)),x=createVector(h+t*(1-a/(a-l)),c+t),y=createVector(h,c+t*(1-l/(l-o)));switch(this.getState(o,n,a,l)){case 1:this.drawLine(e,x,y);break;case 2:this.drawLine(e,p,x);break;case 3:this.drawLine(e,p,y);break;case 4:this.drawLine(e,d,p);break;case 5:this.drawLine(e,d,y),this.drawLine(e,p,x);break;case 6:this.drawLine(e,d,x);break;case 7:case 8:this.drawLine(e,d,y);break;case 9:this.drawLine(e,d,x);break;case 10:this.drawLine(e,d,p),this.drawLine(e,x,y);break;case 11:this.drawLine(e,d,p);break;case 12:this.drawLine(e,p,y);break;case 13:this.drawLine(e,p,x);break;case 14:this.drawLine(e,x,y)}}}}getState(e,t,r,i){return(e>0?8:0)+(t>0?4:0)+(r>0?2:0)+(i>0?1:0)}}
function updateTreasure(){if(TREASURE_MAP){let e=riverDur;if(myFrameCount==e)tps=makeTreasure();else if(myFrameCount>e){let t=tps.length,r=myFrameCount-e,o=r+1;if(o<t&&o%2==0){let e=tps[r],t=tps[o];overlayFg.strokeWeight(.5),overlayFg.stroke(edgeColor),overlayFg.line(e.x,e.y,t.x,t.y)}else o==t&&xMarksTheSpot(overlayFg)}}}function updateContours(){1==myFrameCount&&contours.draw(landBg)}function updateRiver(){myFrameCount<riverDur?(river.checkOxbows(),river.updateOxbows(),river.update(),river.setEndPoints()):myFrameCount==riverDur&&(plotsImg.loadPixels(),river.writeColors(plotsImg),plotsImg.updatePixels())}function updatePlots(){if(myFrameCount==plotStartFrame&&createPlotNetwork(river.getPs(),river.getBs()),myFrameCount>=plotStartFrame){plotsImg.loadPixels();for(let e=0;e<plots.length;e++)plots[e].update();for(let e=0;e<plots.length;e++)plots[e].render();plotsImg.updatePixels();for(let e=0;e<plots.length;e++)plots[e].drawLine()}}function updateRail(){HAS_RAILROAD&&(myFrameCount==riverDur?rail=new Rail(river.getStartPos(),river.getEndPos()):myFrameCount>riverDur&&rail.update())}function updatePoisson(){myFrameCount==riverDur&&(poisson.solve(),poisson.draw(landBg))}function updateContours(){myFrameCount==riverDur&&(contours.solve(river.getPs()),contours.draw(landBg))}function cleanPlots(){for(let e=0;e<plots.length;e++){plots[e].isDead()&&plots.splice(e,1)}}function drawOverlay(){let e=R.random_int(0,1);BIOME==FARMLAND&&(e=1),2==RENDER_TYPE&&(e=0),0==e?borderWidth=.075*MYSIZE:1==e&&(borderWidth=.125*MYSIZE),overlayFg.noFill(),overlayFg.strokeWeight(borderWidth),overlayFg.stroke(bgColor),overlayFg.rect(0,0,MYSIZE,MYSIZE);let t=.5,r=2*t,o=R.random_int(2,5);for(let e=0;e<o;e++){let e=R.random_num(.25*mainSw,2*mainSw);overlayFg.strokeWeight(e),overlayFg.stroke(edgeColor),overlayFg.rect(borderWidth*t,borderWidth*t,MYSIZE-borderWidth*r,MYSIZE-borderWidth*r),r=2*(t=R.random_num(.3,.5))}}function update(){myFrameCount<riverDur&&riverFg.clear(),updateRiver(),BIOME!=DESERT&&BIOME!=MOUNTAINS&&BIOME!=ARCTIC&&BIOME!=SWAMP||updatePlots(),BIOME!=DESERT&&BIOME!=SWAMP&&BIOME!=ARCTIC||updatePoisson(),BIOME==MOUNTAINS&&updateContours(),BIOME!=FARMLAND&&updateRail(),updateTreasure()}function draw(){if(background(bgColor),myFrameCount<TOTAL_DUR&&(update(),myFrameCount>riverStartFrame&&(river.drawOxbows(),river.draw()),HAS_RAILROAD&&rail&&rail.draw(),1==myFrameCount&&HAS_BORDER&&drawOverlay()),myFrameCount==riverDur+1&&BIOME==FARMLAND&&(setupQuadTree(),setupField()),myFrameCount>riverDur+1&&qUpdated&&field.draw(),myFrameCount<=riverDur&&BIOME==FARMLAND&&(landBg.blendMode(REMOVE),drawScreenOverlay(landBg,fgColor,2,.5*mainSw),landBg.blendMode(BLEND)),image(landBg,0,0,dim,dim),image(plotBg,0,0,dim,dim),image(riverBg,0,0,dim,dim),image(riverFg,0,0,dim,dim),image(overlayFg,0,0,dim,dim),clean(),SAVE_IMAGE){let e=(new Date).getTime();save(buffer,str(e),"png"),SAVE_IMAGE=!1}if(SAVE_PRINT_RES||SAVE_ALT_PRINT_RES){if(myFrameCount==TOTAL_DUR){let e=(new Date).getTime();save(buffer,str(e),"png"),SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1}let e=map(myFrameCount,1,TOTAL_DUR,0,dim);fill(255,0,0),noStroke(),rect(0,dim-5,e,dim)}if(SHOW_DETAILS){let e=125,t=dim-370,r=20;fill(color(0)),INVERTED&&fill(color(255)),noStroke(),textSize(15),textFont("Serif"),text(myFrameCount,e,dim-120),text("Biome: ",e,t+0*r),text("Composition: ",e,t+1*r),text("Meander Type: ",e,t+2*r),text("Drifter: ",e,t+3*r),text("Line type: ",e,t+4*r),text("Color type:",e,t+5*r),text("Population: ",e,t+6*r),text("Grid: ",e,t+7*r),text("Palette: ",e,t+8*r),text("History: ",e,t+9*r),text("Railroad: ",e,t+10*r),text("Treasure Map: ",e,t+11*r),e+=200,text(frameRate(),e,dim-120),text(BIOMES[BIOME],e,t+0*r),text(COMPS[COMP],e,t+1*r),text(MEANDER_TYPES[MEANDER_TYPE],e,t+2*r),text(DRIFTER?"TRUE":"FALSE",e,t+3*r),text(LINE_TYPES[LINE_TYPE],e,t+4*r),text(COLOR_TYPES[COLOR_TYPE],e,t+5*r),text(CITY_TYPES[CITY_TYPE],e,t+6*r),text(GRID_TYPES[GRID_TYPE],e,t+7*r),text(PALETTES[PALETTE_ID],e,t+8*r),text(HISTORY_TYPES[HISTORY_TYPE],e,t+9*r),text(HAS_RAILROAD?"TRUE":"FALSE",e,t+10*r),text(TREASURE_MAP?"TRUE":"FALSE",e,t+11*r)}myFrameCount++,introAnim=pow(map(myFrameCount,0,introDur,0,1,!0),2),riverFramePer=map(myFrameCount,0,riverDur,0,1),myFrameCount%riverHistoryIter==1&&riverHistoryCount++}function clean(){cleanPlots()}
class CirclePlot{constructor(e,t){this.pos=e,this.scale=.01*t,this.width=2*t,this.radius=t;let o=map(this.radius,10,MYHALF,5,16);this.ringRadii=[];for(let e=0;e<2*o;e++){let t=map(e,0,2*o,0,1),i=map(t,0,1,0,this.radius);e%2==1&&append(this.ringRadii,i)}this.numRings=this.ringRadii.length,this.angle=R.random_num(0,TWO_PI),this.numStripes=int(this.radius/R.random_num(mainGapMin,mainGapMax)),R.random_bool(.2)&&(this.numStripes=int(1.5*this.numStripes)),this.plotType=getPlotType(),this.densities=[],this.rot=R.random_int(0,3),this.setDensities(this.plotType)}setDensities(e){if(e==EMPTY)this.densities=[0,0,0,0];else if(e==FULL){let e=R.random_num(.2,1);this.densities=[e,e,e,e]}else if(e==HALVED){let e=R.random_num(.2,1),t=R.random_num(.2,1);this.densities=[e,t,e,t],this.rot%2==1&&(this.densities=[e,e,t,t])}else if(e==HALF_QUARTERED){let e=R.random_num(.2,1),t=R.random_num(.2,1),o=R.random_num(.2,1);this.densities=[e,t,o,o],this.rot%2==1&&(this.densities=[e,t,o,t])}else if(e==QUARTERED){let e=R.random_num(.2,1),t=R.random_num(.2,1),o=R.random_num(.2,1),i=R.random_num(.2,1);this.densities=[e,t,o,i]}}draw(e){if(this.plotType>EMPTY){let t=getColor(R.random_dec());e.noStroke(),e.fill(red(t),green(t),blue(t),R.random_int(20,100)),e.circle(this.pos.x,this.pos.y,this.radius),this.drawConcentricCircles(e),this.drawAccessRoad(e),this.drawSwingArm(e)}}drawMainCircle(e){e.noStroke(),e.fill(bgColor),e.circle(this.pos.x,this.pos.y,this.radius-1),e.stroke(edgeColor),e.strokeWeight(mainSw),this.drawDottedCircle(e,this.pos,this.radius)}drawQuarterFieldLines(e){e.stroke(fgColor),e.strokeWeight(mainSw);let t=this.radius-2,o=[];for(let e=0;e<2*this.numStripes;e++){let i,r;if(this.rot%2==0){let o=map(e,0,2*this.numStripes,-t,t),s=sqrt(t*t-o*o);i=createVector(this.pos.x+o,this.pos.y+s),r=createVector(this.pos.x+o,this.pos.y-s)}else{let o=map(e,0,2*this.numStripes,-t,t),s=sqrt(t*t-o*o);i=createVector(this.pos.x-s,this.pos.y+o),r=createVector(this.pos.x+s,this.pos.y+o)}append(o,i),append(o,r)}let i=o.length;for(let t=0;t<i-1;t+=2){let i=resampleLine(o[t],o[t+1],mainGapMax);for(let t=0;t<i.length-1;t++){let o=i[t],r=i[t+1];p5.Vector.dist(this.pos,o);o.x<this.pos.x&&o.y<this.pos.y?this.drawFieldLine(e,o,r,this.densities[0],t):o.x>this.pos.x&&o.y<this.pos.y?this.drawFieldLine(e,o,r,this.densities[1],t):o.x<this.pos.x&&o.y>this.pos.y?this.drawFieldLine(e,o,r,this.densities[2],t):this.drawFieldLine(e,o,r,this.densities[3],t)}}}drawFieldLine(e,t,o,i,r){let s=i;s>.7?(e.point(t.x,t.y),e.point(.5*t.x+.5*o.x,.5*t.y+.5*o.y),e.point(t.x+1,t.y+1)):s>.4?e.line(t.x,t.y,o.x,o.y):e.point(t.x,t.y)}drawConcentricCircles(e){e.noFill(),e.stroke(fgColor),e.strokeWeight(.5*this.scale);for(let t=0;t<this.numRings;t++)this.drawDottedCircle(e,this.pos,this.ringRadii[t])}drawDottedCircle(e,t,o){let i=[];for(let e=0;e<180;e++){let r=map(e,0,180,0,TWO_PI),s=t.x+cos(r)*o,n=t.y+sin(r)*o;append(i,createVector(s,n))}let r=resample(i,1);for(let t=0;t<r.length-1;t++)if(t%3==0){let o=r[t],i=r[t+1];e.line(o.x,o.y,i.x,i.y)}}drawAccessRoad(e){let t,o,i=R.random_int(0,3);0==i?(t=.5*this.width,o=0):1==i?(t=.5*-this.width,o=0):2==i?(t=0,o=.5*this.width):(t=0,o=.5*-this.width);let r=map(this.radius,0,MYHALF,1,6);e.strokeWeight(r-mainSw),e.stroke(bgColor),e.line(this.pos.x,this.pos.y,this.pos.x+t,this.pos.y+o),e.fill(bgColor),e.noStroke(),e.circle(this.pos.x,this.pos.y,r-mainSw)}drawSwingArm(e){let t=.5*this.scale;e.stroke(fgColor),e.strokeWeight(t);for(let o=0;o<this.numRings;o++){let i=this.ringRadii[o],r=Math.cos(this.angle)*(i-.5*this.scale),s=Math.sin(this.angle)*(i-.5*this.scale),n=Math.cos(this.angle)*(i+.5*this.scale),l=Math.sin(this.angle)*(i+.5*this.scale);e.circle(this.pos.x+r,this.pos.y+s,.5*t),e.circle(this.pos.x+n,this.pos.y+l,.5*t)}let o=Math.cos(this.angle)*this.radius*.995,i=Math.sin(this.angle)*this.radius*.995;e.line(this.pos.x,this.pos.y,this.pos.x+o,this.pos.y+i),e.stroke(bgColor),e.line(this.pos.x-.2*SUN_DIRECTION.x,this.pos.y-.2*SUN_DIRECTION.y,this.pos.x+o-.2*SUN_DIRECTION.x,this.pos.y+i-.2*SUN_DIRECTION.y)}}function reset(e){print(tokenData.hash),print(tokenData.tokenId),dim=Math.min(windowWidth,windowHeight),hdim=dim/2,buffer=createCanvas(dim,dim),pixelDensity(e),myFrameCount=0,R=new Random,setupFeatures(),setupColors(),noiseSeed(R.random_dec()),noiseDetail(3,.3),nox=R.random_num(500,5e3),noy=R.random_num(500,5e3),mainRand=R.random_dec(),mainSw=.5,mainGapMin=2,mainGapMax=2,landBg=createGraphics(MYSIZE,MYSIZE),landBg.ellipseMode(RADIUS),setupWeather(),setupOverlay(),setupRiver(),setupPlots(),setupPoisson(),setupContours(),setupGrid(),setupRail(),myFrameCount=0,introAnim=0,outroAnim=1}function setup(){reset(2)}function setupFeatures(){let e=R.random_dec();BIOME=e<.15?FARMLAND:e<.35?SWAMP:e<.5?DESERT:e<.7?ARCTIC:MOUNTAINS,RENDER_TYPE=R.random_bool(.9)?0:2;let t,o=[1,7,11,14,16,17,19,20],i=[0,12,13,15,20],r=[3,10,19,20],s=R.random_dec();PALETTE_ID=s<.15?0:s<.3?1:s<.4?2:s<.45?3:s<.5?4:s<.6?5:R.random_int(6,PALETTES.length-2),2==RENDER_TYPE&&(PALETTE_ID=20),BIOME==DESERT?(t=R.random_int(0,o.length-1),PALETTE_ID=o[t]):BIOME==ARCTIC?(t=R.random_int(0,i.length-1),PALETTE_ID=i[t]):BIOME==SWAMP&&(t=R.random_int(0,r.length-1),PALETTE_ID=r[t]);let n=R.random_dec();if(COMP=n<.3?0:n<.6?1:n<.8?2:n<.9?3:n<.98?4:5,GRID_TYPE=R.random_int(0,GRID_TYPES.length-1),BIOME==FARMLAND&&(GRID_TYPE=0),HISTORY_TYPE=R.random_int(0,HISTORY_TYPES.length-1),BIOME==FARMLAND)CITY_TYPE=REMOTE,LAND_TYPE=R.random_bool(.8)?LAND_MIXED:LAND_SPARSE;else if(BIOME==SWAMP){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.3?RURAL:TOWN,e=R.random_dec(),LAND_TYPE=e<.4?LAND_SWAMP:e<.8?LAND_MIXED:LAND_SPARSE}else if(BIOME==DESERT){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.3?RURAL:TOWN,e=R.random_dec(),LAND_TYPE=e<.4?LAND_DESERT:e<.8?LAND_MIXED:LAND_SPARSE}else if(BIOME==ARCTIC){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.4?RURAL:TOWN,LAND_TYPE=LAND_ARCTIC}else if(BIOME==MOUNTAINS){let e=R.random_dec();CITY_TYPE=e<.1?REMOTE:e<.35?RURAL:e<.95?TOWN:TWIN_TOWNS,LAND_TYPE=R.random_bool(.2)?LAND_DESERT:LAND_MOUNTAIN}COLOR_TYPE=R.random_int(0,COLOR_TYPES.length-1),0==COLOR_TYPE?HISTORY_CONTRAST=.4:HISTORY_CONTRAST=.8;let l=R.random_dec();MEANDER_TYPE=l<.5?EXCESSIVE:l<.9?REALISTIC:CLOSEUP,LINE_TYPE=R.random_int(0,LINE_TYPES.length-1),0==LINE_TYPE&&R.random_bool(.5)&&(LINE_TYPE=1),MEANDER_TYPE==CLOSEUP&&(LINE_TYPE=1),DRIFTER=!!R.random_bool(.4),MEANDER_TYPE==CLOSEUP&&(DRIFTER=!1),TREASURE_MAP=!!R.random_bool(.01),HAS_BORDER=!!R.random_bool(.7),HAS_RAILROAD=!!R.random_bool(.05),CITY_TYPE==REMOTE&&(HAS_RAILROAD=!1),HAS_CONTOURS=!!R.random_bool(.2),HAS_POISSON=!!R.random_bool(.2),HEAVY_SEASON_FREQ=0,R.random_bool(.2)&&(HEAVY_SEASON_FREQ=R.random_num(0,.2))}function setupColors(){createColors(PALETTE_ID),INVERTED=!1;let e=R.random_int(2,4),t=0;R.random_dec()<.25&&(INVERTED=!0,e=R.random_int(0,2),t=4),fgColor=cs[t],bgColor=cs[e],2==RENDER_TYPE&&(fgColor=cs[0],bgColor=cs[4],INVERTED&&(fgColor=cs[4],bgColor=cs[0])),INVERTED?(edgeColor=lerpColor(bgColor,color(255),.4),dkFgColor=lerpColor(fgColor,color(0),.5),ltFgColor=lerpColor(fgColor,color(255),.5),dkBgColor=lerpColor(bgColor,color(0),.5),ltBgColor=lerpColor(bgColor,color(255),.5)):(edgeColor=lerpColor(bgColor,color(0),.4),dkFgColor=lerpColor(fgColor,color(0),.5),ltFgColor=lerpColor(fgColor,color(255),.5),dkBgColor=lerpColor(bgColor,color(0),.5),ltBgColor=lerpColor(bgColor,color(255),.5)),highlightColor=color(255,255,255,30),shadowColor=color(0,0,0,60)}function setupWeather(){SUN_DIRECTION=createVector(R.random_num(-1,1),R.random_num(.3,1)),SUN_DIRECTION.normalize(),2==RENDER_TYPE&&(SUN_DIRECTION=createVector(R.random_num(-1,1),R.random_num(.3,1)),SUN_DIRECTION.normalize())}function setupOverlay(){overlayFg=createGraphics(MYSIZE,MYSIZE)}function setupRiver(){riverDur=450,DRIFTER&&(riverDur=650),riverSpacing=R.random_int(10,25),5==COMP&&(riverSpacing=8),MEANDER_TYPE==CLOSEUP&&(riverSpacing=45),riverSpeed=float(riverSpacing)*R.random_num(.3,.4)*5,MEANDER_TYPE==CLOSEUP&&(riverSpeed*=.85),riverWidth=.8*riverSpacing+1,riverTanLerp=.15,riverHistoryIter=R.random_int(5,10),riverCollSpacing=int(riverSpacing/2)+3;let e=2*float(riverSpacing);MEANDER_TYPE==CLOSEUP&&(e*=1.75),riverCollDistSqrd=e*e,riverStartFrame=3,riverHistoryCount=0,riverBg=createGraphics(MYSIZE,MYSIZE),riverFg=createGraphics(MYSIZE,MYSIZE),river=new River(COMP),riverBg.background(0,0,0,0),riverFg.background(0,0,0,0)}function setupPlots(){plots=[],plotsImg=createImage(SIMSIZE,SIMSIZE),plotBg=createGraphics(MYSIZE,MYSIZE),plotBg.ellipseMode(RADIUS),plotGrowthSpeed=.65,plotTypeThresh=.4,BIOME==SWAMP?plotTypeThresh=R.random_num(.3,.5):BIOME==DESERT?plotTypeThresh=1:BIOME==MOUNTAINS&&(plotTypeThresh=R.random_num(.2,.3)),plotStartFrame=riverDur}function setupPoisson(){poissonStartFrame=2,poisson=new FastPoisson}function setupContours(){contoursStartFrame=3,contours=new Contours}function setupGrid(){0!=GRID_TYPE&&makeGrid(fgColor,landBg)}function setupRail(){railStartFrame=350}function setupQuadTree(){R.random_int(10,40);let e=new Rectangle(MYHALF,MYHALF,MYHALF,MYHALF);qTree=new QuadTree(e,0,0);let t,o=map(riverSpacing,8,25,0,3)%3;t=0==o?R.random_int(225,440):1==o?R.random_int(135,185):R.random_int(63,104);for(let e=0;e<t;e++){addPointToQuadTree(new Point(R.random_num(100,MYSIZE-100),R.random_num(100,MYSIZE-100)))}let i=river.getPs();for(let e=0;e<i.length;e+=3){let t=i[e],o=R.random_num(-50,50),r=R.random_num(-50,50);addPointToQuadTree(createVector(t.x+o,t.y+r))}qRects=[],qTree.getRectangles(qRects),qUpdated=!0}function setupField(){field=new Field(qRects)}function addPointToQuadTree(e){qTree.insert(e),qRects=[],qTree.getRectangles(qRects),qUpdated=!0}function keyTyped(){"d"==key||("r"==key?(SAVE_PRINT_RES=!1,SAVE_ALT_PRINT_RES=!1,reset(2)):"s"==key?SAVE_IMAGE=!0:"h"==key?(reset(8),SAVE_PRINT_RES=!0):"H"==key&&(reset(8),SAVE_ALT_PRINT_RES=!0))}
1-50 of 61