javascript



hello world(data uri)


code

<!doctype html><head><script>{
    console.log(`hello world`)//hello world
}</script></head></html>


const, let(data uri)


code

<!doctype html><head><script>try{
    console.log(`--const--`)
    const v=`hello world`
    console.log(v)//hello world
    v=undefined
}catch(e){
    console.log(e instanceof TypeError)//true
}
{
    console.log(`--let--`)
    let v
    console.log(v)//undefined
    v=`hello world`
    console.log(v)//hello world
}</script></head></html>


Array(data uri)


code

<!doctype html><head><script>{
    console.log(`--Array--`)
    console.log([])//[]
    console.log(Array())//[]
    console.log([0])//[0]
    console.log(Array(0))//[]
    console.log([1])//[1]
    console.log(Array(1))//[empty]
    console.log([2])//[2]
    console.log(Array(2))//[empty, empty]
    console.log([0,1])//[0, 1]
    console.log(Array(0,1))//[0, 1]
}
{
    console.log(`--push, pop, reverse--`)
    const vs=[]
    console.log(vs.push(0))//1
    console.log(vs)//[0]
    console.log(vs.push(1,2))//3
    console.log(vs)//[0, 1, 2]
    console.log(vs[1]=3)//3
    console.log(vs)//[0, 3, 2]
    console.log(vs.pop())//2
    console.log(vs)//[0, 3]
    console.log(vs.reverse())//[3, 0]
    console.log(vs)//[3, 0]
}
{
    console.log(`--isArray--`)
    console.log(Array.isArray([]))//true
    console.log(Array.isArray(Array()))//true
    console.log(Array.isArray(undefined))//false
    console.log(Array.isArray(null))//false
    console.log(Array.isArray(0))//false
    console.log(Array.isArray(``))//false
}
{
    console.log(`--equals--`)
    Array.prototype.equals=function(v){
        return v.length===this.length&&v.every((v,i)=>v===this[i])
    }
    console.log([].equals([]))//true
    console.log([]===[])//false
}</script></head></html>


crypto.subtle(data uri)


code

<!doctype html><head><script>{
    if(!crypto.subtle)throw Error(`available in secure contexts.`)
    const string=`hello world`
    ,encoder=new TextEncoder()
    ,decoder=new TextDecoder()
    ,aesCTR=async(v,keyLength,length,hashParams)=>{
        const algorithm={name:`AES-CTR`},signAlgorithm=`HMAC`,format=`raw`,signFormat=`raw`
        ,aesKeyGenParams=Object.assign({},algorithm,{length:keyLength})
        ,aesCtrParams=Object.assign({},algorithm,{counter:v,length:length})
        ,hmacKeyParams=Object.assign({},{name:signAlgorithm},hashParams)
        ,key=await crypto.subtle.generateKey(aesKeyGenParams,true,[`encrypt`])
        ,exportKey=await crypto.subtle.exportKey(format,key),encrypted=await crypto.subtle.encrypt(aesCtrParams,key,encoder.encode(string))
        ,signKey=await crypto.subtle.generateKey(hmacKeyParams,true,[`sign`])
        ,exportSignKey=await crypto.subtle.exportKey(signFormat,signKey)
        ,sign=await crypto.subtle.sign(signAlgorithm,signKey,encrypted)
        console.log(algorithm.name)
        console.log(await crypto.subtle.verify(signAlgorithm,await crypto.subtle.importKey(signFormat,exportSignKey,hmacKeyParams,false,[`verify`]),sign,encrypted))//true
        console.log(decoder.decode(await crypto.subtle.decrypt(aesCtrParams,await crypto.subtle.importKey(format,exportKey,algorithm,false,[`decrypt`]),encrypted)))//hello world
    }
    ,aesCBC=async(v,keyLength,hashParams)=>{
        const algorithm={name:`AES-CBC`},signAlgorithm=`HMAC`,format=`raw`,signFormat=`raw`
        ,aesKeyGenParams=Object.assign({},algorithm,{length:keyLength})
        ,aesCbcParams=Object.assign({},algorithm,{iv:v})
        ,hmacKeyParams=Object.assign({},{name:signAlgorithm},hashParams)
        ,key=await crypto.subtle.generateKey(aesKeyGenParams,true,[`encrypt`])
        ,exportKey=await crypto.subtle.exportKey(format,key),encrypted=await crypto.subtle.encrypt(aesCbcParams,key,encoder.encode(string))
        ,signKey=await crypto.subtle.generateKey(hmacKeyParams,true,[`sign`])
        ,exportSignKey=await crypto.subtle.exportKey(signFormat,signKey)
        ,sign=await crypto.subtle.sign(signAlgorithm,signKey,encrypted)
        console.log(algorithm.name)
        console.log(await crypto.subtle.verify(signAlgorithm,await crypto.subtle.importKey(signFormat,exportSignKey,hmacKeyParams,false,[`verify`]),sign,encrypted))//true
        console.log(decoder.decode(await crypto.subtle.decrypt(aesCbcParams,await crypto.subtle.importKey(format,exportKey,algorithm,false,[`decrypt`]),encrypted)))//hello world
    }
    ,aesGCM=async(v,keyLength,hashParams)=>{
        const algorithm={name:`AES-GCM`},signAlgorithm=`HMAC`,format=`raw`,signFormat=`raw`
        ,aesKeyGenParams=Object.assign({},algorithm,{length:keyLength})
        ,aesGcmParams=Object.assign({},algorithm,{iv:v})
        ,hmacKeyParams=Object.assign({},{name:signAlgorithm},hashParams)
        ,key=await crypto.subtle.generateKey(aesKeyGenParams,true,[`encrypt`])
        ,exportKey=await crypto.subtle.exportKey(format,key),encrypted=await crypto.subtle.encrypt(aesGcmParams,key,encoder.encode(string))
        ,signKey=await crypto.subtle.generateKey(hmacKeyParams,true,[`sign`])
        ,exportSignKey=await crypto.subtle.exportKey(signFormat,signKey)
        ,sign=await crypto.subtle.sign(signAlgorithm,signKey,encrypted)
        console.log(algorithm.name)
        console.log(await crypto.subtle.verify(signAlgorithm,await crypto.subtle.importKey(signFormat,exportSignKey,hmacKeyParams,false,[`verify`]),sign,encrypted))//true
        console.log(decoder.decode(await crypto.subtle.decrypt(aesGcmParams,await crypto.subtle.importKey(format,exportKey,algorithm,false,[`decrypt`]),encrypted)))//hello world
    }
    ,rsaOAEP=async(modulusLength,params,hashParams)=>{
        const algorithm={name:`RSA-OAEP`},signAlgorithm=`HMAC`,format=`pkcs8`,signFormat=`raw`
        ,rsaHashedKeyGenParams=Object.assign({},algorithm,params,{modulusLength:modulusLength,publicExponent:new Uint8Array([0x01,0x00,0x01])})
        ,rsaHashedImportParams=Object.assign({},algorithm,params)
        ,hmacKeyParams=Object.assign({},{name:signAlgorithm},hashParams)
        ,keys=await crypto.subtle.generateKey(rsaHashedKeyGenParams,true,[`encrypt`,`decrypt`])
        ,exportKey=await crypto.subtle.exportKey(format,keys.privateKey),encrypted=await crypto.subtle.encrypt(algorithm,keys.publicKey,encoder.encode(string))
        ,signKey=await crypto.subtle.generateKey(hmacKeyParams,true,[`sign`])
        ,exportSignKey=await crypto.subtle.exportKey(signFormat,signKey)
        ,sign=await crypto.subtle.sign(signAlgorithm,signKey,encrypted)
        console.log(algorithm.name)
        console.log(await crypto.subtle.verify(signAlgorithm,await crypto.subtle.importKey(signFormat,exportSignKey,hmacKeyParams,false,[`verify`]),sign,encrypted))//true
        console.log(decoder.decode(await crypto.subtle.decrypt(algorithm,await crypto.subtle.importKey(format,exportKey,rsaHashedImportParams,false,[`decrypt`]),encrypted)))//hello world
    }
    (async()=>{
        const v=crypto.getRandomValues(new Uint8Array(16))
        ,keyLength=128//or 256
        console.log(string)//hello world
        await aesCTR(v,keyLength,64,{hash:`SHA-256`})
        await aesCBC(v,keyLength,{hash:`SHA-256`})
        await aesGCM(v,keyLength,{hash:`SHA-256`})
        await rsaOAEP(2048,{hash:`SHA-256`},{hash:`SHA-256`})
    })()
}</script></head></html>


WebGL, WebGL2, WebGPU(data uri)


code

<!doctype html>
<head>
<style>
body{background-color:#ffffffff;color:#000000ff}
@media(prefers-color-scheme:dark){body{background-color:#000000ff;color:#ffffffff}}
</style>
<style>
html{
    *{margin:0;padding:0}
    >body{
        *{font-family:monospace;box-sizing:border-box;overflow-wrap:anywhere}
        >:nth-child(1){
            >dl>dd>canvas{width:100%;aspect-ratio:1}
            display:grid;grid-template-columns:1fr 1fr 1fr
        }
        >:nth-child(2){
            >dd{margin-left:.5rem}
            display:grid;grid-template-columns:auto 1fr
        }
    }
}
</style>
<script>
WebGLRenderingContext.prototype.toDraw=function(p,is,mode,color){
    const vertexShaderSrc=`precision highp float;attribute vec3 p;uniform vec4 q0;uniform vec4 q1;vec3 c(vec3 p,vec4 q){return p+2.0*cross(q.xyz,cross(q.xyz,p)+q.w*p);}void main(){gl_Position=vec4(c(c(p,q0),q1)+vec3(0,0,1.0),2.0);}`
    ,fragmentShaderSrc=`precision highp float;void main(){gl_FragColor=vec4(${color.join(`,`)});}`
    ,program=(()=>{
        const createShader=(type,src)=>{
            const shader=this.createShader(type)
            this.shaderSource(shader,src)
            this.compileShader(shader)
            return shader
        }
        const program=this.createProgram()
        this.attachShader(program,createShader(this.VERTEX_SHADER,vertexShaderSrc))
        this.attachShader(program,createShader(this.FRAGMENT_SHADER,fragmentShaderSrc))
        this.linkProgram(program)
        return program
    })()
    ,q0Location=this.getUniformLocation(program,`q0`)
    ,q1Location=this.getUniformLocation(program,`q1`)
    this.clearColor(0,0,0,0)
    this.useProgram(program)
    this.enableVertexAttribArray(0)
    this.bindBuffer(this.ARRAY_BUFFER,this.createBuffer())
    this.bufferData(this.ARRAY_BUFFER,p,this.STATIC_DRAW)
    this.bindBuffer(this.ELEMENT_ARRAY_BUFFER,this.createBuffer())
    this.bufferData(this.ELEMENT_ARRAY_BUFFER,is,this.STATIC_DRAW)
    this.vertexAttribPointer(0,3,this.FLOAT,false,0,0)
    return(q0,q1)=>{
        this.clear(this.COLOR_BUFFER_BIT|this.DEPTH_BUFFER_BIT)
        this.uniform4f(q0Location,...q0)
        this.uniform4f(q1Location,...q1)
        this.drawElements(mode,is.length,this.UNSIGNED_SHORT,0)
    }
}
WebGL2RenderingContext.prototype.toDraw=function(p,is,mode,color){
    const vertexShaderSrc=`#version 300 es\nprecision highp float;in vec3 p;layout(std140)uniform q{vec4 q0;vec4 q1;};vec3 c(vec3 p,vec4 q){return p+2.0*cross(q.xyz,cross(q.xyz,p)+q.w*p);}void main(){gl_Position=vec4(c(c(p,q0),q1)+vec3(0,0,1.0),2.0);}`
    ,fragmentShaderSrc=`#version 300 es\nprecision highp float;out vec4 c;void main(){c=vec4(${color.join(`,`)});}`
    ,program=(()=>{
        const createShader=(type,src)=>{
            const shader=this.createShader(type)
            this.shaderSource(shader,src)
            this.compileShader(shader)
            return shader
        }
        const program=this.createProgram()
        this.attachShader(program,createShader(this.VERTEX_SHADER,vertexShaderSrc))
        this.attachShader(program,createShader(this.FRAGMENT_SHADER,fragmentShaderSrc))
        this.linkProgram(program)
        return program
    })()
    ,uniformBuffer=this.createBuffer()
    this.clearColor(0,0,0,0)
    this.useProgram(program)
    this.enableVertexAttribArray(0)
    this.bindBuffer(this.ARRAY_BUFFER,this.createBuffer())
    this.bufferData(this.ARRAY_BUFFER,p,this.STATIC_DRAW)
    this.uniformBlockBinding(program,0,0)
    this.bindBuffer(this.UNIFORM_BUFFER,uniformBuffer)
    this.bindBufferBase(this.UNIFORM_BUFFER,0,uniformBuffer)
    this.bindBuffer(this.ELEMENT_ARRAY_BUFFER,this.createBuffer())
    this.bufferData(this.ELEMENT_ARRAY_BUFFER,is,this.STATIC_DRAW)
    this.vertexAttribPointer(0,3,this.FLOAT,false,0,0)
    return(q0,q1)=>{
        this.clear(this.COLOR_BUFFER_BIT|this.DEPTH_BUFFER_BIT)
        const q=new Float32Array(q0.length+q1.length)
        q.set(q0)
        q.set(q1,q0.length)
        this.bufferData(this.UNIFORM_BUFFER,q,this.STATIC_DRAW)
        this.drawElements(mode,is.length,this.UNSIGNED_SHORT,0)
    }
}
if(navigator.gpu)GPUCanvasContext.prototype.toDraw=function(device,p,is,topology,color){
    const createBuffer=(usage,src)=>{
        const buffer=device.createBuffer({usage:usage,size:src.byteLength,mappedAtCreation:true})
        new src.constructor(buffer.getMappedRange()).set(src)
        buffer.unmap()
        return buffer
    }
    ,layout=device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{}}]})
    ,vertexShaderSrc=`struct Q{q0:vec4f,q1:vec4f}@binding(0)@group(0)var<uniform>q:Q;fn c(p:vec3f,q:vec4f)->vec3f{return p+2.0*cross(q.xyz,cross(q.xyz,p)+q.w*p);}@vertex fn main(@location(0)p:vec3f)->@builtin(position)vec4f{return vec4f(c(c(p,q.q0),q.q1)+vec3f(0,0,1.0),2.0);}`
    ,fragmentShaderSrc=`@fragment fn main()->@location(0)vec4f{return vec4f(${color.join(`,`)});}`
    ,format=navigator.gpu.getPreferredCanvasFormat()
    ,pipeline=device.createRenderPipeline({
        layout:device.createPipelineLayout({bindGroupLayouts:[layout]})
        ,primitive:{topology:topology}
        ,vertex:{buffers:[{attributes:[{format:`float32x3`,offset:0,shaderLocation:0}],arrayStride:12}],module:device.createShaderModule({code:vertexShaderSrc})}
        ,fragment:{targets:[{format:format}],module:device.createShaderModule({code:fragmentShaderSrc})}
    })
    ,encoder=device.createRenderBundleEncoder({colorFormats:[format]})
    ,uniformBuffer=device.createBuffer({usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,size:32})
    ,descriptor={colorAttachments:[{loadOp:`clear`,storeOp:`store`,clearValue:[0,0,0,0]}]}
    this.configure({device:device,format:format,alphaMode:`premultiplied`})
    encoder.setPipeline(pipeline)
    encoder.setVertexBuffer(0,createBuffer(GPUBufferUsage.VERTEX,p))
    encoder.setBindGroup(0,device.createBindGroup({entries:[{binding:0,resource:{buffer:uniformBuffer}}],layout:layout}))
    encoder.setIndexBuffer(createBuffer(GPUBufferUsage.INDEX,is),`uint16`)
    encoder.drawIndexed(is.length)
    const bundle=encoder.finish()
    return(q0,q1)=>{
        const q=new Float32Array(q0.length+q1.length)
        q.set(q0)
        q.set(q1,q0.length)
        device.queue.writeBuffer(uniformBuffer,0,q)
        descriptor.colorAttachments[0].view=this.getCurrentTexture().createView()
        const encoder=device.createCommandEncoder(),pass=encoder.beginRenderPass(descriptor)
        pass.executeBundles([bundle])
        pass.end()
        device.queue.submit([encoder.finish()])
    }
}
onload=async()=>{
    const setPointerEvent=(e,c)=>{
        let clientX,clientY
        e.addEventListener(`pointerup`,()=>{
            clientX=clientY=null
            c(new Float32Array([0,0,0,1]),new Float32Array([0,0,0,1]))
        })
        e.addEventListener(`pointerdown`,()=>{
            clientX=event.clientX
            clientY=event.clientY
        })
        e.addEventListener(`pointermove`,()=>{
            if(!clientX&&!clientY)return
            let x,y
            const v=Number(document.querySelector(`body>dl>dd>input[type=number]`).value)
            x=(event.clientX-clientX)*v/2
            y=(event.clientY-clientY)*v/2
            x=new Float32Array([0,Math.sin(x),0,Math.cos(x)])
            y=new Float32Array([Math.sin(y),0,0,Math.cos(y)])
            Number(document.querySelector(`body>dl>dd>select`).value)?c(x,y):c(y,x)
        })
    }
    ,[webGLCanvas,webGL2Canvas,webGPUCanvas]=document.querySelectorAll(`body>:nth-child(1)>dl>dd>canvas`)
    ,[webGLContext,webGL2Context]=[webGLCanvas.getContext(`webgl`),webGL2Canvas.getContext(`webgl2`)]
    ,p=new Float32Array([
        [
           1,1,1
           ,-1,-1,-1
           ,1,-1,1
           ,-1,1,-1
           ,-1,1,1
           ,1,-1,-1
           ,1,1,-1
           ,-1,-1,1
        ].map(v=>v/2)
        ,[
           0,1,0
           ,0,-1,0
           ,1,0,0
           ,-1,0,0
           ,0,0,1
           ,0,0,-1
        ]
    ].flat())
    ,is=new Uint16Array([
        [
            0,2,2,7,0,4,4,3,0,6,6,5
            ,1,3,3,6,1,5,5,2,1,7,7,4
        ]
        ,[
            0,2,2,4,4,1
            ,1,5,5,3,3,0
            ,0,4,4,3,3,1
            ,1,2,2,5,5,0
        ].map(v=>8+v)
    ].flat())
    ,cs=[webGLContext.toDraw(p,is,1,[1,0,0,1]),webGL2Context.toDraw(p,is,1,[0,1,0,1])]
    ,identity=new Float32Array([0,0,0,1])
    if(navigator.gpu){
        const adapter=await navigator.gpu.requestAdapter()
        if(adapter){
            const device=await adapter.requestDevice()
            if(device)cs.push(webGPUCanvas.getContext(`webgpu`).toDraw(device,p,is,`line-list`,[0,0,1,1]))
            else webGPUCanvas.parentElement.textContent=`the device request failed.`
        }else webGPUCanvas.parentElement.textContent=`the adapter request failed.`
    }else webGPUCanvas.parentElement.textContent=`available in secure contexts.`
    setPointerEvent(document.body,(q0,q1)=>cs.forEach(c=>c(q0,q1)))
    let size
    onresize=()=>{
        if(webGLCanvas.clientWidth===size)return
        size=webGLCanvas.clientWidth
        webGPUCanvas.height=webGPUCanvas.width=webGL2Canvas.height=webGL2Canvas.width=webGLCanvas.height=webGLCanvas.width=size
        webGLContext.viewport(0,0,size,size)
        webGL2Context.viewport(0,0,size,size)
        cs.forEach(c=>c(identity,identity))
    }
    onresize()
}
</script>
</head>
<body>
    <dl>
        <dl><dt>WebGL</dt><dd><canvas></canvas></dd></dl>
        <dl><dt>WebGL2</dt><dd><canvas></canvas></dd></dl>
        <dl><dt>WebGPU</dt><dd><canvas></canvas></dd></dl>
    </dl>
    <dl>
        <dt>sensitivity</dt><dd><input type='number' step='.01' min='0' value='.05'></dd>
        <dt>order</dt><dd><select><option value='0'>false</option><option value='1'>true</option></select></dd>
    </dl>
</body>
</html>