Initial commit - BraceIQMed platform with frontend, API, and brace generator

This commit is contained in:
2026-01-29 14:34:05 -08:00
commit 745f9f827f
187 changed files with 534688 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
</head>
<body>
This window will close in 2 seconds. You can close it manually if it doesn't.
<script type="text/javascript">
setTimeout(function(){
window.close();
}, 2000);
</script>
</body>
</html>

View File

@@ -0,0 +1,507 @@
* {
font: 13px 'Open Sans', sans-serif;
color: #bbb;
font-weight: 400;
box-sizing: border-box;
border: 0;
margin: 0;
padding: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
body {
overflow: hidden;
margin: 0;
}
#tablet-plugin {
position: absolute;
top: -1000px;
}
#viewport {
position: absolute;
left: 310px; /* Add left margin to account for sidebar on the left */
right: 0;
top: 0;
bottom: 0;
}
#canvas {
width: 100%;
height: 100%;
display: block;
}
/****** SIDE BAR ******/
.gui-sidebar {
position: absolute;
bottom: 0;
top: 0;
padding-bottom: 20px;
width: 310px;
background: #3c3c3c;
overflow-x: hidden;
overflow-y: auto;
border-right: double;
border-width: 4px;
border-color: rgba(255, 255, 255, 0.3);
}
.gui-sidebar::-webkit-scrollbar {
width: 7px;
background: rgba(0, 0, 0, 0.3);
}
.gui-sidebar::-webkit-scrollbar-thumb {
border-radius: 2px;
background: rgba(255, 255, 255, 0.2);
}
.gui-sidebar::-webkit-scrollbar-corner {
height: 0;
display: none;
}
.gui-resize {
cursor: ew-resize;
position: absolute;
left: 310px;
top: 0;
bottom: 0;
width: 10px;
margin-left: -3px;
margin-right: -3px;
opacity: 0;
}
/****** folder ******/
.gui-sidebar > ul > label {
font-size: 15px;
font-weight: 600;
color: #999;
position: relative;
display: block;
line-height: 30px;
margin: 5px 0 5px 0;
text-transform: uppercase;
cursor: pointer;
vertical-align: middle;
text-align: center;
background: rgba(0, 0, 0, 0.3);
}
.gui-sidebar > ul[opened=true] > label:before {
content: '▼';
text-indent: 1em;
float: left;
}
.gui-sidebar > ul[opened=false] > label:before {
content: '►';
text-indent: 1em;
float: left;
}
.gui-sidebar > ul {
display: block;
list-style: none;
overflow: hidden;
-webkit-transition: max-height 0.3s ease;
-moz-transition: max-height 0.3s ease;
-ms-transition: max-height 0.3s ease;
-o-transition: max-height 0.3s ease;
transition: max-height 0.3s ease;
}
.gui-sidebar > ul[opened=true] {
max-height: 700px;
}
.gui-sidebar > ul[opened=false] {
height: 35px;
max-height: 35px;
}
.gui-sidebar > ul > li {
height: 22px;
margin: 4px 5px 4px 5px;
}
.gui-glowOnHover:hover {
background: rgba(0, 0, 0, 0.2);
}
.gui-pointerOnHover:hover {
cursor: pointer;
}
/****** label ******/
.gui-label-side {
position: relative;
display: inline-block;
height: 100%;
width: 36%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/****** checkbox ******/
.gui-input-checkbox {
display: none;
}
.gui-input-checkbox + label {
float: right;
cursor: pointer;
position: relative;
border: 1px solid;
border-radius: 4px;
margin-top: 2px;
width: 18px;
height: 18px;
}
.gui-input-checkbox + label::before {
position: absolute;
top: -5px;
left: 5px;
height: 14px;
width: 6px;
border-right: 2px solid;
border-bottom: 2px solid;
-webkit-transform: rotate(60deg) skew(25deg, 0);
-ms-transform: rotate(60deg) skew(25deg, 0);
transform: rotate(60deg) skew(25deg, 0);
}
.gui-input-checkbox:checked + label::before {
content: '';
}
/****** input number ******/
.gui-input-number {
-moz-appearance: textfield;
float: right;
position: relative;
width: 10%;
height: 100%;
margin-left: 2%;
text-align: center;
outline: none;
font-size: 10px;
border-radius: 4px;
background: rgba(0, 0, 0, 0.3);
}
.gui-widget-color > input::-webkit-inner-spin-button,
.gui-widget-color > input::-webkit-outer-spin-button,
.gui-input-number::-webkit-inner-spin-button,
.gui-input-number::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
/****** input on hover ******/
.gui-slider:hover,
.gui-input-number:hover {
background: rgba(0, 0, 0, 0.4);
}
/****** slider ******/
.gui-slider {
-webkit-appearance: none;
cursor: ew-resize;
float: right;
width: 52%;
height: 100%;
overflow: hidden;
border-radius: 4px;
background: rgba(0, 0, 0, 0.3);
}
.gui-slider > div {
height: 100%;
background: #525f63;
}
/****** button ******/
.gui-button {
-webkit-appearance: none;
float: right;
cursor: pointer;
position: relative;
display: inline-block;
text-align: center;
width: 100%;
height: 100%;
outline: none;
border-radius: 4px;
background: #525f63;
}
.gui-button::-moz-focus-inner {
padding: 0 !important;
border: 0 none !important;
}
.gui-button:enabled:hover {
color: #fff;
}
.gui-button:active {
box-shadow: 0 1px 0 hsla(0, 0%, 100%, .1), inset 0 1px 4px hsla(0, 0%, 0%, .8);
}
.gui-button:disabled {
background: #444;
color: #555;
}
/****** widget color ******/
.gui-widget-color {
float: right;
display: block;
width: 64%;
height: 100%;
}
.gui-widget-color > input {
-moz-appearance: textfield;
position: relative;
display: inline;
width: 100%;
height: 100%;
text-align: center;
outline: none;
border-radius: 4px;
font-size: 13px;
background: #f00;
}
.gui-widget-color > input + div:hover,
.gui-widget-color > input:hover + div {
display: block;
pointer-events: auto;
}
.gui-widget-color > input + div {
display: none;
position: absolute;
pointer-events: none;
padding: 3px;
width: 125px;
height: 105px;
z-index: 2;
background: #111;
}
/* saturation */
.gui-color-saturation {
display: inline-block;
width: 100px;
height: 100px;
margin-right: 3px;
border: 1px solid #555;
cursor: pointer;
}
.gui-color-saturation > div {
width: 100%;
height: 100%;
pointer-events: none;
border: none;
background: none;
}
.gui-knob-saturation {
position: absolute;
pointer-events: none;
width: 10px;
height: 10px;
z-index: 4;
border: #fff;
border-radius: 10px;
border: 2px solid white;
}
/* hue*/
.gui-color-hue {
display: inline-block;
width: 15px;
height: 100px;
border: 1px solid #555;
cursor: ns-resize;
}
.gui-knob-hue {
pointer-events: none;
position: absolute;
width: 15px;
height: 2px;
border-right: 4px solid #fff;
}
/* alpha */
.gui-color-alpha {
display: inline-block;
margin-left: 3px;
height: 100px;
width: 15px;
border: 1px solid #555;
cursor: ns-resize;
}
.gui-knob-alpha {
pointer-events: none;
position: absolute;
width: 15px;
height: 2px;
border-right: 4px solid #fff;
}
/****** select ******/
.gui-select {
float: right;
cursor: pointer;
position: relative;
display: inline-block;
width: 64%;
height: 100%;
padding-left: 1%;
outline: none;
background: #525f63;
border-radius: 4px;
}
.gui-select:hover {
color: #fff;
}
/****** TOP BAR ******/
.gui-topbar {
position: absolute;
background: #20211d;
width: 100%;
padding-right: 10px;
padding-left: 10px;
z-index: 1;
float: left;
}
.gui-topbar ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.gui-topbar ul > li {
float: left;
line-height: 40px;
padding: 0 15px;
position: relative;
cursor: pointer;
}
.gui-topbar ul > li.gui-logo {
padding: 0 12px 0 0;
cursor: default;
}
.gui-topbar ul > li.gui-logo:hover {
color: inherit;
}
.gui-topbar ul > li.gui-logo img {
display: block;
height: 28px;
margin-top: 6px;
width: auto;
}
.gui-topbar ul > li .shortcut {
float: right;
font-style: oblique;
margin-right: 11px;
}
.gui-topbar ul > li:hover {
color: #fff;
}
.gui-topbar ul > li:hover > ul {
display: block;
opacity: 1;
pointer-events: auto;
top: 30px;
}
.gui-topbar ul > li > ul {
position: absolute;
top: 20px;
left: 10px;
background: #222;
width: 220px;
padding: 8px;
border-radius: 0 4px 4px 0;
pointer-events: none;
opacity: 0;
-webkit-transition: 0.15s all ease;
-ms-transition: 0.15s all ease;
-moz-transition: 0.15s all ease;
-o-transition: 0.15s all ease;
transition: 0.15s all ease;
}
.gui-topbar ul > li > ul > li {
float: none;
height: 22px;
line-height: 22px;
margin: 6px 0 6px 0;
padding-left: 5px;
}
.group-title {
font-size: 14px;
font-weight: 600;
color: #999 !important;
cursor: default !important;
text-align: center;
border-bottom: 1px solid #444444;
padding-bottom: 5px;
margin: 10px 0 10px 0;
}

View File

@@ -0,0 +1,47 @@
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<meta name='description' content='SculptGL is a small sculpting application powered by JavaScript and webGL.'>
<meta name='author' content='stéphane GINIER'>
<meta name='mobile-web-app-capable' content='yes'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<title> BRACE iQ </title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>
<link rel='stylesheet' href='css/yagui.css' type='text/css' />
<script>
'use strict';
window.sketchfabOAuth2Config = {
hostname: 'sketchfab.com',
client_id: 'OWoAmrd1QCS9wB54Ly17rMl2i5AHGvDNfmN4pEUH',
redirect_uri: 'https://stephaneginier.com/sculptgl/authSuccess.html'
};
window.addEventListener('load', function () {
var app = new window.SculptGL();
app.start();
});
</script>
</head>
<body oncontextmenu='return false;'>
<input type='file' id='fileopen' multiple style='display: none' />
<input type='file' id='backgroundopen' style='display: none' />
<input type='file' id='alphaopen' style='display: none' />
<input type='file' id='textureopen' style='display: none' />
<input type='file' id='matcapopen' style='display: none' />
<div id='viewport'>
<canvas id='canvas'></canvas>
</div>
<script src='sculptgl.js'></script>
<!-- <script src='//cdn.webglstats.com/stat.js' defer='defer' async='async'></script> -->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
/*! Hammer.JS - v2.0.7 - 2016-04-22
* http://hammerjs.github.io/
*
* Copyright (c) 2016 Jorik Tangelder;
* Licensed under the MIT license */
/*! exports provided: default */
/*! no static exports found */
/*!**********************!*\
!*** ./src/yagui.js ***!
\**********************/
/*!************************!*\
!*** ./src/GuiMain.js ***!
\************************/
/*!******************************!*\
!*** ./src/widgets/Color.js ***!
\******************************/
/*!******************************!*\
!*** ./src/widgets/Title.js ***!
\******************************/
/*!*******************************!*\
!*** ./src/utils/GuiUtils.js ***!
\*******************************/
/*!*******************************!*\
!*** ./src/widgets/Button.js ***!
\*******************************/
/*!*******************************!*\
!*** ./src/widgets/Slider.js ***!
\*******************************/
/*!********************************!*\
!*** ./src/containers/Menu.js ***!
\********************************/
/*!********************************!*\
!*** ./src/utils/EditStyle.js ***!
\********************************/
/*!*********************************!*\
!*** ./src/widgets/Checkbox.js ***!
\*********************************/
/*!*********************************!*\
!*** ./src/widgets/Combobox.js ***!
\*********************************/
/*!**********************************!*\
!*** ./src/containers/Folder.js ***!
\**********************************/
/*!**********************************!*\
!*** ./src/containers/Topbar.js ***!
\**********************************/
/*!***********************************!*\
!*** ./src/containers/Sidebar.js ***!
\***********************************/
/*!***********************************!*\
!*** ./src/widgets/BaseWidget.js ***!
\***********************************/
/*!***********************************!*\
!*** ./src/widgets/MenuButton.js ***!
\***********************************/
/*!*****************************************!*\
!*** ./src/containers/BaseContainer.js ***!
\*****************************************/

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,147 @@
/* jshint worker:true */
(function main(global) {
"use strict";
if (global.zWorkerInitialized)
throw new Error('z-worker.js should be run only once');
global.zWorkerInitialized = true;
addEventListener("message", function(event) {
var message = event.data, type = message.type, sn = message.sn;
var handler = handlers[type];
if (handler) {
try {
handler(message);
} catch (e) {
onError(type, sn, e);
}
}
//for debug
//postMessage({type: 'echo', originalType: type, sn: sn});
});
var handlers = {
importScripts: doImportScripts,
newTask: newTask,
append: processData,
flush: processData,
};
// deflater/inflater tasks indexed by serial numbers
var tasks = {};
function doImportScripts(msg) {
if (msg.scripts && msg.scripts.length > 0)
importScripts.apply(undefined, msg.scripts);
postMessage({type: 'importScripts'});
}
function newTask(msg) {
var CodecClass = global[msg.codecClass];
var sn = msg.sn;
if (tasks[sn])
throw Error('duplicated sn');
tasks[sn] = {
codec: new CodecClass(msg.options),
crcInput: msg.crcType === 'input',
crcOutput: msg.crcType === 'output',
crc: new Crc32(),
};
postMessage({type: 'newTask', sn: sn});
}
// performance may not be supported
var now = global.performance ? global.performance.now.bind(global.performance) : Date.now;
function processData(msg) {
var sn = msg.sn, type = msg.type, input = msg.data;
var task = tasks[sn];
// allow creating codec on first append
if (!task && msg.codecClass) {
newTask(msg);
task = tasks[sn];
}
var isAppend = type === 'append';
var start = now();
var output;
if (isAppend) {
try {
output = task.codec.append(input, function onprogress(loaded) {
postMessage({type: 'progress', sn: sn, loaded: loaded});
});
} catch (e) {
delete tasks[sn];
throw e;
}
} else {
delete tasks[sn];
output = task.codec.flush();
}
var codecTime = now() - start;
start = now();
if (input && task.crcInput)
task.crc.append(input);
if (output && task.crcOutput)
task.crc.append(output);
var crcTime = now() - start;
var rmsg = {type: type, sn: sn, codecTime: codecTime, crcTime: crcTime};
var transferables = [];
if (output) {
rmsg.data = output;
transferables.push(output.buffer);
}
if (!isAppend && (task.crcInput || task.crcOutput))
rmsg.crc = task.crc.get();
postMessage(rmsg, transferables);
}
function onError(type, sn, e) {
var msg = {
type: type,
sn: sn,
error: formatError(e)
};
postMessage(msg);
}
function formatError(e) {
return { message: e.message, stack: e.stack };
}
// Crc32 code copied from file zip.js
function Crc32() {
this.crc = -1;
}
Crc32.prototype.append = function append(data) {
var crc = this.crc | 0, table = this.table;
for (var offset = 0, len = data.length | 0; offset < len; offset++)
crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
this.crc = crc;
};
Crc32.prototype.get = function get() {
return ~this.crc;
};
Crc32.prototype.table = (function() {
var i, j, t, table = []; // Uint32Array is actually slower than []
for (i = 0; i < 256; i++) {
t = i;
for (j = 0; j < 8; j++)
if (t & 1)
t = (t >>> 1) ^ 0xEDB88320;
else
t = t >>> 1;
table[i] = t;
}
return table;
})();
// "no-op" codec
function NOOP() {}
global.NOOP = NOOP;
NOOP.prototype.append = function append(bytes, onprogress) {
return bytes;
};
NOOP.prototype.flush = function flush() {};
})(this);

1
frontend/public/vite.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB