├── .nvmrc
├── .npmrc
├── shared
├── libs
│ ├── posenet.js
│ ├── artoolkit_wasm.wasm
│ ├── cannon.json
│ ├── ml5.json
│ ├── jszip.json
│ ├── socket.io.min.json
│ ├── d3.json
│ ├── mp_pose.json
│ ├── tone.json
│ ├── colorrick.json
│ ├── exrloader.json
│ ├── hashids.json
│ ├── whammy.json
│ ├── resemble.json
│ ├── bodymovin.json
│ ├── hammer.json
│ ├── lottie_svg.json
│ ├── meyda.json
│ ├── posenet-tfjs.json
│ ├── ammo.json
│ ├── fuse.json
│ ├── lottie.json
│ ├── marked.json
│ ├── mp_face.json
│ ├── mp_hands.json
│ ├── qrcode.json
│ ├── ammo.wasm.json
│ ├── earcut.json
│ ├── fflate.json
│ ├── iwanthue.json
│ ├── mp_camera_utils.json
│ ├── pako.json
│ ├── perlin.json
│ ├── jeelizFaceFilter.json
│ ├── lottie_canvas.min.json
│ ├── p5.json
│ ├── chroma.json
│ ├── clmtrackr.json
│ ├── moment.json
│ ├── socketcluster-client.json
│ ├── conway-hart.json
│ ├── draco_decoder.json
│ ├── jeelizPupillometry.json
│ ├── posenet.json
│ ├── rhill-voronoi-core.json
│ ├── jeelizGlanceTracker.json
│ ├── moment-with-locales.json
│ ├── tracking.json
│ ├── webaudio-peaks.json
│ ├── draco_decoder_wasm.json
│ ├── moment_with_timezones.json
│ ├── mqttws31-min.json
│ ├── navigo.json
│ ├── opentype.json
│ ├── glsltokenizer.json
│ ├── draco_wasm_wrapper.json
│ ├── twitterFetcher_min.json
│ ├── start-audio-context.json
│ ├── platform.json
│ ├── echarts.json
│ ├── webvr-polyfill.json
│ ├── artoolkit.json
│ ├── tess2.json
│ ├── artoolkit_wasm.json
│ ├── artoolkit_worker.json
│ ├── teachablemachine_tf_speech_image_pose.json
│ ├── webaudio-peaks.js
│ ├── mp_camera_utils.js
│ ├── start-audio-context.js
│ └── twitterFetcher_min.js
├── api
│ ├── api_constants.js
│ ├── utils
│ │ ├── shared_libs_util.js
│ │ ├── util_provider.js
│ │ ├── shared_util.js
│ │ ├── shared_teams_util.js
│ │ ├── shared_subpatchop_util.js
│ │ ├── shared_logger.js
│ │ └── shared_files_util.js
│ ├── package.json
│ └── index.js
├── client
│ ├── client_contstants.js
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ ├── eventlistener.js
│ │ ├── modalbg.js
│ │ ├── helper.js
│ │ ├── logger.js
│ │ ├── ele.js
│ │ ├── eventtarget.js
│ │ └── talkerapi.js
│ └── index.js
├── package.json
├── shared_constants.json
└── buildwatcher.js
├── jsdoc
├── .gitignore
├── dev_robots.txt
├── template
│ ├── index.html
│ ├── manual.html
│ ├── image
│ │ ├── search.png
│ │ ├── esdoc-logo-mini.png
│ │ ├── esdoc-logo-mini-black.png
│ │ ├── badge.svg
│ │ └── manual-badge.svg
│ ├── single.html
│ ├── nav.html
│ ├── manualIndex.html
│ ├── file.html
│ ├── script
│ │ ├── patch-for-local.js
│ │ ├── manual.js
│ │ ├── pretty-print.js
│ │ ├── inherited-summary.js
│ │ ├── inner-link.js
│ │ ├── test-summary.js
│ │ └── search.js
│ ├── testInterface.html
│ ├── test.html
│ ├── identifiers.html
│ ├── manualCardIndex.html
│ ├── properties.html
│ ├── css
│ │ ├── identifiers.css
│ │ ├── source.css
│ │ ├── test.css
│ │ ├── github.css
│ │ ├── search.css
│ │ ├── prettify-tomorrow.css
│ │ └── manual.css
│ ├── source.html
│ ├── summary.html
│ ├── layout.html
│ ├── details.html
│ └── class.html
├── cables.css
├── index.html
├── package.json
├── config
│ ├── core.json
│ ├── ui.json
│ └── standalone.json
└── dev_layout.html
├── docs
├── howto_helper_scripts.md
├── howto_changelog.md
├── howto_create_new_ops.md
├── howto_op_new_version.md
├── toolchain.md
└── howto_libraries.md
├── .eslintignore
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── webook_dev.yml
│ ├── webook_pull_dev.yml
│ ├── nightly.yml
│ ├── tests.yml
│ ├── jsdocs_master.yml
│ └── jsdocs.yml
├── index.d.ts
├── co.sh
├── .editorconfig
├── .ignore
├── .gitignore
├── tsconfig.json
├── pm2_ecosystem.config.cjs
├── update_ops.sh
├── LICENCE
├── dev_cables.code-workspace
├── package.json
├── hook_standalone.sh
├── start.js
├── tag_repos.sh
├── README.md
├── .eslintrc
├── install_local.sh
└── update_repos.sh
/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.13.1
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/shared/libs/posenet.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/jsdoc/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | template/layout.html
3 |
--------------------------------------------------------------------------------
/jsdoc/dev_robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/docs/howto_helper_scripts.md:
--------------------------------------------------------------------------------
1 | # Helper scripts in cables_dev
2 |
--------------------------------------------------------------------------------
/jsdoc/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/jsdoc/template/manual.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | !cables/src/ops/patches/*/*
2 | !cables/src/ops/teams/*/*
3 | !cables/src/ops/users/*/*
4 |
--------------------------------------------------------------------------------
/jsdoc/template/image/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cables-gl/cables_dev/HEAD/jsdoc/template/image/search.png
--------------------------------------------------------------------------------
/shared/libs/artoolkit_wasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cables-gl/cables_dev/HEAD/shared/libs/artoolkit_wasm.wasm
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | patreon: cables_gl
4 | ko_fi: cablesgl
5 |
6 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare const vec3:any
3 | declare const vec2:any
4 | declare const mat4:any
5 | declare const chroma:any
6 |
--------------------------------------------------------------------------------
/jsdoc/cables.css:
--------------------------------------------------------------------------------
1 | :not(pre) > code {
2 | background: unset !important;
3 | background-color: rgba(0,0,0,0.04);
4 | }
5 |
--------------------------------------------------------------------------------
/jsdoc/template/single.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/jsdoc/template/image/esdoc-logo-mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cables-gl/cables_dev/HEAD/jsdoc/template/image/esdoc-logo-mini.png
--------------------------------------------------------------------------------
/jsdoc/template/image/esdoc-logo-mini-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cables-gl/cables_dev/HEAD/jsdoc/template/image/esdoc-logo-mini-black.png
--------------------------------------------------------------------------------
/shared/api/api_constants.js:
--------------------------------------------------------------------------------
1 | import CablesConstants from "../shared_constants.json" with { type: "json" };
2 |
3 | export default {
4 | ...CablesConstants
5 | };
6 |
--------------------------------------------------------------------------------
/shared/libs/cannon.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"cannonjs",
3 | "description":"physics library",
4 | "url":"http://www.cannonjs.org/",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/ml5.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "ml5js",
3 | "description": "machine learning library",
4 | "url": "https://ml5js.org",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/client/client_contstants.js:
--------------------------------------------------------------------------------
1 | import CablesConstants from "../shared_constants.json" with { type: "json" };
2 |
3 | export default {
4 | ...CablesConstants
5 | };
6 |
--------------------------------------------------------------------------------
/shared/libs/jszip.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"jszip",
3 | "description":"js zip archive library",
4 | "url":"https://stuk.github.io/jszip/",
5 | "licence": "MIT"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/shared/libs/socket.io.min.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"socket.io library",
3 | "description":"socket.io library",
4 | "url":"https://socket.io",
5 | "licence": "MIT"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/co.sh:
--------------------------------------------------------------------------------
1 | echo "----- share dev"
2 | git checkout $1
3 | cd cables
4 | echo "----- core"
5 | git checkout $1
6 | cd ..
7 | cd cables_ui
8 | echo "----- ui"
9 | git checkout $1
10 | cd ..
11 |
--------------------------------------------------------------------------------
/shared/libs/d3.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"d3",
3 | "description":"library for visualizing data using web standards",
4 | "url":"https://github.com/d3/d3",
5 | "licence": "ISC"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/mp_pose.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "mediapipe pose",
3 | "description": "",
4 | "url": "https://cdn.jsdelivr.net/npm/@mediapipe/pose/pose.js",
5 | "licence": "Apache"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/tone.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Tone.js",
3 | "description":"Webaudio Library",
4 | "url":"https://tonejs.github.io/",
5 | "version": "R12",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug, new, devenv
6 | assignees: ''
7 |
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/shared/libs/colorrick.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"colorRick",
3 | "description":"colorpicker without bullshit",
4 | "url":"https://github.com/pandrr/colorRick",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/exrloader.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"exrloader",
3 | "description":"exrloader from three.js",
4 | "url":"https://threejs.org/",
5 | "version": "0",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/hashids.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"hashid",
3 | "description":"generate short unique ids from integers",
4 | "url":"http://hashids.org/",
5 | "licence": "Public Domain"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/whammy.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Whammy",
3 | "description":"A real time javascript webm encoder",
4 | "url":"https://github.com/antimatter15/whammy",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: new, devenv
6 | assignees: ''
7 |
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/jsdoc/template/nav.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/shared/libs/resemble.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Resemble.js",
3 | "description":"Image analysis and comparison",
4 | "url":"https://github.com/Huddle/Resemble.js/",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/bodymovin.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"bodymovin",
3 | "description":"after effect animation exporer/player",
4 | "url":"https://github.com/airbnb/lottie-web",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/hammer.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"hammer.js",
3 | "description":"touch gesture detection",
4 | "url":"https://hammerjs.github.io/",
5 | "version": "2.0.8",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/lottie_svg.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"lottie svg",
3 | "description":"lottie svg",
4 | "url":"https://github.com/airbnb/lottie-web",
5 | "version": "5.10.2",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/meyda.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "meyda",
3 | "description": "Audio feature extraction",
4 | "url": "https://github.com/meyda/meyda",
5 | "version":"5.3.0",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/posenet-tfjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"posenet tensorflow",
3 | "description":"posenet tensorflow",
4 | "url":"https://github.com/tensorflow/tfjs-models",
5 | "licence": "MIT"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/shared/libs/ammo.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"ammo.js",
3 | "description":"Physics Library",
4 | "url":"https://github.com/kripken/ammo.js/",
5 | "version": "28 Jan",
6 | "licence": "Public Domain"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/fuse.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"fuse.js",
3 | "description":"lightweight fuzzy-search",
4 | "url":"https://fusejs.io/",
5 | "version": "v6.6.2",
6 | "licence": "Apache-2.0 License"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/lottie.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"lottie for web",
3 | "description":"lottie for web",
4 | "url":"https://github.com/airbnb/lottie-web",
5 | "version": "5.7.11",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/marked.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "marked",
3 | "description": "markdown to html parser",
4 | "url": "https://github.com/markedjs/marked",
5 | "version":"4.2.3",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/mp_face.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "mediapipe face mesh",
3 | "description": "",
4 | "url": "https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/face_mesh.js",
5 | "licence": "Apache"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/mp_hands.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "mediapipe hands",
3 | "description": "",
4 | "url": "https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js",
5 | "licence": "Apache"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/qrcode.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"qrcode.js",
3 | "description":"Cross-browser QRCode generator for javascript",
4 | "url":"https://davidshimjs.github.io/qrcodejs/",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/ammo.wasm.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"ammo.js",
3 | "description":"Physics Library",
4 | "url":"https://github.com/kripken/ammo.js/",
5 | "version": "25 Mar",
6 | "licence": "Public Domain"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/earcut.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"earcut.js",
3 | "description":"polygon triangulation library",
4 | "url":"https://github.com/mapbox/earcut",
5 | "licence": "ISC",
6 | "version": "2.2.3"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/fflate.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"fflate",
3 | "description":"High performance (de)compression",
4 | "url":"https://github.com/101arrowz/fflate",
5 | "version": "0",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/iwanthue.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"iwanthue.js",
3 | "description":"palette generator",
4 | "url":"http://medialab.github.io/iwanthue/",
5 | "version": "18 nov 2024",
6 | "licence": ""
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/mp_camera_utils.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "mediapipe camera",
3 | "description": "",
4 | "url": "https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js",
5 | "licence": "Apache"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/pako.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"pako.js",
3 | "description":"zlib port to javascript, very fast!",
4 | "url":"https://github.com/nodeca/pako",
5 | "version": "2.0.3",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/perlin.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"perlin.js",
3 | "description":"perlin noise library",
4 | "url":"https://github.com/josephg/noisejs/blob/master/perlin.js",
5 | "licence": "Public Domain"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/jeelizFaceFilter.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"jeeliz",
3 | "description":"facetracking lib",
4 | "url":"https://github.com/jeeliz",
5 | "version": "24 oct 2019",
6 | "licence": "Apache License"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/lottie_canvas.min.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"lottie for web",
3 | "description":"lottie for web",
4 | "url":"https://github.com/airbnb/lottie-web",
5 | "version": "5.10.2",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/p5.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"p5.js",
3 | "description":"p5.js is an interpretation of Processing for today’s web",
4 | "url":"https://p5js.org/",
5 | "version": "1.2.0",
6 | "licence": "LGPL"
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 | [*]
3 | charset = utf-8
4 | end_of_line = lf
5 | indent_size = 4
6 | indent_style = space
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 | indent_brace_style=Allman
10 |
--------------------------------------------------------------------------------
/shared/libs/chroma.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"chroma.js",
3 | "description":"library for color conversions",
4 | "url":"https://github.com/gka/chroma.js",
5 | "version": "2.4.2",
6 | "licence": "Apache-2.0"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/clmtrackr.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"clmtrackr",
3 | "description":"Javascript library for precise tracking of facial features",
4 | "url":"https://github.com/auduno/clmtrackr",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/jsdoc/template/manualIndex.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/shared/libs/moment.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"moment.js",
3 | "description":"Parse, validate, manipulate, and display dates and times in JavaScript",
4 | "url":"https://momentjs.com/",
5 | "licence": "Public Domain"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/socketcluster-client.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"socketcluster client",
3 | "description":"socketcluster client",
4 | "url":"https://github.com/SocketCluster/socketcluster-client",
5 | "licence": "MIT"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/shared/libs/conway-hart.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"conway-heart",
3 | "description":"polyhedral notation interpreter",
4 | "url":"https://github.com/mikolalysenko/conway-hart",
5 | "licence": "GPL",
6 | "hidden": true
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/draco_decoder.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"draco",
3 | "description":"draco 3d mesh compression",
4 | "url":"https://github.com/google/draco/tree/gltf_2.0_draco_extension",
5 | "licence": " Apache-2.0 License "
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/jeelizPupillometry.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"jeeliz pupillometry",
3 | "description":"pupil tracking lib",
4 | "url":"https://github.com/jeeliz",
5 | "version": "24 nov 2019",
6 | "licence": "Apache License"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/posenet.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"posenet javascript library",
3 | "description":"posenet javascript library",
4 | "url":"https://github.com/tensorflow/tfjs-models/tree/master/posenet",
5 | "licence": "MIT"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/shared/libs/rhill-voronoi-core.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Javascript-Voronoi",
3 | "description":"voronoi algorithm library",
4 | "url":"https://github.com/gorhill/Javascript-Voronoi",
5 | "licence": "Public Domain"
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/shared/libs/jeelizGlanceTracker.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"jeeliz glance tracking",
3 | "description":"glance tracking lib",
4 | "url":"https://github.com/jeeliz",
5 | "version": "24 nov 2019",
6 | "licence": "Apache License"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/moment-with-locales.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"moment.js",
3 | "description":"Parse, validate, manipulate, and display dates and times in JavaScript",
4 | "url":"https://momentjs.com/",
5 | "licence": "Public Domain"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/tracking.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"tracking.js",
3 | "description":"Computer Vision on the web",
4 | "url":"https://github.com/eduardolundgren/tracking.js/",
5 | "version": "20. jan 2021",
6 | "licence": "BSD"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/webaudio-peaks.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Webaudio Peaks",
3 | "description":"extract peaks from audio samples or a webaudio AudioBuffer",
4 | "url":"https://github.com/naomiaro/webaudio-peaks",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/draco_decoder_wasm.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"draco - wasm",
3 | "description":"draco 3d mesh compression",
4 | "url":"https://github.com/google/draco/tree/gltf_2.0_draco_extension",
5 | "licence": " Apache-2.0 License "
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/moment_with_timezones.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"moment.js",
3 | "description":"Parse, validate, manipulate, and display dates and times in JavaScript",
4 | "url":"https://momentjs.com/",
5 | "licence": "Public Domain"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/mqttws31-min.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"websocket to mqtt",
3 | "description":"Use WebSockets to connect to an MQTT Broker",
4 | "url":"https://www.eclipse.org/paho/clients/js/",
5 | "licence": "Eclipse Public License"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/navigo.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "navigo",
3 | "description": "A simple dependency-free minimalistic JavaScript router",
4 | "url": "https://github.com/krasimir/navigo",
5 | "version": "8.1.0",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/opentype.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "opentype",
3 | "description": "A JavaScript parser and writer for TrueType and OpenType fonts",
4 | "url": "https://github.com/opentypejs/opentype.js",
5 | "version": "1.3.4",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/glsltokenizer.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"glsltokenizer.js",
3 | "description":"Maps GLSL string data into GLSL tokens",
4 | "url":"https://www.npmjs.com/package/glsl-tokenizer",
5 | "version": "2.1.5",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/draco_wasm_wrapper.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"draco - wasm wrapper",
3 | "description":"draco 3d mesh compression",
4 | "url":"https://github.com/google/draco/tree/gltf_2.0_draco_extension",
5 | "licence": " Apache-2.0 License "
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/twitterFetcher_min.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"Twitter-Post-Fetcher",
3 | "description":"Allows you to get your tweets displaying on your website",
4 | "url":"https://github.com/jasonmayes/Twitter-Post-Fetcher",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/start-audio-context.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"StartAudioContext",
3 | "description":"Starts the Web Audio API's AudioContext on an explicit user action.",
4 | "url":"https://github.com/tambien/StartAudioContext",
5 | "licence": "MIT"
6 | }
7 |
--------------------------------------------------------------------------------
/jsdoc/template/file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sorry, this documentation does not provide source code.
4 |
--------------------------------------------------------------------------------
/jsdoc/template/script/patch-for-local.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | if (location.protocol === 'file:') {
3 | var elms = document.querySelectorAll('a[href="./"]');
4 | for (var i = 0; i < elms.length; i++) {
5 | elms[i].href = './index.html';
6 | }
7 | }
8 | })();
9 |
--------------------------------------------------------------------------------
/shared/libs/platform.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Platform.js",
3 | "description": "A platform detection library that works on nearly all JavaScript platforms.",
4 | "url": "https://github.com/bestiejs/platform.js/",
5 | "version": "1.3.6",
6 | "licence": "MIT"
7 | }
8 |
--------------------------------------------------------------------------------
/jsdoc/template/testInterface.html:
--------------------------------------------------------------------------------
1 |
2 | |
3 | |
4 |
5 |
--------------------------------------------------------------------------------
/shared/libs/echarts.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"echarts.js",
3 | "description":"Apache ECharts is a powerful, interactive charting and data visualization library for browser",
4 | "url":"https://echarts.apache.org/en/index.html",
5 | "licence": "Apache-2.0",
6 | "version": "5.1.2"
7 | }
8 |
--------------------------------------------------------------------------------
/jsdoc/template/test.html:
--------------------------------------------------------------------------------
1 | Test
2 |
3 |
4 |
5 | | Description |
6 | Identifier |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/libs/webvr-polyfill.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"WebVr Polyfill",
3 | "description":"A JavaScript implementation of the WebVR spec, e.g. use webvr on phones which browsers don't support it",
4 | "url":"https://github.com/immersive-web/webvr-polyfill",
5 | "licence": "Apache License"
6 | }
7 |
--------------------------------------------------------------------------------
/shared/libs/artoolkit.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"artoolkit.js",
3 | "description":"Emscripten port of ARToolKit to JavaScript.",
4 | "url":"https://github.com/artoolkitx/jsartoolkit5",
5 | "version": "27. September 2021",
6 | "licence": "ARToolKit LGPLv3 license and additional permission"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/tess2.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"tess2",
3 | "description":"The tess2.js library performs polygon boolean operations and tesselation to triangles and convex polygons.",
4 | "url":"https://github.com/memononen/tess2.js",
5 | "version": "5 Apr 2016",
6 | "licence": "SGI-B-2.0"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/artoolkit_wasm.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"artoolkit.wasm.js",
3 | "description":"Emscripten port of ARToolKit to JavaScript.",
4 | "url":"https://github.com/artoolkitx/jsartoolkit5",
5 | "version": "27. September 2021",
6 | "licence": "ARToolKit LGPLv3 license and additional permission"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/libs/artoolkit_worker.json:
--------------------------------------------------------------------------------
1 | {
2 | "title":"artoolkit.wasm.js",
3 | "description":"Emscripten port of ARToolKit to JavaScript.",
4 | "url":"https://github.com/artoolkitx/jsartoolkit5",
5 | "version": "27. September 2021",
6 | "licence": "ARToolKit LGPLv3 license and additional permission"
7 | }
8 |
--------------------------------------------------------------------------------
/.ignore:
--------------------------------------------------------------------------------
1 | cables/build/*
2 | cables_ui/dist/
3 | cables_electron/dist/
4 | jsdoc/dist/
5 | cables_api/public/landing/standalone/patch/**
6 | cables_api/public/landing/standalone/hero/js/*
7 | cables_api/public/libs_core/**
8 | **/node_modules/**
9 | **/public/js/
10 | **/gen/**
11 | **/public/js/libs_core/*
12 | **/public/libs_core/*
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | electron/
3 | data/
4 | docker-compose.yml
5 | gen/
6 |
7 | # misc
8 | .idea/
9 | .DS_Store
10 | .vscode
11 | docker-compose.yml
12 |
13 | # OS generated files #
14 | ######################
15 | .DS_Store?
16 | ._*
17 | .Spotlight-V100
18 | .Trashes
19 | ehthumbs.db
20 | Thumbs.db
21 |
22 | #Node modules folder
23 | node_modules
24 | .external-ecmascript.js
25 |
--------------------------------------------------------------------------------
/shared/libs/teachablemachine_tf_speech_image_pose.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "teachablemachine_tf_speech_image_pose",
3 | "description": "Library for using models created with Teachable Machine. Includes tensorflow, tensorflow speech models, 'image' and 'pose'",
4 | "url": "https://github.com/googlecreativelab/teachablemachine-libraries",
5 | "version": "0.8.4",
6 | "licence": "Apache-2.0"
7 | }
8 |
--------------------------------------------------------------------------------
/docs/howto_changelog.md:
--------------------------------------------------------------------------------
1 | # How to add Changelog entries to Ops
2 |
3 | The following terms are used
4 | - New op : Op name here - One line summary of op
5 | - Op enhancement : Op name here - summary of enhancement / can also be a bug fix
6 | - Editor : Summary of changes to editor
7 | - Web : summary of change
8 | - Core : Summary of change
9 |
10 | Check [here](https://cables.gl/changelog) for examples
11 |
--------------------------------------------------------------------------------
/jsdoc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | cables.gl jsdocs
4 |
5 |
6 |
7 | documentation on developing cables
8 |
9 |
10 |
--------------------------------------------------------------------------------
/shared/client/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables-shared-client",
3 | "version": "0.0.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "cables-shared-client",
9 | "version": "0.0.1",
10 | "license": "MIT",
11 | "engines": {
12 | "node": "20.13.1"
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/jsdoc/template/identifiers.html:
--------------------------------------------------------------------------------
1 | References
2 |
3 |
16 |
--------------------------------------------------------------------------------
/jsdoc/template/manualCardIndex.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
14 |
15 |
--------------------------------------------------------------------------------
/shared/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables-shared-client",
3 | "version": "0.0.1",
4 | "author": "undefined development",
5 | "description": "shared client classes between the different subprojects of cables_dev",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/cables-gl/cables_dev.git"
9 | },
10 | "main": "index.js",
11 | "engines": {
12 | "node": "20.13.1"
13 | },
14 | "type": "module",
15 | "license": "MIT"
16 | }
17 |
--------------------------------------------------------------------------------
/jsdoc/template/properties.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | Name | Type | Attribute | Description |
6 |
7 |
8 |
9 | |
10 | |
11 | |
12 | |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/client/src/eventlistener.js:
--------------------------------------------------------------------------------
1 | export class EventListener
2 | {
3 |
4 | /**
5 | * @param {Object} emitter
6 | * @param {string} id
7 | * @param {string} eventName
8 | * @param {Function} cb
9 | */
10 | constructor(emitter, id, eventName, cb)
11 | {
12 | this.targetObj = emitter;
13 | this.id = id;
14 | this.eventName = eventName;
15 | this.cb = cb;
16 | }
17 |
18 | remove()
19 | {
20 | this.targetObj.off(this.id);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ESNext",
4 | "target": "ESNext",
5 | "checkJs": true,
6 | "allowJs": true,
7 | "moduleResolution": "bundler",
8 | "typeRoots": [
9 | "cables/node_modules/@webgpu/types"
10 | ]
11 | },
12 | "include": [
13 | "shared/api/**/*",
14 | "shared/client/src/**/*",
15 | "cables_ui/src/**/*",
16 | "cables/src/core/**/*",
17 | "cables/src/corelibs/**/*"
18 | ]
19 | }
--------------------------------------------------------------------------------
/jsdoc/template/script/manual.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | var matched = location.pathname.match(/\/(manual\/.*\.html)$/);
3 | if (!matched) return;
4 |
5 | var currentName = matched[1];
6 | var cssClass = '.navigation .manual-toc li[data-link="' + currentName + '"]';
7 | var styleText = cssClass + '{ display: block; }\n';
8 | styleText += cssClass + '.indent-h1 a { color: #039BE5 }';
9 | var style = document.createElement('style');
10 | style.textContent = styleText;
11 | document.querySelector('head').appendChild(style);
12 | })();
13 |
--------------------------------------------------------------------------------
/docs/howto_create_new_ops.md:
--------------------------------------------------------------------------------
1 | # How to create new Ops
2 |
3 | - Correct namespace / e.g. `Ops.Gl.TextureEffects.Blur`
4 | - Changelog has been updated with correct op name and one line summary / new op : `Ops.Gl.TextureEffects.Blur - blurs a texture `
5 | - Make sure the op has full documentation, it doesn't matter if it seems obvious what a parameter does its parameters should all be documented.
6 | - Make sure the op has an example patch. Go to the op page, edit the documentation and put in the short-id of the example patch.
7 | - Make sure the author name is correct.
8 |
--------------------------------------------------------------------------------
/.github/workflows/webook_dev.yml:
--------------------------------------------------------------------------------
1 | name: 'webhook dev'
2 |
3 | on:
4 | workflow_dispatch:
5 | # push:
6 | # branches:
7 | # - develop
8 | # paths:
9 | # - "shared/**"
10 |
11 | jobs:
12 | webhook-dev:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: notify dev
16 | uses: distributhor/workflow-webhook@v3
17 | with:
18 | curl_opts: "--retry 5 --retry-all-errors"
19 | webhook_type: "json-extended"
20 | webhook_url: "https://dev.cables.gl/api/webhooks/updateshared?secret=${{ secrets.WEBHOOK_SECRET }}"
21 | webhook_secret: ${{ secrets.WEBHOOK_SECRET }}
22 |
--------------------------------------------------------------------------------
/.github/workflows/webook_pull_dev.yml:
--------------------------------------------------------------------------------
1 | name: 'webhook pull dev'
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - develop
8 | paths-ignore:
9 | - "shared/**"
10 |
11 | jobs:
12 | webhook-dev:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: notify dev
16 | uses: distributhor/workflow-webhook@v3
17 | with:
18 | curl_opts: "--retry 5 --retry-all-errors"
19 | webhook_type: "json-extended"
20 | webhook_url: "https://dev.cables.gl/api/webhooks/pulldev?secret=${{ secrets.WEBHOOK_SECRET }}"
21 | webhook_secret: ${{ secrets.WEBHOOK_SECRET }}
22 |
--------------------------------------------------------------------------------
/shared/client/index.js:
--------------------------------------------------------------------------------
1 | import ele from "./src/ele.js";
2 | import helper from "./src/helper.js";
3 | import Events from "./src/eventtarget.js";
4 | import TalkerAPI from "./src/talkerapi.js";
5 | import Logger from "./src/logger.js";
6 | import ModalBackground from "./src/modalbg.js";
7 | import HandlebarsHelper from "./src/handlebars.js";
8 | import CablesConstants from "./client_contstants.js";
9 | import BuildWatcher from "../buildwatcher.js";
10 |
11 | export {
12 | helper,
13 | ele,
14 | Events,
15 | TalkerAPI,
16 | Logger,
17 | ModalBackground,
18 | HandlebarsHelper,
19 | CablesConstants,
20 | BuildWatcher
21 | };
22 |
--------------------------------------------------------------------------------
/.github/workflows/nightly.yml:
--------------------------------------------------------------------------------
1 | name: 'nightly merge'
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 3 * * *'
7 |
8 | jobs:
9 | nightly-merge:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | with:
15 | fetch-depth: 0
16 |
17 | - name: nightly merge
18 | uses: usertesting/gh-action-nightly-merge@ut-v1.3.1-fixed
19 | with:
20 | stable_branch: 'develop'
21 | development_branch: 'nightly'
22 | allow_ff: false
23 | allow_forks: true
24 | env:
25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26 |
--------------------------------------------------------------------------------
/jsdoc/template/css/identifiers.css:
--------------------------------------------------------------------------------
1 | .identifiers-wrap {
2 | display: flex;
3 | align-items: flex-start;
4 | }
5 |
6 | .identifier-dir-tree {
7 | background: #fff;
8 | border: solid 1px #ddd;
9 | border-radius: 0.25em;
10 | top: 52px;
11 | position: -webkit-sticky;
12 | position: sticky;
13 | max-height: calc(100vh - 155px);
14 | overflow-y: scroll;
15 | min-width: 200px;
16 | margin-left: 1em;
17 | }
18 |
19 | .identifier-dir-tree-header {
20 | padding: 0.5em;
21 | background-color: #fafafa;
22 | border-bottom: solid 1px #ddd;
23 | }
24 |
25 | .identifier-dir-tree-content {
26 | padding: 0 0.5em 0;
27 | }
28 |
29 | .identifier-dir-tree-content > div {
30 | padding-top: 0.25em;
31 | padding-bottom: 0.25em;
32 | }
33 |
34 | .identifier-dir-tree-content a {
35 | color: inherit;
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables-shared",
3 | "version": "0.0.1",
4 | "author": "undefined development",
5 | "description": "shared artifacts between the different subproject builds of cables_dev",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/cables-gl/cables_dev.git"
9 | },
10 | "engines": {
11 | "node": "20.13.1"
12 | },
13 | "devDependencies": {
14 | "npm-run-all": "4.1.5",
15 | "socketcluster-client": "19.2.3",
16 | "jwt-encode": "1.0.1"
17 | },
18 | "type": "module",
19 | "license": "MIT",
20 | "scripts": {
21 | "build": "run-s api client",
22 | "api": "cd ./api && npm install --loglevel silent",
23 | "client": "cd ./client && npm install --loglevel silent"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/jsdoc/template/image/badge.svg:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/jsdoc/template/image/manual-badge.svg:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/jsdoc/template/script/pretty-print.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | prettyPrint();
3 | var lines = document.querySelectorAll('.prettyprint.linenums li[class^="L"]');
4 | for (var i = 0; i < lines.length; i++) {
5 | lines[i].id = 'lineNumber' + (i + 1);
6 | }
7 |
8 | var matched = location.hash.match(/errorLines=([\d,]+)/);
9 | if (matched) {
10 | var lines = matched[1].split(',');
11 | for (var i = 0; i < lines.length; i++) {
12 | var id = '#lineNumber' + lines[i];
13 | var el = document.querySelector(id);
14 | el.classList.add('error-line');
15 | }
16 | return;
17 | }
18 |
19 | if (location.hash) {
20 | // ``[ ] . ' " @`` are not valid in DOM id. so must escape these.
21 | var id = location.hash.replace(/([\[\].'"@$])/g, '\\$1');
22 | var line = document.querySelector(id);
23 | if (line) line.classList.add('active');
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/howto_op_new_version.md:
--------------------------------------------------------------------------------
1 | # How to create a new version of an Op
2 |
3 | - Make sure that the version characters are added correctly. e.g. `Ops.Array.Array` becomes `Ops.Array.Array_v2` the next version would be `Ops.Array.Array_v3`. This removes all previous versions from the op creation menu for users. Old versions can only be found again on the op documentation page.
4 | - Make sure to copy over all relevant documentation from the previous version as the new op will have none.
5 | - Make sure that the op has a new example patch, it won't reference the old one.
6 | - If a port type has to be changed e.g. `op.inValueString` to `op.inString` then a new version of an op must be created, or it will break all patches that use that op.
7 | - A port name cannot be changed without breaking all patches that use it. Make a new version of the op if the port name must be changed.
8 | - Make sure the author name is correct from the user that made the previous version.
9 |
--------------------------------------------------------------------------------
/docs/toolchain.md:
--------------------------------------------------------------------------------
1 | # Tools
2 |
3 | cables uses the following tools for developing, building, deploying:
4 |
5 | - `javascript/ecmascript` as a main language
6 | - [git](https://git-scm.com/) for version control
7 | - [npm](https://www.npmjs.com/) and [nvm](https://github.com/nvm-sh/nvm) for dependency management
8 | - `npm run build` and `npm run start` are the main commands used
9 | - [bash](https://www.gnu.org/software/bash/) for running [shell-scripts](./howto_helper_scripts.md) (mostly helper-script to update/install everything)
10 | - [gulp](https://gulpjs.com/) for running the build scripts
11 | - [webpack](https://webpack.js.org/) to package bundles to use in other parts of the project
12 | - [eslint](https://eslint.org/) for linting code in editors
13 | - [electron](https://www.electronjs.org/) and [electron-builder](https://www.electron.build/) to pack and distribute cables standalone
14 | - several other open-source [tools and libraries](https://cables.gl/support), to get things done
15 |
--------------------------------------------------------------------------------
/jsdoc/template/source.html:
--------------------------------------------------------------------------------
1 | Source 
2 |
3 |
4 |
5 |
6 | | File |
7 | Identifier |
8 | Document |
9 | Size |
10 | Lines |
11 | Updated |
12 |
13 |
14 |
15 |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/shared/api/utils/shared_libs_util.js:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 |
3 | import sanitizeFileName from "sanitize-filename";
4 | import SharedUtil from "./shared_util.js";
5 | import { UtilProvider } from "./util_provider.js";
6 |
7 | /**
8 | * @abstract
9 | */
10 | export default class SharedLibsUtil extends SharedUtil
11 | {
12 | constructor(utilProvider)
13 | {
14 | super(utilProvider);
15 | }
16 |
17 | get utilName()
18 | {
19 | return UtilProvider.LIBS_UTIL;
20 | }
21 |
22 | libExists(libName)
23 | {
24 | let existsLib = false;
25 | if (typeof libName === "string")
26 | {
27 | libName = sanitizeFileName(libName);
28 | const libFilename = this._cables.getLibsPath() + libName;
29 | existsLib = fs.existsSync(libFilename);
30 | }
31 | return existsLib;
32 | }
33 |
34 | isAssetLib(fileName)
35 | {
36 | return (fileName && fileName.startsWith("/assets/") && fileName.endsWith(".js"));
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/shared/api/utils/util_provider.js:
--------------------------------------------------------------------------------
1 | class UtilProvider
2 | {
3 | constructor()
4 | {
5 | this._utils = {};
6 | }
7 |
8 | getUtil(name)
9 | {
10 | return this._utils[name];
11 | }
12 |
13 | register(name, that)
14 | {
15 | const logger = this.getUtil(UtilProvider.LOGGER);
16 | if (logger) logger.info("registering", that.constructor.name, "as", name);
17 | this._utils[name] = that;
18 | }
19 | }
20 | UtilProvider.CABLES = "cables";
21 | UtilProvider.DOCS_UTIL = "docsUtil";
22 | UtilProvider.HELPER_UTIL = "helperUtil";
23 | UtilProvider.LOGGER = "logger";
24 | UtilProvider.OPS_UTIL = "opsUtil";
25 | UtilProvider.SUBPATCH_OP_UTIL = "subPatchOpUtil";
26 | UtilProvider.TEAMS_UTIL = "teamsUtil";
27 | UtilProvider.PROJECTS_UTIL = "projectsUtil";
28 | UtilProvider.FILES_UTIL = "filesUtil";
29 | UtilProvider.LIBS_UTIL = "libsUtil";
30 | UtilProvider.EXPORT_SERVICE = "exportService";
31 | UtilProvider.BUILD_WATCHER = "buildWatcher";
32 |
33 | export { UtilProvider };
34 | export default new UtilProvider();
35 |
--------------------------------------------------------------------------------
/jsdoc/template/script/inherited-summary.js:
--------------------------------------------------------------------------------
1 | (function ()
2 | {
3 | function toggle(ev)
4 | {
5 | let button = ev.target;
6 | let parent = ev.target.parentElement;
7 | while (parent)
8 | {
9 | if (parent.tagName === "TABLE" && parent.classList.contains("summary")) break;
10 | parent = parent.parentElement;
11 | }
12 |
13 | if (!parent) return;
14 |
15 | let tbody = parent.querySelector("tbody");
16 | if (button.classList.contains("opened"))
17 | {
18 | button.classList.remove("opened");
19 | button.classList.add("closed");
20 | tbody.style.display = "none";
21 | }
22 | else
23 | {
24 | button.classList.remove("closed");
25 | button.classList.add("opened");
26 | tbody.style.display = "block";
27 | }
28 | }
29 |
30 | let buttons = document.querySelectorAll(".inherited-summary thead .toggle");
31 | for (let i = 0; i < buttons.length; i++)
32 | {
33 | buttons[i].addEventListener("click", toggle);
34 | }
35 | }());
36 |
--------------------------------------------------------------------------------
/pm2_ecosystem.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "treekill": false,
3 | "apps": [
4 | {
5 | "name": "server_api",
6 | "script": "src/servers/server_api.js",
7 | "cwd": "./cables_api",
8 | "instances": 4,
9 | "increment_var": "PM2_INSTANCE_ID",
10 | "env": {
11 | "PM2_INSTANCE_ID": 0
12 | }
13 | },
14 | {
15 | "name": "server_sandbox",
16 | "script": "src/servers/server_sandbox.js",
17 | "cwd": "./cables_api",
18 | "instances": 4,
19 | "increment_var": "PM2_INSTANCE_ID",
20 | "env": {
21 | "PM2_INSTANCE_ID": 0
22 | }
23 | },
24 | {
25 | "name": "server_socketcluster",
26 | "script": "src/servers/server_socketcluster.js",
27 | "cwd": "./cables_api",
28 | "instances": 1,
29 | "args": "-w 2 -s 2",
30 | "increment_var": "PM2_INSTANCE_ID",
31 | "env": {
32 | "PM2_INSTANCE_ID": 0
33 | }
34 | }]
35 | };
36 |
--------------------------------------------------------------------------------
/jsdoc/template/script/inner-link.js:
--------------------------------------------------------------------------------
1 | // inner link(#foo) can not correctly scroll, because page has fixed header,
2 | // so, I manually scroll.
3 | (function(){
4 | var matched = location.hash.match(/errorLines=([\d,]+)/);
5 | if (matched) return;
6 |
7 | function adjust() {
8 | window.scrollBy(0, -55);
9 | var el = document.querySelector('.inner-link-active');
10 | if (el) el.classList.remove('inner-link-active');
11 |
12 | // ``[ ] . ' " @`` are not valid in DOM id. so must escape these.
13 | var id = location.hash.replace(/([\[\].'"@$])/g, '\\$1');
14 | var el = document.querySelector(id);
15 | if (el) el.classList.add('inner-link-active');
16 | }
17 |
18 | window.addEventListener('hashchange', adjust);
19 |
20 | if (location.hash) {
21 | setTimeout(adjust, 0);
22 | }
23 | })();
24 |
25 | (function(){
26 | var els = document.querySelectorAll('[href^="#"]');
27 | var href = location.href.replace(/#.*$/, ''); // remove existed hash
28 | for (var i = 0; i < els.length; i++) {
29 | var el = els[i];
30 | el.href = href + el.getAttribute('href'); // because el.href is absolute path
31 | }
32 | })();
33 |
--------------------------------------------------------------------------------
/update_ops.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -l
2 | # update userops/teamops if the default-dirs exist
3 |
4 | git pull
5 |
6 | set -e
7 | set -o pipefail
8 |
9 | CWD=`pwd`
10 |
11 | cd cables
12 | cd src/ops/
13 | BASEDIR=`pwd`
14 |
15 | OPSDIR=$BASEDIR/users/
16 | branch="master"
17 | if [ -d "$OPSDIR" ]; then
18 | echo "UPDATING USEROPS..."
19 | cd $OPSDIR
20 | if [ -d ".git" ]; then
21 | git checkout $branch
22 | git pull
23 | else
24 | echo " NOT A GIT REPO AT $OPSDIR, SKIPPING";
25 | fi
26 | else
27 | echo " DIR NOT FOUND AT $OPSDIR, SKIPPING";
28 | fi
29 |
30 | OPSDIR=$BASEDIR/teams/
31 | branch="main"
32 | if [ -d "$OPSDIR" ]; then
33 | echo "UPDATING TEAMOPS..."
34 | cd $OPSDIR
35 | if [ -d ".git" ]; then
36 | git checkout $branch
37 | git pull
38 | else
39 | echo " NOT A GIT REPO AT $OPSDIR, SKIPPING";
40 | fi
41 | else
42 | echo " DIR NOT FOUND AT $OPSDIR, SKIPPING";
43 | fi
44 |
45 | cd $CWD
46 | if [ -d cables_api ]; then
47 | if [ -f cables_api/package.json ]; then
48 | echo "UPDATING OPDOCS..."
49 | cd $CWD/cables_api
50 | npm run opdocs
51 | fi
52 | fi
53 | cd $CWD
54 |
55 | echo "DONE"
56 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019-present undefined development
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/shared/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables-shared-api",
3 | "version": "0.0.1",
4 | "author": "undefined development",
5 | "description": "shared api classes between the different subprojects of cables_dev",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/cables-gl/cables_dev.git"
9 | },
10 | "main": "index.js",
11 | "engines": {
12 | "node": "20.13.1"
13 | },
14 | "type": "module",
15 | "license": "MIT",
16 | "dependencies": {
17 | "archiver": "5.3.1",
18 | "eslint": "7.32.0",
19 | "eslint-config-airbnb-base": "14.2.1",
20 | "eslint-plugin-import": "2.27.5",
21 | "fs-extra": "11.2.0",
22 | "glsl-tokenizer": "2.1.5",
23 | "image-size": "1.0.2",
24 | "jsonfile": "6.1.0",
25 | "marked": "12.0.2",
26 | "mkdirp": "2.1.3",
27 | "moment-mini": "2.29.4",
28 | "project-name-generator": "2.1.9",
29 | "sanitize-filename": "1.6.3",
30 | "uuid-v4": "0.1.0",
31 | "xml-writer": "1.7.0",
32 | "md5-file": "5.0.0"
33 | },
34 | "devDependencies": {
35 | "@types/node": "20.13.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/jsdoc/template/css/source.css:
--------------------------------------------------------------------------------
1 | table.files-summary {
2 | width: 100%;
3 | margin: 10px 0;
4 | border-spacing: 0;
5 | border: 0;
6 | border-collapse: collapse;
7 | text-align: right;
8 | }
9 |
10 | table.files-summary tbody tr:hover {
11 | background: #eee;
12 | }
13 |
14 | table.files-summary td:first-child,
15 | table.files-summary td:nth-of-type(2) {
16 | text-align: left;
17 | }
18 |
19 | table.files-summary[data-use-coverage="false"] td.coverage {
20 | display: none;
21 | }
22 |
23 | table.files-summary thead {
24 | background: #fafafa;
25 | }
26 |
27 | table.files-summary td {
28 | border: solid 1px #ddd;
29 | padding: 4px 10px;
30 | vertical-align: top;
31 | }
32 |
33 | table.files-summary td.identifiers > span {
34 | display: block;
35 | margin-top: 4px;
36 | }
37 | table.files-summary td.identifiers > span:first-child {
38 | margin-top: 0;
39 | }
40 |
41 | table.files-summary .coverage-count {
42 | font-size: 12px;
43 | color: #aaa;
44 | display: inline-block;
45 | min-width: 40px;
46 | }
47 |
48 | .total-coverage-count {
49 | position: relative;
50 | bottom: 2px;
51 | font-size: 12px;
52 | color: #666;
53 | font-weight: 500;
54 | padding-left: 5px;
55 | }
56 |
--------------------------------------------------------------------------------
/dev_cables.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "."
5 | }
6 | ],
7 | "settings": {
8 |
9 | "editor.codeActionsOnSave": {
10 | "source.fixAll.eslint": "explicit"
11 | },
12 | "editor.formatOnSaveTimeout": 1000,
13 | "eslint.alwaysShowStatus": true,
14 | "files.autoSave": "off",
15 | "editor.autoIndent": "full",
16 | "eslint.enable": true,
17 | "prettier.eslintIntegration": true,
18 | "typescript.validate.enable": false,
19 | "javascript.format.enable": false,
20 | "prettier.tabWidth": 4,
21 | "search.useIgnoreFiles": false,
22 | "search.exclude": {
23 | "**/node_modules": true,
24 | "**/bower_components": true,
25 | "**/*min.js": true,
26 | "**/*max.js": true,
27 | "**/*.map.*": true,
28 | "*/ace/*": true,
29 | "*dist/*": true,
30 | "*jsdoc*": true,
31 | "*build*": true,
32 | "*/public/*": true,
33 | "*/logs*": true
34 | },
35 | "files.exclude": {
36 | "**/.node_modules": true
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/jsdoc/template/summary.html:
--------------------------------------------------------------------------------
1 |
2 | |
3 |
4 |
5 | |
6 |
7 |
8 |
9 |
10 |
11 | |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 | |
27 |
28 | version
29 | since
30 | |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/jsdoc/template/css/test.css:
--------------------------------------------------------------------------------
1 | table.test-summary thead {
2 | background: #fafafa;
3 | }
4 |
5 | table.test-summary thead .test-description {
6 | width: 50%;
7 | }
8 |
9 | table.test-summary {
10 | width: 100%;
11 | margin: 10px 0;
12 | border-spacing: 0;
13 | border: 0;
14 | border-collapse: collapse;
15 | }
16 |
17 | table.test-summary thead .test-count {
18 | width: 3em;
19 | }
20 |
21 | table.test-summary tbody tr:hover {
22 | background-color: #eee;
23 | }
24 |
25 | table.test-summary td {
26 | border: solid 1px #ddd;
27 | padding: 4px 10px;
28 | vertical-align: top;
29 | }
30 |
31 | table.test-summary td p {
32 | margin: 0;
33 | }
34 |
35 | table.test-summary tr.test-interface .toggle {
36 | display: inline-block;
37 | float: left;
38 | margin-right: 4px;
39 | cursor: pointer;
40 | font-size: 0.8em;
41 | padding-top: 0.25em;
42 | }
43 |
44 | table.test-summary tr.test-interface .toggle.opened:before {
45 | content: '▼';
46 | }
47 |
48 | table.test-summary tr.test-interface .toggle.closed:before {
49 | content: '▶';
50 | }
51 |
52 | table.test-summary .test-target > span {
53 | display: block;
54 | margin-top: 4px;
55 | }
56 | table.test-summary .test-target > span:first-child {
57 | margin-top: 0;
58 | }
59 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: nightly tests
2 |
3 | on:
4 | workflow_dispatch:
5 | # schedule:
6 | # - cron: '0 3 * * *'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - name: install nodejs
14 | uses: actions/setup-node@v4
15 | with:
16 | node-version-file: ".nvmrc"
17 | check-latest: false
18 | - name: install nvm
19 | run: |
20 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
21 | echo -n 'nvm "$@" && echo $NVM_BIN >> $GITHUB_PATH' >> ~/.nvm/nvm.sh
22 | sudo cp ~/.nvm/nvm.sh /usr/local/bin/nvm
23 | sudo chmod +x /usr/local/bin/nvm
24 | - name: setup repos
25 | run: |
26 | ./install_local.sh https
27 | - name: checkout api
28 | uses: actions/checkout@v4
29 | with:
30 | repository: "undev-studio/cables_api"
31 | ref: develop
32 | token: ${{ secrets.undev_token }}
33 | path: "cables_api/"
34 | fetch-depth: 0
35 | - name: export tests
36 | run: |
37 | cd cables_api/
38 | npm install --no-save
39 | npm run tests:export
40 |
--------------------------------------------------------------------------------
/shared/api/index.js:
--------------------------------------------------------------------------------
1 | import SharedUtil from "./utils/shared_util.js";
2 | import Cables from "./cables.js";
3 | import utilProvider from "./utils/util_provider.js";
4 | import SharedDocUtil from "./utils/shared_doc_util.js";
5 | import SharedHelperUtil from "./utils/shared_helper_util.js";
6 | import SharedOpsUtil from "./utils/shared_ops_util.js";
7 | import SharedTeamsUtil from "./utils/shared_teams_util.js";
8 | import SharedSubPatchOpUtil from "./utils/shared_subpatchop_util.js";
9 | import SharedLogger from "./utils/shared_logger.js";
10 | import SharedProjectsUtil from "./utils/shared_projects_util.js";
11 | import SharedFilesUtil from "./utils/shared_files_util.js";
12 | import SharedLibsUtil from "./utils/shared_libs_util.js";
13 | import SharedExportService from "./export/shared_export_service.js";
14 | import CablesConstants from "./api_constants.js";
15 | import BuildWatcher from "../buildwatcher.js";
16 |
17 | export {
18 | utilProvider,
19 | Cables,
20 | SharedUtil,
21 | SharedDocUtil,
22 | SharedHelperUtil,
23 | SharedOpsUtil,
24 | SharedProjectsUtil,
25 | SharedTeamsUtil,
26 | SharedSubPatchOpUtil,
27 | SharedFilesUtil,
28 | SharedLibsUtil,
29 | SharedLogger,
30 | SharedExportService,
31 | CablesConstants,
32 | BuildWatcher
33 | };
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables_dev",
3 | "version": "1.0.0",
4 | "description": "cables development environment",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "start": "cross-env node start.js",
9 | "watch:standalone": "cross-env node start.js standalone",
10 | "test": "echo \"Error: no test specified\" && exit 1",
11 | "pm2": "pm2 start pm2_ecosystem.config.cjs"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/cables-gl/cables_dev.git"
16 | },
17 | "engines": {
18 | "node": "20.13.1"
19 | },
20 | "author": "",
21 | "license": "ISC",
22 | "bugs": {
23 | "url": "https://github.com/cables-gl/cables/issues"
24 | },
25 | "homepage": "https://github.com/cables-gl/cables_dev#readme",
26 | "devDependencies": {
27 | "concurrently": "8.2.2",
28 | "cross-env": "5.2.0",
29 | "eslint": "8.40.0",
30 | "eslint-config-airbnb-base": "15.0.0",
31 | "eslint-plugin-import": "2.27.5",
32 | "npm": "10.5.2",
33 | "pm2": "6.0.13",
34 | "prettier": "3.2.5",
35 | "prettier-eslint": "16.3.0",
36 | "tree-kill": "1.2.2",
37 | "uglify-js": "3.18.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/jsdoc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cables-jsdoc",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "build.js",
6 | "type": "module",
7 | "scripts": {
8 | "build": "run-s build:core build:ui build:standalone build:index",
9 | "build:dev": "run-s build:devlayout build build:robots",
10 | "build:core": "esdoc -c config/core.json",
11 | "build:ui": "esdoc -c config/ui.json",
12 | "build:standalone": "esdoc -c config/standalone.json",
13 | "build:devlayout": "cp dev_layout.html template/layout.html",
14 | "build:robots": "cp dev_robots.txt dist/robots.txt",
15 | "build:index": "cp index.html dist/index.html",
16 | "start": "http-server dist/"
17 | },
18 | "engines": {
19 | "node": "20.13.1"
20 | },
21 | "author": "",
22 | "license": "ISC",
23 | "devDependencies": {
24 | "@enterthenamehere/esdoc": "2.6.0-dev.1",
25 | "@enterthenamehere/esdoc-importpath-plugin":"2.6.0-dev.1",
26 | "@enterthenamehere/esdoc-standard-plugin": "2.6.0-dev.2",
27 | "@enterthenamehere/esdoc-publish-html-plugin": "2.6.0-dev.1",
28 | "@enterthenamehere/esdoc-inject-style-plugin": "2.6.0-dev.1",
29 | "@itsjamie/esdoc-importpath-plugin": "0.5.0",
30 | "npm-run-all": "4.1.5",
31 | "http-server": "14.1.1"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/jsdoc/config/core.json:
--------------------------------------------------------------------------------
1 | {
2 | "index": "../cables/README.md",
3 | "source": "../",
4 | "destination": "dist/cables",
5 | "includes": [
6 | "^cables/src/core/.*\\.js$",
7 | "^cables/src/libs/.*\\.js$"
8 | ],
9 | "excludes": [
10 | "node_modules"
11 | ],
12 | "plugins": [
13 | {
14 | "name": "@enterthenamehere/esdoc-standard-plugin"
15 | },
16 | {
17 | "name": "@enterthenamehere/esdoc-brand-plugin",
18 | "option": {
19 | "title": "cables.gl",
20 | "repository": "https://github.com/cables-gl/cables",
21 | "site": "https://cables.gl",
22 | "author": "https://undev.studio"
23 | }
24 | },
25 | {
26 | "name": "@enterthenamehere/esdoc-inject-style-plugin",
27 | "option": {
28 | "enable": true,
29 | "styles": [
30 | "./cables.css"
31 | ]
32 | }
33 | },
34 | {
35 | "name": "@enterthenamehere/esdoc-importpath-plugin",
36 | "option": {
37 | "stripPackageName": true,
38 | "replaces": [
39 | {
40 | "from": "^cables_dev/cables/src/",
41 | "to": "./"
42 | }
43 | ]
44 | }
45 | }
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/shared/client/src/modalbg.js:
--------------------------------------------------------------------------------
1 | import ele from "./ele.js";
2 | import Events from "./eventtarget.js";
3 |
4 | export default class ModalBackground extends Events
5 | {
6 | constructor(options = {})
7 | {
8 | super();
9 | this._eleBg = ele.byId("modalbg");
10 | this.showing = false;
11 |
12 | this._eleBg.addEventListener("pointerdown", () =>
13 | {
14 | this.hide();
15 | });
16 | this._eleBg.addEventListener("click", () =>
17 | {
18 | this.hide();
19 | });
20 |
21 | if (options.listenToEsc)
22 | document.body.addEventListener("keydown",
23 | (event) =>
24 | {
25 | if (this.showing && event.key === "Escape") this.hide();
26 | });
27 | }
28 |
29 | /**
30 | * @param {boolean} [transparent]
31 | */
32 | show(transparent = false)
33 | {
34 | if (!this.showing)
35 | {
36 | this.showing = true;
37 | this.emitEvent("show");
38 | }
39 | this._eleBg.style.display = "block";
40 |
41 | if (transparent) this._eleBg.classList.add("modalbgtransparent");
42 | else this._eleBg.classList.remove("modalbgtransparent");
43 | }
44 |
45 | hide()
46 | {
47 | if (this.showing)
48 | {
49 | this.showing = false;
50 | this.emitEvent("hide");
51 | }
52 | this._eleBg.style.display = "none";
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/.github/workflows/jsdocs_master.yml:
--------------------------------------------------------------------------------
1 | name: jsdocs master
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 3 * * *'
7 |
8 | env:
9 | JDOC_APP_ID: "131e893c-eac4-4713-917b-a49fdd10c1c8"
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: checkout cables
17 | uses: actions/checkout@v4
18 | with:
19 | repository: "cables-gl/cables"
20 | ref: master
21 | token: ${{ secrets.undev_token }}
22 | path: "cables/"
23 | - name: checkout cables ui
24 | uses: actions/checkout@v4
25 | with:
26 | repository: "cables-gl/cables_ui"
27 | ref: master
28 | token: ${{ secrets.undev_token }}
29 | path: "cables_ui/"
30 | - name: checkout cables electron
31 | uses: actions/checkout@v4
32 | with:
33 | repository: "cables-gl/cables_electron"
34 | path: "cables_electron/"
35 | ref: master
36 | - name: build jsdoc
37 | run: |
38 | cd jsdoc/
39 | npm install --no-save
40 | npm run build
41 | - name: Deploy jsdocs to netlify
42 | uses: netlify/actions/cli@master
43 | env:
44 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
45 | NETLIFY_SITE_ID: ${{ env.JDOC_APP_ID }}
46 | with:
47 | args: deploy --dir=jsdoc/dist --prod
48 | secrets: '["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]'
49 |
--------------------------------------------------------------------------------
/shared/client/src/helper.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Shared helper methods for cables uis
3 | */
4 | class Helper
5 | {
6 | constructor()
7 | {
8 | this._simpleIdCounter = 0;
9 | }
10 |
11 | /**
12 | * generate a random v4 uuid
13 | *
14 | * @return {string}
15 | */
16 | uuid()
17 | {
18 | let d = new Date().getTime();
19 | return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) =>
20 | {
21 | const r = (d + Math.random() * 16) % 16 | 0;
22 | d = Math.floor(d / 16);
23 | return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
24 | });
25 | }
26 |
27 | /**
28 | * checks value for !isNan and isFinite
29 | *
30 | * @param {string} n
31 | * @return {boolean}
32 | */
33 | isNumeric(n)
34 | {
35 | const nn = parseFloat(n);
36 | return !isNaN(nn) && isFinite(nn);
37 | }
38 |
39 | /**
40 | * generate a simple ID using an internal counter
41 | *
42 | * @return {Number} new id
43 | * @static
44 | */
45 | simpleId()
46 | {
47 | this._simpleIdCounter++;
48 | return this._simpleIdCounter;
49 | }
50 |
51 | pathLookup(obj, path)
52 | {
53 | const parts = path.split(".");
54 | if (parts.length == 1)
55 | {
56 | return obj[parts[0]];
57 | }
58 | return this.pathLookup(obj[parts[0]], parts.slice(1).join("."));
59 | }
60 |
61 | }
62 | export default new Helper();
63 |
--------------------------------------------------------------------------------
/.github/workflows/jsdocs.yml:
--------------------------------------------------------------------------------
1 | name: jsdocs develop
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - develop
8 | paths:
9 | - "shared/**"
10 | - "jsdoc/**"
11 | schedule:
12 | - cron: '0 3 * * *'
13 |
14 | env:
15 | JDOC_APP_ID: "fdb282ef-1a12-4ed8-8859-ac16c5ea3390"
16 |
17 | jobs:
18 | build:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v4
22 | - name: checkout cables
23 | uses: actions/checkout@v4
24 | with:
25 | repository: "cables-gl/cables"
26 | ref: develop
27 | token: ${{ secrets.undev_token }}
28 | path: "cables/"
29 | - name: checkout cables ui
30 | uses: actions/checkout@v4
31 | with:
32 | repository: "cables-gl/cables_ui"
33 | ref: develop
34 | token: ${{ secrets.undev_token }}
35 | path: "cables_ui/"
36 | - name: checkout cables electron
37 | uses: actions/checkout@v4
38 | with:
39 | repository: "cables-gl/cables_electron"
40 | path: "cables_electron/"
41 | ref: develop
42 | - name: build jsdoc
43 | run: |
44 | cd jsdoc/
45 | npm install --no-save
46 | npm run build:dev
47 | - name: Deploy jsdocs to netlify
48 | uses: netlify/actions/cli@master
49 | env:
50 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
51 | NETLIFY_SITE_ID: ${{ env.JDOC_APP_ID }}
52 | with:
53 | args: deploy --dir=jsdoc/dist --prod
54 | secrets: '["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]'
55 |
--------------------------------------------------------------------------------
/jsdoc/template/css/github.css:
--------------------------------------------------------------------------------
1 | /* github markdown */
2 | .github-markdown {
3 | font-size: 16px;
4 | }
5 |
6 | .github-markdown h1,
7 | .github-markdown h2,
8 | .github-markdown h3,
9 | .github-markdown h4,
10 | .github-markdown h5 {
11 | margin-top: 1em;
12 | margin-bottom: 16px;
13 | font-weight: bold;
14 | padding: 0;
15 | }
16 |
17 | .github-markdown h1:nth-of-type(1) {
18 | margin-top: 0;
19 | }
20 |
21 | .github-markdown h1 {
22 | font-size: 2em;
23 | padding-bottom: 0.3em;
24 | }
25 |
26 | .github-markdown h2 {
27 | font-size: 1.75em;
28 | padding-bottom: 0.3em;
29 | }
30 |
31 | .github-markdown h3 {
32 | font-size: 1.5em;
33 | }
34 |
35 | .github-markdown h4 {
36 | font-size: 1.25em;
37 | }
38 |
39 | .github-markdown h5 {
40 | font-size: 1em;
41 | }
42 |
43 | .github-markdown ul, .github-markdown ol {
44 | padding-left: 2em;
45 | }
46 |
47 | .github-markdown pre > code {
48 | font-size: 0.85em;
49 | }
50 |
51 | .github-markdown table {
52 | margin-bottom: 1em;
53 | border-collapse: collapse;
54 | border-spacing: 0;
55 | }
56 |
57 | .github-markdown table tr {
58 | background-color: #fff;
59 | border-top: 1px solid #ccc;
60 | }
61 |
62 | .github-markdown table th,
63 | .github-markdown table td {
64 | padding: 6px 13px;
65 | border: 1px solid #ddd;
66 | }
67 |
68 | .github-markdown table tr:nth-child(2n) {
69 | background-color: #f8f8f8;
70 | }
71 |
72 | .github-markdown hr {
73 | border-right: 0;
74 | border-bottom: 1px solid #e5e5e5;
75 | border-left: 0;
76 | border-top: 0;
77 | }
78 |
79 | /** badge(.svg) does not have border */
80 | .github-markdown img:not([src*=".svg"]) {
81 | max-width: 100%;
82 | box-shadow: 1px 1px 1px rgba(0,0,0,0.5);
83 | }
84 |
--------------------------------------------------------------------------------
/jsdoc/template/css/search.css:
--------------------------------------------------------------------------------
1 | /* search box */
2 | .search-box {
3 | position: absolute;
4 | top: 10px;
5 | right: 50px;
6 | padding-right: 8px;
7 | padding-bottom: 10px;
8 | line-height: normal;
9 | font-size: 12px;
10 | }
11 |
12 | .search-box img {
13 | width: 20px;
14 | vertical-align: top;
15 | }
16 |
17 | .search-input {
18 | display: inline;
19 | visibility: hidden;
20 | width: 0;
21 | padding: 2px;
22 | height: 1.5em;
23 | outline: none;
24 | background: transparent;
25 | border: 1px #0af;
26 | border-style: none none solid none;
27 | vertical-align: bottom;
28 | }
29 |
30 | .search-input-edge {
31 | display: none;
32 | width: 1px;
33 | height: 5px;
34 | background-color: #0af;
35 | vertical-align: bottom;
36 | }
37 |
38 | .search-result {
39 | position: absolute;
40 | display: none;
41 | height: 600px;
42 | width: 100%;
43 | padding: 0;
44 | margin-top: 5px;
45 | margin-left: 24px;
46 | background: white;
47 | box-shadow: 1px 1px 4px rgb(0,0,0);
48 | white-space: nowrap;
49 | overflow-y: scroll;
50 | }
51 |
52 | .search-result-import-path {
53 | color: #aaa;
54 | font-size: 12px;
55 | }
56 |
57 | .search-result li {
58 | list-style: none;
59 | padding: 2px 4px;
60 | }
61 |
62 | .search-result li a {
63 | display: block;
64 | }
65 |
66 | .search-result li.selected {
67 | background: #ddd;
68 | }
69 |
70 | .search-result li.search-separator {
71 | background: rgb(37, 138, 175);
72 | color: white;
73 | }
74 |
75 | .search-box.active .search-input {
76 | visibility: visible;
77 | transition: width 0.2s ease-out;
78 | width: 300px;
79 | }
80 |
81 | .search-box.active .search-input-edge {
82 | display: inline-block;
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/shared/libs/webaudio-peaks.js:
--------------------------------------------------------------------------------
1 | var webaudioPeaks=function(e){function n(t){if(a[t])return a[t].exports;var r=a[t]={exports:{},id:t,loaded:!1};return e[t].call(r.exports,r,r.exports,n),r.loaded=!0,r.exports}var a={};return n.m=e,n.c=a,n.p="",n(0)}([function(module,exports){"use strict";function findMinMax(e){for(var n,a=1/0,t=-(1/0),r=0,i=e.length;i>r;r++)n=e[r],a>n&&(a=n),n>t&&(t=n);return{min:a,max:t}}function convert(e,n){var a=Math.pow(2,n-1),t=0>e?e*a:e*a-1;return Math.max(-a,Math.min(a-1,t))}function extractPeaks(channel,samplesPerPixel,bits){var i,chanLength=channel.length,numPeaks=Math.ceil(chanLength/samplesPerPixel),start,end,segment,max,min,extrema,peaks=new(eval("Int"+bits+"Array"))(2*numPeaks);for(i=0;numPeaks>i;i++)start=i*samplesPerPixel,end=(i+1)*samplesPerPixel>chanLength?chanLength:(i+1)*samplesPerPixel,segment=channel.subarray(start,end),extrema=findMinMax(segment),min=convert(extrema.min,bits),max=convert(extrema.max,bits),peaks[2*i]=min,peaks[2*i+1]=max;return peaks}function makeMono(channelPeaks,bits){var numChan=channelPeaks.length,weight=1/numChan,numPeaks=channelPeaks[0].length/2,c=0,i=0,min,max,peaks=new(eval("Int"+bits+"Array"))(2*numPeaks);for(i=0;numPeaks>i;i++){for(min=0,max=0,c=0;numChan>c;c++)min+=weight*channelPeaks[c][2*i],max+=weight*channelPeaks[c][2*i+1];peaks[2*i]=min,peaks[2*i+1]=max}return[peaks]}module.exports=function(e,n,a,t,r,i){if(n=n||1e4,i=i||8,a=a||!0,[8,16,32].indexOf(i)<0)throw new Error("Invalid number of bits specified for peaks.");var s,m,h,l,o=e.numberOfChannels,u=[];if("undefined"==typeof e.subarray)for(s=0;o>s;s++)h=e.getChannelData(s),t=t||0,r=r||h.length,l=h.subarray(t,r),u.push(extractPeaks(l,n,i));else t=t||0,r=r||e.length,u.push(extractPeaks(e.subarray(t,r),n,i));return a&&u.length>1&&(u=makeMono(u,i)),m=u[0].length/2,{length:m,data:u,bits:i}}}]);
--------------------------------------------------------------------------------
/jsdoc/dev_layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/jsdoc/template/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | USING TEMPLATE!!!
15 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/jsdoc/config/ui.json:
--------------------------------------------------------------------------------
1 | {
2 | "index": "../cables_ui/README.md",
3 | "source": "../",
4 | "destination": "dist/ui",
5 | "includes": [
6 | "^cables_ui/src/.*\\.js$",
7 | "^shared/client/index.js$"
8 | ],
9 | "excludes": [
10 | "node_modules"
11 | ],
12 | "plugins": [
13 | {
14 | "name": "@enterthenamehere/esdoc-standard-plugin"
15 | },
16 | {
17 | "name": "@enterthenamehere/esdoc-type-inference-plugin",
18 | "option": {
19 | "enable": true
20 | }
21 | },
22 | {
23 | "name": "@enterthenamehere/esdoc-brand-plugin",
24 | "option": {
25 | "title": "cables.gl - editor",
26 | "repository": "https://github.com/cables-gl/cables_ui",
27 | "site": "https://cables.gl",
28 | "author": "https://undev.studio"
29 | }
30 | },
31 | {
32 | "name": "@enterthenamehere/esdoc-inject-style-plugin",
33 | "option": {
34 | "enable": true,
35 | "styles": [
36 | "./cables.css"
37 | ]
38 | }
39 | },
40 | {
41 | "name": "@enterthenamehere/esdoc-importpath-plugin",
42 | "option": {
43 | "stripPackageName": true,
44 | "replaces": [
45 | {
46 | "from": "^cables_dev/cables_ui/src/",
47 | "to": "./"
48 | },
49 | {
50 | "from": "^cables_dev/shared/client/index.js",
51 | "to": "cables-shared-client"
52 | }
53 | ]
54 | }
55 | }
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/shared/libs/mp_camera_utils.js:
--------------------------------------------------------------------------------
1 | (function(){/*
2 |
3 | Copyright The Closure Library Authors.
4 | SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';var e="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};function f(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b= targetDepth)
35 | {
36 | if (direction === "opened")
37 | {
38 | if (depth === targetDepth) nextElement.style.display = "";
39 | }
40 | else if (direction === "closed")
41 | {
42 | nextElement.style.display = "none";
43 | let innerButton = nextElement.querySelector(".toggle");
44 | if (innerButton && innerButton.classList.contains("opened"))
45 | {
46 | innerButton.classList.remove("opened");
47 | innerButton.classList.add("closed");
48 | }
49 | }
50 | }
51 | else
52 | {
53 | break;
54 | }
55 | nextElement = nextElement.nextElementSibling;
56 | }
57 | }
58 |
59 | let buttons = document.querySelectorAll(".test-summary tr.test-interface .toggle");
60 | for (var i = 0; i < buttons.length; i++)
61 | {
62 | buttons[i].addEventListener("click", toggle);
63 | }
64 |
65 | let topDescribes = document.querySelectorAll(".test-summary tr[data-test-depth=\"0\"]");
66 | for (var i = 0; i < topDescribes.length; i++)
67 | {
68 | topDescribes[i].style.display = "";
69 | }
70 | }());
71 |
--------------------------------------------------------------------------------
/start.js:
--------------------------------------------------------------------------------
1 | import concurrently from "concurrently";
2 | import kill from "tree-kill";
3 | import fs from "fs";
4 |
5 | const args = process.argv ? process.argv.slice(2) : [];
6 | const electron = args && args[0] === "standalone";
7 |
8 | let commands = [
9 | {
10 | "command": "cd shared && npm run build",
11 | "name": "shared",
12 | "prefixColor": "blue",
13 | "env": { "cables_electron": electron, "NODE_OPTIONS": "--disable-warning=ExperimentalWarning" }
14 | },
15 | {
16 | "command": "cd cables && npm run watch",
17 | "name": "core",
18 | "prefixColor": "yellow",
19 | "env": { "cables_electron": electron, "NODE_OPTIONS": "--disable-warning=ExperimentalWarning" }
20 | },
21 | {
22 | "command": "cd cables_ui && npm run watch",
23 | "name": "gui",
24 | "prefixColor": "green",
25 | "env": { "cables_electron": electron, "NODE_OPTIONS": "--disable-warning=ExperimentalWarning" }
26 | },
27 | ];
28 |
29 | if (!electron)
30 | {
31 | let apiExists = true;
32 | try
33 | {
34 | if (!fs.statSync("cables_api").isDirectory() || !fs.existsSync("cables_api/src/cables.js"))
35 | {
36 | apiExists = false;
37 | }
38 | }
39 | catch (e)
40 | {
41 | apiExists = false;
42 | }
43 | if (apiExists)
44 | {
45 | commands.splice(2, 0, {
46 | "command": "cd cables_api && npm run start",
47 | "name": "api",
48 | "prefixColor": "cyan",
49 | "env": { "cables_electron": electron, "NODE_OPTIONS": "--disable-warning=ExperimentalWarning" }
50 | });
51 | commands.splice(2, 0, {
52 | "command": "cd cables_api && npm run start:socketcluster",
53 | "name": "socketcluster",
54 | "prefixColor": "magenta",
55 | "env": { "cables_electron": electron, "NODE_OPTIONS": "--disable-warning=ExperimentalWarning" }
56 | });
57 | }
58 | else
59 | {
60 | console.warn("FATAL: running `npm run start`, but cables_api/ dir does not exist!");
61 | console.info("are you trying to run `npm run watch:standalone`?");
62 | process.exit(1);
63 | }
64 | }
65 |
66 | const { result } = concurrently(
67 | commands,
68 | {
69 | "prefix": "name",
70 | "killOthers": ["failure"],
71 | "restartTries": 3,
72 | },
73 | );
74 |
75 | result.then(() =>
76 | {
77 | console.log("stopped!");
78 | kill(process.pid, "SIGHUP");
79 | }, () => { console.log("WTF!!!!!!"); }).catch((err) => { return console.log("error", err); });
80 |
81 | process.on("SIGINT", () =>
82 | {
83 | kill(process.pid, "SIGHUP");
84 | });
85 |
--------------------------------------------------------------------------------
/docs/howto_libraries.md:
--------------------------------------------------------------------------------
1 | # How to create/add libraries to cables-core
2 |
3 | ## Internal libraries
4 | If you want to create a library, there are some steps you need to consider:
5 |
6 | 1. Libraries can be found in `src/core/libs`
7 | 2. Files sould be in folders that (by convention) are named after the namespace they export to
8 | 3. Files in subfolders of these will not be built unless they are named `index.js`
9 | 4. Files control their own namespaces, no exports are used (see below)
10 | 5. The resulting filename will have the structure `folder_subfolder.min/max.js`.
11 | 6. If a file is in the `cables/` namespace, the resulting filename will be `filename.js`
12 | 7. Every library in a subfolder (see 3.) needs an `index.js` as the main entry point.
13 | 8. Webpack builds minified and non-minified versions to `build/corelibs/`
14 | 9. use `npm run build` to build the libraries
15 | 10. libraries are copied to `../cables_api/public/js/libs_core/`
16 |
17 | ### Example:
18 |
19 | Input structure:
20 | ```bash
21 | libs
22 | ├── cgl
23 | │ ├── cubemap
24 | │ │ └── index.js
25 | │ ├── light
26 | │ │ ├── createShaders.js
27 | │ │ └── index.js
28 | │ └── functions.js
29 | |── cables
30 | └── vargetset.js
31 | ```
32 |
33 | Output structure:
34 | ```bash
35 | libs
36 | ├── cgl_cubemap.js
37 | ├── cgl_light.js
38 | ├── cgl_functions.js
39 | ├── vargetset.js
40 | ```
41 | ## Working with internal libraries
42 |
43 | ### Root level libraries
44 | 1. All libraries have to "provide" and own or use an existing namespace, i.e.:
45 |
46 | `libs/cables/math.js`:
47 | ```javascript
48 | const add = (num1, num2) => num1 + num2;
49 | const sub = (num1, num2) => num1 - num2;
50 |
51 | CABLES.Math = { add: add, sub: sub };
52 |
53 | // results in CABLES.Math.add(1, 2);
54 | 2. For the above example the exported file would be called `math.max/min.js`.
55 | 3. This also means that these libraries may be dependent on other libraries being loaded alongside or before them (as above with `CABLES`).
56 | 4. Handle with care!
57 | 5. You can use shared imports in subfolders like this:
58 |
59 | `libs/cables/math/index.js`:
60 | ```javascript
61 | import linearAlgebra from "./linearAlgebra" // make sure libs/cables/math/linearAlgebra.js exists!
62 | const add = (num1, num2) => num1 + num2;
63 | const sub = (num1, num2) => num1 - num2;
64 |
65 | CABLES.Math = CABLES.MATH || {};
66 | CABLES.Math.linearAlgebra = linearAlgebra;
67 |
68 | // results in
69 | // - file:
70 | // - CABLES.Math.linearAlgebra;
71 |
72 | ### Adding libraries to ops
73 |
74 | 1. Click the op in the UI
75 | 2. Go to the `Core Libs` tab
76 | 3. Get your library file from the dropdown, click `Add`
77 | 4. Reload patch
78 | 5. profit
79 |
80 |
81 |
--------------------------------------------------------------------------------
/jsdoc/template/css/prettify-tomorrow.css:
--------------------------------------------------------------------------------
1 | /* Tomorrow Theme */
2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */
3 | /* Pretty printing styles. Used with prettify.js. */
4 | /* SPAN elements with the classes below are added by prettyprint. */
5 | /* plain text */
6 | .pln {
7 | color: #4d4d4c; }
8 |
9 | @media screen {
10 | /* string content */
11 | .str {
12 | color: #718c00; }
13 |
14 | /* a keyword */
15 | .kwd {
16 | color: #8959a8; }
17 |
18 | /* a comment */
19 | .com {
20 | color: #8e908c; }
21 |
22 | /* a type name */
23 | .typ {
24 | color: #4271ae; }
25 |
26 | /* a literal value */
27 | .lit {
28 | color: #f5871f; }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #4d4d4c; }
33 |
34 | /* lisp open bracket */
35 | .opn {
36 | color: #4d4d4c; }
37 |
38 | /* lisp close bracket */
39 | .clo {
40 | color: #4d4d4c; }
41 |
42 | /* a markup tag name */
43 | .tag {
44 | color: #c82829; }
45 |
46 | /* a markup attribute name */
47 | .atn {
48 | color: #f5871f; }
49 |
50 | /* a markup attribute value */
51 | .atv {
52 | color: #3e999f; }
53 |
54 | /* a declaration */
55 | .dec {
56 | color: #f5871f; }
57 |
58 | /* a variable name */
59 | .var {
60 | color: #c82829; }
61 |
62 | /* a function name */
63 | .fun {
64 | color: #4271ae; } }
65 | /* Use higher contrast and text-weight for printable form. */
66 | @media print, projection {
67 | .str {
68 | color: #060; }
69 |
70 | .kwd {
71 | color: #006;
72 | font-weight: bold; }
73 |
74 | .com {
75 | color: #600;
76 | font-style: italic; }
77 |
78 | .typ {
79 | color: #404;
80 | font-weight: bold; }
81 |
82 | .lit {
83 | color: #044; }
84 |
85 | .pun, .opn, .clo {
86 | color: #440; }
87 |
88 | .tag {
89 | color: #006;
90 | font-weight: bold; }
91 |
92 | .atn {
93 | color: #404; }
94 |
95 | .atv {
96 | color: #060; } }
97 | /* Style */
98 | /*
99 | pre.prettyprint {
100 | background: white;
101 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
102 | font-size: 12px;
103 | line-height: 1.5;
104 | border: 1px solid #ccc;
105 | padding: 10px; }
106 | */
107 |
108 | /* Specify class=linenums on a pre to get line numbering */
109 | ol.linenums {
110 | margin-top: 0;
111 | margin-bottom: 0; }
112 |
113 | /* IE indents via margin-left */
114 | li.L0,
115 | li.L1,
116 | li.L2,
117 | li.L3,
118 | li.L4,
119 | li.L5,
120 | li.L6,
121 | li.L7,
122 | li.L8,
123 | li.L9 {
124 | /* */ }
125 |
126 | /* Alternate shading for lines */
127 | li.L1,
128 | li.L3,
129 | li.L5,
130 | li.L7,
131 | li.L9 {
132 | /* */ }
133 |
--------------------------------------------------------------------------------
/tag_repos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -l
2 | #
3 | # checks out repos at branch, updates, then tags them with the same tag
4 | #
5 |
6 | RED='\033[0;31m'
7 | YELLOW='\033[1;33m'
8 | GREEN='\033[0;32m'
9 | NC='\033[0m' # No Color
10 |
11 | WAIT=10
12 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
13 | git fetch || true
14 |
15 | set -e
16 | set -o pipefail
17 |
18 | echo -e ""
19 | echo -e "${GREEN}TAGGING DEV...${NC}"
20 | if [[ `git status --porcelain --untracked-files=no` ]]; then
21 | echo -e "${RED}repository has local changes stash/commit before you tag...${NC}"
22 | exit 1
23 | fi
24 | branch=`git rev-parse --abbrev-ref HEAD`
25 | echo -e "${GREEN}tagging current state of '${branch}' with '${1}'...${NC}"
26 | git tag "${1}"
27 | git push origin tag "${1}"
28 |
29 | echo -e ""
30 | echo -e "${GREEN}TAGGING CORE...${NC}"
31 | cd cables
32 | if [[ `git status --porcelain --untracked-files=no` ]]; then
33 | echo -e "${RED}repository has local changes stash/commit before you tag...${NC}"
34 | exit 1
35 | fi
36 | branch=`git rev-parse --abbrev-ref HEAD`
37 | echo -e "${GREEN}tagging current state of '${branch}' with '${1}'...${NC}"
38 | git tag "${1}"
39 | git push origin tag "${1}"
40 | cd "$BASEDIR"
41 |
42 | if [ -d cables_api ]; then
43 | if [ -f cables_api/package.json ]; then
44 | echo -e ""
45 | echo -e "${GREEN}TAGGING API...${NC}"
46 | if [[ `git status --porcelain --untracked-files=no` ]]; then
47 | echo -e "${RED}repository has local changes stash/commit before you tag...${NC}"
48 | exit 1
49 | fi
50 | branch=`git rev-parse --abbrev-ref HEAD`
51 | echo -e "${GREEN}tagging current state of '${branch}' with '${1}'...${NC}"
52 | cd cables_api
53 | git tag "${1}"
54 | git push origin tag "${1}"
55 | fi
56 | fi
57 | cd "$BASEDIR"
58 |
59 | echo -e ""
60 | echo -e "${GREEN}TAGGING UI...${NC}"
61 | cd cables_ui
62 | if [[ `git status --porcelain --untracked-files=no` ]]; then
63 | echo -e "${RED}repository has local changes stash/commit before you tag...${NC}"
64 | exit 1
65 | fi
66 | branch=`git rev-parse --abbrev-ref HEAD`
67 | echo -e "${GREEN}tagging current state of '${branch}' with '${1}'...${NC}"
68 | git tag "${1}"
69 | git push origin tag "${1}"
70 | cd "$BASEDIR"
71 |
72 | if [ -d cables_electron ]; then
73 | echo -e ""
74 | echo -e "${GREEN}TAGGING ELECTRON...${NC}"
75 | cd cables_electron
76 | if [[ `git status --porcelain --untracked-files=no` ]]; then
77 | echo -e "${RED}repository has local changes stash/commit before you tag...${NC}"
78 | exit 1
79 | fi
80 | branch=`git rev-parse --abbrev-ref HEAD`
81 | echo -e "${GREEN}tagging current state of '${branch}' with '${1}'...${NC}"
82 | git tag "${1}"
83 | git push origin tag "${1}"
84 | fi
85 | cd "$BASEDIR"
86 |
87 | echo -e ""
88 | echo -e "${GREEN}DONE${NC}"
89 |
--------------------------------------------------------------------------------
/shared/api/utils/shared_util.js:
--------------------------------------------------------------------------------
1 | import { UtilProvider } from "./util_provider.js";
2 |
3 | /**
4 | * abstract class for cables utils
5 | *
6 | * @param {UtilProvider} utilProvider
7 | * @abstract
8 | */
9 | export default class SharedUtil
10 | {
11 |
12 | /**
13 | *
14 | *
15 | */
16 | constructor(utilProvider, register = true)
17 | {
18 | if (utilProvider)
19 | {
20 | this._utilProvider = utilProvider;
21 | if (register) this._utilProvider.register(this.utilName, this);
22 | }
23 | }
24 |
25 | /**
26 | * @abstract
27 | */
28 | get utilName()
29 | {
30 | return "not implemented, abstract class";
31 | }
32 |
33 | /**
34 | *
35 | * @return {*}
36 | * @protected
37 | */
38 | get _log()
39 | {
40 | return this._utilProvider.getUtil(UtilProvider.LOGGER);
41 | }
42 |
43 | /**
44 | *
45 | * @return {*}
46 | * @protected
47 | */
48 | get _cables()
49 | {
50 | return this._utilProvider.getUtil(UtilProvider.CABLES);
51 | }
52 |
53 | /**
54 | *
55 | * @return {*}
56 | * @protected
57 | */
58 | get _opsUtil()
59 | {
60 | return this._utilProvider.getUtil(UtilProvider.OPS_UTIL);
61 | }
62 |
63 | /**
64 | *
65 | * @return {*}
66 | * @protected
67 | */
68 | get _docsUtil()
69 | {
70 | return this._utilProvider.getUtil(UtilProvider.DOCS_UTIL);
71 | }
72 |
73 | /**
74 | *
75 | * @return {*}
76 | * @protected
77 | */
78 | get _subPatchOpUtil()
79 | {
80 | return this._utilProvider.getUtil(UtilProvider.SUBPATCH_OP_UTIL);
81 | }
82 |
83 | /**
84 | *
85 | * @return {*}
86 | * @protected
87 | */
88 | get _teamsUtil()
89 | {
90 | return this._utilProvider.getUtil(UtilProvider.TEAMS_UTIL);
91 | }
92 |
93 | /**
94 | *
95 | * @return {*}
96 | * @protected
97 | */
98 | get _helperUtil()
99 | {
100 | return this._utilProvider.getUtil(UtilProvider.HELPER_UTIL);
101 | }
102 |
103 | /**
104 | *
105 | * @return {*}
106 | * @protected
107 | */
108 | get _projectsUtil()
109 | {
110 | return this._utilProvider.getUtil(UtilProvider.PROJECTS_UTIL);
111 | }
112 |
113 | /**
114 | *
115 | * @return {*}
116 | * @protected
117 | */
118 | get _libsUtil()
119 | {
120 | return this._utilProvider.getUtil(UtilProvider.LIBS_UTIL);
121 | }
122 |
123 | /**
124 | *
125 | * @return {*}
126 | * @protected
127 | */
128 | get _filesUtil()
129 | {
130 | return this._utilProvider.getUtil(UtilProvider.FILES_UTIL);
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/jsdoc/template/css/manual.css:
--------------------------------------------------------------------------------
1 | .github-markdown .manual-toc {
2 | padding-left: 0;
3 | }
4 |
5 | .manual-index .manual-cards {
6 | display: flex;
7 | flex-wrap: wrap;
8 | }
9 |
10 | .manual-index .manual-card-wrap {
11 | width: 280px;
12 | padding: 10px 20px 10px 0;
13 | box-sizing: border-box;
14 | }
15 |
16 | .manual-index .manual-card-wrap > h1 {
17 | margin: 0;
18 | font-size: 1em;
19 | font-weight: 600;
20 | padding: 0.2em 0 0.2em 0.5em;
21 | border-radius: 0.1em 0.1em 0 0;
22 | border: none;
23 | }
24 |
25 | .manual-index .manual-card-wrap > h1 span {
26 | color: #555;
27 | }
28 |
29 | .manual-index .manual-card {
30 | height: 200px;
31 | overflow: hidden;
32 | border: solid 1px rgba(230, 230, 230, 0.84);
33 | border-radius: 0 0 0.1em 0.1em;
34 | padding: 8px;
35 | position: relative;
36 | }
37 |
38 | .manual-index .manual-card > div {
39 | transform: scale(0.4);
40 | transform-origin: 0 0;
41 | width: 250%;
42 | }
43 |
44 | .manual-index .manual-card > a {
45 | position: absolute;
46 | top: 0;
47 | left: 0;
48 | width: 100%;
49 | height: 100%;
50 | background: rgba(210, 210, 210, 0.1);
51 | }
52 |
53 | .manual-index .manual-card > a:hover {
54 | background: none;
55 | }
56 |
57 | .manual-index .manual-badge {
58 | margin: 0;
59 | }
60 |
61 | .manual-index .manual-user-index {
62 | margin-bottom: 1em;
63 | border-bottom: solid 1px #ddd;
64 | }
65 |
66 | .manual-root .navigation {
67 | padding-left: 4px;
68 | margin-top: 4px;
69 | }
70 |
71 | .navigation .manual-toc-root > div {
72 | padding-left: 0.25em;
73 | padding-right: 0.75em;
74 | }
75 |
76 | .github-markdown .manual-toc-title a {
77 | color: inherit;
78 | }
79 |
80 | .manual-breadcrumb-list {
81 | font-size: 0.8em;
82 | margin-bottom: 1em;
83 | }
84 |
85 | .manual-toc-title a:hover {
86 | color: #039BE5;
87 | }
88 |
89 | .manual-toc li {
90 | margin: 0.75em 0;
91 | list-style-type: none;
92 | }
93 |
94 | .navigation .manual-toc [class^="indent-h"] a {
95 | color: #666;
96 | }
97 |
98 | .navigation .manual-toc .indent-h1 a {
99 | color: #555;
100 | font-weight: 600;
101 | display: block;
102 | }
103 |
104 | .manual-toc .indent-h1 {
105 | display: block;
106 | margin: 0.4em 0 0 0.25em;
107 | padding: 0.2em 0 0.2em 0.5em;
108 | border-radius: 0.1em;
109 | }
110 |
111 | .manual-root .navigation .manual-toc li:not(.indent-h1) {
112 | margin-top: 0.5em;
113 | }
114 |
115 | .manual-toc .indent-h2 {
116 | display: none;
117 | margin-left: 1.5em;
118 | }
119 | .manual-toc .indent-h3 {
120 | display: none;
121 | margin-left: 2.5em;
122 | }
123 | .manual-toc .indent-h4 {
124 | display: none;
125 | margin-left: 3.5em;
126 | }
127 | .manual-toc .indent-h5 {
128 | display: none;
129 | margin-left: 4.5em;
130 | }
131 |
132 | .manual-nav li {
133 | margin: 0.75em 0;
134 | }
135 |
--------------------------------------------------------------------------------
/jsdoc/template/details.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | version
13 | since
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Override:
24 |
25 |
26 |
27 |
28 |
Return:
29 |
30 |
31 |
32 | |
33 | |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
Emit:
42 |
43 |
44 |
45 | |
46 | |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
Listen:
54 |
55 |
56 |
57 | |
58 | |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
Throw:
66 |
67 |
68 |
69 | |
70 | |
71 |
72 |
73 |
74 |
75 |
76 |
Decorators:
77 |
78 |
85 |
86 |
92 |
93 |
See:
94 |
TODO:
95 |
96 |
--------------------------------------------------------------------------------
/jsdoc/template/class.html:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 | You can directly use an instance of this class.
16 |
17 |
18 |
19 |
20 |
Mixin Extends:
21 |
Extends:
22 |
Direct Subclass:
23 |
Indirect Subclass:
24 |
Implements:
25 |
Indirect Implements:
26 |
Direct Implemented:
27 |
Indirect Implemented:
28 |
29 |
30 |
31 |
32 |
Decorators:
33 |
34 |
See:
35 |
36 |
43 |
44 |
50 |
51 |
TODO:
52 |
53 |
54 | Static Member Summary
55 | Static Method Summary
56 | Constructor Summary
57 | Member Summary
58 | Method Summary
59 |
60 | Inherited Summary
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/shared/api/utils/shared_teams_util.js:
--------------------------------------------------------------------------------
1 | import SharedUtil from "./shared_util.js";
2 | import { UtilProvider } from "./util_provider.js";
3 |
4 | /**
5 | * @abstract
6 | */
7 | export default class SharedTeamsUtil extends SharedUtil
8 | {
9 | get utilName()
10 | {
11 | return UtilProvider.TEAMS_UTIL;
12 | }
13 |
14 | isPublic(team)
15 | {
16 | if (!team) return false;
17 | return team.visibility === "public";
18 | }
19 |
20 |
21 | isOwner(user, team)
22 | {
23 | if (!user) return false;
24 | if (!team) return false;
25 | return team.owner._id == user._id;
26 | }
27 |
28 | isMember(user, team)
29 | {
30 | if (!user) return false;
31 | if (!team) return false;
32 | if (!team.members) return false;
33 | if (this.isOwner(user, team))
34 | {
35 | return true;
36 | }
37 | else
38 | {
39 | return team.members.some((m) => { return String(m._id) === String(user._id); }) || team.membersReadOnly.some((m) => { return String(m._id) === String(user._id); });
40 | }
41 | }
42 |
43 |
44 | userHasWriteAccess(user, team)
45 | {
46 | if (!user) return false;
47 | if (!team) return false;
48 | if (user.isAdmin) return true;
49 | if (this.isOwner(user, team))
50 | {
51 | return true;
52 | }
53 | else
54 | {
55 | return team.members.some((m) => { return String(m._id) === String(user._id); });
56 | }
57 | }
58 |
59 | getFullExtensionName(shortName)
60 | {
61 | let name = shortName;
62 | if (!name.endsWith(".")) name += ".";
63 | if (!name.startsWith("Ops.Extension."))
64 | {
65 | return "Ops.Extension." + name;
66 | }
67 | return name;
68 | }
69 |
70 | makeReadable(teams)
71 | {
72 | if (!teams) return {};
73 | if (!(teams instanceof Array)) return this._makeTeamReadable(teams);
74 |
75 | const readables = [];
76 | teams.forEach((p) =>
77 | {
78 | const readable = this._makeTeamReadable(p);
79 | readables.push(readable);
80 | });
81 | return readables;
82 | }
83 |
84 | _makeTeamReadable(team)
85 | {
86 | if (!team) return {};
87 | const readable = {
88 | "_id": team._id,
89 | "link": team.link,
90 | "name": team.name,
91 | "description": team.description,
92 | "visibility": team.visibility,
93 | "created": team.created,
94 | "updated": team.updated,
95 | "published": team.published
96 | };
97 | if (team.isMember) readable.isMember = team.isMember;
98 | return readable;
99 | }
100 |
101 | sanitizeShortNameForNamespace(teamName)
102 | {
103 | let name = teamName || "";
104 | name = name.replace(/[^\x00-\x7F]/g, "");
105 | name = name.split(" ").join("");
106 | name = name.replaceAll(/\./g, "");
107 | name = name.replaceAll("_", "");
108 | name = name.replaceAll("-", "");
109 | if (name.match(/^\d/))name = "T" + name;
110 | name = name.substring(0, 16);
111 | return this._helperUtil.capitalizeFirstLetter(name);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/shared/shared_constants.json:
--------------------------------------------------------------------------------
1 | {
2 | "DATE_FORMAT_LOGDATE": "YYYY-MM-DD HH:mm",
3 | "DATE_FORMAT_DISPLAYDATE_DATE": "YYYY-MM-DD HH:mm",
4 | "DATE_FORMAT_DISPLAYDATE_DISPLAY": "MMM D, YYYY [at] HH:mm",
5 | "DATE_FORMAT_TOOLTIPDATE": "MMM D, YYYY [at] HH:mm",
6 | "DATE_FORMAT_DISPLAYDATE_NO_TIME_DATE": "YYYY-MM-DD",
7 | "DATE_FORMAT_DISPLAYDATE_NO_TIME_DISPLAY": "MMM D, YYYY ",
8 | "DATE_FORMAT_RELATIVEDATE_CUTOFF_DAYS": 7,
9 | "DATE_FORMAT_RELATIVEDATE_FULL": "MMM D, YYYY [at] HH:mm",
10 | "IFRAME_OPTIONS_ALLOW": "clipboard-read;clipboard-write;gyroscope;accelerometer;geolocation;camera;microphone;midi;usb;serial;xr-spatial-tracking;web-share;ambient-light-sensor;window-management;bluetooth",
11 | "IFRAME_OPTIONS_SANDBOX": "allow-scripts allow-same-origin allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-presentation allow-downloads allow-popups allow-popups-to-escape-sandbox",
12 | "FILETYPES": {
13 | "image": [
14 | ".jpg",
15 | ".jpeg",
16 | ".png",
17 | ".gif",
18 | ".webp",
19 | ".avif",
20 | ".jxl"
21 | ],
22 | "binary": [
23 | ".bin"
24 | ],
25 | "audio": [
26 | ".mp3",
27 | ".wav",
28 | ".ogg",
29 | ".aac",
30 | ".mid",
31 | ".flac"
32 | ],
33 | "video": [
34 | ".m4a",
35 | ".mp4",
36 | ".mpg",
37 | ".webm",
38 | ".mkv"
39 | ],
40 | "gltf": [
41 | ".glb"
42 | ],
43 | "3d raw": [
44 | ".obj",
45 | ".fbx",
46 | ".3ds",
47 | ".ply",
48 | ".dae",
49 | ".blend",
50 | ".md2",
51 | ".md3",
52 | ".ase"
53 | ],
54 | "JSON": [
55 | ".json"
56 | ],
57 | "CSS": [
58 | ".css",
59 | ".scss"
60 | ],
61 | "textfile": [
62 | ".txt",
63 | ".md"
64 | ],
65 | "pointcloud": [
66 | ".pc.txt"
67 | ],
68 | "shader": [
69 | ".frag",
70 | ".vert"
71 | ],
72 | "SVG": [
73 | ".svg"
74 | ],
75 | "CSV": [
76 | ".csv"
77 | ],
78 | "XML": [
79 | ".xml"
80 | ],
81 | "font": [
82 | ".otf",
83 | ".ttf",
84 | ".woff",
85 | ".woff2"
86 | ],
87 | "mesh sequence": [
88 | ".seq.zip"
89 | ],
90 | "pointcloud json": [
91 | ".pc.txt"
92 | ],
93 | "3d json": [
94 | ".3d.json"
95 | ],
96 | "javascript": [
97 | ".js",
98 | ".cjs",
99 | ".mjs"
100 | ],
101 | "ar markers": [
102 | ".iset",
103 | ".fset",
104 | ".fset3"
105 | ]
106 | },
107 | "EDITABLE_FILETYPES": [
108 | "textfile",
109 | "CSS",
110 | "javascript",
111 | "XML",
112 | "JSON",
113 | "shader"
114 | ],
115 | "text": {
116 | "en": {
117 | "leave_patch": "Leave Patch"
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/shared/client/src/logger.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | export default class Logger
3 | {
4 |
5 | /**
6 | * @param {any} initiator
7 | * @param {Object} options
8 | */
9 | constructor(initiator, options)
10 | {
11 | this.initiator = initiator;
12 | this._options = options;
13 | if (!this.initiator)
14 | {
15 | console.error("no log initator given");
16 | CABLES.logStack();
17 | }
18 | }
19 |
20 | /**
21 | * @param {string} t
22 | */
23 | stack(t)
24 | {
25 | console.info("[" + this.initiator + "] ", t);
26 | console.log((new Error()).stack);
27 | }
28 |
29 | /**
30 | * @param {string} t
31 | */
32 | groupCollapsed(t)
33 | {
34 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent) console.log("[" + this.initiator + "]", ...arguments);
35 |
36 | console.groupCollapsed("[" + this.initiator + "] " + t);
37 | }
38 |
39 | /**
40 | * @param {any[][]} t
41 | */
42 | table(t)
43 | {
44 | console.table(t);
45 | }
46 |
47 | groupEnd()
48 | {
49 | console.groupEnd();
50 | }
51 |
52 | error()
53 | {
54 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 2 }, ...arguments)) || !CABLES.UI)
55 | {
56 | console.error("[" + this.initiator + "]", ...arguments);
57 | }
58 |
59 | if (this._options && this._options.onError)
60 | {
61 | this._options.onError(this.initiator, ...arguments);
62 | // console.log("emitevent onerror...");
63 | // CABLES.patch.emitEvent("onError", this.initiator, ...arguments);
64 | // CABLES.logErrorConsole("[" + this.initiator + "]", ...arguments);
65 | }
66 | }
67 |
68 | errorGui()
69 | {
70 | if (CABLES.UI) CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 2 }, ...arguments);
71 | }
72 |
73 | warn()
74 | {
75 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 1 }, ...arguments)) || !CABLES.logSilent)
76 | console.warn("[" + this.initiator + "]", ...arguments);
77 | }
78 |
79 | verbose()
80 | {
81 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
82 | console.log("[" + this.initiator + "]", ...arguments);
83 | }
84 |
85 | info()
86 | {
87 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
88 | console.info("[" + this.initiator + "]", ...arguments);
89 | }
90 |
91 | log()
92 | {
93 | if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
94 | console.log("[" + this.initiator + "]", ...arguments);
95 | }
96 |
97 | logGui()
98 | {
99 | if (CABLES.UI) CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments);
100 | }
101 |
102 | userInteraction(text)
103 | {
104 | // this.log({ "initiator": "userinteraction", "text": text });
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/shared/api/utils/shared_subpatchop_util.js:
--------------------------------------------------------------------------------
1 | import SharedUtil from "./shared_util.js";
2 | import { UtilProvider } from "./util_provider.js";
3 |
4 | /**
5 | * @abstract
6 | */
7 | export default class SharedSubPatchOpUtil extends SharedUtil
8 | {
9 | get utilName()
10 | {
11 | return UtilProvider.SUBPATCH_OP_UTIL;
12 | }
13 |
14 | getSaveSubPatchOpProblems(opName, subPatch)
15 | {
16 | if (!opName) return null;
17 | if (!subPatch || !subPatch.ops) return null;
18 | let problem = null;
19 | for (let i = 0; i < subPatch.ops.length; i++)
20 | {
21 | const subPatchOp = subPatch.ops[i];
22 | const subPatchOpName = this._opsUtil.getOpNameById(subPatchOp.opId);
23 | const outerNamespace = this._opsUtil.getNamespace(opName);
24 | const opId = this._opsUtil.getOpIdByObjName(opName);
25 |
26 | const opProblem = {
27 | "outerNamespace": outerNamespace,
28 | "outerOpName": opName,
29 | "outerOpId": opId,
30 | "innerOpName": subPatchOpName,
31 | "innerOpId": subPatchOp.opId,
32 | "innerOpInstanceId": subPatchOp.id,
33 | "subPatch": subPatch
34 | };
35 | const hierarchyProblem = this._opsUtil.getNamespaceHierarchyProblem(opName, subPatchOpName);
36 | if (hierarchyProblem)
37 | {
38 | opProblem.msg = hierarchyProblem;
39 | }
40 | if (opProblem.msg)
41 | {
42 | problem = opProblem;
43 | break;
44 | }
45 | }
46 | return problem;
47 | }
48 |
49 | getOpsUsedInSubPatches(subPatch)
50 | {
51 | let opsInSubPatches = [];
52 | if (!subPatch || !subPatch.ops) return opsInSubPatches;
53 | const v2Bps = subPatch.ops.filter((op) => { return this._opsUtil.isSubPatchOp(op); });
54 | opsInSubPatches = opsInSubPatches.concat(this._getOpsUsedInSubPatch({ "ops": v2Bps }));
55 | opsInSubPatches = opsInSubPatches.filter((obj, index) => { return opsInSubPatches.findIndex((item) => { return item.opId === obj.opId; }) === index; });
56 | return opsInSubPatches;
57 | }
58 |
59 | _getOpsUsedInSubPatch(subPatch, currentOp = null)
60 | {
61 | let opsInSubPatch = [];
62 | if (!subPatch) return [];
63 | if (subPatch && subPatch.ops) opsInSubPatch = opsInSubPatch.concat(subPatch.ops);
64 |
65 | const subPatchOps = subPatch.ops.filter((op) => { return this._opsUtil.isSubPatchOp(op); });
66 |
67 | if (subPatchOps.length > 0)
68 | {
69 | try
70 | {
71 | subPatchOps.forEach((subPatchOp) =>
72 | {
73 | if (!currentOp || (currentOp.opId !== subPatchOp.opId))
74 | {
75 | const attachmentOps = this._opsUtil.getSubPatchOpAttachment(this._opsUtil.getOpNameById(subPatchOp.opId));
76 | opsInSubPatch = opsInSubPatch.concat(this._getOpsUsedInSubPatch(attachmentOps, subPatchOp));
77 | }
78 | else
79 | {
80 | this._log.warn("skipping recursive subpatches", subPatchOp.opId, currentOp.opId);
81 | }
82 | });
83 | }
84 | catch (e)
85 | {
86 | this._log.error(e);
87 | }
88 |
89 | opsInSubPatch = opsInSubPatch.filter((obj, index) => { return opsInSubPatch.findIndex((item) => { return item.opId === obj.opId; }) === index; });
90 | }
91 | return opsInSubPatch;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cables development environment
2 |
3 | [cables.gl](https://cables.gl) and [cables standalone](https://cables.gl/standalone) are mainly developed by [undev](https://undev.studio/),
4 | with contributions by the [cables community](https://discord.gg/cablesgl) and support by [various other parties and projects](https://cables.gl/support).
5 |
6 | This is the repository that holds the parent directory for cables development. Read up about
7 | setting up everything for you to start contributing to cables in the section on ["Developing Cables"](https://cables.gl/docs/6_1_developing_cables/developing_cables)
8 | of the official cables documentation.
9 |
10 | If you want to learn more about the tools and processes involved, check our ["toolchain"](docs/toolchain.md) guide.
11 |
12 | ## Structure
13 |
14 | cables development is spread across five git-repositories
15 |
16 | ### [cables_dev](https://github.com/cables-gl/cables_dev)
17 |
18 | the current repository is the "root folder" for all cables development, it holds
19 | documentation, helper scripts to set up your environment and keep it up to date.
20 |
21 | it also contains shared code between the different projects and holds npm commands to run watchers
22 | for file changes during development (see below).
23 |
24 | ### [cables](https://github.com/cables-gl/cables)
25 |
26 | the cables repository holds all the core ops of cables, and everything that is needed
27 | to run cables patches (in the editor, but also in exported patches).
28 |
29 | ### [cables_ui](https://github.com/cables-gl/cables_ui)
30 |
31 | cables_ui contains all code that makes up the cables editor, the ui. everything that is needed
32 | to work on patches on cables.gl and in cables standalone lives in this repository.
33 |
34 | ### [cables_electron](https://github.com/cables-gl/cables_electron)
35 |
36 | the repository to bring all of the above together to have a running version of the cables ui
37 | with the cables code and ops. runs (and builds/packs) an electron executable that can be
38 | used to create patches locally, or develop on core and ui features on your local machine.
39 |
40 | ### [cables_extensionops](https://github.com/undev-studio/cables_extensionops)
41 |
42 | a repository containing all the extensions on cables.gl that are not in the core. it is not
43 | needed for local development but will give you a few more ops to work with.
44 |
45 | ## Giving Feedback
46 |
47 | ### Issue Workflow
48 |
49 | - create an issue, pick "Bug report" or "Feature Request" from the templates
50 | - the issue will be assigned a "new" label
51 | - we will check on these issues regularly, add them to a milestone and remove the "new" label
52 | - once we added the feature or fixed the bug in any release (also dev/nightly) we will close the issue
53 | - stable releases will have a changelog with all the closed issues
54 |
55 | ## Appreciation
56 |
57 | Thanks to the [cables community](https://discord.gg/cablesgl) and our [supporters](https://cables.gl/support) for making this possible. If you like this project, think about [supporting it](https://cables.gl/support).
58 |
59 | This project was partly funded through the [NGI0 Entrust Fund](https://nlnet.nl/entrust/), a fund established by [NLnet](https://nlnet.nl/) with financial support
60 | from the European Commission's [Next Generation Internet](https://www.ngi.eu/) programme, under the aegis of [DG Communications Networks](https://commission.europa.eu/about-european-commission/departments-and-executive-agencies/communications-networks-content-and-technology_en),
61 | Content and Technology under grant agreement No 101069594.
62 |
63 | ## More...
64 | - [tools involved](docs/toolchain.md)
65 | - [howto create_new_ops](docs/howto_create_new_ops.md)
66 | - [howto op_new_version](docs/howto_op_new_version.md)
67 | - [howto libraries](docs/howto_libraries.md)
68 |
--------------------------------------------------------------------------------
/jsdoc/template/script/search.js:
--------------------------------------------------------------------------------
1 | (function ()
2 | {
3 | let searchIndex = window.esdocSearchIndex;
4 | let searchBox = document.querySelector(".search-box");
5 | let input = document.querySelector(".search-input");
6 | let result = document.querySelector(".search-result");
7 | let selectedIndex = -1;
8 | let prevText;
9 |
10 | // active search box and focus when mouse enter on search box.
11 | searchBox.addEventListener("mouseenter", function ()
12 | {
13 | searchBox.classList.add("active");
14 | input.focus();
15 | });
16 |
17 | // search with text when key is upped.
18 | input.addEventListener("keyup", function (ev)
19 | {
20 | let text = ev.target.value.toLowerCase();
21 | if (!text)
22 | {
23 | result.style.display = "none";
24 | result.innerHTML = "";
25 | return;
26 | }
27 |
28 | if (text === prevText) return;
29 | prevText = text;
30 |
31 | let html = { "class": [], "method": [], "member": [], "function": [], "variable": [], "typedef": [], "external": [], "file": [], "test": [], "testFile": [] };
32 | let len = searchIndex.length;
33 | let kind;
34 | for (let i = 0; i < len; i++)
35 | {
36 | let pair = searchIndex[i];
37 | if (pair[0].indexOf(text) !== -1)
38 | {
39 | kind = pair[3];
40 | html[kind].push("" + pair[2] + "");
41 | }
42 | }
43 |
44 | let innerHTML = "";
45 | for (kind in html)
46 | {
47 | let list = html[kind];
48 | if (!list.length) continue;
49 | innerHTML += "" + kind + "\n" + list.join("\n");
50 | }
51 | result.innerHTML = innerHTML;
52 | if (innerHTML) result.style.display = "block";
53 | selectedIndex = -1;
54 | });
55 |
56 | // down, up and enter key are pressed, select search result.
57 | input.addEventListener("keydown", function (ev)
58 | {
59 | if (ev.keyCode === 40)
60 | {
61 | // arrow down
62 | var current = result.children[selectedIndex];
63 | var selected = result.children[selectedIndex + 1];
64 | if (selected && selected.classList.contains("search-separator"))
65 | {
66 | var selected = result.children[selectedIndex + 2];
67 | selectedIndex++;
68 | }
69 |
70 | if (selected)
71 | {
72 | if (current) current.classList.remove("selected");
73 | selectedIndex++;
74 | selected.classList.add("selected");
75 | }
76 | }
77 | else if (ev.keyCode === 38)
78 | {
79 | // arrow up
80 | var current = result.children[selectedIndex];
81 | var selected = result.children[selectedIndex - 1];
82 | if (selected && selected.classList.contains("search-separator"))
83 | {
84 | var selected = result.children[selectedIndex - 2];
85 | selectedIndex--;
86 | }
87 |
88 | if (selected)
89 | {
90 | if (current) current.classList.remove("selected");
91 | selectedIndex--;
92 | selected.classList.add("selected");
93 | }
94 | }
95 | else if (ev.keyCode === 13)
96 | {
97 | // enter
98 | var current = result.children[selectedIndex];
99 | if (current)
100 | {
101 | let link = current.querySelector("a");
102 | if (link) location.href = link.href;
103 | }
104 | }
105 | else
106 | {
107 | return;
108 | }
109 |
110 | ev.preventDefault();
111 | });
112 |
113 | // select search result when search result is mouse over.
114 | result.addEventListener("mousemove", function (ev)
115 | {
116 | let current = result.children[selectedIndex];
117 | if (current) current.classList.remove("selected");
118 |
119 | let li = ev.target;
120 | while (li)
121 | {
122 | if (li.nodeName === "LI") break;
123 | li = li.parentElement;
124 | }
125 |
126 | if (li)
127 | {
128 | selectedIndex = Array.prototype.indexOf.call(result.children, li);
129 | li.classList.add("selected");
130 | }
131 | });
132 |
133 | // clear search result when body is clicked.
134 | document.body.addEventListener("click", function (ev)
135 | {
136 | selectedIndex = -1;
137 | result.style.display = "none";
138 | result.innerHTML = "";
139 | });
140 |
141 | }());
142 |
--------------------------------------------------------------------------------
/shared/buildwatcher.js:
--------------------------------------------------------------------------------
1 | import socketClusterClient from "socketcluster-client";
2 | import sign from "jwt-encode";
3 |
4 | export default class BuildWatcher
5 | {
6 |
7 | constructor(gulp, cablesConfig, module)
8 | {
9 | this._gulp = gulp;
10 | this._module = module;
11 | this._config = cablesConfig.socketclusterClient || {};
12 | const serverConfig = cablesConfig.socketclusterServer || {};
13 | this._socketCluster = {
14 | "active": this._config.enabled && cablesConfig.watchBuildWhenLocal,
15 | "config": serverConfig,
16 | "connected": false,
17 | "socket": null,
18 | "secret": serverConfig.secret
19 | };
20 |
21 | this._log = {
22 | "info": (...args) =>
23 | {
24 | const date = new Date();
25 | let hours = ("0" + date.getHours()).slice(-2);
26 | let minutes = ("0" + date.getMinutes()).slice(-2);
27 | let seconds = ("0" + date.getMinutes()).slice(-2);
28 | console.log("[" + hours + ":" + minutes + ":" + seconds + "]", "[buildwatcher]", ...args);
29 | }
30 | };
31 |
32 | }
33 |
34 | watch(glob, watchOptions, task)
35 | {
36 | if (this._socketCluster.active)
37 | {
38 | if (!this._socketCluster.connected) this._connect();
39 | const _build_watcher = (done) =>
40 | {
41 | this._sendBroadcast({ "build": "started", "time": Date.now(), "module": this._module });
42 | task(() =>
43 | {
44 | this._sendBroadcast({ "build": "ended", "time": Date.now(), "module": this._module });
45 | done();
46 | });
47 | };
48 | this._gulp.watch(glob, watchOptions, _build_watcher);
49 | }
50 | else
51 | {
52 | this._gulp.watch(glob, watchOptions, task);
53 | }
54 |
55 | }
56 |
57 | notify(glob, watchOptions, eventName)
58 | {
59 | if (this._socketCluster.active)
60 | {
61 | if (!this._socketCluster.connected) this._connect();
62 | const _build_notify = (fileName) =>
63 | {
64 | const data = { "build": eventName, "time": Date.now(), "module": this._module };
65 | let send = true;
66 | const dirSeperator = process && process.platform === "win32" ? "\\" : "/";
67 | switch (eventName)
68 | {
69 | case "opchange":
70 | if (fileName)
71 | {
72 | data.opName = fileName.split(dirSeperator).reverse().find((pathPart) => { return pathPart && pathPart.startsWith("Ops.") && !pathPart.endsWith(".js"); });
73 | }
74 | break;
75 | case "attachmentchange":
76 | if (fileName)
77 | {
78 | data.opName = fileName.split(dirSeperator).reverse().find((pathPart) => { return pathPart && pathPart.startsWith("Ops.") && !pathPart.endsWith(".js"); });
79 | data.attachmentName = fileName.split(dirSeperator).reverse()[0];
80 | }
81 | break;
82 | }
83 | if (send) this._sendBroadcast(data);
84 | };
85 | const watcher = this._gulp.watch(glob, watchOptions);
86 | watcher.on("change", _build_notify);
87 | }
88 | }
89 |
90 | _connect()
91 | {
92 | if (this._socketCluster.active && !this._socketCluster.connected)
93 | {
94 | this._socketCluster.socket = socketClusterClient.create({
95 | "hostname": this._socketCluster.config.interface,
96 | "port": this._socketCluster.config.port,
97 | "secure": false
98 | });
99 | this._log.info(this._module, "- connected to socketcluster server at", this._socketCluster.config.interface + ":" + this._socketCluster.config.port);
100 | this._socketCluster.connected = true;
101 | }
102 | }
103 |
104 | _sendBroadcast(data)
105 | {
106 | if (!this._socketCluster.active) return;
107 | if (!this._socketCluster.connected) this._connect();
108 | const channelName = "broadcast";
109 | if (!this._socketCluster.connected)
110 | {
111 | this._log.info("not broadcasting serverside message - not connected");
112 | return;
113 | }
114 |
115 | const socketclusterToken = sign({
116 | "channels": [channelName],
117 | }, this._socketCluster.secret);
118 |
119 | const payload = {
120 | "token": socketclusterToken,
121 | "topic": "notify",
122 | "data": data
123 | };
124 | this._socketCluster.socket.transmitPublish(channelName, payload);
125 |
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb-base",
3 | "globals": {
4 | "CABLES": true,
5 | "CABLESUILOADER": true,
6 | "CGL": true,
7 | "gui":true,
8 | "CGP":true,
9 | "Ops":true,
10 | "op": true,
11 | "logStartup": true,
12 | "attachments": true,
13 | "GPUShaderStage":true,
14 | "GPUTextureUsage":true,
15 | "GPUBufferUsage":true,
16 | "GPUMapMode":true,
17 | "BroadcastChannel": true,
18 | "document": true,
19 | "window": true,
20 | "navigator": true,
21 | "AudioContext": true,
22 | "XMLHttpRequest": true,
23 | "ace": true,
24 | "iziToast": true,
25 | "vec2": true,
26 | "vec3": true,
27 | "vec4": true,
28 | "mat3": true,
29 | "mat4": true,
30 | "quat": true,
31 | "chroma":true,
32 | "QRCode":true,
33 | "moment":true,
34 | "ColorRick":true,
35 | "introJs": true,
36 | "UndoManager": true,
37 | "Handlebars": true,
38 | "hljs": true,
39 | "loadjs": true,
40 | "pako": true,
41 | "MathParser": true,
42 | "socketClusterClient": true,
43 | "incrementStartup": true,
44 | "mmd": true,
45 | "platformLib": true,
46 | "Sortable": true,
47 | "tinysort":true,
48 | "marked":true
49 | },
50 | "env": {
51 | "browser": true
52 | },
53 | "parserOptions": {
54 | "ecmaVersion": "latest"
55 | },
56 | "rules": {
57 | "no-useless-concat": 0,
58 | "object-property-newline": "error",
59 | "global-require": 1,
60 | "no-compare-neg-zero": 0,
61 | "camelcase": 0,
62 | "class-methods-use-this": 0,
63 | "no-var": 1,
64 | "vars-on-top": 0,
65 | "no-bitwise": 0,
66 | "no-underscore-dangle": 0,
67 | "brace-style": [
68 | 1,
69 | "allman",
70 | {
71 | "allowSingleLine": true
72 | }
73 | ],
74 | "func-names": 0,
75 | "max-classes-per-file":0,
76 | "max-len": [
77 | 0,
78 | {
79 | "code": 120,
80 | "tabWidth": 4,
81 | "comments": 300,
82 | "ignoreComments": true
83 | }
84 | ],
85 | "no-param-reassign": 0,
86 | "consistent-return": 0,
87 | "eqeqeq": 0,
88 | "one-var": 0,
89 | "no-unused-vars": 0,
90 | "no-lonely-if": 0,
91 | "no-plusplus": 0,
92 | "indent": [
93 | 1,
94 | 4
95 | ],
96 | "quotes": [
97 | 1,
98 | "double"
99 | ],
100 | "quote-props": [
101 | 1,
102 | "always"
103 | ],
104 | "comma-dangle": 0,
105 | "nonblock-statement-body-position": 0,
106 | "curly": 0,
107 | "object-shorthand": 0,
108 | "prefer-spread": 0,
109 | "no-loop-func": 0,
110 | "no-trailing-spaces": 1,
111 | "space-before-function-paren": 1,
112 | "space-in-parens": 1,
113 | "space-infix-ops": 1,
114 | "keyword-spacing": 1,
115 | "padded-blocks": 0,
116 | "comma-spacing": 1,
117 | "space-before-blocks": 1,
118 | "spaced-comment": 1,
119 | "object-curly-spacing": 1,
120 | "object-curly-newline": 0,
121 | "implicit-arrow-linebreak": 0,
122 | "operator-linebreak": 0,
123 | "array-element-newline": 0,
124 | "function-paren-newline": 0,
125 | "no-self-compare": 0,
126 | "no-case-declarations": 0,
127 | "default-case": 0,
128 | "no-empty": 0,
129 | "no-use-before-define": 0,
130 | "no-multi-assign": 0,
131 | "no-extend-native": 0,
132 | "no-prototype-builtins": 0,
133 | "array-callback-return": 1,
134 | "prefer-destructuring": 0,
135 | "no-restricted-syntax": ["error", "TemplateLiteral"],
136 | "no-restricted-globals": 0,
137 | "no-continue": 0,
138 | "no-console": 1,
139 | "no-else-return": 0,
140 | "no-useless-return":0,
141 | "one-var-declaration-per-line": 0,
142 | "guard-for-in": 0,
143 | "no-new": 0,
144 | "radix": 0,
145 | "no-template-curly-in-string": 0,
146 | "no-useless-constructor": 0,
147 | "import/no-dynamic-require": 0,
148 | "import/no-cycle": [
149 | 0,
150 | {
151 | "maxDepth": 3
152 | }
153 | ],
154 | "import/no-relative-packages": 0,
155 | "prefer-template": 0,
156 | "prefer-rest-params": 0,
157 | "no-restricted-properties": 0,
158 | "import/prefer-default-export": 0,
159 | "import/no-default-export": 0,
160 | "import/extensions": 0,
161 | "prefer-arrow-callback": 0,
162 | "arrow-body-style": [ "error", "always"],
163 | "new-cap": 0,
164 | "prefer-const": 0,
165 | "padding-line-between-statements": [
166 | 1,
167 | {
168 | "blankLine": "always",
169 | "prev": "function",
170 | "next": "*"
171 | }
172 | ],
173 | "no-return-await": 0,
174 | "no-multiple-empty-lines": 1,
175 | "no-mixed-operators":0,
176 | "no-inner-declarations":0,
177 | "lines-around-comment": ["error", { "beforeBlockComment": true }],
178 | "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
179 | "newline-per-chained-call": 0
180 | }
181 |
182 | }
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/shared/libs/start-audio-context.js:
--------------------------------------------------------------------------------
1 | /**
2 | * StartAudioContext.js
3 | * @author Yotam Mann
4 | * @license http://opensource.org/licenses/MIT MIT License
5 | * @copyright 2016 Yotam Mann
6 | */
7 | (function (root, factory) {
8 | if (typeof define === "function" && define.amd) {
9 | define([], factory)
10 | } else if (typeof module === "object" && module.exports) {
11 | module.exports = factory()
12 | } else {
13 | root.StartAudioContext = factory()
14 | }
15 | }(this, function () {
16 |
17 | //TAP LISTENER/////////////////////////////////////////////////////////////
18 |
19 | /**
20 | * @class Listens for non-dragging tap ends on the given element
21 | * @param {Element} element
22 | * @internal
23 | */
24 | var TapListener = function(element, context){
25 |
26 | this._dragged = false
27 |
28 | this._element = element
29 |
30 | this._bindedMove = this._moved.bind(this)
31 | this._bindedEnd = this._ended.bind(this, context)
32 |
33 | element.addEventListener("touchstart", this._bindedEnd)
34 | element.addEventListener("touchmove", this._bindedMove)
35 | element.addEventListener("touchend", this._bindedEnd)
36 | element.addEventListener("mouseup", this._bindedEnd)
37 | }
38 |
39 | /**
40 | * drag move event
41 | */
42 | TapListener.prototype._moved = function(e){
43 | this._dragged = true
44 | };
45 |
46 | /**
47 | * tap ended listener
48 | */
49 | TapListener.prototype._ended = function(context){
50 | if (!this._dragged){
51 | startContext(context)
52 | }
53 | this._dragged = false
54 | };
55 |
56 | /**
57 | * remove all the bound events
58 | */
59 | TapListener.prototype.dispose = function(){
60 | this._element.removeEventListener("touchstart", this._bindedEnd)
61 | this._element.removeEventListener("touchmove", this._bindedMove)
62 | this._element.removeEventListener("touchend", this._bindedEnd)
63 | this._element.removeEventListener("mouseup", this._bindedEnd)
64 | this._bindedMove = null
65 | this._bindedEnd = null
66 | this._element = null
67 | };
68 |
69 | //END TAP LISTENER/////////////////////////////////////////////////////////
70 |
71 | /**
72 | * Plays a silent sound and also invoke the "resume" method
73 | * @param {AudioContext} context
74 | * @private
75 | */
76 | function startContext(context){
77 | // this accomplishes the iOS specific requirement
78 | var buffer = context.createBuffer(1, 1, context.sampleRate)
79 | var source = context.createBufferSource()
80 | source.buffer = buffer
81 | source.connect(context.destination)
82 | source.start(0)
83 |
84 | // resume the audio context
85 | if (context.resume){
86 | context.resume()
87 | }
88 | }
89 |
90 | /**
91 | * Returns true if the audio context is started
92 | * @param {AudioContext} context
93 | * @return {Boolean}
94 | * @private
95 | */
96 | function isStarted(context){
97 | return context.state === "running"
98 | }
99 |
100 | /**
101 | * Invokes the callback as soon as the AudioContext
102 | * is started
103 | * @param {AudioContext} context
104 | * @param {Function} callback
105 | */
106 | function onStarted(context, callback){
107 |
108 | function checkLoop(){
109 | if (isStarted(context)){
110 | callback()
111 | } else {
112 | requestAnimationFrame(checkLoop)
113 | if (context.resume){
114 | context.resume()
115 | }
116 | }
117 | }
118 |
119 | if (isStarted(context)){
120 | callback()
121 | } else {
122 | checkLoop()
123 | }
124 | }
125 |
126 | /**
127 | * Add a tap listener to the audio context
128 | * @param {Array|Element|String|jQuery} element
129 | * @param {Array} tapListeners
130 | */
131 | function bindTapListener(element, tapListeners, context){
132 | if (Array.isArray(element) || (NodeList && element instanceof NodeList)){
133 | for (var i = 0; i < element.length; i++){
134 | bindTapListener(element[i], tapListeners, context)
135 | }
136 | } else if (typeof element === "string"){
137 | bindTapListener(document.querySelectorAll(element), tapListeners, context)
138 | } else if (element.jquery && typeof element.toArray === "function"){
139 | bindTapListener(element.toArray(), tapListeners, context)
140 | } else if (Element && element instanceof Element){
141 | //if it's an element, create a TapListener
142 | var tap = new TapListener(element, context)
143 | tapListeners.push(tap)
144 | }
145 | }
146 |
147 | /**
148 | * @param {AudioContext} context The AudioContext to start.
149 | * @param {Array|String|Element|jQuery=} elements For iOS, the list of elements
150 | * to bind tap event listeners
151 | * which will start the AudioContext. If
152 | * no elements are given, it will bind
153 | * to the document.body.
154 | * @param {Function=} callback The callback to invoke when the AudioContext is started.
155 | * @return {Promise} The promise is invoked when the AudioContext
156 | * is started.
157 | */
158 | function StartAudioContext(context, elements, callback){
159 |
160 | //the promise is invoked when the AudioContext is started
161 | var promise = new Promise(function(success) {
162 | onStarted(context, success)
163 | })
164 |
165 | // The TapListeners bound to the elements
166 | var tapListeners = []
167 |
168 | // add all the tap listeners
169 | if (!elements){
170 | elements = document.body
171 | }
172 | bindTapListener(elements, tapListeners, context)
173 |
174 | //dispose all these tap listeners when the context is started
175 | promise.then(function(){
176 | for (var i = 0; i < tapListeners.length; i++){
177 | tapListeners[i].dispose()
178 | }
179 | tapListeners = null
180 |
181 | if (callback){
182 | callback()
183 | }
184 | })
185 |
186 | return promise
187 | }
188 |
189 | return StartAudioContext
190 | }))
--------------------------------------------------------------------------------
/shared/client/src/ele.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @callback whatever
3 | * @param {...any} param
4 | */
5 |
6 | /**
7 | * @typedef myElement
8 | * @type {HTMLElement}
9 | * @extends {HTMLInputElement}
10 | */
11 |
12 | /**
13 | * Ele - minimalistic html dom helper
14 | *
15 | * @class
16 | */
17 | class Ele
18 | {
19 |
20 | /**
21 | * shortcut for document.getElementById(id)
22 | *
23 | * @param {String} id
24 | * @returns {HTMLElement&any} DOM element
25 | */
26 | byId(id)
27 | {
28 | if (id && id[0] === "#") console.warn("ele.byId should not contain #");
29 | return document.getElementById(id);
30 | }
31 |
32 | /**
33 | * shortcut for document.querySelector(id)
34 | *
35 | * @param {String} q
36 | * @returns {any} DOM element
37 | */
38 | byQuery(q)
39 | {
40 | return document.querySelector(q);
41 | }
42 |
43 | /**
44 | * shortcut for document.querySelectorAll(id)
45 | *
46 | * @param {String} q
47 | * @returns {NodeListOf} DOM elements
48 | */
49 | byQueryAll(q)
50 | {
51 | return document.querySelectorAll(q);
52 | }
53 |
54 | /**
55 | * returns the first element with class
56 | *
57 | * @param {String} name
58 | * @returns {HTMLElement|null|Element} DOM element
59 | */
60 | byClass(name)
61 | {
62 | if (name && name[0] === ".") console.warn("ele.byClass should not contain .");
63 | const els = document.getElementsByClassName(name);
64 | if (els.length > 0) return els[0];
65 | return null;
66 | }
67 |
68 | /**
69 | * returns the all elements with class
70 | *
71 | * @param {String} name
72 | * @returns {HTMLCollectionOf|Array} DOM elements
73 | */
74 | byClassAll(name)
75 | {
76 | if (name && name[0] === ".") console.warn("ele.byClassAll should not contain .");
77 | const els = document.getElementsByClassName(name);
78 | if (!els) return [];
79 | return els;
80 | }
81 |
82 | /**
83 | * runs the callback with all elements that have the given class as first argument
84 | *
85 | * @param {String} name
86 | */
87 | forEachClass(name, cb)
88 | {
89 | if (name && name[0] === ".") console.warn("ele.forEachClass should not contain .");
90 |
91 | const eles = document.getElementsByClassName(name);
92 | for (let i = 0; i < eles.length; i++) cb(eles[i]);
93 | }
94 |
95 | /**
96 | * returns the currently selected value for a