diff --git a/js/css/styles.css b/js/css/styles.css index 7a1a0ca..9f10eac 100644 --- a/js/css/styles.css +++ b/js/css/styles.css @@ -48,3 +48,25 @@ border-style: solid; border-width: 1px; } + +.lil-gui { + --padding: 2px; + --spacing: 2px; + --widget-height: 11px; + --font-size: 11px; + --input-font-size: 10px; + --widget-border-radius: 0px; + --slider-input-min-width: 30px; + --color-input-min-width: 30px; + --width:160px; + --name-width:30%; + --background-color: none; + --title-background-color:none; + --text-color: #ebebeb; + --title-text-color: #ebebeb; + --widget-color: rgba(20,20,10,0.5); + --hover-color: rgba(30,30,50,0.8);; + --focus-color: #595959; + --number-color: #2cc9ff; + --string-color: #a2db3c; +} \ No newline at end of file diff --git a/js/lib/Hub.js b/js/lib/Hub.js index b11f5fb..0b50f6c 100644 --- a/js/lib/Hub.js +++ b/js/lib/Hub.js @@ -1,10 +1,10 @@ +import GUI from './lil-gui.esm.js'; + let unselectable = '-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select: none; pointer-events:none; '; export class Hub { - constructor( controls ) { - - this.controls = controls; + constructor() { const content = document.createElement( 'div' ); content.style.cssText = unselectable + 'position:absolute; top:0; left:0; width:100%; height:100%;';// font-family: Mulish,sans-serif;z-index: 100000;pointer-events:auto; cursor: pointer; @@ -25,12 +25,30 @@ export class Hub { if(this.ready) return dom.parentElement.appendChild( this.content ); this.ready = true; + this.init(); } + init(){ + + return + + + const iner = document.createElement( 'div' ); + iner.style.cssText = unselectable + 'position:absolute; top:0; left:0; pointer-events:auto;'; + this.content.appendChild( iner ); + + let gui = new GUI( { container:iner, width:160, title: 'Option' } ) + gui.add( { test: 0.5 }, 'test', 0, 1 ) + gui.add( { value: 0.5 }, 'value', 0, 1 ) + gui.add( { here: 0.5 }, 'here', 0, 1 ) + + console.log(gui) + } + } - +/* export class micoSlide { @@ -66,4 +84,4 @@ export class micoSlide { } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/js/lib/lil-gui.esm.js b/js/lib/lil-gui.esm.js new file mode 100644 index 0000000..de146b4 --- /dev/null +++ b/js/lib/lil-gui.esm.js @@ -0,0 +1,2403 @@ +/** + * lil-gui + * https://lil-gui.georgealways.com + * @version 0.20.0 + * @author George Michael Brower + * @license MIT + */ +/** @module Controller */ + +/** + * Base class for all controllers. + */ +class Controller { + + constructor( parent, object, property, className, elementType = 'div' ) { + + /** + * The GUI that contains this controller. + * @type {GUI} + */ + this.parent = parent; + + /** + * The object this controller will modify. + * @type {object} + */ + this.object = object; + + /** + * The name of the property to control. + * @type {string} + */ + this.property = property; + + /** + * Used to determine if the controller is disabled. + * Use `controller.disable( true|false )` to modify this value. + * @type {boolean} + */ + this._disabled = false; + + /** + * Used to determine if the Controller is hidden. + * Use `controller.show()` or `controller.hide()` to change this. + * @type {boolean} + */ + this._hidden = false; + + /** + * The value of `object[ property ]` when the controller was created. + * @type {any} + */ + this.initialValue = this.getValue(); + + /** + * The outermost container DOM element for this controller. + * @type {HTMLElement} + */ + this.domElement = document.createElement( elementType ); + this.domElement.classList.add( 'controller' ); + this.domElement.classList.add( className ); + + /** + * The DOM element that contains the controller's name. + * @type {HTMLElement} + */ + this.$name = document.createElement( 'div' ); + this.$name.classList.add( 'name' ); + + Controller.nextNameID = Controller.nextNameID || 0; + this.$name.id = `lil-gui-name-${++Controller.nextNameID}`; + + /** + * The DOM element that contains the controller's "widget" (which differs by controller type). + * @type {HTMLElement} + */ + this.$widget = document.createElement( 'div' ); + this.$widget.classList.add( 'widget' ); + + /** + * The DOM element that receives the disabled attribute when using disable(). + * @type {HTMLElement} + */ + this.$disable = this.$widget; + + this.domElement.appendChild( this.$name ); + this.domElement.appendChild( this.$widget ); + + // Don't fire global key events while typing in a controller + this.domElement.addEventListener( 'keydown', e => e.stopPropagation() ); + this.domElement.addEventListener( 'keyup', e => e.stopPropagation() ); + + this.parent.children.push( this ); + this.parent.controllers.push( this ); + + this.parent.$children.appendChild( this.domElement ); + + this._listenCallback = this._listenCallback.bind( this ); + + this.name( property ); + + } + + /** + * Sets the name of the controller and its label in the GUI. + * @param {string} name + * @returns {this} + */ + name( name ) { + /** + * The controller's name. Use `controller.name( 'Name' )` to modify this value. + * @type {string} + */ + this._name = name; + this.$name.textContent = name; + return this; + } + + /** + * Pass a function to be called whenever the value is modified by this controller. + * The function receives the new value as its first parameter. The value of `this` will be the + * controller. + * + * For function controllers, the `onChange` callback will be fired on click, after the function + * executes. + * @param {Function} callback + * @returns {this} + * @example + * const controller = gui.add( object, 'property' ); + * + * controller.onChange( function( v ) { + * console.log( 'The value is now ' + v ); + * console.assert( this === controller ); + * } ); + */ + onChange( callback ) { + /** + * Used to access the function bound to `onChange` events. Don't modify this value directly. + * Use the `controller.onChange( callback )` method instead. + * @type {Function} + */ + this._onChange = callback; + return this; + } + + /** + * Calls the onChange methods of this controller and its parent GUI. + * @protected + */ + _callOnChange() { + + this.parent._callOnChange( this ); + + if ( this._onChange !== undefined ) { + this._onChange.call( this, this.getValue() ); + } + + this._changed = true; + + } + + /** + * Pass a function to be called after this controller has been modified and loses focus. + * @param {Function} callback + * @returns {this} + * @example + * const controller = gui.add( object, 'property' ); + * + * controller.onFinishChange( function( v ) { + * console.log( 'Changes complete: ' + v ); + * console.assert( this === controller ); + * } ); + */ + onFinishChange( callback ) { + /** + * Used to access the function bound to `onFinishChange` events. Don't modify this value + * directly. Use the `controller.onFinishChange( callback )` method instead. + * @type {Function} + */ + this._onFinishChange = callback; + return this; + } + + /** + * Should be called by Controller when its widgets lose focus. + * @protected + */ + _callOnFinishChange() { + + if ( this._changed ) { + + this.parent._callOnFinishChange( this ); + + if ( this._onFinishChange !== undefined ) { + this._onFinishChange.call( this, this.getValue() ); + } + + } + + this._changed = false; + + } + + /** + * Sets the controller back to its initial value. + * @returns {this} + */ + reset() { + this.setValue( this.initialValue ); + this._callOnFinishChange(); + return this; + } + + /** + * Enables this controller. + * @param {boolean} enabled + * @returns {this} + * @example + * controller.enable(); + * controller.enable( false ); // disable + * controller.enable( controller._disabled ); // toggle + */ + enable( enabled = true ) { + return this.disable( !enabled ); + } + + /** + * Disables this controller. + * @param {boolean} disabled + * @returns {this} + * @example + * controller.disable(); + * controller.disable( false ); // enable + * controller.disable( !controller._disabled ); // toggle + */ + disable( disabled = true ) { + + if ( disabled === this._disabled ) return this; + + this._disabled = disabled; + + this.domElement.classList.toggle( 'disabled', disabled ); + this.$disable.toggleAttribute( 'disabled', disabled ); + + return this; + + } + + /** + * Shows the Controller after it's been hidden. + * @param {boolean} show + * @returns {this} + * @example + * controller.show(); + * controller.show( false ); // hide + * controller.show( controller._hidden ); // toggle + */ + show( show = true ) { + + this._hidden = !show; + + this.domElement.style.display = this._hidden ? 'none' : ''; + + return this; + + } + + /** + * Hides the Controller. + * @returns {this} + */ + hide() { + return this.show( false ); + } + + /** + * Changes this controller into a dropdown of options. + * + * Calling this method on an option controller will simply update the options. However, if this + * controller was not already an option controller, old references to this controller are + * destroyed, and a new controller is added to the end of the GUI. + * @example + * // safe usage + * + * gui.add( obj, 'prop1' ).options( [ 'a', 'b', 'c' ] ); + * gui.add( obj, 'prop2' ).options( { Big: 10, Small: 1 } ); + * gui.add( obj, 'prop3' ); + * + * // danger + * + * const ctrl1 = gui.add( obj, 'prop1' ); + * gui.add( obj, 'prop2' ); + * + * // calling options out of order adds a new controller to the end... + * const ctrl2 = ctrl1.options( [ 'a', 'b', 'c' ] ); + * + * // ...and ctrl1 now references a controller that doesn't exist + * assert( ctrl2 !== ctrl1 ) + * @param {object|Array} options + * @returns {Controller} + */ + options( options ) { + const controller = this.parent.add( this.object, this.property, options ); + controller.name( this._name ); + this.destroy(); + return controller; + } + + /** + * Sets the minimum value. Only works on number controllers. + * @param {number} min + * @returns {this} + */ + // eslint-disable-next-line no-unused-vars + min( min ) { + return this; + } + + /** + * Sets the maximum value. Only works on number controllers. + * @param {number} max + * @returns {this} + */ + // eslint-disable-next-line no-unused-vars + max( max ) { + return this; + } + + /** + * Values set by this controller will be rounded to multiples of `step`. Only works on number + * controllers. + * @param {number} step + * @returns {this} + */ + // eslint-disable-next-line no-unused-vars + step( step ) { + return this; + } + + /** + * Rounds the displayed value to a fixed number of decimals, without affecting the actual value + * like `step()`. Only works on number controllers. + * @example + * gui.add( object, 'property' ).listen().decimals( 4 ); + * @param {number} decimals + * @returns {this} + */ + // eslint-disable-next-line no-unused-vars + decimals( decimals ) { + return this; + } + + /** + * Calls `updateDisplay()` every animation frame. Pass `false` to stop listening. + * @param {boolean} listen + * @returns {this} + */ + listen( listen = true ) { + + /** + * Used to determine if the controller is currently listening. Don't modify this value + * directly. Use the `controller.listen( true|false )` method instead. + * @type {boolean} + */ + this._listening = listen; + + if ( this._listenCallbackID !== undefined ) { + cancelAnimationFrame( this._listenCallbackID ); + this._listenCallbackID = undefined; + } + + if ( this._listening ) { + this._listenCallback(); + } + + return this; + + } + + _listenCallback() { + + this._listenCallbackID = requestAnimationFrame( this._listenCallback ); + + // To prevent framerate loss, make sure the value has changed before updating the display. + // Note: save() is used here instead of getValue() only because of ColorController. The !== operator + // won't work for color objects or arrays, but ColorController.save() always returns a string. + + const curValue = this.save(); + + if ( curValue !== this._listenPrevValue ) { + this.updateDisplay(); + } + + this._listenPrevValue = curValue; + + } + + /** + * Returns `object[ property ]`. + * @returns {any} + */ + getValue() { + return this.object[ this.property ]; + } + + /** + * Sets the value of `object[ property ]`, invokes any `onChange` handlers and updates the display. + * @param {any} value + * @returns {this} + */ + setValue( value ) { + + if ( this.getValue() !== value ) { + + this.object[ this.property ] = value; + this._callOnChange(); + this.updateDisplay(); + + } + + return this; + + } + + /** + * Updates the display to keep it in sync with the current value. Useful for updating your + * controllers when their values have been modified outside of the GUI. + * @returns {this} + */ + updateDisplay() { + return this; + } + + load( value ) { + this.setValue( value ); + this._callOnFinishChange(); + return this; + } + + save() { + return this.getValue(); + } + + /** + * Destroys this controller and removes it from the parent GUI. + */ + destroy() { + this.listen( false ); + this.parent.children.splice( this.parent.children.indexOf( this ), 1 ); + this.parent.controllers.splice( this.parent.controllers.indexOf( this ), 1 ); + this.parent.$children.removeChild( this.domElement ); + } + +} + +class BooleanController extends Controller { + + constructor( parent, object, property ) { + + super( parent, object, property, 'boolean', 'label' ); + + this.$input = document.createElement( 'input' ); + this.$input.setAttribute( 'type', 'checkbox' ); + this.$input.setAttribute( 'aria-labelledby', this.$name.id ); + + this.$widget.appendChild( this.$input ); + + this.$input.addEventListener( 'change', () => { + this.setValue( this.$input.checked ); + this._callOnFinishChange(); + } ); + + this.$disable = this.$input; + + this.updateDisplay(); + + } + + updateDisplay() { + this.$input.checked = this.getValue(); + return this; + } + +} + +/* eslint-disable no-cond-assign */ + +function normalizeColorString( string ) { + + let match, result; + + if ( match = string.match( /(#|0x)?([a-f0-9]{6})/i ) ) { + + result = match[ 2 ]; + + } else if ( match = string.match( /rgb\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*\)/ ) ) { + + result = parseInt( match[ 1 ] ).toString( 16 ).padStart( 2, 0 ) + + parseInt( match[ 2 ] ).toString( 16 ).padStart( 2, 0 ) + + parseInt( match[ 3 ] ).toString( 16 ).padStart( 2, 0 ); + + } else if ( match = string.match( /^#?([a-f0-9])([a-f0-9])([a-f0-9])$/i ) ) { + + result = match[ 1 ] + match[ 1 ] + match[ 2 ] + match[ 2 ] + match[ 3 ] + match[ 3 ]; + + } + + if ( result ) { + return '#' + result; + } + + return false; + +} + +const STRING = { + isPrimitive: true, + match: v => typeof v === 'string', + fromHexString: normalizeColorString, + toHexString: normalizeColorString +}; + +const INT = { + isPrimitive: true, + match: v => typeof v === 'number', + fromHexString: string => parseInt( string.substring( 1 ), 16 ), + toHexString: value => '#' + value.toString( 16 ).padStart( 6, 0 ) +}; + +const ARRAY = { + isPrimitive: false, + + // The arrow function is here to appease tree shakers like esbuild or webpack. + // See https://esbuild.github.io/api/#tree-shaking + match: v => Array.isArray( v ), + + fromHexString( string, target, rgbScale = 1 ) { + + const int = INT.fromHexString( string ); + + target[ 0 ] = ( int >> 16 & 255 ) / 255 * rgbScale; + target[ 1 ] = ( int >> 8 & 255 ) / 255 * rgbScale; + target[ 2 ] = ( int & 255 ) / 255 * rgbScale; + + }, + toHexString( [ r, g, b ], rgbScale = 1 ) { + + rgbScale = 255 / rgbScale; + + const int = ( r * rgbScale ) << 16 ^ + ( g * rgbScale ) << 8 ^ + ( b * rgbScale ) << 0; + + return INT.toHexString( int ); + + } +}; + +const OBJECT = { + isPrimitive: false, + match: v => Object( v ) === v, + fromHexString( string, target, rgbScale = 1 ) { + + const int = INT.fromHexString( string ); + + target.r = ( int >> 16 & 255 ) / 255 * rgbScale; + target.g = ( int >> 8 & 255 ) / 255 * rgbScale; + target.b = ( int & 255 ) / 255 * rgbScale; + + }, + toHexString( { r, g, b }, rgbScale = 1 ) { + + rgbScale = 255 / rgbScale; + + const int = ( r * rgbScale ) << 16 ^ + ( g * rgbScale ) << 8 ^ + ( b * rgbScale ) << 0; + + return INT.toHexString( int ); + + } +}; + +const FORMATS = [ STRING, INT, ARRAY, OBJECT ]; + +function getColorFormat( value ) { + return FORMATS.find( format => format.match( value ) ); +} + +class ColorController extends Controller { + + constructor( parent, object, property, rgbScale ) { + + super( parent, object, property, 'color' ); + + this.$input = document.createElement( 'input' ); + this.$input.setAttribute( 'type', 'color' ); + this.$input.setAttribute( 'tabindex', -1 ); + this.$input.setAttribute( 'aria-labelledby', this.$name.id ); + + this.$text = document.createElement( 'input' ); + this.$text.setAttribute( 'type', 'text' ); + this.$text.setAttribute( 'spellcheck', 'false' ); + this.$text.setAttribute( 'aria-labelledby', this.$name.id ); + + this.$display = document.createElement( 'div' ); + this.$display.classList.add( 'display' ); + + this.$display.appendChild( this.$input ); + this.$widget.appendChild( this.$display ); + this.$widget.appendChild( this.$text ); + + this._format = getColorFormat( this.initialValue ); + this._rgbScale = rgbScale; + + this._initialValueHexString = this.save(); + this._textFocused = false; + + this.$input.addEventListener( 'input', () => { + this._setValueFromHexString( this.$input.value ); + } ); + + this.$input.addEventListener( 'blur', () => { + this._callOnFinishChange(); + } ); + + this.$text.addEventListener( 'input', () => { + const tryParse = normalizeColorString( this.$text.value ); + if ( tryParse ) { + this._setValueFromHexString( tryParse ); + } + } ); + + this.$text.addEventListener( 'focus', () => { + this._textFocused = true; + this.$text.select(); + } ); + + this.$text.addEventListener( 'blur', () => { + this._textFocused = false; + this.updateDisplay(); + this._callOnFinishChange(); + } ); + + this.$disable = this.$text; + + this.updateDisplay(); + + } + + reset() { + this._setValueFromHexString( this._initialValueHexString ); + return this; + } + + _setValueFromHexString( value ) { + + if ( this._format.isPrimitive ) { + + const newValue = this._format.fromHexString( value ); + this.setValue( newValue ); + + } else { + + this._format.fromHexString( value, this.getValue(), this._rgbScale ); + this._callOnChange(); + this.updateDisplay(); + + } + + } + + save() { + return this._format.toHexString( this.getValue(), this._rgbScale ); + } + + load( value ) { + this._setValueFromHexString( value ); + this._callOnFinishChange(); + return this; + } + + updateDisplay() { + this.$input.value = this._format.toHexString( this.getValue(), this._rgbScale ); + if ( !this._textFocused ) { + this.$text.value = this.$input.value.substring( 1 ); + } + this.$display.style.backgroundColor = this.$input.value; + return this; + } + +} + +class FunctionController extends Controller { + + constructor( parent, object, property ) { + + super( parent, object, property, 'function' ); + + // Buttons are the only case where widget contains name + this.$button = document.createElement( 'button' ); + this.$button.appendChild( this.$name ); + this.$widget.appendChild( this.$button ); + + this.$button.addEventListener( 'click', e => { + e.preventDefault(); + this.getValue().call( this.object ); + this._callOnChange(); + } ); + + // enables :active pseudo class on mobile + this.$button.addEventListener( 'touchstart', () => {}, { passive: true } ); + + this.$disable = this.$button; + + } + +} + +class NumberController extends Controller { + + constructor( parent, object, property, min, max, step ) { + + super( parent, object, property, 'number' ); + + this._initInput(); + + this.min( min ); + this.max( max ); + + const stepExplicit = step !== undefined; + this.step( stepExplicit ? step : this._getImplicitStep(), stepExplicit ); + + this.updateDisplay(); + + } + + decimals( decimals ) { + this._decimals = decimals; + this.updateDisplay(); + return this; + } + + min( min ) { + this._min = min; + this._onUpdateMinMax(); + return this; + } + + max( max ) { + this._max = max; + this._onUpdateMinMax(); + return this; + } + + step( step, explicit = true ) { + this._step = step; + this._stepExplicit = explicit; + return this; + } + + updateDisplay() { + + const value = this.getValue(); + + if ( this._hasSlider ) { + + let percent = ( value - this._min ) / ( this._max - this._min ); + percent = Math.max( 0, Math.min( percent, 1 ) ); + + this.$fill.style.width = percent * 100 + '%'; + + } + + if ( !this._inputFocused ) { + this.$input.value = this._decimals === undefined ? value : value.toFixed( this._decimals ); + } + + return this; + + } + + _initInput() { + + this.$input = document.createElement( 'input' ); + this.$input.setAttribute( 'type', 'text' ); + this.$input.setAttribute( 'aria-labelledby', this.$name.id ); + + // On touch devices only, use input[type=number] to force a numeric keyboard. + // Ideally we could use one input type everywhere, but [type=number] has quirks + // on desktop, and [inputmode=decimal] has quirks on iOS. + // See https://github.com/georgealways/lil-gui/pull/16 + + const isTouch = window.matchMedia( '(pointer: coarse)' ).matches; + + if ( isTouch ) { + this.$input.setAttribute( 'type', 'number' ); + this.$input.setAttribute( 'step', 'any' ); + } + + this.$widget.appendChild( this.$input ); + + this.$disable = this.$input; + + const onInput = () => { + + let value = parseFloat( this.$input.value ); + + if ( isNaN( value ) ) return; + + if ( this._stepExplicit ) { + value = this._snap( value ); + } + + this.setValue( this._clamp( value ) ); + + }; + + // Keys & mouse wheel + // --------------------------------------------------------------------- + + const increment = delta => { + + const value = parseFloat( this.$input.value ); + + if ( isNaN( value ) ) return; + + this._snapClampSetValue( value + delta ); + + // Force the input to updateDisplay when it's focused + this.$input.value = this.getValue(); + + }; + + const onKeyDown = e => { + // Using `e.key` instead of `e.code` also catches NumpadEnter + if ( e.key === 'Enter' ) { + this.$input.blur(); + } + if ( e.code === 'ArrowUp' ) { + e.preventDefault(); + increment( this._step * this._arrowKeyMultiplier( e ) ); + } + if ( e.code === 'ArrowDown' ) { + e.preventDefault(); + increment( this._step * this._arrowKeyMultiplier( e ) * -1 ); + } + }; + + const onWheel = e => { + if ( this._inputFocused ) { + e.preventDefault(); + increment( this._step * this._normalizeMouseWheel( e ) ); + } + }; + + // Vertical drag + // --------------------------------------------------------------------- + + let testingForVerticalDrag = false, + initClientX, + initClientY, + prevClientY, + initValue, + dragDelta; + + // Once the mouse is dragged more than DRAG_THRESH px on any axis, we decide + // on the user's intent: horizontal means highlight, vertical means drag. + const DRAG_THRESH = 5; + + const onMouseDown = e => { + + initClientX = e.clientX; + initClientY = prevClientY = e.clientY; + testingForVerticalDrag = true; + + initValue = this.getValue(); + dragDelta = 0; + + window.addEventListener( 'mousemove', onMouseMove ); + window.addEventListener( 'mouseup', onMouseUp ); + + }; + + const onMouseMove = e => { + + if ( testingForVerticalDrag ) { + + const dx = e.clientX - initClientX; + const dy = e.clientY - initClientY; + + if ( Math.abs( dy ) > DRAG_THRESH ) { + + e.preventDefault(); + this.$input.blur(); + testingForVerticalDrag = false; + this._setDraggingStyle( true, 'vertical' ); + + } else if ( Math.abs( dx ) > DRAG_THRESH ) { + + onMouseUp(); + + } + + } + + // This isn't an else so that the first move counts towards dragDelta + if ( !testingForVerticalDrag ) { + + const dy = e.clientY - prevClientY; + + dragDelta -= dy * this._step * this._arrowKeyMultiplier( e ); + + // Clamp dragDelta so we don't have 'dead space' after dragging past bounds. + // We're okay with the fact that bounds can be undefined here. + if ( initValue + dragDelta > this._max ) { + dragDelta = this._max - initValue; + } else if ( initValue + dragDelta < this._min ) { + dragDelta = this._min - initValue; + } + + this._snapClampSetValue( initValue + dragDelta ); + + } + + prevClientY = e.clientY; + + }; + + const onMouseUp = () => { + this._setDraggingStyle( false, 'vertical' ); + this._callOnFinishChange(); + window.removeEventListener( 'mousemove', onMouseMove ); + window.removeEventListener( 'mouseup', onMouseUp ); + }; + + // Focus state & onFinishChange + // --------------------------------------------------------------------- + + const onFocus = () => { + this._inputFocused = true; + }; + + const onBlur = () => { + this._inputFocused = false; + this.updateDisplay(); + this._callOnFinishChange(); + }; + + this.$input.addEventListener( 'input', onInput ); + this.$input.addEventListener( 'keydown', onKeyDown ); + this.$input.addEventListener( 'wheel', onWheel, { passive: false } ); + this.$input.addEventListener( 'mousedown', onMouseDown ); + this.$input.addEventListener( 'focus', onFocus ); + this.$input.addEventListener( 'blur', onBlur ); + + } + + _initSlider() { + + this._hasSlider = true; + + // Build DOM + // --------------------------------------------------------------------- + + this.$slider = document.createElement( 'div' ); + this.$slider.classList.add( 'slider' ); + + this.$fill = document.createElement( 'div' ); + this.$fill.classList.add( 'fill' ); + + this.$slider.appendChild( this.$fill ); + this.$widget.insertBefore( this.$slider, this.$input ); + + this.domElement.classList.add( 'hasSlider' ); + + // Map clientX to value + // --------------------------------------------------------------------- + + const map = ( v, a, b, c, d ) => { + return ( v - a ) / ( b - a ) * ( d - c ) + c; + }; + + const setValueFromX = clientX => { + const rect = this.$slider.getBoundingClientRect(); + let value = map( clientX, rect.left, rect.right, this._min, this._max ); + this._snapClampSetValue( value ); + }; + + // Mouse drag + // --------------------------------------------------------------------- + + const mouseDown = e => { + this._setDraggingStyle( true ); + setValueFromX( e.clientX ); + window.addEventListener( 'mousemove', mouseMove ); + window.addEventListener( 'mouseup', mouseUp ); + }; + + const mouseMove = e => { + setValueFromX( e.clientX ); + }; + + const mouseUp = () => { + this._callOnFinishChange(); + this._setDraggingStyle( false ); + window.removeEventListener( 'mousemove', mouseMove ); + window.removeEventListener( 'mouseup', mouseUp ); + }; + + // Touch drag + // --------------------------------------------------------------------- + + let testingForScroll = false, prevClientX, prevClientY; + + const beginTouchDrag = e => { + e.preventDefault(); + this._setDraggingStyle( true ); + setValueFromX( e.touches[ 0 ].clientX ); + testingForScroll = false; + }; + + const onTouchStart = e => { + + if ( e.touches.length > 1 ) return; + + // If we're in a scrollable container, we should wait for the first + // touchmove to see if the user is trying to slide or scroll. + if ( this._hasScrollBar ) { + + prevClientX = e.touches[ 0 ].clientX; + prevClientY = e.touches[ 0 ].clientY; + testingForScroll = true; + + } else { + + // Otherwise, we can set the value straight away on touchstart. + beginTouchDrag( e ); + + } + + window.addEventListener( 'touchmove', onTouchMove, { passive: false } ); + window.addEventListener( 'touchend', onTouchEnd ); + + }; + + const onTouchMove = e => { + + if ( testingForScroll ) { + + const dx = e.touches[ 0 ].clientX - prevClientX; + const dy = e.touches[ 0 ].clientY - prevClientY; + + if ( Math.abs( dx ) > Math.abs( dy ) ) { + + // We moved horizontally, set the value and stop checking. + beginTouchDrag( e ); + + } else { + + // This was, in fact, an attempt to scroll. Abort. + window.removeEventListener( 'touchmove', onTouchMove ); + window.removeEventListener( 'touchend', onTouchEnd ); + + } + + } else { + + e.preventDefault(); + setValueFromX( e.touches[ 0 ].clientX ); + + } + + }; + + const onTouchEnd = () => { + this._callOnFinishChange(); + this._setDraggingStyle( false ); + window.removeEventListener( 'touchmove', onTouchMove ); + window.removeEventListener( 'touchend', onTouchEnd ); + }; + + // Mouse wheel + // --------------------------------------------------------------------- + + // We have to use a debounced function to call onFinishChange because + // there's no way to tell when the user is "done" mouse-wheeling. + const callOnFinishChange = this._callOnFinishChange.bind( this ); + const WHEEL_DEBOUNCE_TIME = 400; + let wheelFinishChangeTimeout; + + const onWheel = e => { + + // ignore vertical wheels if there's a scrollbar + const isVertical = Math.abs( e.deltaX ) < Math.abs( e.deltaY ); + if ( isVertical && this._hasScrollBar ) return; + + e.preventDefault(); + + // set value + const delta = this._normalizeMouseWheel( e ) * this._step; + this._snapClampSetValue( this.getValue() + delta ); + + // force the input to updateDisplay when it's focused + this.$input.value = this.getValue(); + + // debounce onFinishChange + clearTimeout( wheelFinishChangeTimeout ); + wheelFinishChangeTimeout = setTimeout( callOnFinishChange, WHEEL_DEBOUNCE_TIME ); + + }; + + this.$slider.addEventListener( 'mousedown', mouseDown ); + this.$slider.addEventListener( 'touchstart', onTouchStart, { passive: false } ); + this.$slider.addEventListener( 'wheel', onWheel, { passive: false } ); + + } + + _setDraggingStyle( active, axis = 'horizontal' ) { + if ( this.$slider ) { + this.$slider.classList.toggle( 'active', active ); + } + document.body.classList.toggle( 'lil-gui-dragging', active ); + document.body.classList.toggle( `lil-gui-${axis}`, active ); + } + + _getImplicitStep() { + + if ( this._hasMin && this._hasMax ) { + return ( this._max - this._min ) / 1000; + } + + return 0.1; + + } + + _onUpdateMinMax() { + + if ( !this._hasSlider && this._hasMin && this._hasMax ) { + + // If this is the first time we're hearing about min and max + // and we haven't explicitly stated what our step is, let's + // update that too. + if ( !this._stepExplicit ) { + this.step( this._getImplicitStep(), false ); + } + + this._initSlider(); + this.updateDisplay(); + + } + + } + + _normalizeMouseWheel( e ) { + + let { deltaX, deltaY } = e; + + // Safari and Chrome report weird non-integral values for a notched wheel, + // but still expose actual lines scrolled via wheelDelta. Notched wheels + // should behave the same way as arrow keys. + if ( Math.floor( e.deltaY ) !== e.deltaY && e.wheelDelta ) { + deltaX = 0; + deltaY = -e.wheelDelta / 120; + deltaY *= this._stepExplicit ? 1 : 10; + } + + const wheel = deltaX + -deltaY; + + return wheel; + + } + + _arrowKeyMultiplier( e ) { + + let mult = this._stepExplicit ? 1 : 10; + + if ( e.shiftKey ) { + mult *= 10; + } else if ( e.altKey ) { + mult /= 10; + } + + return mult; + + } + + _snap( value ) { + + // Make the steps "start" at min or max. + let offset = 0; + if ( this._hasMin ) { + offset = this._min; + } else if ( this._hasMax ) { + offset = this._max; + } + + value -= offset; + + value = Math.round( value / this._step ) * this._step; + + value += offset; + + // Used to prevent "flyaway" decimals like 1.00000000000001 + value = parseFloat( value.toPrecision( 15 ) ); + + return value; + + } + + _clamp( value ) { + // either condition is false if min or max is undefined + if ( value < this._min ) value = this._min; + if ( value > this._max ) value = this._max; + return value; + } + + _snapClampSetValue( value ) { + this.setValue( this._clamp( this._snap( value ) ) ); + } + + get _hasScrollBar() { + const root = this.parent.root.$children; + return root.scrollHeight > root.clientHeight; + } + + get _hasMin() { + return this._min !== undefined; + } + + get _hasMax() { + return this._max !== undefined; + } + +} + +class OptionController extends Controller { + + constructor( parent, object, property, options ) { + + super( parent, object, property, 'option' ); + + this.$select = document.createElement( 'select' ); + this.$select.setAttribute( 'aria-labelledby', this.$name.id ); + + this.$display = document.createElement( 'div' ); + this.$display.classList.add( 'display' ); + + this.$select.addEventListener( 'change', () => { + this.setValue( this._values[ this.$select.selectedIndex ] ); + this._callOnFinishChange(); + } ); + + this.$select.addEventListener( 'focus', () => { + this.$display.classList.add( 'focus' ); + } ); + + this.$select.addEventListener( 'blur', () => { + this.$display.classList.remove( 'focus' ); + } ); + + this.$widget.appendChild( this.$select ); + this.$widget.appendChild( this.$display ); + + this.$disable = this.$select; + + this.options( options ); + + } + + options( options ) { + + this._values = Array.isArray( options ) ? options : Object.values( options ); + this._names = Array.isArray( options ) ? options : Object.keys( options ); + + this.$select.replaceChildren(); + + this._names.forEach( name => { + const $option = document.createElement( 'option' ); + $option.textContent = name; + this.$select.appendChild( $option ); + } ); + + this.updateDisplay(); + + return this; + + } + + updateDisplay() { + const value = this.getValue(); + const index = this._values.indexOf( value ); + this.$select.selectedIndex = index; + this.$display.textContent = index === -1 ? value : this._names[ index ]; + return this; + } + +} + +class StringController extends Controller { + + constructor( parent, object, property ) { + + super( parent, object, property, 'string' ); + + this.$input = document.createElement( 'input' ); + this.$input.setAttribute( 'type', 'text' ); + this.$input.setAttribute( 'spellcheck', 'false' ); + this.$input.setAttribute( 'aria-labelledby', this.$name.id ); + + this.$input.addEventListener( 'input', () => { + this.setValue( this.$input.value ); + } ); + + this.$input.addEventListener( 'keydown', e => { + if ( e.code === 'Enter' ) { + this.$input.blur(); + } + } ); + + this.$input.addEventListener( 'blur', () => { + this._callOnFinishChange(); + } ); + + this.$widget.appendChild( this.$input ); + + this.$disable = this.$input; + + this.updateDisplay(); + + } + + updateDisplay() { + this.$input.value = this.getValue(); + return this; + } + +} + +var stylesheet = `.lil-gui { + font-family: var(--font-family); + font-size: var(--font-size); + line-height: 1; + font-weight: normal; + font-style: normal; + text-align: left; + color: var(--text-color); + user-select: none; + -webkit-user-select: none; + touch-action: manipulation; + --background-color: #1f1f1f; + --text-color: #ebebeb; + --title-background-color: #111111; + --title-text-color: #ebebeb; + --widget-color: #424242; + --hover-color: #4f4f4f; + --focus-color: #595959; + --number-color: #2cc9ff; + --string-color: #a2db3c; + --font-size: 11px; + --input-font-size: 11px; + --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; + --font-family-mono: Menlo, Monaco, Consolas, "Droid Sans Mono", monospace; + --padding: 4px; + --spacing: 4px; + --widget-height: 20px; + --title-height: calc(var(--widget-height) + var(--spacing) * 1.25); + --name-width: 45%; + --slider-knob-width: 2px; + --slider-input-width: 27%; + --color-input-width: 27%; + --slider-input-min-width: 45px; + --color-input-min-width: 45px; + --folder-indent: 7px; + --widget-padding: 0 0 0 3px; + --widget-border-radius: 2px; + --checkbox-size: calc(0.75 * var(--widget-height)); + --scrollbar-width: 5px; +} +.lil-gui, .lil-gui * { + box-sizing: border-box; + margin: 0; + padding: 0; +} +.lil-gui.root { + width: var(--width, 245px); + display: flex; + flex-direction: column; + background: var(--background-color); +} +.lil-gui.root > .title { + background: var(--title-background-color); + color: var(--title-text-color); +} +.lil-gui.root > .children { + overflow-x: hidden; + overflow-y: auto; +} +.lil-gui.root > .children::-webkit-scrollbar { + width: var(--scrollbar-width); + height: var(--scrollbar-width); + background: var(--background-color); +} +.lil-gui.root > .children::-webkit-scrollbar-thumb { + border-radius: var(--scrollbar-width); + background: var(--focus-color); +} +@media (pointer: coarse) { + .lil-gui.allow-touch-styles, .lil-gui.allow-touch-styles .lil-gui { + --widget-height: 28px; + --padding: 6px; + --spacing: 6px; + --font-size: 13px; + --input-font-size: 16px; + --folder-indent: 10px; + --scrollbar-width: 7px; + --slider-input-min-width: 50px; + --color-input-min-width: 65px; + } +} +.lil-gui.force-touch-styles, .lil-gui.force-touch-styles .lil-gui { + --widget-height: 28px; + --padding: 6px; + --spacing: 6px; + --font-size: 13px; + --input-font-size: 16px; + --folder-indent: 10px; + --scrollbar-width: 7px; + --slider-input-min-width: 50px; + --color-input-min-width: 65px; +} +.lil-gui.autoPlace { + max-height: 100%; + position: fixed; + top: 0; + right: 15px; + z-index: 1001; +} + +.lil-gui .controller { + display: flex; + align-items: center; + padding: 0 var(--padding); + margin: var(--spacing) 0; +} +.lil-gui .controller.disabled { + opacity: 0.5; +} +.lil-gui .controller.disabled, .lil-gui .controller.disabled * { + pointer-events: none !important; +} +.lil-gui .controller > .name { + min-width: var(--name-width); + flex-shrink: 0; + white-space: pre; + padding-right: var(--spacing); + line-height: var(--widget-height); +} +.lil-gui .controller .widget { + position: relative; + display: flex; + align-items: center; + width: 100%; + min-height: var(--widget-height); +} +.lil-gui .controller.string input { + color: var(--string-color); +} +.lil-gui .controller.boolean { + cursor: pointer; +} +.lil-gui .controller.color .display { + width: 100%; + height: var(--widget-height); + border-radius: var(--widget-border-radius); + position: relative; +} +@media (hover: hover) { + .lil-gui .controller.color .display:hover:before { + content: " "; + display: block; + position: absolute; + border-radius: var(--widget-border-radius); + border: 1px solid #fff9; + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} +.lil-gui .controller.color input[type=color] { + opacity: 0; + width: 100%; + height: 100%; + cursor: pointer; +} +.lil-gui .controller.color input[type=text] { + margin-left: var(--spacing); + font-family: var(--font-family-mono); + min-width: var(--color-input-min-width); + width: var(--color-input-width); + flex-shrink: 0; +} +.lil-gui .controller.option select { + opacity: 0; + position: absolute; + width: 100%; + max-width: 100%; +} +.lil-gui .controller.option .display { + position: relative; + pointer-events: none; + border-radius: var(--widget-border-radius); + height: var(--widget-height); + line-height: var(--widget-height); + max-width: 100%; + overflow: hidden; + word-break: break-all; + padding-left: 0.55em; + padding-right: 1.75em; + background: var(--widget-color); +} +@media (hover: hover) { + .lil-gui .controller.option .display.focus { + background: var(--focus-color); + } +} +.lil-gui .controller.option .display.active { + background: var(--focus-color); +} +.lil-gui .controller.option .display:after { + font-family: "lil-gui"; + content: "↕"; + position: absolute; + top: 0; + right: 0; + bottom: 0; + padding-right: 0.375em; +} +.lil-gui .controller.option .widget, +.lil-gui .controller.option select { + cursor: pointer; +} +@media (hover: hover) { + .lil-gui .controller.option .widget:hover .display { + background: var(--hover-color); + } +} +.lil-gui .controller.number input { + color: var(--number-color); +} +.lil-gui .controller.number.hasSlider input { + margin-left: var(--spacing); + width: var(--slider-input-width); + min-width: var(--slider-input-min-width); + flex-shrink: 0; +} +.lil-gui .controller.number .slider { + width: 100%; + height: var(--widget-height); + background: var(--widget-color); + border-radius: var(--widget-border-radius); + padding-right: var(--slider-knob-width); + overflow: hidden; + cursor: ew-resize; + touch-action: pan-y; +} +@media (hover: hover) { + .lil-gui .controller.number .slider:hover { + background: var(--hover-color); + } +} +.lil-gui .controller.number .slider.active { + background: var(--focus-color); +} +.lil-gui .controller.number .slider.active .fill { + opacity: 0.95; +} +.lil-gui .controller.number .fill { + height: 100%; + border-right: var(--slider-knob-width) solid var(--number-color); + box-sizing: content-box; +} + +.lil-gui-dragging .lil-gui { + --hover-color: var(--widget-color); +} +.lil-gui-dragging * { + cursor: ew-resize !important; +} + +.lil-gui-dragging.lil-gui-vertical * { + cursor: ns-resize !important; +} + +.lil-gui .title { + height: var(--title-height); + font-weight: 600; + padding: 0 var(--padding); + width: 100%; + text-align: left; + background: none; + text-decoration-skip: objects; +} +.lil-gui .title:before { + font-family: "lil-gui"; + content: "▾"; + padding-right: 2px; + display: inline-block; +} +.lil-gui .title:active { + background: var(--title-background-color); + opacity: 0.75; +} +@media (hover: hover) { + body:not(.lil-gui-dragging) .lil-gui .title:hover { + background: var(--title-background-color); + opacity: 0.85; + } + .lil-gui .title:focus { + text-decoration: underline var(--focus-color); + } +} +.lil-gui.root > .title:focus { + text-decoration: none !important; +} +.lil-gui.closed > .title:before { + content: "▸"; +} +.lil-gui.closed > .children { + transform: translateY(-7px); + opacity: 0; +} +.lil-gui.closed:not(.transition) > .children { + display: none; +} +.lil-gui.transition > .children { + transition-duration: 300ms; + transition-property: height, opacity, transform; + transition-timing-function: cubic-bezier(0.2, 0.6, 0.35, 1); + overflow: hidden; + pointer-events: none; +} +.lil-gui .children:empty:before { + content: "Empty"; + padding: 0 var(--padding); + margin: var(--spacing) 0; + display: block; + height: var(--widget-height); + font-style: italic; + line-height: var(--widget-height); + opacity: 0.5; +} +.lil-gui.root > .children > .lil-gui > .title { + border: 0 solid var(--widget-color); + border-width: 1px 0; + transition: border-color 300ms; +} +.lil-gui.root > .children > .lil-gui.closed > .title { + border-bottom-color: transparent; +} +.lil-gui + .controller { + border-top: 1px solid var(--widget-color); + margin-top: 0; + padding-top: var(--spacing); +} +.lil-gui .lil-gui .lil-gui > .title { + border: none; +} +.lil-gui .lil-gui .lil-gui > .children { + border: none; + margin-left: var(--folder-indent); + border-left: 2px solid var(--widget-color); +} +.lil-gui .lil-gui .controller { + border: none; +} + +.lil-gui label, .lil-gui input, .lil-gui button { + -webkit-tap-highlight-color: transparent; +} +.lil-gui input { + border: 0; + outline: none; + font-family: var(--font-family); + font-size: var(--input-font-size); + border-radius: var(--widget-border-radius); + height: var(--widget-height); + background: var(--widget-color); + color: var(--text-color); + width: 100%; +} +@media (hover: hover) { + .lil-gui input:hover { + background: var(--hover-color); + } + .lil-gui input:active { + background: var(--focus-color); + } +} +.lil-gui input:disabled { + opacity: 1; +} +.lil-gui input[type=text], +.lil-gui input[type=number] { + padding: var(--widget-padding); + -moz-appearance: textfield; +} +.lil-gui input[type=text]:focus, +.lil-gui input[type=number]:focus { + background: var(--focus-color); +} +.lil-gui input[type=checkbox] { + appearance: none; + width: var(--checkbox-size); + height: var(--checkbox-size); + border-radius: var(--widget-border-radius); + text-align: center; + cursor: pointer; +} +.lil-gui input[type=checkbox]:checked:before { + font-family: "lil-gui"; + content: "✓"; + font-size: var(--checkbox-size); + line-height: var(--checkbox-size); +} +@media (hover: hover) { + .lil-gui input[type=checkbox]:focus { + box-shadow: inset 0 0 0 1px var(--focus-color); + } +} +.lil-gui button { + outline: none; + cursor: pointer; + font-family: var(--font-family); + font-size: var(--font-size); + color: var(--text-color); + width: 100%; + border: none; +} +.lil-gui .controller button { + height: var(--widget-height); + text-transform: none; + background: var(--widget-color); + border-radius: var(--widget-border-radius); +} +@media (hover: hover) { + .lil-gui .controller button:hover { + background: var(--hover-color); + } + .lil-gui .controller button:focus { + box-shadow: inset 0 0 0 1px var(--focus-color); + } +} +.lil-gui .controller button:active { + background: var(--focus-color); +} + +@font-face { + font-family: "lil-gui"; + src: url("data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAUsAAsAAAAACJwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAAH4AAADAImwmYE9TLzIAAAGIAAAAPwAAAGBKqH5SY21hcAAAAcgAAAD0AAACrukyyJBnbHlmAAACvAAAAF8AAACEIZpWH2hlYWQAAAMcAAAAJwAAADZfcj2zaGhlYQAAA0QAAAAYAAAAJAC5AHhobXR4AAADXAAAABAAAABMAZAAAGxvY2EAAANsAAAAFAAAACgCEgIybWF4cAAAA4AAAAAeAAAAIAEfABJuYW1lAAADoAAAASIAAAIK9SUU/XBvc3QAAATEAAAAZgAAAJCTcMc2eJxVjbEOgjAURU+hFRBK1dGRL+ALnAiToyMLEzFpnPz/eAshwSa97517c/MwwJmeB9kwPl+0cf5+uGPZXsqPu4nvZabcSZldZ6kfyWnomFY/eScKqZNWupKJO6kXN3K9uCVoL7iInPr1X5baXs3tjuMqCtzEuagm/AAlzQgPAAB4nGNgYRBlnMDAysDAYM/gBiT5oLQBAwuDJAMDEwMrMwNWEJDmmsJwgCFeXZghBcjlZMgFCzOiKOIFAB71Bb8AeJy1kjFuwkAQRZ+DwRAwBtNQRUGKQ8OdKCAWUhAgKLhIuAsVSpWz5Bbkj3dEgYiUIszqWdpZe+Z7/wB1oCYmIoboiwiLT2WjKl/jscrHfGg/pKdMkyklC5Zs2LEfHYpjcRoPzme9MWWmk3dWbK9ObkWkikOetJ554fWyoEsmdSlt+uR0pCJR34b6t/TVg1SY3sYvdf8vuiKrpyaDXDISiegp17p7579Gp3p++y7HPAiY9pmTibljrr85qSidtlg4+l25GLCaS8e6rRxNBmsnERunKbaOObRz7N72ju5vdAjYpBXHgJylOAVsMseDAPEP8LYoUHicY2BiAAEfhiAGJgZWBgZ7RnFRdnVJELCQlBSRlATJMoLV2DK4glSYs6ubq5vbKrJLSbGrgEmovDuDJVhe3VzcXFwNLCOILB/C4IuQ1xTn5FPilBTj5FPmBAB4WwoqAHicY2BkYGAA4sk1sR/j+W2+MnAzpDBgAyEMQUCSg4EJxAEAwUgFHgB4nGNgZGBgSGFggJMhDIwMqEAYAByHATJ4nGNgAIIUNEwmAABl3AGReJxjYAACIQYlBiMGJ3wQAEcQBEV4nGNgZGBgEGZgY2BiAAEQyQWEDAz/wXwGAAsPATIAAHicXdBNSsNAHAXwl35iA0UQXYnMShfS9GPZA7T7LgIu03SSpkwzYTIt1BN4Ak/gKTyAeCxfw39jZkjymzcvAwmAW/wgwHUEGDb36+jQQ3GXGot79L24jxCP4gHzF/EIr4jEIe7wxhOC3g2TMYy4Q7+Lu/SHuEd/ivt4wJd4wPxbPEKMX3GI5+DJFGaSn4qNzk8mcbKSR6xdXdhSzaOZJGtdapd4vVPbi6rP+cL7TGXOHtXKll4bY1Xl7EGnPtp7Xy2n00zyKLVHfkHBa4IcJ2oD3cgggWvt/V/FbDrUlEUJhTn/0azVWbNTNr0Ens8de1tceK9xZmfB1CPjOmPH4kitmvOubcNpmVTN3oFJyjzCvnmrwhJTzqzVj9jiSX911FjeAAB4nG3HMRKCMBBA0f0giiKi4DU8k0V2GWbIZDOh4PoWWvq6J5V8If9NVNQcaDhyouXMhY4rPTcG7jwYmXhKq8Wz+p762aNaeYXom2n3m2dLTVgsrCgFJ7OTmIkYbwIbC6vIB7WmFfAAAA==") format("woff"); +}`; + +function _injectStyles( cssContent ) { + const injected = document.createElement( 'style' ); + injected.innerHTML = cssContent; + const before = document.querySelector( 'head link[rel=stylesheet], head style' ); + if ( before ) { + document.head.insertBefore( injected, before ); + } else { + document.head.appendChild( injected ); + } +} + +/** @module GUI */ + + +let stylesInjected = false; + +class GUI { + + /** + * Creates a panel that holds controllers. + * @example + * new GUI(); + * new GUI( { container: document.getElementById( 'custom' ) } ); + * + * @param {object} [options] + * @param {boolean} [options.autoPlace=true] + * Adds the GUI to `document.body` and fixes it to the top right of the page. + * + * @param {HTMLElement} [options.container] + * Adds the GUI to this DOM element. Overrides `autoPlace`. + * + * @param {number} [options.width=245] + * Width of the GUI in pixels, usually set when name labels become too long. Note that you can make + * name labels wider in CSS with `.lil‑gui { ‑‑name‑width: 55% }`. + * + * @param {string} [options.title=Controls] + * Name to display in the title bar. + * + * @param {boolean} [options.closeFolders=false] + * Pass `true` to close all folders in this GUI by default. + * + * @param {boolean} [options.injectStyles=true] + * Injects the default stylesheet into the page if this is the first GUI. + * Pass `false` to use your own stylesheet. + * + * @param {number} [options.touchStyles=true] + * Makes controllers larger on touch devices. Pass `false` to disable touch styles. + * + * @param {GUI} [options.parent] + * Adds this GUI as a child in another GUI. Usually this is done for you by `addFolder()`. + */ + constructor( { + parent, + autoPlace = parent === undefined, + container, + width, + title = 'Controls', + closeFolders = false, + injectStyles = true, + touchStyles = true + } = {} ) { + + /** + * The GUI containing this folder, or `undefined` if this is the root GUI. + * @type {GUI} + */ + this.parent = parent; + + /** + * The top level GUI containing this folder, or `this` if this is the root GUI. + * @type {GUI} + */ + this.root = parent ? parent.root : this; + + /** + * The list of controllers and folders contained by this GUI. + * @type {Array} + */ + this.children = []; + + /** + * The list of controllers contained by this GUI. + * @type {Array} + */ + this.controllers = []; + + /** + * The list of folders contained by this GUI. + * @type {Array} + */ + this.folders = []; + + /** + * Used to determine if the GUI is closed. Use `gui.open()` or `gui.close()` to change this. + * @type {boolean} + */ + this._closed = false; + + /** + * Used to determine if the GUI is hidden. Use `gui.show()` or `gui.hide()` to change this. + * @type {boolean} + */ + this._hidden = false; + + /** + * The outermost container element. + * @type {HTMLElement} + */ + this.domElement = document.createElement( 'div' ); + this.domElement.classList.add( 'lil-gui' ); + + /** + * The DOM element that contains the title. + * @type {HTMLElement} + */ + this.$title = document.createElement( 'button' ); + this.$title.classList.add( 'title' ); + this.$title.setAttribute( 'aria-expanded', true ); + + this.$title.addEventListener( 'click', () => this.openAnimated( this._closed ) ); + + // enables :active pseudo class on mobile + this.$title.addEventListener( 'touchstart', () => {}, { passive: true } ); + + /** + * The DOM element that contains children. + * @type {HTMLElement} + */ + this.$children = document.createElement( 'div' ); + this.$children.classList.add( 'children' ); + + this.domElement.appendChild( this.$title ); + this.domElement.appendChild( this.$children ); + + this.title( title ); + + if ( this.parent ) { + + this.parent.children.push( this ); + this.parent.folders.push( this ); + + this.parent.$children.appendChild( this.domElement ); + + // Stop the constructor early, everything onward only applies to root GUI's + return; + + } + + this.domElement.classList.add( 'root' ); + + if ( touchStyles ) { + this.domElement.classList.add( 'allow-touch-styles' ); + } + + // Inject stylesheet if we haven't done that yet + if ( !stylesInjected && injectStyles ) { + _injectStyles( stylesheet ); + stylesInjected = true; + } + + if ( container ) { + + container.appendChild( this.domElement ); + + } else if ( autoPlace ) { + + this.domElement.classList.add( 'autoPlace' ); + document.body.appendChild( this.domElement ); + + } + + if ( width ) { + this.domElement.style.setProperty( '--width', width + 'px' ); + } + + this._closeFolders = closeFolders; + + } + + /** + * Adds a controller to the GUI, inferring controller type using the `typeof` operator. + * @example + * gui.add( object, 'property' ); + * gui.add( object, 'number', 0, 100, 1 ); + * gui.add( object, 'options', [ 1, 2, 3 ] ); + * + * @param {object} object The object the controller will modify. + * @param {string} property Name of the property to control. + * @param {number|object|Array} [$1] Minimum value for number controllers, or the set of + * selectable values for a dropdown. + * @param {number} [max] Maximum value for number controllers. + * @param {number} [step] Step value for number controllers. + * @returns {Controller} + */ + add( object, property, $1, max, step ) { + + if ( Object( $1 ) === $1 ) { + + return new OptionController( this, object, property, $1 ); + + } + + const initialValue = object[ property ]; + + switch ( typeof initialValue ) { + + case 'number': + + return new NumberController( this, object, property, $1, max, step ); + + case 'boolean': + + return new BooleanController( this, object, property ); + + case 'string': + + return new StringController( this, object, property ); + + case 'function': + + return new FunctionController( this, object, property ); + + } + + // eslint-disable-next-line no-console + console.error( `gui.add failed + property:`, property, ` + object:`, object, ` + value:`, initialValue ); + + } + + /** + * Adds a color controller to the GUI. + * @example + * params = { + * cssColor: '#ff00ff', + * rgbColor: { r: 0, g: 0.2, b: 0.4 }, + * customRange: [ 0, 127, 255 ], + * }; + * + * gui.addColor( params, 'cssColor' ); + * gui.addColor( params, 'rgbColor' ); + * gui.addColor( params, 'customRange', 255 ); + * + * @param {object} object The object the controller will modify. + * @param {string} property Name of the property to control. + * @param {number} rgbScale Maximum value for a color channel when using an RGB color. You may + * need to set this to 255 if your colors are too bright. + * @returns {Controller} + */ + addColor( object, property, rgbScale = 1 ) { + return new ColorController( this, object, property, rgbScale ); + } + + /** + * Adds a folder to the GUI, which is just another GUI. This method returns + * the nested GUI so you can add controllers to it. + * @example + * const folder = gui.addFolder( 'Position' ); + * folder.add( position, 'x' ); + * folder.add( position, 'y' ); + * folder.add( position, 'z' ); + * + * @param {string} title Name to display in the folder's title bar. + * @returns {GUI} + */ + addFolder( title ) { + const folder = new GUI( { parent: this, title } ); + if ( this.root._closeFolders ) folder.close(); + return folder; + } + + /** + * Recalls values that were saved with `gui.save()`. + * @param {object} obj + * @param {boolean} recursive Pass false to exclude folders descending from this GUI. + * @returns {this} + */ + load( obj, recursive = true ) { + + if ( obj.controllers ) { + + this.controllers.forEach( c => { + + if ( c instanceof FunctionController ) return; + + if ( c._name in obj.controllers ) { + c.load( obj.controllers[ c._name ] ); + } + + } ); + + } + + if ( recursive && obj.folders ) { + + this.folders.forEach( f => { + + if ( f._title in obj.folders ) { + f.load( obj.folders[ f._title ] ); + } + + } ); + + } + + return this; + + } + + /** + * Returns an object mapping controller names to values. The object can be passed to `gui.load()` to + * recall these values. + * @example + * { + * controllers: { + * prop1: 1, + * prop2: 'value', + * ... + * }, + * folders: { + * folderName1: { controllers, folders }, + * folderName2: { controllers, folders } + * ... + * } + * } + * + * @param {boolean} recursive Pass false to exclude folders descending from this GUI. + * @returns {object} + */ + save( recursive = true ) { + + const obj = { + controllers: {}, + folders: {} + }; + + this.controllers.forEach( c => { + + if ( c instanceof FunctionController ) return; + + if ( c._name in obj.controllers ) { + throw new Error( `Cannot save GUI with duplicate property "${c._name}"` ); + } + + obj.controllers[ c._name ] = c.save(); + + } ); + + if ( recursive ) { + + this.folders.forEach( f => { + + if ( f._title in obj.folders ) { + throw new Error( `Cannot save GUI with duplicate folder "${f._title}"` ); + } + + obj.folders[ f._title ] = f.save(); + + } ); + + } + + return obj; + + } + + /** + * Opens a GUI or folder. GUI and folders are open by default. + * @param {boolean} open Pass false to close. + * @returns {this} + * @example + * gui.open(); // open + * gui.open( false ); // close + * gui.open( gui._closed ); // toggle + */ + open( open = true ) { + + this._setClosed( !open ); + + this.$title.setAttribute( 'aria-expanded', !this._closed ); + this.domElement.classList.toggle( 'closed', this._closed ); + + return this; + + } + + /** + * Closes the GUI. + * @returns {this} + */ + close() { + return this.open( false ); + } + + _setClosed( closed ) { + if ( this._closed === closed ) return; + this._closed = closed; + this._callOnOpenClose( this ); + } + + /** + * Shows the GUI after it's been hidden. + * @param {boolean} show + * @returns {this} + * @example + * gui.show(); + * gui.show( false ); // hide + * gui.show( gui._hidden ); // toggle + */ + show( show = true ) { + + this._hidden = !show; + + this.domElement.style.display = this._hidden ? 'none' : ''; + + return this; + + } + + /** + * Hides the GUI. + * @returns {this} + */ + hide() { + return this.show( false ); + } + + openAnimated( open = true ) { + + // set state immediately + this._setClosed( !open ); + + this.$title.setAttribute( 'aria-expanded', !this._closed ); + + // wait for next frame to measure $children + requestAnimationFrame( () => { + + // explicitly set initial height for transition + const initialHeight = this.$children.clientHeight; + this.$children.style.height = initialHeight + 'px'; + + this.domElement.classList.add( 'transition' ); + + const onTransitionEnd = e => { + if ( e.target !== this.$children ) return; + this.$children.style.height = ''; + this.domElement.classList.remove( 'transition' ); + this.$children.removeEventListener( 'transitionend', onTransitionEnd ); + }; + + this.$children.addEventListener( 'transitionend', onTransitionEnd ); + + // todo: this is wrong if children's scrollHeight makes for a gui taller than maxHeight + const targetHeight = !open ? 0 : this.$children.scrollHeight; + + this.domElement.classList.toggle( 'closed', !open ); + + requestAnimationFrame( () => { + this.$children.style.height = targetHeight + 'px'; + } ); + + } ); + + return this; + + } + + /** + * Change the title of this GUI. + * @param {string} title + * @returns {this} + */ + title( title ) { + /** + * Current title of the GUI. Use `gui.title( 'Title' )` to modify this value. + * @type {string} + */ + this._title = title; + this.$title.textContent = title; + return this; + } + + /** + * Resets all controllers to their initial values. + * @param {boolean} recursive Pass false to exclude folders descending from this GUI. + * @returns {this} + */ + reset( recursive = true ) { + const controllers = recursive ? this.controllersRecursive() : this.controllers; + controllers.forEach( c => c.reset() ); + return this; + } + + /** + * Pass a function to be called whenever a controller in this GUI changes. + * @param {function({object:object, property:string, value:any, controller:Controller})} callback + * @returns {this} + * @example + * gui.onChange( event => { + * event.object // object that was modified + * event.property // string, name of property + * event.value // new value of controller + * event.controller // controller that was modified + * } ); + */ + onChange( callback ) { + /** + * Used to access the function bound to `onChange` events. Don't modify this value + * directly. Use the `gui.onChange( callback )` method instead. + * @type {Function} + */ + this._onChange = callback; + return this; + } + + _callOnChange( controller ) { + + if ( this.parent ) { + this.parent._callOnChange( controller ); + } + + if ( this._onChange !== undefined ) { + this._onChange.call( this, { + object: controller.object, + property: controller.property, + value: controller.getValue(), + controller + } ); + } + } + + /** + * Pass a function to be called whenever a controller in this GUI has finished changing. + * @param {function({object:object, property:string, value:any, controller:Controller})} callback + * @returns {this} + * @example + * gui.onFinishChange( event => { + * event.object // object that was modified + * event.property // string, name of property + * event.value // new value of controller + * event.controller // controller that was modified + * } ); + */ + onFinishChange( callback ) { + /** + * Used to access the function bound to `onFinishChange` events. Don't modify this value + * directly. Use the `gui.onFinishChange( callback )` method instead. + * @type {Function} + */ + this._onFinishChange = callback; + return this; + } + + _callOnFinishChange( controller ) { + + if ( this.parent ) { + this.parent._callOnFinishChange( controller ); + } + + if ( this._onFinishChange !== undefined ) { + this._onFinishChange.call( this, { + object: controller.object, + property: controller.property, + value: controller.getValue(), + controller + } ); + } + } + + /** + * Pass a function to be called when this GUI or its descendants are opened or closed. + * @param {function(GUI)} callback + * @returns {this} + * @example + * gui.onOpenClose( changedGUI => { + * console.log( changedGUI._closed ); + * } ); + */ + onOpenClose( callback ) { + this._onOpenClose = callback; + return this; + } + + _callOnOpenClose( changedGUI ) { + if ( this.parent ) { + this.parent._callOnOpenClose( changedGUI ); + } + + if ( this._onOpenClose !== undefined ) { + this._onOpenClose.call( this, changedGUI ); + } + } + + /** + * Destroys all DOM elements and event listeners associated with this GUI. + */ + destroy() { + + if ( this.parent ) { + this.parent.children.splice( this.parent.children.indexOf( this ), 1 ); + this.parent.folders.splice( this.parent.folders.indexOf( this ), 1 ); + } + + if ( this.domElement.parentElement ) { + this.domElement.parentElement.removeChild( this.domElement ); + } + + Array.from( this.children ).forEach( c => c.destroy() ); + + } + + /** + * Returns an array of controllers contained by this GUI and its descendents. + * @returns {Controller[]} + */ + controllersRecursive() { + let controllers = Array.from( this.controllers ); + this.folders.forEach( f => { + controllers = controllers.concat( f.controllersRecursive() ); + } ); + return controllers; + } + + /** + * Returns an array of folders contained by this GUI and its descendents. + * @returns {GUI[]} + */ + foldersRecursive() { + let folders = Array.from( this.folders ); + this.folders.forEach( f => { + folders = folders.concat( f.foldersRecursive() ); + } ); + return folders; + } + +} + +export { BooleanController, ColorController, Controller, FunctionController, GUI, NumberController, OptionController, StringController, GUI as default }; diff --git a/js/lib/uil.module.js b/js/lib/uil.module.js deleted file mode 100644 index 769f7c1..0000000 --- a/js/lib/uil.module.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @license - * Copyright 2010-2021 Uil.js Authors - * SPDX-License-Identifier: MIT - */ -const t="4.3.0",s={ui:[],dom:null,ID:null,lock:!1,wlock:!1,current:-1,needReZone:!0,needResize:!1,forceZone:!1,isEventsInit:!1,isLeave:!1,downTime:0,prevTime:0,prevDefault:["contextmenu"],pointerEvent:["pointerdown","pointermove","pointerup"],eventOut:["pointercancel","pointerout","pointerleave"],xmlserializer:null,tmpTime:null,tmpImage:null,oldCursor:"auto",input:null,parent:null,firstImput:!0,hiddenImput:null,hiddenSizer:null,hasFocus:!1,startInput:!1,inputRange:[0,0],cursorId:0,str:"",pos:0,startX:-1,moveX:-1,debugInput:!1,isLoop:!1,listens:[],e:{type:null,clientX:0,clientY:0,keyCode:NaN,key:null,delta:0},isMobile:!1,now:null,getTime:function(){return self.performance&&self.performance.now?self.performance.now.bind(performance):Date.now},add:function(t){s.ui.push(t),s.getZone(t),s.isEventsInit||s.initEvents()},testMobile:function(){let t=navigator.userAgent;return!!(t.match(/Android/i)||t.match(/webOS/i)||t.match(/iPhone/i)||t.match(/iPad/i)||t.match(/iPod/i)||t.match(/BlackBerry/i)||t.match(/Windows Phone/i))},remove:function(t){let i=s.ui.indexOf(t);-1!==i&&(s.removeListen(t),s.ui.splice(i,1)),0===s.ui.length&&s.removeEvents()},initEvents:function(){if(s.isEventsInit)return;let t=document.body;s.isMobile=s.testMobile(),s.now=s.getTime(),s.isMobile?t.style.touchAction="none":t.addEventListener("wheel",s,{passive:!1}),t.addEventListener("pointercancel",s),t.addEventListener("pointerleave",s),t.addEventListener("pointermove",s),t.addEventListener("pointerdown",s),t.addEventListener("pointerup",s),t.addEventListener("keydown",s,!1),t.addEventListener("keyup",s,!1),window.addEventListener("resize",s.resize,!1),s.isEventsInit=!0,s.dom=t},removeEvents:function(){if(!s.isEventsInit)return;let t=document.body;s.isMobile||t.removeEventListener("wheel",s),t.removeEventListener("pointercancel",s),t.removeEventListener("pointerleave",s),t.removeEventListener("pointermove",s),t.removeEventListener("pointerdown",s),t.removeEventListener("pointerup",s),t.removeEventListener("keydown",s),t.removeEventListener("keyup",s),window.removeEventListener("resize",s.resize),s.isEventsInit=!1},resize:function(){let t,i=s.ui.length;for(;i--;)t=s.ui[i],t.isGui&&!t.isCanvasOnly&&t.autoResize&&t.calc();s.needReZone=!0,s.needResize=!1},out:function(){console.log("im am out"),s.clearOldID()},in:function(){console.log("im am in")},fakeUp:function(){this.handleEvent({type:"pointerup"})},handleEvent:function(t){-1!==s.prevDefault.indexOf(t.type)&&t.preventDefault(),s.needResize&&s.resize(),s.findZone(s.forceZone);let i=s.e,e=!1;"keydown"===t.type&&s.keydown(t),"keyup"===t.type&&s.keyup(t),"wheel"===t.type?i.delta=t.deltaY>0?1:-1:i.delta=0;let h=t.pointerType;if(i.clientX=("touch"===h?t.pageX:t.clientX)||0,i.clientY=("touch"===h?t.pageY:t.clientY)||0,i.type=t.type,-1!==s.eventOut.indexOf(t.type)&&(e=!0,i.type="mouseup"),"pointerleave"===t.type&&(s.isLeave=!0),"pointerdown"===t.type&&(i.type="mousedown"),"pointerup"===t.type&&(i.type="mouseup"),"pointermove"===t.type&&(s.isLeave&&(s.isLeave=!1,s.resize()),i.type="mousemove"),"mousedown"===i.type){if(s.downTime=s.now(),s.downTime-s.prevTime<200)return s.selectAll(),!1;s.prevTime=s.downTime,s.forceZone=!1}"mousedown"===i.type&&s.clearInput(),"mousedown"===i.type&&(s.lock=!0),"mouseup"===i.type&&(s.lock=!1),s.isMobile&&"mousedown"===i.type&&s.findID(i),"mousemove"!==i.type||s.lock||s.findID(i),null!==s.ID&&(s.ID.isCanvasOnly&&(i.clientX=s.ID.mouse.x,i.clientY=s.ID.mouse.y),s.ID.handleEvent(i)),s.isMobile&&"mouseup"===i.type&&s.clearOldID(),e&&s.clearOldID()},findID:function(t){let i,e,h,o=s.ui.length,n=-1;for(;o--;)if(i=s.ui[o],i.isCanvasOnly?(e=i.mouse.x,h=i.mouse.y):(e=t.clientX,h=t.clientY),s.onZone(i,e,h)){n=o,n!==s.current&&(s.clearOldID(),s.current=n,s.ID=i);break}-1===n&&s.clearOldID()},clearOldID:function(){s.ID&&(s.current=-1,s.ID.reset(),s.ID=null,s.cursor())},calcUis:(t,i,e,h=!1)=>{let o,n,r=t.length,l=0,a=0,c=0;for(;r--;){o=t[a],a++,!h&&o.isGroup&&o.calcUis();let r=o.margin||0;o.zone.w=o.w,o.zone.h=o.h+r,o.autoWidth?(l=0,o.zone.x=i.x+o.dx,o.zone.y=e,e+=o.h+r,c+=o.h+r):(0===l&&(c+=o.h+r),o.zone.x=i.x+l,o.zone.y=e,n=s.getWidth(o),n?o.zone.w=o.w=n:o.fw&&(o.zone.w=o.w=o.fw),l+=o.zone.w,l>=i.w&&(e+=o.h+r,l=0))}return c},findTarget:function(t,i){let e=t.length;for(;e--;)if(s.onZone(t[e],i.clientX,i.clientY))return e;return-1},findZone:function(t){if(s.needReZone||t){for(var i,e=s.ui.length;e--;)i=s.ui[e],s.getZone(i),i.isGui&&i.calcUis();s.needReZone=!1}},onZone:function(t,s,i){if(void 0===s||void 0===i)return!1;let e=t.zone,h=s-e.x,o=i-e.y,n=h>=0&&o>=0&&h<=e.w&&o<=e.h;return n?t.local.set(h,o):t.local.neg(),n},getWidth:function(t){return t.getDom().clientWidth},getZone:function(t){if(t.isCanvasOnly)return;let s=t.getDom().getBoundingClientRect();t.zone={x:s.left,y:s.top,w:s.width,h:s.height}},cursor:function(t){(t=t||"auto")!==s.oldCursor&&(document.body.style.cursor=t,s.oldCursor=t)},toCanvas:function(t,i,e,h){if(s.xmlserializer||(s.xmlserializer=new XMLSerializer),h&&null!==s.tmpTime&&(clearTimeout(s.tmpTime),s.tmpTime=null),null!==s.tmpTime)return;s.lock&&(s.tmpTime=setTimeout((function(){s.tmpTime=null}),10));let o=!1;i===t.canvas.width&&e===t.canvas.height||(o=!0),null===s.tmpImage&&(s.tmpImage=new Image);let n=s.tmpImage,r=s.xmlserializer.serializeToString(t.content),l=''+r+"";n.onload=function(){let s=t.canvas.getContext("2d");o?(t.canvas.width=i,t.canvas.height=e):s.clearRect(0,0,i,e),s.drawImage(this,0,0),t.onDraw()},n.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(l),n.crossOrigin=""},setHidden:function(){null===s.hiddenImput&&(s.hiddenImput=document.createElement("input"),s.hiddenImput.type="text",s.hiddenSizer=document.createElement("div"),document.body.appendChild(s.hiddenImput),document.body.appendChild(s.hiddenSizer));let t=s.debugInput?"":"opacity:0; zIndex:0;",i=s.parent.css.txtselect+"padding:0; width:auto; height:auto; left:10px; top:auto; color:#FFF; background:#000;"+t;s.hiddenImput.style.cssText=i+"bottom:10px;"+(s.debugInput?"":"transform:scale(0);"),s.hiddenSizer.style.cssText=i+"bottom:40px;",s.hiddenImput.style.width=s.input.clientWidth+"px",s.hiddenImput.value=s.str,s.hiddenSizer.innerHTML=s.str,s.hasFocus=!0},clearHidden:function(t){null!==s.hiddenImput&&(s.hasFocus=!1)},clickPos:function(t){let i=s.str.length,e=0,h=0;for(;i--&&(e+=s.textWidth(s.str[h]),!(e>=t));)h++;return h},upInput:function(t,i){if(null===s.parent)return!1;let e=!1;if(i){let i=s.clickPos(t);if(s.moveX=i,-1===s.startX)s.startX=i,s.cursorId=i,s.inputRange=[s.startX,s.startX];else{s.moveX!==s.startX&&(s.startX>s.moveX?s.inputRange=[s.moveX,s.startX]:s.inputRange=[s.startX,s.moveX])}e=!0}else-1!==s.startX&&(s.hasFocus=!0,s.hiddenImput.focus(),s.hiddenImput.selectionStart=s.inputRange[0],s.hiddenImput.selectionEnd=s.inputRange[1],s.startX=-1,e=!0);return e&&s.selectParent(),e},selectAll:function(){s.parent&&(s.str=s.input.textContent,s.inputRange=[0,s.str.length],s.hasFocus=!0,s.hiddenImput.focus(),s.hiddenImput.selectionStart=s.inputRange[0],s.hiddenImput.selectionEnd=s.inputRange[1],s.cursorId=s.inputRange[1],s.selectParent())},selectParent:function(){var t=s.textWidth(s.str.substring(0,s.cursorId)),i=s.textWidth(s.str.substring(0,s.inputRange[0])),e=s.textWidth(s.str.substring(s.inputRange[0],s.inputRange[1]));s.parent.select(t,i,e,s.hiddenSizer.innerHTML)},textWidth:function(t){return null===s.hiddenSizer?0:(t=t.replace(/ /g," "),s.hiddenSizer.innerHTML=t,s.hiddenSizer.clientWidth)},clearInput:function(){null!==s.parent&&(s.firstImput||s.parent.validate(!0),s.clearHidden(),s.parent.unselect(),s.input.style.background=s.parent.colors.back,s.input.style.borderColor=s.parent.colors.border,s.parent.isEdit=!1,s.input=null,s.parent=null,s.str="",s.firstImput=!0)},setInput:function(t,i){s.clearInput(),s.input=t,s.parent=i,s.input.style.background=s.parent.colors.backoff,s.input.style.borderColor=s.parent.colors.select,s.str=s.input.textContent,s.setHidden()},keydown:function(t){if(null===s.parent)return;let i=t.which;t.shiftKey,s.firstImput=!1,s.hasFocus&&(window.focus(),s.hiddenImput.focus()),s.parent.isEdit=!0,13===i?s.clearInput():s.input.isNum?t.keyCode>47&&t.keyCode<58||t.keyCode>95&&t.keyCode<106||190===t.keyCode||110===t.keyCode||8===t.keyCode||109===t.keyCode?s.hiddenImput.readOnly=!1:s.hiddenImput.readOnly=!0:s.hiddenImput.readOnly=!1},keyup:function(t){null!==s.parent&&(s.str=s.hiddenImput.value,s.parent.allEqual?s.parent.sameStr(s.str):s.input.textContent=s.str,s.cursorId=s.hiddenImput.selectionStart,s.inputRange=[s.hiddenImput.selectionStart,s.hiddenImput.selectionEnd],s.selectParent(),s.parent.validate())},loop:function(){s.isLoop&&requestAnimationFrame(s.loop),s.update()},update:function(){let t=s.listens.length;for(;t--;)s.listens[t].listening()},removeListen:function(t){let i=s.listens.indexOf(t);-1!==i&&s.listens.splice(i,1),0===s.listens.length&&(s.isLoop=!1)},addListen:function(t){return-1===s.listens.indexOf(t)&&(s.listens.push(t),s.isLoop||(s.isLoop=!0,s.loop()),!0)}},i=s,e={texture:null,transition:.1,frag:document.createDocumentFragment(),colorRing:null,joystick_0:null,joystick_1:null,circular:null,knob:null,pad2d:null,svgns:"http://www.w3.org/2000/svg",links:"http://www.w3.org/1999/xlink",htmls:"http://www.w3.org/1999/xhtml",DOM_SIZE:["height","width","top","left","bottom","right","margin-left","margin-right","margin-top","margin-bottom"],SVG_TYPE_D:["pattern","defs","transform","stop","animate","radialGradient","linearGradient","animateMotion","use","filter","feColorMatrix"],SVG_TYPE_G:["svg","rect","circle","path","polygon","text","g","line","foreignObject"],PI:Math.PI,TwoPI:2*Math.PI,pi90:.5*Math.PI,pi60:Math.PI/3,torad:Math.PI/180,todeg:180/Math.PI,clamp:(t,s,i)=>t=(t=ti?i:t,isDivid:t=>.5*t===Math.floor(.5*t),size:{w:320,h:24,p:30,s:8},defineColor:(t,s=e.colors)=>{let i={...s},h=["fontFamily","fontWeight","fontShadow","fontSize"],o=!1;t.font&&(t.fontFamily=t.font),t.shadow&&(t.fontShadow=t.shadow),t.weight&&(t.fontWeight=t.weight),t.fontColor&&(t.text=t.fontColor),t.color&&(t.text=t.color),t.text&&(i.text=t.text,t.fontColor||t.color||(i.title=e.ColorLuma(t.text,-.25),i.titleoff=e.ColorLuma(t.text,-.5)),i.textOver=e.ColorLuma(t.text,.25),i.textSelect=e.ColorLuma(t.text,.5)),t.button&&(i.button=t.button,i.border=e.ColorLuma(t.button,.1),i.overoff=e.ColorLuma(t.button,.2)),t.select&&(i.select=t.select,i.over=e.ColorLuma(t.select,-.1)),t.itemBg&&(t.back=t.itemBg),t.back&&(i.back=t.back,i.backoff=e.ColorLuma(t.back,-.1)),t.fontSelect&&(i.textSelect=t.fontSelect),t.groupBorder&&(i.gborder=t.groupBorder),t.bgOver&&(i.backgroundOver=t.bgOver);for(let s in i)void 0!==t[s]&&(i[s]=t[s]);for(let s in t)-1!==h.indexOf(s)&&(o=!0);return o&&e.defineText(i),i},colors:{sx:4,sy:2,radius:2,showOver:1,content:"#37383d",background:"#28292e",backgroundOver:"rgba(40,40,40,0)",title:"#CCC",titleoff:"#BBB",text:"#DDD",textOver:"#EEE",textSelect:"#FFF",back:"rgba(0,0,0,0.2)",backoff:"rgba(0,0,0,0.3)",border:"#4c4c4c",borderSize:1,gborder:"none",groups:"none",button:"#3c3c3c",overoff:"#5c5c5c",over:"#024699",select:"#308AFF",action:"#FF3300",fontFamily:"'SegoeUI', 'Segoe UI', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, Roboto, Oxygen-Sans, Ubuntu, Cantarell, sans-serif",fontWeight:"normal",fontShadow:"none",fontSize:12,joyOver:"rgba(48,138,255,0.25)",joyOut:"rgba(100,100,100,0.5)",joySelect:"#308AFF",hide:"rgba(0,0,0,0)"},css:{basic:"position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; overflow:hidden; -o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;",button:"display:flex; align-items:center; justify-content:center; text-align:center;",middle:"display:flex; align-items:center; justify-content:left; text-align:left; flex-direction: row-reverse;"},svgs:{g1:"M 6 4 L 0 4 0 6 6 6 6 4 M 6 0 L 0 0 0 2 6 2 6 0 Z",g2:"M 6 0 L 4 0 4 6 6 6 6 0 M 2 0 L 0 0 0 6 2 6 2 0 Z",group:"M 7 7 L 7 8 8 8 8 7 7 7 M 5 7 L 5 8 6 8 6 7 5 7 M 3 7 L 3 8 4 8 4 7 3 7 M 7 5 L 7 6 8 6 8 5 7 5 M 6 6 L 6 5 5 5 5 6 6 6 M 7 3 L 7 4 8 4 8 3 7 3 M 6 4 L 6 3 5 3 5 4 6 4 M 3 5 L 3 6 4 6 4 5 3 5 M 3 3 L 3 4 4 4 4 3 3 3 Z",arrow:"M 3 8 L 8 5 3 2 3 8 Z",arrowDown:"M 5 8 L 8 3 2 3 5 8 Z",arrowUp:"M 5 2 L 2 7 8 7 5 2 Z",solid:"M 13 10 L 13 1 4 1 1 4 1 13 10 13 13 10 M 11 3 L 11 9 9 11 3 11 3 5 5 3 11 3 Z",body:"M 13 10 L 13 1 4 1 1 4 1 13 10 13 13 10 M 11 3 L 11 9 9 11 3 11 3 5 5 3 11 3 M 5 4 L 4 5 4 10 9 10 10 9 10 4 5 4 Z",vehicle:"M 13 6 L 11 1 3 1 1 6 1 13 3 13 3 11 11 11 11 13 13 13 13 6 M 2.4 6 L 4 2 10 2 11.6 6 2.4 6 M 12 8 L 12 10 10 10 10 8 12 8 M 4 8 L 4 10 2 10 2 8 4 8 Z",articulation:"M 13 9 L 12 9 9 2 9 1 5 1 5 2 2 9 1 9 1 13 5 13 5 9 4 9 6 5 8 5 10 9 9 9 9 13 13 13 13 9 Z",character:"M 13 4 L 12 3 9 4 5 4 2 3 1 4 5 6 5 8 4 13 6 13 7 9 8 13 10 13 9 8 9 6 13 4 M 6 1 L 6 3 8 3 8 1 6 1 Z",terrain:"M 13 8 L 12 7 Q 9.06 -3.67 5.95 4.85 4.04 3.27 2 7 L 1 8 7 13 13 8 M 3 8 Q 3.78 5.420 5.4 6.6 5.20 7.25 5 8 L 7 8 Q 8.39 -0.16 11 8 L 7 11 3 8 Z",joint:"M 7.7 7.7 Q 8 7.45 8 7 8 6.6 7.7 6.3 7.45 6 7 6 6.6 6 6.3 6.3 6 6.6 6 7 6 7.45 6.3 7.7 6.6 8 7 8 7.45 8 7.7 7.7 M 3.35 8.65 L 1 11 3 13 5.35 10.65 Q 6.1 11 7 11 8.28 11 9.25 10.25 L 7.8 8.8 Q 7.45 9 7 9 6.15 9 5.55 8.4 5 7.85 5 7 5 6.54 5.15 6.15 L 3.7 4.7 Q 3 5.712 3 7 3 7.9 3.35 8.65 M 10.25 9.25 Q 11 8.28 11 7 11 6.1 10.65 5.35 L 13 3 11 1 8.65 3.35 Q 7.9 3 7 3 5.7 3 4.7 3.7 L 6.15 5.15 Q 6.54 5 7 5 7.85 5 8.4 5.55 9 6.15 9 7 9 7.45 8.8 7.8 L 10.25 9.25 Z",ray:"M 9 11 L 5 11 5 12 9 12 9 11 M 12 5 L 11 5 11 9 12 9 12 5 M 11.5 10 Q 10.9 10 10.45 10.45 10 10.9 10 11.5 10 12.2 10.45 12.55 10.9 13 11.5 13 12.2 13 12.55 12.55 13 12.2 13 11.5 13 10.9 12.55 10.45 12.2 10 11.5 10 M 9 10 L 10 9 2 1 1 2 9 10 Z",collision:"M 11 12 L 13 10 10 7 13 4 11 2 7.5 5.5 9 7 7.5 8.5 11 12 M 3 2 L 1 4 4 7 1 10 3 12 8 7 3 2 Z",map:"M 13 1 L 1 1 1 13 13 13 13 1 M 12 2 L 12 7 7 7 7 12 2 12 2 7 7 7 7 2 12 2 Z",material:"M 13 1 L 1 1 1 13 13 13 13 1 M 12 2 L 12 7 7 7 7 12 2 12 2 7 7 7 7 2 12 2 Z",texture:"M 13 4 L 13 1 1 1 1 4 5 4 5 13 9 13 9 4 13 4 Z",object:"M 10 1 L 7 4 4 1 1 1 1 13 4 13 4 5 7 8 10 5 10 13 13 13 13 1 10 1 Z",none:"M 9 5 L 5 5 5 9 9 9 9 5 Z",cursor:"M 4 7 L 1 10 1 12 2 13 4 13 7 10 9 14 14 0 0 5 4 7 Z",load:"M 13 8 L 11.5 6.5 9 9 9 3 5 3 5 9 2.5 6.5 1 8 7 14 13 8 M 9 2 L 9 0 5 0 5 2 9 2 Z",save:"M 9 12 L 5 12 5 14 9 14 9 12 M 11.5 7.5 L 13 6 7 0 1 6 2.5 7.5 5 5 5 11 9 11 9 5 11.5 7.5 Z",extern:"M 14 14 L 14 0 0 0 0 14 14 14 M 12 6 L 12 12 2 12 2 6 12 6 M 12 2 L 12 4 2 4 2 2 12 2 Z"},rezone(){i.needReZone=!0},getImput:function(){return!!i.input},setStyle:function(t){for(var s in t)e.colors[s]&&(e.colors[s]=t[s]);e.setText()},defineText:function(t){e.setText(t.fontSize,t.text,t.fontFamily,t.fontShadow,t.fontWeight)},setText:function(t,s,i,h,o){let n=e.colors;void 0===i&&(i=n.fontFamily),void 0===t&&(t=n.fontSize),void 0===h&&(h=n.fontShadow),void 0===o&&(o=n.fontWeight),void 0===s&&(s=n.text),isNaN(t)?-1===t.search("em")&&(t+="px"):t+="px",e.css.txt=e.css.basic+e.css.middle+" font-family:"+i+"; font-weight:"+o+"; font-size:"+t+"; color:"+n.text+"; padding:0px 8px; left:0; top:2px; height:16px; width:100px; overflow:hidden; white-space: nowrap; letter-spacing: normal;","none"!==h&&(e.css.txt+=" text-shadow: 1px 1px 1px "+h+";"),e.css.txtselect=e.css.txt+"padding:0px 4px; border:1px dashed "+n.border+";",e.css.item=e.css.txt+"padding:0px 4px; position:relative; margin-bottom:1px; "},cloneCss:function(){return{...e.css}},clone:function(t){return t.cloneNode(!0)},setSvg:function(t,s,i,e,h){-1===e?t.setAttributeNS(null,s,i):void 0!==h?t.childNodes[e||0].childNodes[h||0].setAttributeNS(null,s,i):t.childNodes[e||0].setAttributeNS(null,s,i)},setCss:function(t,s){for(let i in s)-1!==e.DOM_SIZE.indexOf(i)?t.style[i]=s[i]+"px":t.style[i]=s[i]},set:function(t,s){for(let i in s)"txt"===i&&(t.textContent=s[i]),"link"===i?t.setAttributeNS(e.links,"xlink:href",s[i]):t.setAttributeNS(null,i,s[i])},get:function(t,s){if(void 0===s)return t;if(!isNaN(s))return t.childNodes[s];if(s instanceof Array){if(2===s.length)return t.childNodes[s[0]].childNodes[s[1]];if(3===s.length)return t.childNodes[s[0]].childNodes[s[1]].childNodes[s[2]]}},dom:function(t,s,i,h,o){return t=t||"div",-1!==e.SVG_TYPE_D.indexOf(t)||-1!==e.SVG_TYPE_G.indexOf(t)?"svg"===t?(h=document.createElementNS(e.svgns,"svg"),e.set(h,i)):(void 0===h&&(h=document.createElementNS(e.svgns,"svg")),e.addAttributes(h,t,i,o)):h=void 0===h?document.createElementNS(e.htmls,t):h.appendChild(document.createElementNS(e.htmls,t)),s&&(h.style.cssText=s),void 0===o?h:h.childNodes[o||0]},addAttributes:function(t,s,i,h){let o=document.createElementNS(e.svgns,s);return e.set(o,i),e.get(t,h).appendChild(o),-1!==e.SVG_TYPE_G.indexOf(s)&&(o.style.pointerEvents="none"),o},clear:function(t){for(e.purge(t);t.firstChild;)t.firstChild.firstChild&&e.clear(t.firstChild),t.removeChild(t.firstChild)},purge:function(t){let s,i,h=t.attributes;if(h)for(s=h.length;s--;)i=h[s].name,"function"==typeof t[i]&&(t[i]=null);if(h=t.childNodes,h)for(s=h.length;s--;)e.purge(t.childNodes[s])},addSVGGlowEffect:function(){if(null!==document.getElementById("UILGlow"))return;let t=e.initUILEffects(),s=e.addAttributes(t,"filter",{id:"UILGlow",x:"-20%",y:"-20%",width:"140%",height:"140%"});e.addAttributes(s,"feGaussianBlur",{in:"SourceGraphic",stdDeviation:"3",result:"uilBlur"});let i=e.addAttributes(s,"feMerge",{});for(let t=0;t<=3;t++)e.addAttributes(i,"feMergeNode",{in:"uilBlur"});e.addAttributes(i,"feMergeNode",{in:"SourceGraphic"})},initUILEffects:function(){let t=document.getElementById("UILSVGEffects");return null===t&&(t=e.dom("svg",void 0,{id:"UILSVGEffects",width:"0",height:"0"}),document.body.appendChild(t)),t},ColorLuma:function(t,s){"n"===t&&(t="#000"),(t=String(t).replace(/[^0-9a-f]/gi,"")).length<6&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),s=s||0;let i,e,h="#";for(e=0;e<3;e++)i=parseInt(t.substr(2*e,2),16),i=Math.round(Math.min(Math.max(0,i+i*s),255)).toString(16),h+=("00"+i).substr(i.length);return h},findDeepInver:function(t){return.3*t[0]+.59*t[1]+.11*t[2]<=.6},lerpColor:function(t,s,i){let e={};for(let h=0;h<3;h++)e[h]=t[h]+(s[h]-t[h])*i;return e},hexToHtml:function(t){return"#"+("000000"+(t=void 0===t?0:t).toString(16)).substr(-6)},htmlToHex:function(t){return t.toUpperCase().replace("#","0x")},u255:function(t,s){return parseInt(t.substring(s,s+2),16)/255},u16:function(t,s){return parseInt(t.substring(s,s+1),16)/15},unpack:function(t){return 7==t.length?[e.u255(t,1),e.u255(t,3),e.u255(t,5)]:4==t.length?[e.u16(t,1),e.u16(t,2),e.u16(t,3)]:void 0},p255:function(t){let s=Math.round(255*t).toString(16);return s.length<2&&(s="0"+s),s},pack:function(t){return"#"+e.p255(t[0])+e.p255(t[1])+e.p255(t[2])},htmlRgba:function(t,s){return t=e.unpack(t),"rgba("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+","+s+")"},htmlRgb:function(t,s){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},pad:function(t){return 1==t.length&&(t="0"+t),t},rgbToHex:function(t){let s=Math.round(255*t[0]).toString(16),i=Math.round(255*t[1]).toString(16),h=Math.round(255*t[2]).toString(16);return"#"+e.pad(s)+e.pad(i)+e.pad(h)},hueToRgb:function(t,s,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(s-t)*i:i<.5?s:i<2/3?t+6*(s-t)*(2/3-i):t},rgbToHsl:function(t){let s=t[0],i=t[1],e=t[2],h=Math.min(s,i,e),o=Math.max(s,i,e),n=o-h,r=0,l=0,a=(h+o)/2;return a>0&&a<1&&(l=n/(a<.5?2*a:2-2*a)),n>0&&(o==s&&o!=i&&(r+=(i-e)/n),o==i&&o!=e&&(r+=2+(e-s)/n),o==e&&o!=s&&(r+=4+(s-i)/n),r/=6),[r,l,a]},hslToRgb:function(t){let s,i,h=t[0],o=t[1],n=t[2];return 0===o?[n,n,n]:(i=n<=.5?n*(o+1):n+o-n*o,s=2*n-i,[e.hueToRgb(s,i,h+.33333),e.hueToRgb(s,i,h),e.hueToRgb(s,i,h-.33333)])},makeGradiant:function(t,s,i,h){e.dom(t,null,s,i,0);let o,n=i.childNodes[0].childNodes.length-1;for(let t=0;t0){for(a=6;a--;)r[a]=(113*r[a]+u).toFixed(2);c=" M"+r[0]+" "+r[1]+" Q"+r[2]+" "+r[3]+" "+r[4]+" "+r[5],d=[[0,g[0],1],[100,g[1],1]],e.makeGradiant("linearGradient",{id:"G"+l,x1:r[0],y1:r[1],x2:r[4],y2:r[5],gradientUnits:"userSpaceOnUse"},s,d),e.dom("path","",{d:c,"stroke-width":30,stroke:"url(#G"+l+")","stroke-linecap":"butt"},s,1)}m=n-p,g[0]=g[1]}d=[[0,"#FFFFFF",1],[50,"#FFFFFF",0],[50,"#000000",0],[100,"#000000",1]],e.makeGradiant("linearGradient",{id:"GL0",x1:0,y1:u-84.9,x2:0,y2:212.9,gradientUnits:"userSpaceOnUse"},s,d),d=[[0,"#7f7f7f",1],[50,"#7f7f7f",.5],[100,"#7f7f7f",0]],e.makeGradiant("linearGradient",{id:"GL1",x1:78.95,y1:0,x2:226,y2:0,gradientUnits:"userSpaceOnUse"},s,d),e.dom("g",null,{"transform-origin":"128px 128px",transform:"rotate(0)"},s),e.dom("polygon","",{points:"78.95 43.1 78.95 212.85 226 128",fill:"red"},s,2),e.dom("polygon","",{points:"78.95 43.1 78.95 212.85 226 128",fill:"url(#GL1)","stroke-width":1,stroke:"url(#GL1)"},s,2),e.dom("polygon","",{points:"78.95 43.1 78.95 212.85 226 128",fill:"url(#GL0)","stroke-width":1,stroke:"url(#GL0)"},s,2),e.dom("path","",{d:"M 255.75 136.5 Q 256 132.3 256 128 256 123.7 255.75 119.5 L 241 128 255.75 136.5 Z",fill:"none","stroke-width":2,stroke:"#000"},s,2),e.dom("circle","",{cx:128,cy:128,r:6,"stroke-width":2,stroke:"#000",fill:"none"},s),e.colorRing=s},icon:function(t,s,i){i=i||40;let h=[""];switch(t){case"logo":h[1]="";break;case"donate":h[1]="";break;case"neo":h[1]="";break;case"phy":h[1]="";break;case"config":h[1]="";break;case"github":h[1]="";break;case"save":h[1]=""}return h[2]="",h.join("\n")},logoFill_d:"\n M 171 150.75 L 171 33.25 155.5 33.25 155.5 150.75 Q 155.5 162.2 147.45 170.2 139.45 178.25 128 178.25 116.6 178.25 108.55 170.2 100.5 162.2 100.5 150.75 \n L 100.5 33.25 85 33.25 85 150.75 Q 85 168.65 97.55 181.15 110.15 193.75 128 193.75 145.9 193.75 158.4 181.15 171 168.65 171 150.75 \n M 200 33.25 L 184 33.25 184 150.8 Q 184 174.1 167.6 190.4 151.3 206.8 128 206.8 104.75 206.8 88.3 190.4 72 174.1 72 150.8 L 72 33.25 56 33.25 56 150.75 \n Q 56 180.55 77.05 201.6 98.2 222.75 128 222.75 157.8 222.75 178.9 201.6 200 180.55 200 150.75 L 200 33.25 Z\n ",logo_github:"\n M 180.5 70 Q 186.3 82.4 181.55 96.55 196.5 111.5 189.7 140.65 183.65 168.35 146 172.7 152.5 178.7 152.55 185.9 L 152.55 218.15 Q 152.84 224.56 159.15 223.3 \n 159.21 223.3 159.25 223.3 181.14 216.25 198.7 198.7 228 169.4 228 128 228 86.6 198.7 57.3 169.4 28 128 28 86.6 28 57.3 57.3 28 86.6 28 128 28 169.4 57.3 198.7 74.85 \n 216.25 96.75 223.3 96.78 223.3 96.8 223.3 103.16 224.54 103.45 218.15 L 103.45 200 Q 82.97 203.1 75.1 196.35 69.85 191.65 68.4 185.45 64.27 177.055 59.4 174.15 49.20 \n 166.87 60.8 167.8 69.85 169.61 75.7 180 81.13 188.09 90 188.55 98.18 188.86 103.45 185.9 103.49 178.67 110 172.7 72.33 168.33 66.3 140.65 59.48 111.49 74.45 96.55 69.7 \n 82.41 75.5 70 84.87 68.74 103.15 80 115.125 76.635 128 76.85 140.85 76.65 152.85 80 171.1 68.75 180.5 70 Z\n ",logo_neo:"\n M 219 52 L 206 52 206 166 Q 206 183.4 193.75 195.65 181.4 208 164 208 146.6 208 134.35 195.65 122 183.4 122 166 L 122 90 Q 122 77.6 113.15 68.85 104.4 60 92 60 79.55 \n 60 70.75 68.85 62 77.6 62 90 L 62 204 75 204 75 90 Q 75 83 79.95 78 84.95 73 92 73 99 73 104 78 109 83 109 90 L 109 166 Q 109 188.8 125.15 204.85 141.2 221 164 221 \n 186.75 221 202.95 204.85 219 188.8 219 166 L 219 52 M 194 52 L 181 52 181 166 Q 181 173 176.05 178 171.05 183 164 183 157 183 152 178 147 173 147 166 L 147 90 Q 147 \n 67.2 130.85 51.15 114.8 35 92 35 69.25 35 53.05 51.15 37 67.2 37 90 L 37 204 50 204 50 90 Q 50 72.6 62.25 60.35 74.6 48 92 48 109.4 48 121.65 60.35 134 72.6 134 90 L \n 134 166 Q 134 178.4 142.85 187.15 151.6 196 164 196 176.45 196 185.25 187.15 194 178.4 194 166 L 194 52 Z\n ",logo_phy:"\n M 103.55 37.95 L 127.95 37.95 Q 162.35 37.95 186.5 55 210.9 72.35 210.9 96.5 210.9 120.65 186.5 137.7 162.35 155 127.95 155 L 127.95 237.95 M 127.95 155 \n Q 93.55 155 69.15 137.7 45 120.65 45 96.5 45 72.35 69.15 55 70.9 53.8 72.85 52.85 M 127.95 155 L 127.95 37.95\n ",logo_config:"\n M 204.35 51.65 L 173.25 82.75 Q 192 101.5 192 128 L 236 128 M 192 128 Q 192 154.55 173.25 173.25 L 204.4 204.4 M 51.65 51.65 L 82.75 82.75 Q 101.5 64 128 64 \n L 128 20 M 51.6 204.4 L 82.75 173.25 Q 64 154.55 64 128 L 20 128 M 128 236 L 128 192 Q 101.5 192 82.75 173.25 M 64 128 Q 64 101.5 82.75 82.75 M 173.25 173.25 \n Q 154.55 192 128 192 M 128 64 Q 154.55 64 173.25 82.75\n ",logo_donate:"\n M 171.3 80.3 Q 179.5 62.15 171.3 45.8 164.1 32.5 141.35 30.1 L 94.35 30.1 Q 89.35 30.4 88.3 35.15 L 70.5 148.05 Q 70.2 152.5 73.7 152.6 L 100.95 152.6 107 111.6 Q 108.75 \n 106.55 112.6 106.45 130.45 108.05 145.3 103.9 163.35 98.75 171.3 80.3 M 179.8 71.5 Q 178.6 79.75 174.9 87.85 168.45 102.9 151.9 109.15 140.65 113.95 117.55 113 113.15 \n 112.75 111 117.45 L 102.7 169.95 Q 102.45 173.8 105.5 173.85 L 128.95 173.85 Q 132.2 174.2 133.35 169.65 L 138.3 139.95 Q 139.75 135.6 143.1 135.5 146.6 135.75 150.6 135.65 \n 154.55 135.5 157.35 135.1 160.15 134.7 166.75 132.35 181.35 127.4 187.9 111.2 194.25 95.75 189.5 81.95 186.75 74.85 179.8 71.5 M 103.5 209.9 Q 103.5 202.85 99.7 198.85 95.95 \n 194.75 89.4 194.75 82.8 194.75 79.05 198.85 75.3 202.9 75.3 209.9 75.3 216.85 79.05 220.95 82.8 225.05 89.4 225.05 95.95 225.05 99.7 221 103.5 216.95 103.5 209.9 M 95.45 205.5 \n Q 95.95 207.3 95.95 209.9 95.95 212.65 95.45 214.35 94.95 216 94 217.3 93.1 218.45 91.9 219 90.7 219.55 89.4 219.55 88.15 219.55 86.95 219.05 85.75 218.55 84.8 217.3 83.9 216.15 \n 83.4 214.35 82.85 212.6 82.85 209.9 82.85 207.3 83.4 205.45 83.95 203.55 84.85 202.45 85.9 201.2 86.95 200.75 88.05 200.25 89.4 200.25 90.7 200.25 91.85 200.8 93.05 201.3 94 202.5 \n 94.9 203.65 95.45 205.5 M 153.3 195.35 L 145.3 195.35 135.5 224.45 142.8 224.45 144.6 218.5 153.75 218.5 155.6 224.45 163.1 224.45 153.3 195.35 M 152.15 213.25 L 146.25 213.25 \n 149.2 203.65 152.15 213.25 M 116.75 195.35 L 107.8 195.35 107.8 224.45 114.5 224.45 114.5 204.2 125.7 224.45 132.75 224.45 132.75 195.35 126.05 195.35 126.05 212.05 116.75 195.35 M \n 66.5 197.65 Q 64.15 196.15 61.45 195.75 58.8 195.35 55.75 195.35 L 46.7 195.35 46.7 224.45 55.8 224.45 Q 58.8 224.45 61.5 224.05 64.15 223.6 66.4 222.15 69.15 220.45 70.9 217.2 \n 72.7 214 72.7 209.95 72.7 205.7 71 202.6 69.35 199.5 66.5 197.65 M 64.2 205 Q 65.2 207 65.2 209.9 65.2 212.75 64.25 214.75 63.3 216.75 61.5 217.85 60 218.85 58.3 218.9 56.6 219 \n 54.15 219 L 54 219 54 200.8 54.15 200.8 Q 56.4 200.8 58.05 200.9 59.7 200.95 61.15 201.75 63.2 202.95 64.2 205 M 210.2 195.35 L 190.5 195.35 190.5 224.45 210.2 224.45 210.2 218.9 \n 197.75 218.9 197.75 211.55 209.2 211.55 209.2 206 197.75 206 197.75 200.9 210.2 200.9 210.2 195.35 M 187.5 195.35 L 163 195.35 163 200.9 171.6 200.9 171.6 224.45 178.9 224.45 178.9 \n 200.9 187.5 200.9 187.5 195.35 Z\n "};e.setText();const h=e;class o{static autoTypes(t){let s=[];switch(t){case"svg":s=[{accept:{"image/svg+xml":".svg"}}];break;case"wav":s=[{accept:{"audio/wav":".wav"}}];break;case"mp3":s=[{accept:{"audio/mpeg":".mp3"}}];break;case"mp4":s=[{accept:{"video/mp4":".mp4"}}];break;case"bin":case"hex":s=[{description:"Binary Files",accept:{"application/octet-stream":[".bin",".hex"]}}];break;case"text":s=[{description:"Text Files",accept:{"text/plain":[".txt",".text"],"text/html":[".html",".htm"]}}];break;case"json":s=[{description:"JSON Files",accept:{"application/json":[".json"]}}];break;case"js":s=[{description:"JavaScript Files",accept:{"text/javascript":[".js"]}}];break;case"image":s=[{description:"Images",accept:{"image/*":[".png",".gif",".jpeg",".jpg"]}}];break;case"icon":s=[{description:"Icons",accept:{"image/x-ico":[".ico"]}}];break;case"lut":s=[{description:"Lut",accept:{"text/plain":[".cube",".3dl"]}}]}return s}static async load(t={}){"function"!=typeof window.showOpenFilePicker&&(window.showOpenFilePicker=o.showOpenFilePickerPolyfill);try{let s=t.type||"";const i={excludeAcceptAllOption:!!s,multiple:!1};i.types=o.autoTypes(s);const e=await window.showOpenFilePicker(i),h=await e[0].getFile();if(!h)return null;let n=h.name,r=n.substring(n.lastIndexOf(".")+1,n.length);const l=["png","jpg","jpeg","mp4","webm","ogg","mp3"],a=["sea","z","hex","bvh","BVH","glb","gltf","exr"],c=new FileReader;-1!==l.indexOf(r)?c.readAsDataURL(h):-1!==a.indexOf(r)?c.readAsArrayBuffer(h):c.readAsText(h),c.onload=function(i){let e=i.target.result;switch(s){case"image":let s=new Image;s.onload=function(){s.width=s.width,s.height=s.height,t.callback&&t.callback(s,n,r,[s.width,s.height])},s.src=e;break;case"json":t.callback&&t.callback(JSON.parse(e),n,r);break;default:t.callback&&t.callback(e,n,r)}}}catch(s){console.log(s),t.always&&t.callback&&t.callback(null)}}static showOpenFilePickerPolyfill(t){return new Promise((s=>{const i=document.createElement("input");i.type="file",i.multiple=t.multiple,i.accept=t.types.map((t=>t.accept)).flatMap((t=>Object.keys(t).flatMap((s=>t[s])))).join(","),i.addEventListener("change",(()=>{s([...i.files].map((t=>({getFile:async()=>new Promise((s=>{s(t)}))}))))})),i.click()}))}static async save(t={}){let s=!1;"function"!=typeof window.showSaveFilePicker&&(window.showSaveFilePicker=o.showSaveFilePickerPolyfill,s=!0);try{let i=t.type||"";const e={suggestedName:t.name||"hello",data:t.data||""};e.types=o.autoTypes(i),e.finalType=Object.keys(e.types[0].accept)[0],e.suggestedName+=e.types[0].accept[e.finalType][0];const h=await window.showSaveFilePicker(e);if(s)return;const n=await h.createWritable();let r=new Blob([e.data],{type:e.finalType});await n.write(r),await n.close()}catch(t){console.log(t)}}static showSaveFilePickerPolyfill(t){return new Promise((s=>{const i=document.createElement("a");i.download=t.suggestedName||"my-file.txt";let e=new Blob([t.data],{type:t.finalType});i.href=URL.createObjectURL(e),i.addEventListener("click",(()=>{s(setTimeout((()=>URL.revokeObjectURL(i.href)),1e3))})),i.click()}))}static async getFolder(){try{const t=await window.showDirectoryPicker(),s=[];for await(const i of t.values()){const t=await i.getFile();s.push(t)}return console.log(s),s}catch(t){console.log(t)}}}class n{constructor(t=0,s=0){this.x=t,this.y=s}set(t,s){return this.x=t,this.y=s,this}divide(t){return this.x/=t.x,this.y/=t.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divideScalar(t){return this.multiplyScalar(1/t)}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}angle(){var t=Math.atan2(this.y,this.x);return t<0&&(t+=2*Math.PI),t}addScalar(t){return this.x+=t,this.y+=t,this}negate(){return this.x*=-1,this.y*=-1,this}neg(){return this.x=-1,this.y=-1,this}isZero(){return 0===this.x&&0===this.y}copy(t){return this.x=t.x,this.y=t.y,this}equals(t){return t.x===this.x&&t.y===this.y}nearEquals(t,s){return t.x.toFixed(s)===this.x.toFixed(s)&&t.y.toFixed(s)===this.y.toFixed(s)}lerp(t,s){return null===t?(this.x-=this.x*s,this.y-=this.y*s):(this.x+=(t.x-this.x)*s,this.y+=(t.y-this.y)*s),this}}class r{constructor(t={}){this.lock=t.lock||!1,this.neverlock=!1,this.isSpace=t.isSpace||!1,this.main=t.main||null,this.isUI=t.isUI||!1,this.group=t.group||null,this.isListen=!1,this.top=0,this.ytop=0,this.dx=t.dx||0,this.isSelectable=void 0!==t.selectable&&t.selectable,this.unselectable=void 0!==t.unselect?t.unselect:this.isSelectable,this.ontop=!!t.ontop&&t.ontop,this.css=this.main?this.main.css:h.css,this.colors=h.defineColor(t,this.main?this.group?this.group.colors:this.main.colors:h.colors),this.overEffect=this.colors.showOver,this.svgs=h.svgs,this.zone={x:0,y:0,w:0,h:0,d:0},this.local=(new n).neg(),this.isCanvasOnly=!1,this.isSelect=!1,this.p=void 0!==t.p?t.p:h.size.p,this.w=this.isUI?this.main.size.w:h.size.w,void 0!==t.w&&(this.w=t.w),this.h=this.isUI?this.main.size.h:h.size.h,void 0!==t.h&&(this.h=t.h),this.isSpace?this.lock=!0:this.h=this.h<11?11:this.h,this.fw=t.fw||0,this.autoWidth=t.auto||!0,this.isOpen=!1,this.radius=t.radius||this.colors.radius,this.transition=t.transition||h.transition,this.isNumber=!1,this.noNeg=t.noNeg||!1,this.allEqual=t.allEqual||!1,this.mono=!1,this.isEdit=!1,this.simple=t.simple||!1,this.simple&&(this.sa=0),this.setSize(this.w),void 0!==t.sa&&(this.sa=t.sa),void 0!==t.sb&&(this.sb=t.sb),this.simple&&(this.sb=this.w-this.sa),this.sc=void 0===t.sc?47:t.sc,this.objectLink=null,this.isSend=!1,this.objectKey=null,this.txt=t.name||"",this.name=t.rename||this.txt,this.target=t.target||null,this.callback=void 0===t.callback?null:t.callback,this.endCallback=null,this.openCallback=void 0===t.openCallback?null:t.openCallback,this.closeCallback=void 0===t.closeCallback?null:t.closeCallback,null===this.callback&&this.isUI&&null!==this.main.callback&&(this.callback=this.group?this.group.callback:this.main.callback),this.c=[],this.s=[],this.useFlex=!!this.isUI&&this.main.useFlex;let s=this.useFlex?"display:flex; justify-content:center; align-items:center; text-align:center; flex: 1 100%;":"float:left;";this.c[0]=h.dom("div",this.css.basic+s+"position:relative; height:20px;"),this.s[0]=this.c[0].style,this.margin=this.colors.sy,this.mtop=0;let i=h.isDivid(this.margin);if(this.isUI&&this.margin&&(this.s[0].boxSizing="content-box",i?(this.mtop=.5*this.margin,this.s[0].borderTop=this.mtop+"px solid transparent",this.s[0].borderBottom=this.mtop+"px solid transparent"):this.s[0].borderBottom=this.margin+"px solid transparent"),this.simple||(this.c[1]=h.dom("div",this.css.txt+this.css.middle),this.s[1]=this.c[1].style,this.c[1].textContent=this.name,this.s[1].color=this.lock?this.colors.titleoff:this.colors.title),t.pos){this.s[0].position="absolute";for(let s in t.pos)this.s[0][s]=t.pos[s];this.mono=!0}t.css&&(this.s[0].cssText=t.css)}init(){this.ytop=this.top+this.mtop,this.zone.h=this.h+this.margin,this.zone.w=this.w;let t=this.s,s=this.c;t[0].height=this.h+"px",this.isUI&&(t[0].background=this.colors.background),!this.autoWidth&&this.useFlex?(t[0].flex="1 0 auto",t[0].minWidth=this.minw+"px",t[0].textAlign="center"):this.isUI&&(t[0].width="100%"),void 0!==s[1]&&this.autoWidth&&(t[1]=s[1].style,t[1].top="1px",t[1].height=this.h-2+"px");let e=h.frag;for(let i=1,h=s.length;i!==h;i++)void 0!==s[i]&&(e.appendChild(s[i]),t[i]=s[i].style);let o=null!==this.target?this.target:this.isUI?this.main.inner:document.body;this.ontop?o.insertAdjacentElement("afterbegin",s[0]):o.appendChild(s[0]),s[0].appendChild(e),this.rSize(),this.isUI||(this.c[0].style.pointerEvents="auto",i.add(this))}addTransition(){this.baseH&&this.transition&&this.isUI&&(this.c[0].style.transition="height "+this.transition+"s ease-out")}dom(t,s,i,e,o){return h.dom(t,s,i,e,o)}setSvg(t,s,i,e,o){h.setSvg(t,s,i,e,o)}setCss(t,s){h.setCss(t,s)}clamp(t,s,i){return h.clamp(t,s,i)}getColorRing(){return h.colorRing||h.makeColorRing(),h.clone(h.colorRing)}getJoystick(t){return h["joystick_"+t]||h.makeJoystick(t),h.clone(h["joystick_"+t])}getCircular(t){return h.circular||h.makeCircular(t),h.clone(h.circular)}getKnob(t){return h.knob||h.makeKnob(t),h.clone(h.knob)}getPad2d(t){return h.pad2d||h.makePad(t),h.clone(h.pad2d)}cursor(t){i.cursor(t)}update(){}reset(){}appendChild(t){this.c[0].appendChild(t)}content(){return this.c[0]}getDom(){return this.c[0]}uiout(){this.lock||this.overEffect&&this.s&&(this.s[0].background=this.colors.background)}uiover(){this.lock||this.overEffect&&this.s&&(this.s[0].background=this.colors.backgroundOver)}rename(t){void 0!==this.c[1]&&(this.c[1].textContent=t)}listen(){return this.isListen=i.addListen(this),this}listening(){null!==this.objectLink&&(this.isSend||this.isEdit||this.setValue(this.objectLink[this.objectKey]))}setValue(t){this.isNumber?this.value=this.numValue(t):this.value=t,this.update()}onChange(t){if(!this.isSpace)return this.callback=t||null,this}onFinishChange(t){if(!this.isSpace)return this.callback=null,this.endCallback=t,this}onOpen(t){return this.openCallback=t,this}onClose(t){return this.closeCallback=t,this}send(t){(t=t||this.value)instanceof Array&&1===t.length&&(t=t[0]),this.isSend=!0,null!==this.objectLink&&(this.objectLink[this.objectKey]&&this.objectLink[this.objectKey].isColor?this.objectLink[this.objectKey].setHex(t):this.objectLink[this.objectKey]=t),this.callback&&this.callback(t,this.objectKey),this.isSend=!1}sendEnd(t){(t=t||this.value)instanceof Array&&1===t.length&&(t=t[0]),this.endCallback&&this.endCallback(t),null!==this.objectLink&&(this.objectLink[this.objectKey]=t)}dispose(){this.isListen&&i.removeListen(this),h.clear(this.c[0]),null!==this.target?null!==this.group?this.group.clearOne(this):this.target.removeChild(this.c[0]):this.isUI?this.main.clearOne(this):document.body.removeChild(this.c[0]),this.isUI||i.remove(this),this.c=null,this.s=null,this.callback=null,this.target=null,this.isListen=!1}clear(){}getWidth(){let t=i.getWidth(this);t&&(this.w=t)}setSize(t){if(this.autoWidth)if(this.w=t,this.simple)this.sb=this.w-this.sa;else{let t=this.w*(this.p/100);this.sa=Math.floor(t+8),this.sb=Math.floor(this.w-t-16)}}rSize(){this.autoWidth&&(this.isUI||(this.s[0].width=this.w+"px"),this.simple||(this.s[1].width=this.sa+"px"))}setTypeNumber(t){let s;switch(this.isNumber=!0,this.value=0,void 0!==t.value&&("string"==typeof t.value?this.value=1*t.value:this.value=t.value),this.min=void 0===t.min?-1/0:t.min,this.max=void 0===t.max?1/0:t.max,this.precision=void 0===t.precision?2:t.precision,this.precision){case 0:s=1;break;case 1:s=.1;break;case 2:s=.01;break;case 3:s=.001;break;case 4:s=1e-4;break;case 5:s=1e-5;break;case 6:s=1e-6}this.step=void 0===t.step?s:t.step,this.range=this.max-this.min,this.value=this.numValue(this.value)}numValue(t){return this.noNeg&&(t=Math.abs(t)),1*Math.min(this.max,Math.max(this.min,t)).toFixed(this.precision)}handleEvent(t){if(!this.lock)return this.neverlock&&(i.lock=!1),this[t.type]?this[t.type](t):console.error(t.type,"this type of event no existe !")}wheel(t){return!1}mousedown(t){return!1}mousemove(t){return!1}mouseup(t){return!1}keydown(t){return!1}keyup(t){return!1}setReferency(t,s){this.objectLink=t,this.objectKey=s}display(t=!1){this.s[0].visibility=t?"visible":"hidden"}open(){this.isOpen||(this.isOpen=!0,i.needResize=!0,this.openCallback&&this.openCallback())}close(){this.isOpen&&(this.isOpen=!1,i.needResize=!0,this.closeCallback&&this.closeCallback())}needZone(){i.needReZone=!0}rezone(){i.needReZone=!0}select(){}unselect(){}setInput(t){i.setInput(t,this)}upInput(t,s){return i.upInput(t,s)}selected(t){this.isSelect=t||!1}}class l extends r{constructor(t={}){super(t),this.value=t.value||!1,this.model=void 0!==t.mode?t.mode:0,this.onName=t.rename||this.txt,t.onName&&(t.onname=t.onName),t.onname&&(this.onName=t.onname),this.inh=t.inh||Math.floor(.8*this.h),this.inw=t.inw||36;let s=this.colors;if(0===this.model){let t=Math.floor(.5*this.h)-.5*(this.inh-2);this.c[2]=this.dom("div",this.css.basic+"background:"+s.inputBg+"; height:"+(this.inh-2)+"px; width:"+this.inw+"px; top:"+t+"px; border-radius:10px; border:2px solid "+s.back),this.c[3]=this.dom("div",this.css.basic+"height:"+(this.inh-6)+"px; width:16px; top:"+(t+2)+"px; border-radius:10px; background:"+s.button+";")}else this.p=0,void 0!==this.c[1]&&(this.c[1].textContent=""),this.c[2]=this.dom("div",this.css.txt+this.css.button+"top:1px; background:"+s.button+"; height:"+(this.h-2)+"px; border:"+s.borderSize+"px solid "+s.border+"; border-radius:"+this.radius+"px;");this.stat=-1,this.init(),this.update()}mousedown(t){return this.value=!this.value,this.update(!0),this.mousemove(t)}mousemove(t){return this.cursor("pointer"),this.mode(!0)}reset(){return this.cursor(),this.mode()}mode(t){let s,i=!1,e=this.colors,h=this.s,o=this.value;if(s=t?o?4:3:o?2:1,this.stat!==s){if(this.stat=s,0!==this.model){switch(s){case 1:h[2].color=e.text,h[2].background=e.button;break;case 2:h[2].color=e.textSelect,h[2].background=e.select;break;case 3:h[2].color=e.textOver,h[2].background=e.overoff;break;case 4:h[2].color=e.textOver,h[2].background=e.over}this.c[2].innerHTML=o?this.onName:this.name}else{switch(s){case 1:h[2].background=h[2].borderColor=e.backoff,h[3].background=e.button;break;case 2:h[2].background=h[2].borderColor=e.back,h[3].background=e.textOver;break;case 3:h[2].background=h[2].borderColor=e.back,h[3].background=e.overoff;break;case 4:h[2].background=h[2].borderColor=e.backoff,h[3].background=e.textSelect}h[3].marginLeft=o?"17px":"2px",this.c[1].textContent=o?this.onName:this.name}i=!0}return i}update(t){this.mode(),t&&this.send()}rSize(){super.rSize();let t=this.s,s=this.w-10-this.inw;0===this.model?(t[2].left=s+"px",t[3].left=s+"px"):(t[2].left=this.sa+"px",t[2].width=this.sb+"px")}}class a extends r{constructor(t={}){super(t),this.value="",void 0!==t.value&&(this.value=t.value),this.values=t.value||this.txt,t.values&&(this.values=t.values),t.values||t.value||(this.txt=""),this.onName=t.onName||null,this.on=!1,this.bw=t.forceWidth||0,t.bw&&(this.bw=t.bw),this.space=t.space||3,"string"==typeof this.values&&(this.values=[this.values]),this.isDown=!1,this.neverlock=!0,this.res=0,this.lng=this.values.length,this.tmp=[],this.stat=[];let s,i=this.colors;for(let t=0;te[i][0]&&s.x0?h.pack(h.lerpColor(h.unpack(h.ColorLuma(i.text,-.75)),h.unpack(i.text),this.percent)):i.text,this.setSvg(this.c[3],"stroke",s,1);break;case 1:this.s[2].color=i.textOver,this.setSvg(this.c[3],"stroke",i.backoff,0),s=this.model>0?h.pack(h.lerpColor(h.unpack(h.ColorLuma(i.text,-.75)),h.unpack(i.text),this.percent)):i.textOver,this.setSvg(this.c[3],"stroke",s,1)}return this.cmode=t,!0}reset(){this.isDown=!1}testZone(t){let s=this.local;return-1===s.x&&-1===s.y?"":s.y<=this.c[1].offsetHeight?"title":s.y>this.h-this.c[2].offsetHeight?"text":"circular"}mouseup(t){return this.isDown=!1,this.sendEnd(),this.mode(0)}mousedown(t){return this.isDown=!0,this.old=this.value,this.oldr=null,this.mousemove(t),this.mode(1)}mousemove(t){if(!this.isDown)return;let s=this.offset;if(s.x=.5*this.w-(t.clientX-this.zone.x),s.y=.5*this.diam-(t.clientY-this.zone.y-this.ytop),this.r=s.angle()-this.pi90,this.r=(this.r%this.twoPi+this.twoPi)%this.twoPi,null!==this.oldr){let t=this.r-this.oldr;this.r=Math.abs(t)>Math.PI?this.oldr:this.r,t>6&&(this.r=0),t<-6&&(this.r=this.twoPi)}let i=1/this.twoPi,e=this.r*i,h=this.range*e+this.min-this.old;(h>=this.step||h<=this.step)&&(h=~~(h/this.step),this.value=this.numValue(this.old+h*this.step),this.update(!0),this.old=this.value,this.oldr=this.r)}wheel(t){if("circular"===this.testZone(t)){let s=this.value-this.step*t.delta;return s>this.max?s=this.isCyclic?this.min:this.max:sMath.PI?1:0)+" 1 "+i+","+e}update(t){if(this.c[2].textContent=this.value,this.percent=(this.value-this.min)/this.range,this.setSvg(this.c[3],"d",this.makePath(),1),this.model>0){let t=this.colors,s=h.pack(h.lerpColor(h.unpack(h.ColorLuma(t.text,-.75)),h.unpack(t.text),this.percent));this.setSvg(this.c[3],"stroke",s,1)}t&&this.send()}}class d extends r{constructor(t={}){super(t),this.ctype=t.ctype||"hex",this.wfixe=256,this.cw=this.sb>256?256:this.sb,null!=t.cw&&(this.cw=t.cw),this.side=t.side||"down",this.up="down"===this.side?0:1,this.baseH=this.h,this.offset=new n,this.decal=new n,this.pp=new n;let s=this.colors;this.c[2]=this.dom("div",`${this.css.txt} ${this.css.middle} top:1px; height:${this.h-2}px; border-radius:${this.radius}px; text-shadow:none; border:${s.borderSize}px solid ${s.border};`),this.c[0].style.display="block",this.c[3]=this.getColorRing(),this.c[3].style.visibility="hidden",this.hsl=null,this.value="#ffffff",void 0!==t.value&&(t.value.isColor?this.value="#"+t.value.getHexString():t.value instanceof Array?this.value=h.rgbToHex(t.value):isNaN(t.value)?this.value=t.value:this.value=h.hexToHtml(t.value)),this.bcolor=null,this.isDown=!1,this.fistDown=!1,this.notext=t.notext||!1,this.tr=98,this.tsl=Math.sqrt(3)*this.tr,this.hue=0,this.d=256,this.init(),this.setColor(this.value),void 0!==t.open&&this.open()}testZone(t,s){let i=this.local;return-1===i.x&&-1===i.y?"":this.up&&this.isOpen?i.y>this.wfixe?"title":"color":i.ythis.tr)e=(c+u.pi90)/u.TwoPI,this.hue=(e+1)%1,this.setHSL([(e+1)%1,this.hsl[1],this.hsl[2]]);else{l=s.x*this.ratio,a=s.y*this.ratio;let t=this.hue*u.TwoPI+u.PI;t<0&&(t+=2*u.PI),r=Math.atan2(-a,l),r<0&&(r+=2*u.PI);let i=(r+u.pi90+u.TwoPI+t)%u.TwoPI,e=i%(2/3*u.PI)-u.pi60,h=.5*this.tr,c=Math.tan(e)*h,d=Math.sqrt(l*l+a*a),p=Math.sqrt(h*h+c*c);if(d>p){let s=Math.tan(e)*d,o=Math.atan(s/p);o>u.pi60?o=u.pi60:o<-u.pi60&&(o=-u.pi60),r+=o-e,i=(r+u.pi90+u.TwoPI+t)%u.TwoPI,e=i%(2/3*u.PI)-u.pi60,c=Math.tan(e)*h,d=p=Math.sqrt(h*h+c*c)}n=Math.sin(i)*d/this.tsl+.5;let m=1-2*Math.abs(n-.5);o=(Math.cos(i)*d+this.tr/2)/(1.5*this.tr)/m,o=u.clamp(o,0,1),this.setHSL([this.hsl[0],o,n])}}setHeight(){this.h=this.isOpen?this.wfixe+this.baseH+5:this.baseH,this.s[0].height=this.h+"px",this.zone.h=this.h}parentHeight(t){null!==this.group?this.group.calc(t):this.isUI&&this.main.calc(t)}open(){super.open(),this.setHeight(),this.up&&(this.zone.y-=this.wfixe+5);let t=this.h-this.baseH;this.s[3].visibility="visible",this.parentHeight(t)}close(){super.close(),this.up&&(this.zone.y+=this.wfixe+5);let t=this.h-this.baseH;this.setHeight(),this.s[3].visibility="hidden",this.parentHeight(-t)}update(t){let s=h.rgbToHex(h.hslToRgb([this.hsl[0],1,.5]));this.moveMarkers(),this.value=this.bcolor,this.setSvg(this.c[3],"fill",s,2,0),this.s[2].background=this.bcolor,this.notext||(this.c[2].textContent=h.htmlToHex(this.bcolor)),this.invert=h.findDeepInver(this.rgb),this.s[2].color=this.invert?"#fff":"#000",t&&("array"===this.ctype&&this.send(this.rgb),"rgb"===this.ctype&&this.send(h.htmlRgb(this.rgb)),"hex"===this.ctype&&this.send(h.htmlToHex(this.value)),"html"===this.ctype&&this.send())}setValue(t){t instanceof Array?this.value=h.rgbToHex(t):isNaN(t)?this.value=t:this.value=h.hexToHtml(t),this.setColor(this.value),this.update()}setColor(t){let s=h.unpack(t);return this.bcolor!==t&&s&&(this.bcolor=t,this.rgb=s,this.hsl=h.rgbToHsl(this.rgb),this.hue=this.hsl[0],this.update()),this}setHSL(t){return this.hsl=t,this.rgb=h.hslToRgb(t),this.bcolor=h.rgbToHex(this.rgb),this.update(!0),this}moveMarkers(){let t=this.pp,s=h;this.invert;let i=this.hsl[0]*s.TwoPI,e=2/3*s.PI,o=this.tr,n=this.hsl[0],r=this.hsl[1],l=this.hsl[2],a=(i-s.pi90)*s.todeg;n=-i+s.pi90;let c=Math.cos(n)*o,d=-Math.sin(n)*o,u=Math.cos(n-e)*o,p=-Math.sin(n-e)*o,m=Math.cos(n+e)*o,g=-Math.sin(n+e)*o,x=(u+m)/2,v=(p+g)/2;i=(1-2*Math.abs(l-.5))*r;let b=u+(m-u)*l+(c-x)*i,f=p+(g-p)*l+(d-v)*i;t.set(b,f).addScalar(128),this.setSvg(this.c[3],"transform","rotate("+a+" )",2),this.setSvg(this.c[3],"cx",t.x,3),this.setSvg(this.c[3],"cy",t.y,3),this.setSvg(this.c[3],"stroke",this.invert?"#fff":"#000",2,3),this.setSvg(this.c[3],"stroke",this.invert?"#fff":"#000",3),this.setSvg(this.c[3],"fill",this.bcolor,3)}rSize(){super.rSize();let t=this.s;t[2].width=this.sb+"px",t[2].left=this.sa+"px",this.cw=this.sb>256?256:this.sb,this.rSizeColor(this.cw),this.decal.x=Math.floor(.5*(this.w-this.wfixe))}rSizeColor(t){if(t===this.wfixe)return;this.wfixe=t;let s=this.s;this.decal.y="up"===this.side?2:this.baseH+2,this.mid=Math.floor(.5*this.wfixe),this.setSvg(this.c[3],"viewBox","0 0 "+this.wfixe+" "+this.wfixe),s[3].width=this.wfixe+"px",s[3].height=this.wfixe+"px",s[3].top=this.decal.y+"px",this.ratio=256/this.wfixe,this.square=1/(this.wfixe/256*60),this.setHeight()}}class u extends r{constructor(t={}){super(t),this.round=Math.round,this.baseH=this.h,this.hplus=t.hplus||50,this.res=t.res||40,this.l=1,this.precision=t.precision||0,this.custom=t.custom||!1,this.names=t.names||["FPS","MS"];let s=t.cc||["220,220,220","255,255,0"];this.adding=t.adding||!1,this.range=t.range||[165,100,100],this.alpha=t.alpha||.25,this.values=[],this.points=[],this.textDisplay=[],this.custom||(this.now=i.getTime(),this.startTime=0,this.prevTime=0,this.frames=0,this.ms=0,this.fps=0,this.mem=0,this.mm=0,this.isMem=!(!self.performance||!self.performance.memory),this.isMem&&(this.names.push("MEM"),s.push("0,255,255")),this.txt=t.name||"Fps");let e=Math.floor(.5*this.h)-3;const h=this.colors;this.c[1].textContent=this.txt,this.c[0].style.cursor="pointer",this.c[0].style.pointerEvents="auto";let o="display:none; left:10px; top:"+this.h+"px; height:"+(this.hplus-8)+"px; box-sizing:border-box; background: rgba(0, 0, 0, 0.2); border:1px solid "+h.border+";";0!==this.radius&&(o+="border-radius:"+this.radius+"px;"),this.c[2]=this.dom("path",this.css.basic+o,{}),this.c[2].setAttribute("viewBox","0 0 "+this.res+" 50"),this.c[2].setAttribute("height","100%"),this.c[2].setAttribute("width","100%"),this.c[2].setAttribute("preserveAspectRatio","none"),this.c[3]=this.dom("path",this.css.basic+"position:absolute; width:6px; height:6px; left:0; top:"+e+"px;",{d:this.svgs.g1,fill:h.text,stroke:"none"}),this.c[4]=this.dom("div",this.css.txt+"position:absolute; left:10px; top:"+(this.h+2)+"px; display:none; width:100%; text-align:center;"),t.bottomLine&&(this.c[4]=this.dom("div",this.css.basic+"width:100%; bottom:0px; height:1px; background: rgba(255, 255, 255, 0.2);")),this.isShow=!1;let n=this.s;n[1].lineHeight=this.h-4,n[1].color=h.text,0!==this.radius&&(n[0].borderRadius=this.radius+"px"),"none"!==this.colors.gborder&&(n[0].border="1px solid "+h.gborder);let r=0;for(r=0;r "+this.names[r]+" ")}for(r=this.names.length;r--;)this.dom("path",null,{fill:"rgba("+s[r]+","+this.alpha+")","stroke-width":1,stroke:"rgba("+s[r]+",1)","vector-effect":"non-scaling-stroke"},this.c[2]);this.init()}mousedown(t){this.isShow?this.close():this.open()}tick(t){this.values=t,this.isShow&&(this.drawGraph(),this.upText())}makePath(t){let s="";s+="M -1 50";for(let i=0;i";this.c[4].innerHTML=i}drawGraph(){let t,s=this.c[2],i=this.names.length,e=0,h=0;for(;i--;)t=this.adding?(this.values[h]+e)*this.range[h]:this.values[h]*this.range[h],this.points[h].shift(),this.points[h].push(50-t),this.setSvg(s,"d",this.makePath(this.points[h]),i+1),e+=this.values[h],h++}open(){super.open(),this.h=this.hplus+this.baseH,this.setSvg(this.c[3],"d",this.svgs.g2),null!==this.group?this.group.calc(this.hplus):this.isUI&&this.main.calc(this.hplus),this.s[0].height=this.h+"px",this.s[2].display="block",this.s[4].display="block",this.isShow=!0,this.custom||i.addListen(this)}close(){super.close(),this.h=this.baseH,this.setSvg(this.c[3],"d",this.svgs.g1),null!==this.group?this.group.calc(-this.hplus):this.isUI&&this.main.calc(-this.hplus),this.s[0].height=this.h+"px",this.s[2].display="none",this.s[4].display="none",this.isShow=!1,this.custom||i.removeListen(this),this.c[4].innerHTML=""}begin(){this.startTime=this.now()}end(){let t=this.now();if(this.ms=t-this.startTime,this.frames++,t>this.prevTime+1e3&&(this.fps=this.round(1e3*this.frames/(t-this.prevTime)),this.prevTime=t,this.frames=0,this.isMem)){let t=performance.memory.usedJSHeapSize,s=performance.memory.jsHeapSizeLimit;this.mem=this.round(954e-9*t),this.mm=t/s}return this.values=[this.fps,this.ms,this.mm],this.drawGraph(),this.upText([this.fps,this.ms,this.mem]),t}listening(){this.custom||(this.startTime=this.end())}rSize(){let t=this.s,s=this.w;t[3].left=this.sa+this.sb-6+"px",t[0].width=s+"px",t[1].width=s+"px",t[2].left="10px",t[2].width=s-20+"px",t[4].width=s-20+"px"}}class p extends r{constructor(t={}){super(t),this.value=void 0!==t.value?t.value:[0,0,0],this.lng=this.value.length,this.precision=void 0!==t.precision?t.precision:2,this.multiplicator=t.multiplicator||1,this.neg=t.neg||!1,this.line=void 0===t.line||t.line,this.autoWidth=void 0===t.autoWidth||t.autoWidth,this.isNumber=!1,this.isDown=!1,this.h=t.h||138,this.rh=this.h-10,this.top=0,this.c[0].style.width=this.w+"px",void 0!==this.c[1]&&(this.c[1].style.width=this.w+"px",this.autoWidth||(this.c[1].style.width="100%",this.c[1].style.justifyContent="center"),this.top=10,this.h+=10),this.gh=this.rh-28,this.gw=this.w-28,this.c[2]=this.dom("div",this.css.txt+"display:block; text-align:center; padding:0px 0px; top:"+(this.h-20)+"px; left:14px; width:"+this.gw+"px; color:"+this.colors.text),this.c[2].innerHTML=this.valueToHtml();let s=this.dom("svg",this.css.basic,{viewBox:"0 0 "+this.w+" "+this.rh,width:this.w,height:this.rh,preserveAspectRatio:"none"});this.setCss(s,{width:this.w,height:this.rh,left:0,top:this.top}),this.dom("path","",{d:"",stroke:this.colors.text,"stroke-width":2,fill:"none","stroke-linecap":"butt"},s),this.dom("rect","",{x:10,y:10,width:this.gw+8,height:this.gh+8,stroke:"rgba(0,0,0,0.3)","stroke-width":1,fill:"none"},s),this.iw=(this.gw-4*(this.lng-1))/this.lng;let i=[];this.cMode=[],this.v=[];for(let t=0;t',e="width:"+100/this.lng+"%;";for(;t--;)s===this.lng-1?i+=""+this.value[s]+"":i+=""+this.value[s]+"",s++;return i}updateSVG(){this.line&&this.setSvg(this.c[3],"d",this.makePath(),0);for(let t=0;tthis.top&&s.ye[i][0]&&s.xthis.distance){let t=Math.atan2(this.tmp.x,this.tmp.y);this.tmp.x=Math.sin(t)*this.distance,this.tmp.y=Math.cos(t)*this.distance}this.pos.copy(this.tmp).divideScalar(this.distance).negate(),this.update()}setValue(t){void 0===t&&(t=[0,0]),this.pos.set(t[0]||0,t[1]||0),this.updateSVG()}update(t){void 0===t&&(t=!0),null!==this.interval&&(this.isDown||(this.pos.lerp(null,.3),this.pos.x=Math.abs(this.pos.x)<.01?0:this.pos.x,this.pos.y=Math.abs(this.pos.y)<.01?0:this.pos.y,this.isUI&&this.main.isCanvas&&this.main.draw())),this.updateSVG(),t&&this.send(),this.pos.isZero()&&this.stopInterval()}updateSVG(){let t=.5*this.diam- -this.pos.x*this.distance,s=.5*this.diam- -this.pos.y*this.distance;if(0===this.model){let i=t+5*this.pos.x+5,e=s+5*this.pos.y+10;this.setSvg(this.c[3],"cx",i*this.ratio,3),this.setSvg(this.c[3],"cy",e*this.ratio,3)}else this.setSvg(this.c[3],"cx",t*this.ratio,3),this.setSvg(this.c[3],"cy",s*this.ratio,3);this.setSvg(this.c[3],"cx",t*this.ratio,4),this.setSvg(this.c[3],"cy",s*this.ratio,4),this.value[0]=1*(this.pos.x*this.multiplicator).toFixed(this.precision),this.value[1]=1*(this.pos.y*this.multiplicator).toFixed(this.precision),this.haveText&&(this.c[2].textContent=this.value)}clear(){this.stopInterval(),super.clear()}}class v extends r{constructor(t={}){super(t),this.isCyclic=t.cyclic||!1,this.model=t.stype||0,void 0!==t.mode&&(this.model=t.mode),this.autoWidth=!1,this.setTypeNumber(t),this.minw=this.w,this.diam=t.diam||this.w,this.mPI=.8*Math.PI,this.toDeg=180/Math.PI,this.cirRange=2*this.mPI,this.offset=new n,this.h=t.h||this.w+10,this.c[0].style.width=this.w+"px",this.c[0].style.display="block",void 0!==this.c[1]&&(this.c[1].style.width="100%",this.c[1].style.justifyContent="center",this.top=10,this.h+=10),this.percent=0,this.cmode=0;let s=this.colors;this.c[2]=this.dom("div",this.css.txt+"justify-content:center; top:"+(this.h-20)+"px; width:100%; color:"+s.text),this.c[3]=this.getKnob(),this.setSvg(this.c[3],"fill",s.button,0),this.setSvg(this.c[3],"stroke",s.text,1),this.setSvg(this.c[3],"stroke",s.text,3),this.setSvg(this.c[3],"d",this.makeGrad(),3),this.setSvg(this.c[3],"viewBox","0 0 "+this.diam+" "+this.diam),this.setCss(this.c[3],{width:this.diam,height:this.diam,left:0,top:this.top}),this.model>0&&(h.dom("path","",{d:"",stroke:s.text,"stroke-width":2,fill:"none","stroke-linecap":"round"},this.c[3]),2==this.model&&(h.addSVGGlowEffect(),this.setSvg(this.c[3],"style",'filter: url("#UILGlow");',4))),this.r=0,this.init(),this.update()}mode(t){let s=this.colors;if(this.cmode===t)return!1;switch(t){case 0:this.s[2].color=s.text,this.setSvg(this.c[3],"fill",s.button,0),this.setSvg(this.c[3],"stroke",s.text,1);break;case 1:this.s[2].color=s.textOver,this.setSvg(this.c[3],"fill",s.select,0),this.setSvg(this.c[3],"stroke",s.textOver,1)}return this.cmode=t,!0}testZone(t){let s=this.local;return-1===s.x&&-1===s.y?"":s.y<=this.c[1].offsetHeight?"title":s.y>this.h-this.c[2].offsetHeight?"text":"knob"}mouseup(t){return this.isDown=!1,this.sendEnd(),this.mode(0)}mousedown(t){return this.isDown=!0,this.old=this.value,this.oldr=null,this.mousemove(t),this.mode(1)}mousemove(t){if(!this.isDown)return;let s=this.offset;s.x=.5*this.w-(t.clientX-this.zone.x),s.y=.5*this.diam-(t.clientY-this.zone.y-this.ytop),this.r=-Math.atan2(s.x,s.y),null!==this.oldr&&(this.r=Math.abs(this.r-this.oldr)>Math.PI?this.oldr:this.r),this.r=this.r>this.mPI?this.mPI:this.r,this.r=this.r<-this.mPI?-this.mPI:this.r;let i=1/this.cirRange,e=(this.r+this.mPI)*i,h=this.range*e+this.min-this.old;(h>=this.step||h<=this.step)&&(h=Math.floor(h/this.step),this.value=this.numValue(this.old+h*this.step),this.update(!0),this.old=this.value,this.oldr=this.r)}wheel(t){if("knob"===this.testZone(t)){let s=this.value-this.step*t.delta;return s>this.max?s=this.isCyclic?this.min:this.max:s5?(s=this.range/this.step,t=(a-c)/s):(t=(a-c)/l*2,s=32);for(let c=0;c<=s;++c)i=a-t*c,e=l+44*Math.sin(i),h=l+44*Math.cos(i),o=l+40*Math.sin(i),n=l+40*Math.cos(i),r+="M"+e+" "+h+" L"+o+" "+n+" ";return r}update(t){this.c[2].textContent=this.value,this.percent=(this.value-this.min)/this.range;let s=Math.PI+this.mPI,i=this.percent*this.cirRange-this.mPI,e=Math.sin(i),o=Math.cos(i),n=25*e+64,r=-25*o+64,l=20*e+64,a=-20*o+64;if(this.setSvg(this.c[3],"d","M "+n+" "+r+" L "+l+" "+a,1),this.model>0){let t=36*Math.sin(s)+64,n=36*Math.cos(s)+64,r=36*e+64,l=-36*o+64,a=i<=Math.PI-this.mPI?0:1;this.setSvg(this.c[3],"d","M "+t+","+n+" A 36,36 1 "+a+" 1 "+r+","+l,4);let c=h.pack(h.lerpColor(h.unpack(h.ColorLuma(this.colors.text,-.75)),h.unpack(this.colors.text),this.percent));this.setSvg(this.c[3],"stroke",c,4)}t&&this.send()}}class b extends r{constructor(t={}){super(t),this.hideCurrent=!1,this.path=t.path||"",this.format=t.format||"",this.isWithImage=""!==this.path,this.preLoadComplete=!1,this.tmpImage={},this.tmpUrl=[],this.m=void 0!==t.m?t.m:5;let s=t.align||"left",i=t.scrollSize||10;this.ss=i+1,this.sMode=0,this.tMode=0,this.listOnly=t.listOnly||!1,this.staticTop=t.staticTop||!1,this.isSelectable=this.listOnly,void 0!==t.select&&(t.selectable=t.select),void 0!==t.selectable&&(this.isSelectable=t.selectable),""===this.txt&&(this.p=0);let e=Math.floor(.5*this.h)-3,h=this.colors;if(this.c[2]=this.dom("div",this.css.basic+"top:0; display:none; border-radius:"+this.radius+"px;"),this.c[3]=this.dom("div",this.css.item+"padding:0px "+this.m+"px; margin-bottom:0px; position:absolute; justify-content:"+s+"; text-align:"+s+"; line-height:"+(this.h-4)+"px; top:1px; background:"+h.button+"; height:"+(this.h-2)+"px; border:1px solid "+h.border+"; border-radius:"+this.radius+"px;"),this.c[4]=this.dom("path",this.css.basic+"position:absolute; width:6px; height:6px; top:"+e+"px;",{d:this.svgs.g1,fill:h.text,stroke:"none"}),this.scrollerBack=this.dom("div",this.css.basic+"right:0px; width:"+i+"px; background:"+h.back+"; display:none;"),this.scroller=this.dom("div",this.css.basic+"right:"+.5*(i-.25*i)+"px; width:"+.25*i+"px; background:"+h.text+"; display:none; "),this.c[3].style.color=h.text,this.list=[],this.refObject=null,t.list)if(t.list instanceof Array)this.list=t.list;else if(t.list instanceof Object){this.refObject=t.list;for(let t in this.refObject)this.list.push(t)}this.items=[],this.prevName="",this.tmpId=0,this.baseH=this.h,this.itemHeight=t.itemHeight||this.h,this.full=t.full||!1,this.py=0,this.ww=this.sb,this.scroll=!1,this.isDown=!1,this.current=null,this.side=t.side||"down",this.up="down"===this.side?0:1,this.up?(this.c[2].style.top="auto",this.c[3].style.top="auto",this.c[4].style.top="auto",this.c[2].style.bottom=this.h-2+"px",this.c[3].style.bottom="1px",this.c[4].style.bottom=e+"px"):this.c[2].style.top=this.baseH+"px",this.listIn=this.dom("div",this.css.basic+"left:0; top:0; width:100%; background:none;"),this.listIn.name="list",this.topList=0,this.c[2].appendChild(this.listIn),this.c[2].appendChild(this.scrollerBack),this.c[2].appendChild(this.scroller),void 0!==t.value?isNaN(t.value)?this.value=t.value:this.value=this.list[t.value]:this.value=this.list[0],this.isOpenOnStart=t.open||!1,this.listOnly&&(this.baseH=5,this.c[3].style.display="none",this.c[4].style.display="none",this.c[2].style.top=this.baseH+"px",this.isOpenOnStart=!0),this.miniCanvas=t.miniCanvas||!1,this.canvasBg=t.canvasBg||"rgba(0,0,0,0)",this.imageSize=t.imageSize||[20,20],this.drag=t.drag||!1,this.dragout=t.dragout||!1,this.dragstart=t.dragstart||null,this.dragend=t.dragend||null,this.setList(this.list),this.init(),this.isWithImage&&this.preloadImage(),this.isOpenOnStart&&this.open(!0),this.baseH+=this.mtop}preloadImage(){this.preLoadComplete=!1,this.tmpImage={};for(let t=0;tthis.h-this.baseH)return"title";if(this.scroll&&s.x>this.sa+this.sb-this.ss)return"scroll";if(s.x>this.sa)return this.testItems(s.y-this.baseH)}else{if(s.ythis.sa+this.sb-this.ss)return"scroll";if(s.x>this.sa)return this.testItems(s.y-this.baseH)}}return""}testItems(t){let s,i,e,h="",o=this.items,n=o.length;for(;n--;)if(s=o[n],i=s.posy+this.topList,e=s.posy+this.itemHeight+1+this.topList,t>=i&&t<=e)return h="item"+n,this.modeItem(0),this.current=s,this.modeItem(1),h;return h}modeItem(t){if(!this.current)return;this.current.select&&0===t&&(t=2);let s=this.colors;switch(t){case 0:this.current.style.background=s.back,this.current.style.color=s.text;break;case 1:this.current.style.background=s.over,this.current.style.color=s.textOver;break;case 2:this.current.style.background=s.select,this.current.style.color=s.textSelect}}unSelected(){this.current&&(this.modeItem(0),this.current=null)}selected(){this.current&&(this.resetItems(),this.modeItem(2),this.current.select=!0)}resetItems(){let t=this.items.length;for(;t--;)this.items[t].select=!1,this.items[t].style.background=this.colors.back,this.items[t].style.color=this.colors.text}hideActive(){this.hideCurrent&&(this.current&&(this.tmpId=this.current.id),this.resetHide())}resetHide(){console.log(this.tmpId);let t=this.items.length;for(;t--;)t===this.tmpId?(this.items[t].style.height="0px",this.items[t].posy=-1):(this.items[t].style.height=this.itemHeight+"px",this.items[t].posy=(this.itemHeight+1)*(t-1))}mouseup(t){this.isDown=!1}mousedown(t){let s=this.testZone(t);return!!s&&("scroll"===s?(this.isDown=!0,this.mousemove(t)):"title"===s?(this.modeTitle(2),this.listOnly||(this.hideActive(),this.isOpen?this.close():this.open())):this.current&&(this.value=this.list[this.current.id],this.isSelectable&&this.selected(),this.send(this.value),this.listOnly||(this.close(),this.setTopItem())),!0)}mousemove(t){let s=!1,i=this.testZone(t);if(!i)return s;if("title"===i)this.unSelected(),this.modeTitle(1),this.cursor("pointer");else if("scroll"===i){if(this.cursor("s-resize"),this.modeScroll(1),this.isDown){this.modeScroll(2);let s=this.zone.y+this.baseH-2;this.update(t.clientY-s-.5*this.sh)}}else this.modeTitle(0),this.modeScroll(0),this.cursor("pointer");return i!==this.prevName&&(s=!0),this.prevName=i,s}wheel(t){return"title"!==this.testZone(t)&&(this.py+=10*t.delta,this.update(this.py),!0)}reset(){this.prevName="",this.unSelected(),this.modeTitle(0),this.modeScroll(0)}modeScroll(t){if(t===this.sMode)return;let s=this.scroller.style,i=this.colors;switch(t){case 0:s.background=i.text;break;case 1:case 2:s.background=i.select}this.sMode=t}modeTitle(t){if(t===this.tMode)return;let s=this.s,i=this.colors;switch(t){case 0:s[3].color=i.text,s[3].background=i.button;break;case 1:s[3].color=i.textOver,s[3].background=i.overoff;break;case 2:s[3].color=i.textSelect,s[3].background=i.overoff}this.tMode=t}clearList(){for(;this.listIn.children.length;)this.listIn.removeChild(this.listIn.lastChild);this.items=[]}setList(t){this.clearList(),this.list=t,this.length=this.list.length;let s,e,h=this.hideCurrent?this.length-1:this.length;this.maxItem=this.full?h:5,this.maxItem=hthis.maxHeight&&(this.ww=this.sb-this.ss,this.scroll=!0),this.miniCanvas&&(this.tmpCanvas=document.createElement("canvas"),this.tmpCanvas.width=this.imageSize[0],this.tmpCanvas.height=this.imageSize[1],this.tmpCtx=this.tmpCanvas.getContext("2d"),this.tmpCtx.fillStyle=this.canvasBg,this.tmpCtx.fillRect(0,0,this.imageSize[0],this.imageSize[1]));for(let t=0;tthis.range?this.range:t,this.topList=-Math.floor(t/this.ratio),this.listIn.style.top=this.topList+"px",this.scroller.style.top=Math.floor(t)+"px",this.py=t)}parentHeight(t){null!==this.group?this.group.calc(t):this.isUI&&this.main.calc(t)}open(t){super.open(),this.update(0),this.h=this.maxHeight+this.baseH+5,this.scroll?(this.scroller.style.display="block",this.scrollerBack.style.display="block"):(this.topList=0,this.h=this.baseH+5+this.max,this.scroller.style.display="none",this.scrollerBack.style.display="none"),this.s[0].height=this.h+"px",this.s[2].display="block",this.up?(this.zone.y-=this.h-(this.baseH-10),this.setSvg(this.c[4],"d",this.svgs.g1)):this.setSvg(this.c[4],"d",this.svgs.g2),this.rSizeContent();let s=this.h-this.baseH;this.zone.h=this.h,t||this.parentHeight(s)}close(){super.close(),this.up&&(this.zone.y+=this.h-(this.baseH-10));let t=this.h-this.baseH;this.h=this.baseH,this.s[0].height=this.h+"px",this.s[2].display="none",this.setSvg(this.c[4],"d",this.svgs.g1),this.zone.h=this.h,this.parentHeight(-t)}text(t){this.c[3].textContent=t}rSizeContent(){let t=this.length;for(;t--;)this.listIn.children[t].style.width=this.ww+"px"}rSize(){super.rSize();let t=this.s,s=this.sb,i=this.sa;void 0!==t[2]&&(t[2].width=s+"px",t[2].left=i+"px",t[3].width=s+"px",t[3].left=i+"px",t[4].left=i+s-15+"px",this.ww=s,this.max>this.maxHeight&&(this.ww=s-this.ss),this.isOpen&&this.rSizeContent())}}class f extends r{constructor(t={}){super(t),this.setTypeNumber(t),this.allway=t.allway||!1,this.isDown=!1,this.value=[0],this.multy=1,this.invmulty=1,this.isSingle=!0,this.isAngle=!1,this.isVector=!1,t.isAngle&&(this.isAngle=!0,this.multy=h.torad,this.invmulty=h.todeg),this.isDrag=t.drag||!1,void 0!==t.value&&(isNaN(t.value)?t.value instanceof Array?(this.value=t.value,this.isSingle=!1):t.value instanceof Object&&(this.value=[],void 0!==t.value.x&&(this.value[0]=t.value.x),void 0!==t.value.y&&(this.value[1]=t.value.y),void 0!==t.value.z&&(this.value[2]=t.value.z),void 0!==t.value.w&&(this.value[3]=t.value.w),this.isSingle=!1,this.isVector=!0):this.value=[t.value]),this.lng=this.value.length,this.tmp=[],this.current=-1,this.prev={x:0,y:0,d:0,v:0};let s=this.colors;this.c[2]=this.dom("div",this.css.basic+" background:"+s.select+"; top:4px; width:0px; height:"+(this.h-8)+"px;"),this.cMode=[];let i=this.lng;for(;i--;)this.isAngle&&(this.value[i]=(180*this.value[i]/Math.PI).toFixed(this.precision)),this.c[3+i]=this.dom("div",this.css.txtselect+"top:1px; height:"+(this.h-2)+"px; color:"+s.text+"; background:"+s.back+"; borderColor:"+s.border+"; border-radius:"+this.radius+"px;"),t.center&&(this.c[2+i].style.textAlign="center"),this.c[3+i].textContent=this.value[i],this.c[3+i].style.color=this.colors.text,this.c[3+i].isNum=!0,this.cMode[i]=0;this.selectId=3+this.lng,this.c[this.selectId]=this.dom("div",this.css.txtselect+"position:absolute; top:2px; height:"+(this.h-4)+"px; padding:0px 0px; width:0px; color:"+s.textSelect+"; background:"+s.select+"; border:none; border-radius:0px;"),this.cursorId=4+this.lng,this.c[this.cursorId]=this.dom("div",this.css.basic+"top:2px; height:"+(this.h-4)+"px; width:0px; background:"+s.text+";"),this.init()}testZone(t){let s=this.local;if(-1===s.x&&-1===s.y)return"";let i=this.lng,e=this.tmp;for(;i--;)if(s.x>e[i][0]&&s.x=this.txl?"text":s.x>=this.sa?"scroll":""}mouseup(t){this.isDown&&(this.isDown=!1)}mousedown(t){let s=this.testZone(t);return!!s&&("scroll"===s&&(this.isDown=!0,this.old=this.value,this.mousemove(t)),!0)}mousemove(t){let s=!1;if("scroll"===this.testZone(t)?(this.mode(1),this.cursor("w-resize")):this.cursor(),this.isDown){let i=(t.clientX-(this.zone.x+this.sa)-3)/this.ww*this.range+this.min-this.old;(i>=this.step||i<=this.step)&&(i=Math.floor(i/this.step),this.value=this.numValue(this.old+i*this.step),this.update(!0),this.old=this.value),s=!0}return s}wheel(t){if("scroll"===this.testZone(t)){let s=this.value-this.step*t.delta;return s>this.max?s=this.isCyclic?this.min:this.max:s=this.sa?"text":""}mouseup(t){if(this.editable)return!!this.isDown&&(this.isDown=!1,this.mousemove(t))}mousedown(t){if(!this.editable)return;let s=this.testZone(t);return!this.isDown&&(this.isDown=!0,"text"===s&&this.setInput(this.c[2]),this.mousemove(t))}mousemove(t){if(!this.editable)return;let s=0;return"text"===this.testZone(t)?this.cursor("text"):this.cursor(),this.isDown&&(s=t.clientX-this.zone.x),this.upInput(s-this.sa-3,this.isDown)}update(){this.c[2].textContent=this.value}reset(){this.cursor()}select(t,s,i,e){let h=this.s,o=this.sa+5;h[4].width="1px",h[4].left=o+s+"px",h[3].left=o+s+"px",h[3].width=i+"px",this.c[3].innerHTML=e}unselect(){let t=this.s;t&&(t[3].width="0px",this.c[3].innerHTML="t",t[4].width="0px")}validate(t){this.allway&&(t=!0),this.value=this.c[2].textContent,""!==this.value?this.c[5].textContent="":this.c[5].textContent=this.placeHolder,t&&this.send()}rSize(){super.rSize();let t=this.s;t[2].left=this.sa+"px",t[2].width=this.sb+"px",t[5].left=this.sa+"px",t[5].width=this.sb+"px"}}class k extends r{constructor(t={}){super(t);let s=t.prefix||"";this.c[2]=this.dom("div",this.css.txt+"justify-content:right; width:60px; line-height:"+(this.h-8)+"px; color:"+this.colors.text),31===this.h&&(this.s[0].height=this.h+"px",this.s[1].top="8px",this.c[2].style.top="8px");let i=this.s;i[1].justifyContent=t.align||"left",i[1].fontWeight=t.fontWeight||"bold",this.c[1].textContent=this.txt.substring(0,1).toUpperCase()+this.txt.substring(1).replace("-"," "),this.c[2].textContent=s,this.init()}text(t){this.c[1].textContent=t}text2(t){this.c[2].textContent=t}rSize(){super.rSize(),this.s[1].width=this.w+"px",this.s[2].left=this.w+"px"}setColor(t){this.s[1].color=t,this.s[2].color=t}}class S extends r{constructor(t={}){super(t),this.value=t.value||"",this.isDown=!1,this.onActif=t.onActif||function(){};const s=this.colors;this.c[2]=this.dom("div",this.css.txt+this.css.button+" top:1px; background:"+s.button+"; height:"+(this.h-2)+"px; border:"+s.buttonBorder+"; border-radius:15px; width:30px; left:10px;"),this.c[3]=this.dom("div",this.css.txtselect+"height:"+(this.h-4)+"px; background:"+s.inputBg+"; borderColor:"+s.inputBorder+"; border-radius:"+this.radius+"px;"),this.c[3].textContent=this.value;let i=Math.floor(.5*this.h)-7;this.c[4]=this.dom("path",this.css.basic+"position:absolute; width:14px; height:14px; left:5px; top:"+i+"px;",{d:this.svgs.cursor,fill:s.text,stroke:"none"}),this.stat=1,this.isActif=!1,this.init()}testZone(t){let s=this.local;return-1===s.x&&-1===s.y?"":s.x>this.sa&&s.xthis.sa&&s.xthis.sa-30&&s.xi[r][0]&&s.xe[r][0]&&s.ythis.lng-1&&(h=-1)),h}mouseup(t){return!!this.isDown&&(this.isDown=!1,-1!==this.res&&(this.value=this.values[this.res],this.send()),this.mousemove(t))}mousedown(t){return!this.isDown&&(this.isDown=!0,this.mousemove(t))}mousemove(t){let s=!1;return this.res=this.testZone(t),-1!==this.res?(this.cursor("pointer"),s=this.modes(this.isDown?3:2,this.res)):s=this.reset(),s}update(){this.modes(2,this.values.indexOf(this.value))}modes(t=1,s=-1){let i,e,h=this.lng,o=!1;for(;h--;)e=t,i=!!this.isSelectable&&this.values[h]===this.value,h===s?i&&2===e&&(e=3):(e=1,i&&(e=4)),this.mode(e,h)&&(o=!0);return o}mode(t,s){let i=!1,e=this.colors,h=this.buttons,o=s;if(this.stat[s]!==t){switch(this.stat[s]=t,t){case 1:h[o].style.color=e.text,h[o].style.background=e.button;break;case 2:h[o].style.color=e.textOver,h[o].style.background=e.overoff;break;case 3:h[o].style.color=e.textOver,h[o].style.background=e.over;break;case 4:h[o].style.color=e.textSelect,h[o].style.background=e.select}i=!0}return i}reset(){return this.res=-1,this.cursor(),this.modes()}label(t,s){this.buttons[s].textContent=t}icon(t,s,i){this.buttons[i].style.padding=(s||0)+"px 0px",this.buttons[i].innerHTML=t}testW(){let t=!1;if(3*this.spaces[0]+2*this.bsizeMax>this.w?(this.bsize[0]=.5*(this.w-3*this.spaces[0]),t=!0):this.bsize[0]!==this.bsizeMax&&(this.bsize[0]=this.bsizeMax,t=!0),!t)return;let s=this.buttons.length;for(;s--;)this.buttons[s].style.width=this.bsize[0]+"px"}rSize(){let t;super.rSize(),this.testW(),this.tmpX=[],this.tmpY=[];for(let s=0;sthis.h-this.c[2].offsetHeight?"text":"pad"}mouseup(t){return this.isDown=!1,this.mode(0)}mousedown(t){if("pad"===this.testZone(t))return this.isDown=!0,this.mousemove(t),this.mode(1)}mousemove(t){if(!this.isDown)return;let s=.5*this.w-(t.clientX-this.zone.x),i=.5*this.diam-(t.clientY-this.zone.y-this.ytop),e=256/this.diam;s=-s*e,i=-i*e,s=h.clamp(s,-this.maxPos,this.maxPos),i=h.clamp(i,-this.maxPos,this.maxPos),this.setPos([s,i]),this.update(!0)}mode(t){if(this.cmode===t)return!1;let s=this.colors;switch(t){case 0:this.s[2].color=s.text,this.setSvg(this.c[3],"fill",s.back,0),this.setSvg(this.c[3],"fill",s.button,1),this.setSvg(this.c[3],"stroke",s.back,2),this.setSvg(this.c[3],"stroke",s.back,3),this.setSvg(this.c[3],"stroke",s.text,4);break;case 1:this.s[2].color=s.textSelect,this.setSvg(this.c[3],"fill",s.backoff,0),this.setSvg(this.c[3],"fill",s.overoff,1),this.setSvg(this.c[3],"stroke",s.backoff,2),this.setSvg(this.c[3],"stroke",s.backoff,3),this.setSvg(this.c[3],"stroke",s.textSelect,4)}return this.cmode=t,!0}update(t){this.c[2].textContent=this.value,this.updateSVG(),t&&this.send()}updateSVG(){1==this.model&&(this.setSvg(this.c[3],"y1",this.pos.y,2),this.setSvg(this.c[3],"y2",this.pos.y,2),this.setSvg(this.c[3],"x1",this.pos.x,3),this.setSvg(this.c[3],"x2",this.pos.x,3)),this.setSvg(this.c[3],"cx",this.pos.x,4),this.setSvg(this.c[3],"cy",this.pos.y,4)}setPos(t){this.pos.set(t[0]+128,t[1]+128);let s=1/this.maxPos;this.value[0]=(t[0]*s*this.range).toFixed(this.precision),this.value[1]=(t[1]*s*this.range).toFixed(this.precision)}setValue(t,s=!1){void 0===t&&(t=this.value),this.value[0]=1*Math.min(this.max,Math.max(this.min,t[0])).toFixed(this.precision),this.value[1]=1*Math.min(this.max,Math.max(this.min,t[1])).toFixed(this.precision),this.pos.set(this.value[0]/this.range*this.maxPos+128,this.value[1]/this.range*this.maxPos+128),this.update(s)}}const T=function(){let t,s,e=arguments,h=!1,o=null;"string"==typeof e[0]?(t=e[0],s=e[1]||{}):"object"==typeof e[0]&&(h=!0,void 0===e[2]&&[].push.call(e,{}),t=e[2].type?e[2].type:O(e[0][e[1]],e[2]),s=e[2],s.name=e[1],"list"!==t||s.list?s.value=e[0][e[1]]:s.list=e[0][e[1]]);let n=t.toLowerCase();switch("group"===n&&(s.add=T),n){case"bool":case"boolean":o=new l(s);break;case"button":o=new a(s);break;case"circular":o=new c(s);break;case"color":o=new d(s);break;case"fps":o=new u(s);break;case"graph":o=new p(s);break;case"group":o=new g(s);break;case"joystick":o=new x(s);break;case"knob":o=new v(s);break;case"list":o=new b(s);break;case"numeric":case"number":o=new f(s);break;case"slide":o=new w(s);break;case"textInput":case"string":o=new y(s);break;case"title":case"text":o=new k(s);break;case"select":o=new S(s);break;case"bitmap":o=new I(s);break;case"selector":o=new C(s);break;case"empty":case"space":o=new m(s);break;case"item":o=new M(s);break;case"grid":o=new L(s);break;case"pad2d":case"pad":o=new z(s)}if(null!==o)return i.needResize=!0,h&&o.setReferency(e[0],e[1]),o},O=function(t,s){let i="slide";return t.isColor?i="color":t.isTexture?i="bitmap":"boolean"==typeof t?i="bool":"string"==typeof t?i="#"===t.substring(0,1)?"color":"string":"number"==typeof t?i=s.ctype?"color":"slide":"array"==typeof t&&t instanceof Array?"number"==typeof t[0]?i="number":"string"==typeof t[0]&&(i="list"):"object"==typeof t&&t instanceof Object&&(i=void 0!==t.x?"number":"list"),i};class H{constructor(t={}){this.isGui=!0,this.name="gui",this.canvas=null,this.screen=null,this.plane=t.plane||null,t.config&&(t.colors=t.config),t.colors?this.setConfig(t.colors):this.colors=h.defineColor(t),this.css=h.cloneCss(),this.isReset=!0,this.tmpAdd=null,this.isCanvas=t.isCanvas||!1,this.isCanvasOnly=!1,this.callback=void 0===t.callback?null:t.callback,this.forceHeight=t.maxHeight||0,this.lockHeight=t.lockHeight||!1,this.isItemMode=void 0!==t.itemMode&&t.itemMode,this.cn="",this.size=h.size,void 0!==t.p&&(this.size.p=t.p),void 0!==t.w&&(this.size.w=t.w),void 0!==t.h&&(this.size.h=t.h),void 0!==t.s&&(this.size.s=t.s),this.size.h=this.size.h<11?11:this.size.h,this.local=(new n).neg(),this.zone={x:0,y:0,w:this.size.w,h:0},this.mouse=(new n).neg(),this.h=0,this.sw=0,this.margin=this.colors.sy,this.marginDiv=h.isDivid(this.margin),this.isWithClose=void 0===t.close||t.close,this.bh=this.isWithClose?this.size.h:0,this.autoResize=void 0===t.autoResize||t.autoResize,this.isCenter=t.center||!1,this.isBottom=t.bottom||!1,this.bottomPosition=t.bottom||0,this.cssGui=void 0!==t.css?t.css:this.isCenter?"":"right:10px;",this.isOpen=void 0===t.open||t.open,this.isDown=!1,this.isScroll=!1,this.uis=[],this.current=-1,this.proto=null,this.isEmpty=!0,this.decal=0,this.ratio=1,this.oy=0,this.isNewTarget=!1;let s=this.colors,e="border: 2px solid "+s.content+"; ";this.content=h.dom("div",this.css.basic+" width:0px; height:auto; top:0px; background:"+s.content+"; "+this.cssGui+e),this.innerContent=h.dom("div",this.css.basic+"width:100%; top:0; left:0; height:auto; overflow:hidden;"),this.content.appendChild(this.innerContent),this.useFlex=!0;let o=this.useFlex?"display:flex; flex-flow: row wrap;":"";this.inner=h.dom("div",this.css.basic+o+"width:100%; left:0; "),this.innerContent.appendChild(this.inner),this.scrollBG=h.dom("div",this.css.basic+"right:0; top:0; width:"+(this.size.s-1)+"px; height:10px; display:none; background:"+s.background+";"),this.content.appendChild(this.scrollBG),this.scroll=h.dom("div",this.css.basic+"background:"+s.button+"; right:2px; top:0; width:"+(this.size.s-4)+"px; height:10px;"),this.scrollBG.appendChild(this.scroll),this.bottomText=t.bottomText||["open","close"];let r=s.radius;this.bottom=h.dom("div",this.css.txt+"width:100%; top:auto; bottom:0; left:0; border-bottom-right-radius:"+r+"px; border-bottom-left-radius:"+r+"px; justify-content:center; height:"+this.bh+"px; line-height:"+(this.bh-5)+"px; color:"+s.text+";"),this.content.appendChild(this.bottom),this.bottom.textContent=this.isOpen?this.bottomText[1]:this.bottomText[0],this.bottom.style.background=s.background,this.parent=void 0!==t.parent?t.parent:null,this.parent=void 0!==t.target?t.target:this.parent,null!==this.parent||this.isCanvas||(this.parent=document.body),null!==this.parent&&this.parent.appendChild(this.content),this.isCanvas&&null===this.parent&&(this.isCanvasOnly=!0),this.isCanvasOnly?(this.content.style.left="0px",this.content.style.right="auto",t.transition=0):this.content.style.pointerEvents="auto",this.transition=void 0!==t.transition?t.transition:h.transition,this.transition&&setTimeout(this.addTransition.bind(this),1e3),this.setWidth(),this.isCanvas&&this.makeCanvas(),i.add(this)}setLeft(t){this.content.style.left=t+"px",i.needReZone=!0}setTop(t,s){this.content.style.top=t+"px",void 0!==s&&(this.forceHeight=s),this.calc(),i.needReZone=!0}addTransition(){this.transition&&!this.isCanvas&&(this.innerContent.style.transition="height "+this.transition+"s ease-out",this.content.style.transition="height "+this.transition+"s ease-out",this.bottom.style.transition="top "+this.transition+"s ease-out");let t=this.uis.length;for(;t--;)this.uis[t].addTransition()}onDraw(){}makeCanvas(){this.canvas=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"),this.canvas.width=this.zone.w,this.canvas.height=this.forceHeight?this.forceHeight:this.zone.h}draw(t){if(null===this.canvas)return;let s=this.zone.w,e=this.forceHeight?this.forceHeight:this.zone.h;i.toCanvas(this,s,e,t)}getDom(){return this.content}noMouse(){this.mouse.neg()}setMouse(t,s=!0){s?this.mouse.set(Math.round(t.x*this.canvas.width),this.canvas.height-Math.round(t.y*this.canvas.height)):this.mouse.set(Math.round(t.x*this.canvas.width),Math.round(t.y*this.canvas.height))}setConfig(t){h.setText(),this.colors=h.defineColor(t)}setColors(t){for(let s in t)this.colors[s]&&(this.colors[s]=t[s])}setText(t,s,i,e){h.setText(t,s,i,e)}hide(t){this.content.style.visibility=t?"hidden":"visible"}display(t=!1){this.content.style.visibility=t?"visible":"hidden"}onChange(t){return this.callback=t||null,this}mode(t){let s=!1,e=this.colors;if(t!==this.cn){switch(this.cn=t,t){case"def":i.cursor(),this.scroll.style.background=e.button,this.bottom.style.background=e.background,this.bottom.style.color=e.text;break;case"scrollOver":i.cursor("ns-resize"),this.scroll.style.background=e.select;break;case"scrollDown":this.scroll.style.background=e.select;break;case"bottomOver":i.cursor("pointer"),this.bottom.style.background=e.backgroundOver,this.bottom.style.color=e.textOver}s=!0}return s}clearTarget(){return-1!==this.current&&(this.proto.s&&(this.proto.uiout(),this.proto.reset()),this.proto=null,this.current=-1,i.cursor(),!0)}testZone(t){let s=this.local;if(-1===s.x&&-1===s.y)return"";this.isReset=!1;let i="",e=this.isScroll?this.zone.w-this.size.s:this.zone.w;return i=s.y>this.zone.h-this.bh&&s.ye?"scroll":"content",i}handleEvent(t){let s=t.type,e=!1,h=!1,o=this.testZone(t);if("mouseup"===s&&this.isDown&&(this.isDown=!1),"mousedown"!==s||this.isDown||(this.isDown=!0),this.isDown&&this.isNewTarget&&(i.clearInput(),this.isNewTarget=!1),o){switch(o){case"content":t.clientY=this.isScroll?t.clientY+this.decal:t.clientY,i.isMobile&&"mousedown"===s&&this.getNext(t,e),this.proto&&(h=this.proto.handleEvent(t)),"mousemove"===s&&(e=this.mode("def")),"wheel"===s&&!h&&this.isScroll&&(e=this.onWheel(t)),i.lock||this.getNext(t,e);break;case"bottom":this.clearTarget(),"mousemove"===s&&(e=this.mode("bottomOver")),"mousedown"===s&&(this.isOpen=!this.isOpen,this.bottom.textContent=this.isOpen?this.bottomText[1]:this.bottomText[0],this.calc(),this.mode("def"),e=!0);break;case"scroll":this.clearTarget(),"mousemove"===s&&(e=this.mode("scrollOver")),"mousedown"===s&&(e=this.mode("scrollDown")),"wheel"===s&&(e=this.onWheel(t)),this.isDown&&this.update(t.clientY-this.zone.y-.5*this.sh)}this.isDown&&(e=!0),h&&(e=!0),"keyup"===s&&(e=!0),"keydown"===s&&(e=!0),e&&this.draw()}}getNext(t,s){let e=i.findTarget(this.uis,t);e!==this.current&&(this.clearTarget(),this.current=e,this.isNewTarget=!0),-1!==e&&(this.proto=this.uis[this.current],this.proto.uiover())}onWheel(t){return this.oy+=20*t.delta,this.update(this.oy),!0}reset(t){if(this.isReset)return;this.mouse.neg(),this.isDown=!1;let s=this.mode("def"),i=this.clearTarget();(s||i)&&this.draw(!0),this.isReset=!0}add(){let t=arguments,s=!1;"object"==typeof t[1]?(t[1].isUI=!0,t[1].main=this,s=!!t[1].ontop&&t[1].ontop):"string"==typeof t[1]&&(void 0===t[2]?[].push.call(t,{isUI:!0,main:this}):(t[2].isUI=!0,t[2].main=this,s=!!t[2].ontop&&t[2].ontop));let i=T.apply(this,t);if(null!==i)return s?this.uis.unshift(i):this.uis.push(i),this.calc(),this.isEmpty=!1,i}remove(t){t.dispose&&t.dispose()}clearOne(t){let s=this.uis.indexOf(t);-1!==s&&(this.inner.removeChild(this.uis[s].c[0]),this.uis.splice(s,1),this.calc())}empty(){let t,s=this.uis.length;for(;s--;)t=this.uis.pop(),this.inner.removeChild(t.c[0]),t.dispose();this.uis=[],this.isEmpty=!0,this.calc()}clear(){this.empty()}clear2(){setTimeout(this.empty.bind(this),0)}dispose(){this.clear(),null!==this.parent&&this.parent.removeChild(this.content),i.remove(this)}resetItem(){if(!this.isItemMode)return;let t=this.uis.length;for(;t--;)this.uis[t].selected()}setItem(t){if(!this.isItemMode)return;if(t=t||"",this.resetItem(),!t)return void this.update(0);let s=this.uis.length;for(;s--;)this.uis[s].value===t&&(this.uis[s].selected(!0),this.isScroll&&this.update(s*(this.uis[s].h+this.margin)*this.ratio))}upScroll(t){this.sw=t?this.size.s:0,this.oy=t?this.oy:0,this.scrollBG.style.display=t?"block":"none",t&&(this.total=this.h,this.maxView=this.maxHeight,this.ratio=this.maxView/this.total,this.sh=this.maxView*this.ratio,this.range=this.maxView-this.sh,this.oy=h.clamp(this.oy,0,this.range),this.scrollBG.style.height=this.maxView+"px",this.scroll.style.height=this.sh+"px"),this.setItemWidth(this.zone.w-this.sw),this.update(this.oy)}update(t){t=h.clamp(t,0,this.range),this.decal=Math.floor(t/this.ratio),this.inner.style.top=-this.decal+"px",this.scroll.style.top=Math.floor(t)+"px",this.oy=t}calcUis(){return i.calcUis(this.uis,this.zone,this.zone.y)}calc(){clearTimeout(this.tmp),this.tmp=setTimeout(this.setHeight.bind(this),10)}setHeight(){if(this.tmp&&clearTimeout(this.tmp),this.zone.h=this.bh,this.isScroll=!1,this.isOpen){this.h=this.calcUis();let t=this.forceHeight?this.forceHeight+this.zone.y:window.innerHeight,s=this.isBottom?this.bottomPosition:this.zone.y;this.maxHeight=t-s-this.bh,this.h-this.maxHeight>1?(this.isScroll=!0,this.zone.h=this.maxHeight+this.bh):this.zone.h=this.h+this.bh}this.upScroll(this.isScroll),this.innerContent.style.height=this.zone.h-this.bh+"px",this.content.style.height=this.zone.h+"px",this.bottom.style.top=this.zone.h-this.bh+"px",this.isBottom&&(this.content.style.top=window.innerHeight-this.zone.h-this.bottomPosition+"px",this.rezone()),this.forceHeight&&this.lockHeight&&(this.content.style.height=this.forceHeight+"px"),this.isCanvas&&this.draw(!0)}rezone(){i.needReZone=!0}zoneReset(){}setWidth(t){t&&(this.zone.w=t),this.zone.w=Math.floor(this.zone.w),this.content.style.width=this.zone.w+"px",this.isCenter&&(this.content.style.marginLeft=-Math.floor(.5*this.zone.w)+"px"),this.setItemWidth(this.zone.w-this.sw)}setItemWidth(t){let s=this.uis.length;for(;s--;)this.uis[s].setSize(t),this.uis[s].rSize()}}export{o as Files,H as Gui,t as REVISION,h as Tools,T as add};