some visuals for โ€˜mainโ€™ model

Some visuals

Code
viewof keys = {
  let e = html`<div class='target' style='color:pink; background:#eee' tabIndex=1>Keyboard target</div>`;
  let keys = [];
  e.value = keys;
  let gap = new Date();
  e.addEventListener("keyup", (evt) => {
    keys.push({
      key: evt.key,
      delay: new Date() - gap,
      frame: mutable frame_val
    });
    gap = new Date();
    e.dispatchEvent(new CustomEvent("input"));
    evt.preventDefault(); // for revealjs? not enough
  });
  e.addEventListener("keydown", (evt) => {
    evt.preventDefault();
  });
  return e;
}

mutable frame_val = 0

{
  frame_in;
  mutable frame_val = frame_in;
}
Code
import {Scrubber} from "@mbostock/scrubber"

keys_stream_in = [{ key: "ArrowRight", frame: 20 },
  { key: "ArrowUp", frame: 30 },
  { key: "ArrowLeft", frame: 45 },{ key: "ArrowLeft", frame: 48 },
  { key: "ArrowUp", frame: 60 },
  { key: "ArrowUp", frame: 64 },
  { key: "ArrowUp", frame: 100 },
  { key: "ArrowUp", frame: 200 },
  { key: "ArrowUp", frame: 300 },
  { key: "ArrowUp", frame: 301 },
  { key: "ArrowUp", frame: 304 }]

mutable key_stream_in2 = [{ key: "ArrowRight", frame: 20 }]

//import {viewof keys} from 'd/867e1424e1d093ab'

keys
Code
viewof g_in = Inputs.range([-1,2], {value:1, step:0.01, label:'g_in'})

viewof s_in = Inputs.range([-6,6], {value:4, step:0.01, label:'s_in'})
viewof jump_limit_in = Inputs.range([0,3], {value:2, step:1, label:'jump_limit_in'})

gameplay (for fixed key stream) (workings are below)

```{ojs}

viewof frame_in = Scrubber(_.range(0,900), {delay: 100, autoplay:false})

viewof keys

main.keys$m.cache

viz_spec = ({
  data: {name: 'data'},
  datasets: {data: viz_data0},
  "mark": {"type": "text", "align": "left", "tooltip": true},

  encoding: {
    x: {field: 'player_x', axis:{grid:false}, type:'quantitative', scale: {domain:[-30,50]}},
    y: {field: 'player_y', axis:{grid:false}, type:'quantitative', scale: {domain:[-5,50]}},
    size: {value: 20},
    text: {field: 'keys_annotation', type: 'nominal'}, // keys_annotation includes the emoji, will fix
  },
  height:150,
  width: 200,
})

viz_data = calcuvegadata({
  models: [main],
  spec: viz_spec,
  domains: {  },
  input_cursors: [{frame_in, keys_stream_in: keys.filter(d =>d.frame == frame_in) /*prob not using memo, but still pure, do a filter?*/, g_in, s_in, jump_limit_in}]
})

viz_data

viewof viz = embed(viz_spec)

keys

{
  console.log(Object.entries(main.player_x$m.cache).length)
  frame_in; keys_stream_in; g_in; s_in; jump_limit_in;
  viz.data("data", viz_data)/*.resize()*/.run();
}

mutable viz_data0 = [] // includes data in spec for when I Open in Vega Editor

htl.html`<button onclick=${() => (mutable viz_data0 = viz_data)}>insert data -> vega editor (dev)</button>`

import { fps, color } from "@ondras/fps"

div = {
  let node = html`<div>fps: ${Math.floor(fps)}</div>`;
  node.style.fontSize = "1em";
  node.style.color = color;
  node.style.textShadow = "0 0 0.08em #000";
  return node;
}


```
OJS Syntax Error (line 115, column 1)Unexpected token

Appendix

Code
import { calcuvegadata } from "baafa4b071a5b66a" // draft API!

import { calcuvizspec } from "@declann/little-calcu-helpers"
embed = require('vega-embed');

entrypoint = './models/vek.cul.js'//Inputs.select(['models/main/main.cul.js'], {label:'entrypoint'})

entrypoint_no_cul_js = entrypoint.slice(0,-7)

main = require(`${entrypoint_no_cul_js}.js`);

//import { player_x } from './models/vek-nomemo_esm/cul_scope_0.mjs'

/*md`player x?`

player_x*/

introspection_fetch = await fetch(`${entrypoint_no_cul_js}.introspection.json`)

introspection = introspection_fetch.json({typed:true})

introspection_nomemo_fetch = await fetch(`${entrypoint_no_cul_js}-nomemo.introspection.json`)

introspection_nomemo = introspection_nomemo_fetch.json({typed:true})

inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'input definition').map(d => d.name).sort()

formulae = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition').map(d => d.name)

// formulae excluding pure inputs
formulae_not_inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition' && inputs.indexOf(d.name+'_in') == -1).map(d => d.name)
|