toto10 commited on
Commit
4769705
·
1 Parent(s): 7cfb96a

Delete posex

Browse files
posex/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- __pycache__
2
- .vscode/
3
- venv/
 
 
 
 
posex/README.md DELETED
@@ -1,98 +0,0 @@
1
- # Posex - Estimated Image Generator for Pose2Image
2
-
3
- ![cover](./image/sample.png)
4
-
5
- ## Quick Start with [Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
6
-
7
- 1. Install [Mikubill/sd-webui-controlnet](https://github.com/Mikubill/sd-webui-controlnet).
8
- 2. Install Posex (this).
9
- 3. Open `Posex` accordion in t2i tab (or i2i as you like). Enable `Send this image to ControlNet` checkbox. Editor will appear.
10
- 4. Configure ControlNet as below.
11
- ```
12
- Preprocessor: none
13
- Model: control_sd15_openpose
14
- ```
15
- 5. Make pose.
16
- 6. Generate images.
17
-
18
- ## How to use
19
-
20
- ```
21
- Click: select body
22
- Left Drag: move joint (on joint)
23
- rotate camera (otherwise)
24
- Right Drag: move whole body (if selected)
25
- move camera (otherwise)
26
- Wheel: zoom
27
- ```
28
-
29
- ## Installation
30
-
31
- - [Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) Extension
32
- - Online (Github Pages)
33
- - Standalone
34
-
35
- ### [Web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) Extension
36
-
37
- **Prerequirement: You need to install [Mikubill/sd-webui-controlnet](https://github.com/Mikubill/sd-webui-controlnet) to use Posex with ControlNet Pose2Img.**
38
-
39
- Go to `Extensions` tab, then select `Install from URL` tab and input `https://github.com/hnmr293/posex`.
40
-
41
- Or move to `extensions` directory and type `git clone https://github.com/hnmr293/posex`.
42
-
43
- In webui, open `Posex` accordion in `txt2img` or `img2img` tab, then click a checkbox. The canvas will be opened.
44
-
45
- ### Online
46
-
47
- See Github Pages.
48
-
49
- [https://hnmr293.github.io/posex](https://hnmr293.github.io/posex)
50
-
51
- ### Standalone
52
-
53
- ```
54
- $ pip install -r requirements.txt
55
- $ python app.py
56
- ```
57
-
58
- Then open `localhost:55502` or `127.0.0.1:55502` in your browser.
59
-
60
- ## Example
61
-
62
- ### Web UI
63
-
64
- sample 1:
65
-
66
- ![sample](./image/sample-webui.png)
67
-
68
- result:
69
-
70
- ![sample result](./image/sample-webui2.jpg)
71
-
72
- sample 2:
73
-
74
- ![sample 2](./saved_poses/bridge.png)
75
-
76
- result:
77
-
78
- ![sample 2 result](./image/sample-webui3.png)
79
-
80
- ### Standalone
81
-
82
- ![sample](./image/sample.png)
83
-
84
- ## History
85
-
86
- ### v0.3 -> v0.4 features
87
- - background setting
88
- - save/load pose
89
- - fixed camera roll
90
-
91
- ### v0.2 -> v0.3 features
92
- - Web UI extension
93
-
94
- ### v0.1 -> v0.2 features
95
- - copying the image to clipboard
96
- - multiple bodies
97
- - canvas size changing
98
- - UI has become ugly >_<;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/app.py DELETED
@@ -1,85 +0,0 @@
1
- from typing import Union
2
-
3
- def ensure_install(module_name: str, lib_name: Union[str,None] = None):
4
- from importlib.util import find_spec
5
-
6
- if lib_name is None:
7
- lib_name = module_name
8
-
9
- if find_spec(module_name) is None:
10
- import subprocess
11
- try:
12
- print('-' * 80, file=sys.stderr)
13
- print(f'| installing {lib_name} ...', file=sys.stderr)
14
- print('-' * 80, file=sys.stderr)
15
- subprocess.check_call(
16
- [sys.executable, "-m", "pip", "install", lib_name],
17
- stdout=sys.stdout,
18
- stderr=sys.stderr
19
- )
20
- except Exception as e:
21
- msg = ''.join(traceback.TracebackException.from_exception(e).format())
22
- print(msg, file=sys.stderr)
23
- print('-' * 80, file=sys.stderr)
24
- print(f'| failed to install {lib_name}. exit...', file=sys.stderr)
25
- print('-' * 80, file=sys.stderr)
26
- sys.exit(1)
27
-
28
- if __name__ == '__main__':
29
- import mimetypes
30
- mimetypes.add_type('application/javascript', '.js')
31
-
32
- import os, sys, traceback
33
- from functools import wraps
34
-
35
- ensure_install('flask')
36
- ensure_install('PIL', 'pillow')
37
-
38
- from flask import Flask, jsonify, request
39
- from common import posex_utils as posex
40
-
41
- app = Flask(__name__, static_folder='.', static_url_path='')
42
-
43
- posex.set_save_dir(os.path.join(app.static_folder, 'saved_poses'))
44
-
45
- @app.route('/')
46
- def index():
47
- return app.send_static_file('index.html')
48
-
49
- def api_try(fn):
50
- @wraps(fn)
51
- def f(*args, **kwargs):
52
- try:
53
- return fn(*args, **kwargs)
54
- except Exception as e:
55
- msg = ''.join(traceback.TracebackException.from_exception(e).format())
56
- print(msg, file=sys.stderr)
57
- return jsonify(result=str(e), ok=False)
58
- return f
59
-
60
- @app.route('/pose/all')
61
- @api_try
62
- def all_poses():
63
- return jsonify(list(posex.all_poses()))
64
-
65
- @app.route('/pose/save', methods=['POST'])
66
- @api_try
67
- def save_pose():
68
- data = request.json
69
- posex.save_pose(data)
70
- return jsonify(result='pose saved', ok=True)
71
-
72
- @app.route('/pose/delete', methods=['POST'])
73
- @api_try
74
- def delete_pose():
75
- data = request.json
76
- posex.delete_pose(data['name'])
77
- return jsonify(result='pose deleted', ok=True)
78
-
79
- @app.route('/pose/load', methods=['POST'])
80
- @api_try
81
- def load_pose():
82
- data = request.json
83
- return jsonify(posex.load_pose(data['name']))
84
-
85
- app.run(port=55502, debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/common/__pycache__/posex_utils.cpython-310.pyc DELETED
Binary file (3.67 kB)
 
posex/common/posex_utils.py DELETED
@@ -1,111 +0,0 @@
1
- import os, glob, json, base64, re
2
- from io import BytesIO
3
- from PIL import Image, PngImagePlugin
4
-
5
- _SAVED_POSES_DIR = ''
6
-
7
- def set_save_dir(dir: str):
8
- global _SAVED_POSES_DIR
9
- _SAVED_POSES_DIR = os.path.realpath(str(dir))
10
-
11
- def get_save_dir():
12
- assert len(_SAVED_POSES_DIR) != 0
13
- return _SAVED_POSES_DIR
14
-
15
- def get_saved_path(name: str):
16
- #return os.path.realpath(os.path.join(get_save_dir(), name))
17
- return os.path.join(get_save_dir(), name)
18
-
19
- def atoi(text):
20
- return int(text) if text.isdigit() else text
21
-
22
- def natural_keys(text):
23
- return [ atoi(c) for c in re.split(r'(\d+)', text) ]
24
-
25
- def sorted_glob(path):
26
- return sorted(glob.glob(path), key=natural_keys)
27
-
28
- def name2path(name: str):
29
- if not isinstance(name, str):
30
- raise ValueError(f'str object expected, but {type(name)}')
31
-
32
- if len(name) == 0:
33
- raise ValueError(f'empty name')
34
-
35
- if '.' in name or '/' in name or '\\' in name:
36
- raise ValueError(f'invalid name: {name}')
37
-
38
- path = get_saved_path(f'{name}.png')
39
- if not path.startswith(get_save_dir()):
40
- raise ValueError(f'invalid name: {name}')
41
-
42
- return path
43
-
44
- def saved_poses():
45
- for path in sorted_glob(os.path.join(get_save_dir(), '*.png')):
46
- yield Image.open(path)
47
-
48
- def all_poses():
49
- for img in saved_poses():
50
- buffer = BytesIO()
51
- img.save(buffer, format='png')
52
-
53
- if not hasattr(img, 'text'):
54
- continue
55
-
56
- pose_dict = {
57
- 'name': img.text['name'], # type: ignore
58
- 'image': base64.b64encode(buffer.getvalue()).decode('ascii'),
59
- 'screen': json.loads(img.text['screen']), # type: ignore
60
- 'camera': json.loads(img.text['camera']), # type: ignore
61
- 'joints': json.loads(img.text['joints']), # type: ignore
62
- }
63
-
64
- yield pose_dict
65
-
66
- def save_pose(data: dict):
67
- name = data['name']
68
- screen = data['screen']
69
- camera = data['camera']
70
- joints = data['joints']
71
-
72
- info = PngImagePlugin.PngInfo()
73
- info.add_text('name', name)
74
- info.add_text('screen', json.dumps(screen))
75
- info.add_text('camera', json.dumps(camera))
76
- info.add_text('joints', json.dumps(joints))
77
-
78
- filepath = name2path(name)
79
-
80
- image = Image.open(BytesIO(base64.b64decode(data['image'][len('data:image/png;base64,'):])))
81
- unit = max(image.width, image.height)
82
- mx, my = (unit - image.width) // 2, (unit - image.height) // 2
83
- canvas = Image.new('RGB', (unit, unit), color=(68, 68, 68))
84
- canvas.paste(image, (mx, my))
85
- image = canvas.resize((canvas.width//4, canvas.height//4))
86
-
87
- image.save(filepath, pnginfo=info)
88
-
89
- def delete_pose(name: str):
90
- filepath = name2path(name)
91
- os.remove(filepath)
92
-
93
- def load_pose(name: str):
94
- filepath = name2path(name)
95
- img = Image.open(filepath)
96
-
97
- buffer = BytesIO()
98
- img.save(buffer, format='png')
99
-
100
- if not hasattr(img, 'text'):
101
- raise ValueError(f'not pose data: {filepath}')
102
-
103
- pose_dict = {
104
- 'name': img.text['name'], # type: ignore
105
- 'image': base64.b64encode(buffer.getvalue()).decode('ascii'),
106
- 'screen': json.loads(img.text['screen']), # type: ignore
107
- 'camera': json.loads(img.text['camera']), # type: ignore
108
- 'joints': json.loads(img.text['joints']), # type: ignore
109
- }
110
-
111
- return pose_dict
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/css/main.css DELETED
@@ -1,125 +0,0 @@
1
- #cont {
2
- display: flex;
3
- flex-flow: column;
4
- gap: 0.5em 0;
5
- width: max-content;
6
- }
7
-
8
- .box {
9
- display: block;
10
- border: 1px solid gray;
11
- padding: 0.5em 0;
12
- text-decoration: none;
13
- text-align: center;
14
- }
15
-
16
- #notation {
17
- display: none;
18
- position: absolute;
19
- color: black;
20
- background-color: rgba(255, 255, 255, 0.75);
21
- padding: 0.1em 0.25em;
22
- pointer-events: none;
23
- font-size: small;
24
- }
25
-
26
- #notifications {
27
- left: 1em;
28
- bottom: 0;
29
- width: 25%;
30
- }
31
-
32
- #notifications .item {
33
- padding: 0.5em;
34
- border: 1px solid gray;
35
- animation: erase 2s ease-out 0.5s forwards;
36
- }
37
-
38
- @keyframes erase {
39
- 100% {
40
- opacity: 0;
41
- }
42
- }
43
-
44
- #notifications .success {
45
- background-color: #aaccaa;
46
- color: #004000;
47
- }
48
-
49
- #notifications .info {
50
- background-color: white;
51
- color: black;
52
- }
53
-
54
- #notifications .error {
55
- background-color: #ffcccc;
56
- color: red;
57
- }
58
-
59
- #body_indicator1 {
60
- display: none;
61
- position: absolute;
62
- outline: 1px solid white;
63
- pointer-events: none;
64
- }
65
-
66
- #body_indicator2 {
67
- display: none;
68
- position: absolute;
69
- outline: 1px solid gray;
70
- pointer-events: none;
71
- }
72
-
73
- #saved_poses {
74
- display: flex;
75
- flex-direction: row;
76
- gap: 0.25em;
77
- font-size: small;
78
- }
79
-
80
- #saved_poses > * {
81
- margin: 0;
82
- outline: 1px solid gray;
83
- max-width: 128px;
84
- }
85
-
86
- #saved_poses img {
87
- max-width: 128px;
88
- max-height: 128px;
89
- }
90
-
91
- #saved_poses figcaption {
92
- padding: 0 0.25em;
93
- overflow-wrap: anywhere; /* Opera Android may not be able to interpret `anywhere` keyword. */
94
- }
95
-
96
- #saved_poses .close {
97
- position: absolute;
98
- cursor: pointer;
99
- border: 1px solid gray;
100
- background-color: white;
101
- opacity: 0.5;
102
- width: 1.25em;
103
- height: 1.25em;
104
- text-align: center;
105
- vertical-align: middle;
106
- margin: 0;
107
- font-family: monospace;
108
- }
109
-
110
- #saved_poses .close:hover {
111
- opacity: 1.0;
112
- }
113
-
114
- #saved_poses .close2 {
115
- display: none;
116
- position: absolute;
117
- left: 1.5em;
118
- top: 0;
119
- }
120
-
121
- #saved_poses .close:hover .close2 {
122
- display: block;
123
- color: white;
124
- pointer-events: none;
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/image/favicon.ico DELETED
Binary file (1.41 kB)
 
posex/image/favicon.png DELETED
Binary file (898 Bytes)
 
posex/image/sample-webui.png DELETED
Binary file (48.3 kB)
 
posex/image/sample-webui2.jpg DELETED

Git LFS Details

  • SHA256: 223435fe63ead0763f59af73c8cc76fa4f54a22d98efcc2923b2bdbbee8ad97b
  • Pointer size: 132 Bytes
  • Size of remote file: 1.36 MB
posex/image/sample-webui2.png DELETED

Git LFS Details

  • SHA256: e1aec128752571d39aea4e7f9faad31976f14a538defb07637dc939e84a1af2a
  • Pointer size: 132 Bytes
  • Size of remote file: 4.05 MB
posex/image/sample-webui3.png DELETED
Binary file (578 kB)
 
posex/image/sample.png DELETED
Binary file (32.7 kB)
 
posex/index.html DELETED
@@ -1,74 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
-
4
- <head>
5
- <title>Posex - Estimated Image Generator for Pose2Image</title>
6
- <link rel="icon" type="image/png" href="image/favicon.png">
7
- <link rel="stylesheet" href="css/main.css">
8
- <script async src="js/es-module-shims.js"></script>
9
- <script type="importmap">
10
- {
11
- "imports": {
12
- "three": "./js/three.module.js",
13
- "three-trackballcontrols": "./js/TrackballControls.js",
14
- "three-dragcontrols": "./js/DragControls.js",
15
- "three-meshline": "./js/THREE.MeshLine.Module.min.js",
16
- "posex": "./js/posex.js"
17
- }
18
- }
19
- </script>
20
- <script type="esms-options">
21
- {
22
- "noLoadEventRetriggers": true
23
- }
24
- </script>
25
- <script defer type="module" src="js/app.js"></script>
26
- </head>
27
-
28
- <body>
29
- <div id="cont">
30
- <button id="all_reset" class="box">&#x1f504; All Reset</button>
31
- <div style="display: flex; flex-direction: row; gap: 0 0.5em;">
32
- <button id="reset_camera" class="box" style="flex: 1 1 0">&#x1f3a5; Reset Camera</button>
33
- <button id="reset_pose" class="box" style="flex: 1 1 0">&#x1f9cd; Reset Pose</button>
34
- </div>
35
- <div style="display: flex; flex-direction: row; ">
36
-
37
- <canvas width="512" height="512" id="main_canvas"></canvas>
38
-
39
- <div style="margin-left: 1em; display: flex; flex-direction: column; gap: 0.25em; font-size: smaller;">
40
- <div>- Camera</div>
41
- <label><input type="checkbox" id="fixed_roll">Fixed Roll</label>
42
- <div>- Body</div>
43
- <button id="add_body" style="width: max-content; min-width: 100%; text-align: left;">&#x2795; Add</button>
44
- <button id="remove_body" style="width: max-content; min-width: 100%; text-align: left;">&#x2796; Remove</button>
45
- <div>- Canvas Size</div>
46
- <input type="number" id="canvas_width" value="512" min="64" />
47
- <input type="number" id="canvas_height" value="512" min="64" />
48
- <div>- Background</div>
49
- <div style="display: flex; flex-direction: row; gap: 0 0.25em;">
50
- <label style="flex: 0 0 0;"><button onclick="document.querySelector('#bg_file').click();">&#x1f5bc; Set</button><input type="file" id="bg_file" style="display: none;"/></label>
51
- <button id="reset_bg" style="flex: 0 0 0;">&#x274c; Del</button>
52
- </div>
53
- <div>- Joints and Limbs</div>
54
- <!-- <label><input type="range" id="joint_radius" min="1" max="16" value="4" />Joint Radius</label> -->
55
- <label><input type="range" id="limb_width" min="1" max="16" value="4" />Limb Width</label>
56
- <label><input type="checkbox" id="elliptic_limbs" checked />Elliptic Limbs</label>
57
- <div>- Others</div>
58
- <label><input type="checkbox" id="low_fps" />Low fps</label>
59
- </div>
60
- </div>
61
- <div id="body_indicator2"></div>
62
- <div id="body_indicator1"></div>
63
- <div style="display: flex; flex-direction: row; gap: 0 0.25em;">
64
- <a id="save_button" class="box" style="flex: 1 1 0;" href="#">&#x1f4be; Save Image</a>
65
- <a id="copy_button" class="box" style="flex: 1 1 0;" href="#">&#x1f4cb; Copy to clipboard</a>
66
- </div>
67
- <button id="save_pose" class="box">&#x1f4be;&#x1f9cd; Save Pose</button>
68
- <div id="saved_poses"></div>
69
- </div>
70
- <p id="notation"></p>
71
- <div id="notifications"></div>
72
- </body>
73
-
74
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/javascript/lazyload/posex-webui.js DELETED
@@ -1,386 +0,0 @@
1
- async function _import() {
2
- if (!globalThis.posex || !globalThis.posex.import) {
3
- return await import('posex');
4
- } else {
5
- return await globalThis.posex.imports.posex();
6
- }
7
- }
8
- const { init, init_3d } = await _import();
9
-
10
- (async function () {
11
- let _r = 0;
12
- function to_gradio(v) {
13
- // force call `change` event on gradio
14
- return [v.toString(), (_r++).toString()];
15
- }
16
-
17
- function js2py(type, gradio_field, value) {
18
- // set `value` to gradio's field
19
- // (1) Click gradio's button.
20
- // (2) Gradio will fire js callback to retrieve value to be set.
21
- // (3) Gradio will fire another js callback to notify the process has been completed.
22
- return new Promise(resolve => {
23
- const callback_name = `posex-${type}-${gradio_field}`;
24
-
25
- // (2)
26
- globalThis[callback_name] = () => {
27
-
28
- delete globalThis[callback_name];
29
-
30
- // (3)
31
- const callback_after = callback_name + '_after';
32
- globalThis[callback_after] = () => {
33
- delete globalThis[callback_after];
34
- resolve();
35
- };
36
-
37
- return to_gradio(value);
38
- };
39
-
40
- // (1)
41
- gradioApp().querySelector(`#${callback_name}_set`).click();
42
- });
43
- }
44
-
45
- function py2js(type, pyname, ...args) {
46
- // call python's function
47
- // (1) Set args to gradio's field
48
- // (2) Click gradio's button
49
- // (3) JS callback will be kicked with return value from gradio
50
-
51
- // (1)
52
- return (args.length == 0 ? Promise.resolve() : js2py(type, pyname + '_args', JSON.stringify(args)))
53
- .then(() => {
54
- return new Promise(resolve => {
55
- const callback_name = `posex-${type}-${pyname}`;
56
- // (3)
57
- globalThis[callback_name] = value => {
58
- delete globalThis[callback_name];
59
- resolve(value);
60
- }
61
- // (2)
62
- gradioApp().querySelector(`#${callback_name}_get`).click();
63
- });
64
- });
65
- }
66
-
67
- function reload_poses(json, ui) {
68
- const df = document.createDocumentFragment();
69
- for (let data of json) {
70
- const fig = document.createElement('figure')
71
- const img = document.createElement('img');
72
- const cap = document.createElement('figcaption');
73
- const clo = document.createElement('div');
74
- const cloimg = document.createElement('img');
75
- const clo2 = document.createElement('span');
76
- fig.dataset.poseName = data.name;
77
- cap.textContent = data.name;
78
- clo.classList.add('close');
79
- cloimg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAAG3RFWHRTb2Z0d2FyZQBDZWxzeXMgU3R1ZGlvIFRvb2zBp+F8AAAAxElEQVQ4y82T0REBQRBEX0dAJk4GJwKXgZMBESADIiADJwKXATI4GRBB+1lqKa62+DFV+7E7U6+6e2plm19K/wWQ1AE2QBcobZ9fehVwCb3rWwWShmHwaLsfvW+BAihs71otSJoBc2BuexFBl7anSRlI2gN5OBXQxIpSAB2gCXlcgCzOJGkLkg5ABhyB/B5cqoI1UAb5BbCxPU4CSBqFdda2B1GoE9urVoCkHlCH68N3ZOfzGkNw9dvBZ3Bu+/SHf+GbugG9/4ThhKqF8gAAAABJRU5ErkJggg==';
80
- clo2.classList.add('close2');
81
- clo2.textContent = 'delete';
82
- clo.append(cloimg, clo2);
83
-
84
- img.src = 'data:image/png;base64,' + data.image;
85
- img.title = data.name;
86
- fig.append(clo, img, cap);
87
-
88
- df.appendChild(fig);
89
- }
90
-
91
- ui.saved_poses.innerHTML = '';
92
- ui.saved_poses.appendChild(df);
93
- }
94
-
95
- function init_ui(type, api) {
96
- const $ = x => document.createElement(x);
97
-
98
- const all_reset = $('button');
99
- all_reset.innerHTML = '&#x1f504; All Reset';
100
- all_reset.classList.add('posex_all_reset', 'posex_box');
101
-
102
- const reset_camera = $('button');
103
- reset_camera.innerHTML = '&#x1f3a5; Reset Camera';
104
- reset_camera.classList.add('posex_reset_camera', 'posex_box');
105
-
106
- const reset_pose = $('button');
107
- reset_pose.innerHTML = '&#x1f9cd; Reset Pose';
108
- reset_pose.classList.add('posex_reset_pose', 'posex_box');
109
-
110
- const reset_cont = $('div');
111
- reset_cont.classList.add('posex_reset_cont');
112
- reset_cont.append(reset_camera, reset_pose);
113
-
114
- const canvas = $('canvas');
115
- canvas.width = 512;
116
- canvas.height = 512;
117
-
118
- const camera_marker = $('div'); camera_marker.textContent = '- Camera';
119
- const fixed_roll_label = $('label');
120
- const fixed_roll = $('input'); fixed_roll.type = 'checkbox'; fixed_roll.classList.add('posex_fixed_roll', 'posex_camera'); fixed_roll.checked = true;
121
- fixed_roll_label.append(fixed_roll, document.createTextNode('Fixed Roll'));
122
- const body_marker = $('div'); body_marker.textContent = '- Body';
123
- const add_body = $('button'); add_body.classList.add('posex_add_body', 'posex_body'); add_body.innerHTML = '&#x2795; Add';
124
- const remove_body = $('button'); remove_body.classList.add('posex_remove_body', 'posex_body'); remove_body.innerHTML = '&#x2796; Remove';
125
- const canvas_marker = $('div'); canvas_marker.textContent = '- Canvas Size';
126
- const canvas_width = $('input'); canvas_width.type = 'number'; canvas_width.value = 512; canvas_width.min = 64; canvas_width.classList.add('posex_canvas_width', 'posex_canvas_size');
127
- const canvas_height = $('input'); canvas_height.type = 'number'; canvas_height.value = 512; canvas_height.min = 64; canvas_height.classList.add('posex_canvas_height', 'posex_canvas_size');
128
- const bg_marker = $('div'); bg_marker.textContent = '- Background';
129
- const set_bg = $('label'); set_bg.classList.add('posex_bg');
130
- const bg_button = $('button'); bg_button.innerHTML = '&#x1f5bc; Set'; bg_button.onclick = () => bg_input.click();
131
- const bg_input = $('input'); bg_input.type = 'file'; bg_input.style.display = 'none';
132
- set_bg.append(bg_button, bg_input);
133
- const reset_bg = $('button'); reset_bg.classList.add('posex_bg'); reset_bg.innerHTML = '&#x274c; Del';
134
- const bg_cont = $('div'); bg_cont.classList.add('posex_bg_cont');
135
- bg_cont.append(set_bg, reset_bg);
136
- const joint_marker = $('div'); joint_marker.textContent = '- Joints and Limbs';
137
- const limb_width_label = $('label');
138
- const limb_width = $('input'); limb_width.type = 'range'; limb_width.min = 1; limb_width.max = 16; limb_width.value = 4; limb_width.classList.add('posex_joints', 'posex_limb_width');
139
- limb_width_label.append(limb_width, document.createTextNode('Limb Width'));
140
- const elliptic_limbs_label = $('label');
141
- const elliptic_limbs = $('input'); elliptic_limbs.type = 'checkbox'; elliptic_limbs.classList.add('posex_joints', 'posex_elliptic_limbs'); elliptic_limbs.checked = true;
142
- elliptic_limbs_label.append(elliptic_limbs, document.createTextNode('Elliptic Limbs'));
143
- const other_marker = $('div'); other_marker.textContent = '- Others';
144
- const low_fps_label = $('label');
145
- const low_fps = $('input'); low_fps.type = 'checkbox'; low_fps.classList.add('posex_low_fps', 'posex_others'); low_fps.checked = false;
146
- low_fps_label.append(low_fps, document.createTextNode('Low fps'));
147
-
148
- const setting_cont = $('div');
149
- setting_cont.classList.add('posex_setting_cont');
150
- setting_cont.append(
151
- camera_marker,
152
- fixed_roll_label,
153
- body_marker,
154
- add_body,
155
- remove_body,
156
- canvas_marker,
157
- canvas_width,
158
- canvas_height,
159
- bg_marker,
160
- bg_cont,
161
- joint_marker,
162
- limb_width_label,
163
- elliptic_limbs_label,
164
- other_marker,
165
- low_fps_label,
166
- );
167
-
168
- const canvas_cont = $('div');
169
- canvas_cont.classList.add('posex_canvas_cont');
170
- canvas_cont.append(
171
- canvas,
172
- setting_cont,
173
- );
174
-
175
- const notation = $('p');
176
- notation.classList.add('posex_notation');
177
-
178
- const indicator1 = $('div');
179
- indicator1.classList.add('posex_indicator1');
180
-
181
- const indicator2 = $('div');
182
- indicator2.classList.add('posex_indicator2');
183
-
184
- const copy = $('button'); copy.classList.add('posex_copy', 'posex_misc', 'posex_box'); copy.innerHTML = '&#x1f4cb; Copy to clipboard';
185
- const save = $('button'); save.classList.add('posex_save', 'posex_misc', 'posex_box'); save.innerHTML = '&#x1f4be; Download image';
186
-
187
- const misc_cont = $('div');
188
- misc_cont.classList.add('posex_misc_cont');
189
- misc_cont.append(
190
- copy,
191
- save
192
- );
193
-
194
- const save_pose = $('button');
195
- save_pose.classList.add('posex_save_pose', 'posex_box');
196
- save_pose.innerHTML = '&#x1f4be;&#x1f9cd; Save Pose';
197
-
198
- const save_pose_callback = async obj => {
199
- await py2js(type, 'savepose', obj);
200
- const json = await py2js(type, 'allposes')
201
- reload_poses(JSON.parse(json), ui);
202
- return { result: '', ok: true };
203
- };
204
-
205
- const saved_poses = $('div');
206
- saved_poses.classList.add('posex_saved_poses');
207
-
208
- saved_poses.addEventListener('click', async e => {
209
- const get_name = ele => {
210
- while (ele && ele !== document) {
211
- if (ele.dataset && ele.dataset.poseName !== undefined)
212
- return ele.dataset.poseName;
213
- ele = ele.parentNode;
214
- }
215
- return '';
216
- };
217
-
218
- let target = e.target;
219
- if (target.tagName === 'IMG') target = target.parentNode;
220
- if (target.classList.contains('close2')) target = target.parentNode;
221
- if (target.tagName === 'FIGURE') {
222
- const name = get_name(target);
223
- if (name.length != 0) {
224
- const json = await py2js(type, 'loadpose', name);
225
- ui.loadPose(JSON.parse(json));
226
- }
227
- } else if (target.classList.contains('close')) {
228
- const name = get_name(target);
229
- if (name.length != 0) {
230
- await py2js(type, 'delpose', name);
231
- const json = await py2js(type, 'allposes')
232
- reload_poses(JSON.parse(json), ui);
233
- }
234
- }
235
- }, false);
236
-
237
- const ui = {
238
- canvas,
239
- notation,
240
- indicator1,
241
- indicator2,
242
- all_reset,
243
- reset_camera,
244
- reset_pose,
245
- fixed_roll,
246
- add_body,
247
- remove_body,
248
- canvas_width,
249
- canvas_height,
250
- bg: bg_input,
251
- reset_bg,
252
- limb_width,
253
- elliptic_limbs,
254
- low_fps,
255
- save,
256
- copy,
257
- save_pose,
258
- save_pose_callback,
259
- saved_poses,
260
- };
261
-
262
- const df = document.createDocumentFragment();
263
- df.append(
264
- all_reset,
265
- reset_cont,
266
- canvas_cont,
267
- indicator2,
268
- indicator1,
269
- notation,
270
- misc_cont,
271
- save_pose,
272
- saved_poses,
273
- );
274
-
275
- return { ui, df };
276
- };
277
-
278
- async function init_canvas(
279
- type,
280
- enabled,
281
- generate_button,
282
- container,
283
- api
284
- ) {
285
- container.classList.add('posex_cont');
286
- container.innerHTML = '';
287
- const { ui, df } = init_ui(type, api);
288
- container.appendChild(df);
289
-
290
- ui.container = container;
291
- ui.notify = function (str, type) { if (type === 'error') console.error(str); };
292
-
293
- if (!posex[`${type}_click`]) {
294
- // Send canvas image to ControlNet when button is clicked.
295
- let force = false;
296
- gradioApp().addEventListener('click', async e => {
297
- if (e.target !== generate_button) return;
298
-
299
- if (!enabled.checked) return;
300
-
301
- if (force) {
302
- force = false;
303
- return;
304
- }
305
-
306
- // hook `generate` button to add canvas data
307
- e.preventDefault();
308
- e.stopPropagation();
309
-
310
- const data_url = await ui.getDataURL();
311
- await js2py(type, 'base64', data_url);
312
- force = true;
313
- generate_button.click();
314
- }, true);
315
- posex[`${type}_click`] = true;
316
- }
317
-
318
- {
319
- // Load saved poses.
320
- const json = await py2js(type, 'allposes')
321
- reload_poses(JSON.parse(json), ui);
322
- }
323
-
324
- init(ui);
325
-
326
- const animate = init_3d(ui);
327
-
328
- animate();
329
-
330
- onUiTabChange(() => {
331
- const tabname = get_uiCurrentTabContent().id;
332
- if (type === 't2i') {
333
- if (0 <= tabname.indexOf('txt2img')) {
334
- ui.play();
335
- } else {
336
- ui.stop();
337
- }
338
- } else if (type === 'i2i') {
339
- if (0 <= tabname.indexOf('img2img')) {
340
- ui.play();
341
- } else {
342
- ui.stop();
343
- }
344
- } else {
345
- ui.stop();
346
- }
347
- });
348
- }
349
-
350
- async function init_t2i() {
351
- const app = gradioApp();
352
- await init_canvas(
353
- 't2i',
354
- app.querySelector('#posex-t2i-enabled input[type=checkbox]'),
355
- app.querySelector('#txt2img_generate'),
356
- Array.from(app.querySelectorAll('#posex-t2i-html')).at(-1), // !
357
- {
358
- load_all_poses: app.querySelector('#posex-t2i-api-all_pose'),
359
- delete_pose: app.querySelector('#posex-t2i-api-delete_pose'),
360
- }
361
- );
362
- }
363
-
364
- async function init_i2i() {
365
- const app = gradioApp();
366
- await init_canvas(
367
- 'i2i',
368
- app.querySelector('#posex-i2i-enabled input[type=checkbox]'),
369
- app.querySelector('#img2img_generate'),
370
- Array.from(app.querySelectorAll('#posex-i2i-html')).at(-1), // !
371
- {
372
- load_all_poses: app.querySelector('#posex-i2i-api-all_pose'),
373
- delete_pose: app.querySelector('#posex-i2i-api-delete_pose'),
374
- }
375
- );
376
- }
377
-
378
- if (!globalThis.posex) globalThis.posex = {};
379
- const posex = globalThis.posex;
380
- posex.init_t2i = init_t2i;
381
- posex.init_i2i = init_i2i;
382
-
383
- posex.script_loaded = true;
384
- document.dispatchEvent(new CustomEvent('posexscriptloaded'));
385
-
386
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/javascript/posex-webui.js DELETED
@@ -1,93 +0,0 @@
1
- (function () {
2
- if (!globalThis.posex) globalThis.posex = {};
3
- const posex = globalThis.posex;
4
-
5
- function load(cont) {
6
- function load_() {
7
- if (posex.script_loading || posex.script_loaded) return;
8
- posex.script_loading = true;
9
-
10
- const scripts = cont.textContent.trim().split('\n');
11
- const base_path = `/file=${scripts.shift()}/js`;
12
- cont.textContent = '';
13
-
14
- const df = document.createDocumentFragment();
15
- for (let src of scripts) {
16
- console.log(`[Posex] loading ${src}`);
17
- const script = document.createElement('script');
18
- script.async = true;
19
- script.type = 'module';
20
- script.src = `file=${src}`;
21
- df.appendChild(script);
22
- }
23
-
24
- globalThis.posex.import = async () => {
25
- const THREE = await import(`${base_path}/three.module.js`);
26
- const { TrackballControls } = await import(`${base_path}/TrackballControls.js`);
27
- const { DragControls } = await import(`${base_path}/DragControls.js`);
28
- const { MeshLine, MeshLineMaterial } = await import(`${base_path}/THREE.MeshLine.Module.min.js`);
29
- return { THREE, TrackballControls, DragControls, MeshLine, MeshLineMaterial };
30
- };
31
- if (!globalThis.posex.imports) globalThis.posex.imports = {};
32
- if (!globalThis.posex.imports.three) globalThis.posex.imports.three = async () => await import(`${base_path}/three.module.js`);
33
- if (!globalThis.posex.imports.posex) globalThis.posex.imports.posex = async () => await import(`${base_path}/posex.js`);
34
- cont.appendChild(df);
35
- }
36
-
37
- return posex.script_loaded ? Promise.resolve() : new Promise(resolve => {
38
- document.addEventListener('posexscriptloaded', () => resolve(), false);
39
- load_();
40
- });
41
- }
42
-
43
- function lazy(fn, timeout) {
44
- if (timeout === undefined) timeout = 500;
45
- return new Promise(function callback(resolve) {
46
- const result = fn();
47
- if (result) {
48
- resolve(result);
49
- } else {
50
- setTimeout(() => callback(resolve), timeout);
51
- }
52
- });
53
- }
54
-
55
- function hook_acc(acc, fn) {
56
- const observer = new MutationObserver(list => {
57
- for (let mut of list) {
58
- if (mut.type === 'childList') {
59
- if (mut.addedNodes.length != 0) {
60
- // closed -> opened
61
- fn();
62
- } else {
63
- // opened -> closed
64
- // do nothing
65
- }
66
- }
67
- }
68
- });
69
- observer.observe(acc, { childList: true, attributes: false, subtree: false });
70
- }
71
-
72
- function launch(type) {
73
- return lazy(() => gradioApp()?.querySelector(`#posex-${type}-accordion`)).
74
- then(acc => hook_acc(acc, async () => {
75
- const cont = Array.from(acc.querySelectorAll(`#posex-${type}-js`)).at(-1); // !
76
- const enabled = acc.querySelector(`#posex-${type}-enabled input[type=checkbox]`);
77
- await load(cont);
78
- if (enabled.checked) {
79
- await posex[`init_${type}`]();
80
- console.log(`[Posex] ${type} initialized`);
81
- } else {
82
- enabled.addEventListener('change', async () => {
83
- await posex[`init_${type}`]();
84
- console.log(`[Posex] ${type} initialized`);
85
- }, { once: true });
86
- }
87
- }));
88
- }
89
-
90
- launch('t2i');
91
- launch('i2i');
92
-
93
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/DragControls.js DELETED
@@ -1,228 +0,0 @@
1
- async function _import() {
2
- if (!globalThis.posex || !globalThis.posex.import) {
3
- return await import('three');
4
- } else {
5
- return await globalThis.posex.imports.three();
6
- }
7
- }
8
- const {
9
- EventDispatcher,
10
- Matrix4,
11
- Plane,
12
- Raycaster,
13
- Vector2,
14
- Vector3
15
- } = await _import();
16
-
17
- const _plane = new Plane();
18
- const _raycaster = new Raycaster();
19
-
20
- const _pointer = new Vector2();
21
- const _offset = new Vector3();
22
- const _intersection = new Vector3();
23
- const _worldPosition = new Vector3();
24
- const _inverseMatrix = new Matrix4();
25
-
26
- class DragControls extends EventDispatcher {
27
-
28
- constructor( _objects, _camera, _domElement ) {
29
-
30
- super();
31
-
32
- _domElement.style.touchAction = 'none'; // disable touch scroll
33
-
34
- let _selected = null, _hovered = null;
35
-
36
- const _intersections = [];
37
-
38
- //
39
-
40
- const scope = this;
41
-
42
- function activate() {
43
-
44
- _domElement.addEventListener( 'pointermove', onPointerMove );
45
- _domElement.addEventListener( 'pointerdown', onPointerDown );
46
- _domElement.addEventListener( 'pointerup', onPointerCancel );
47
- _domElement.addEventListener( 'pointerleave', onPointerCancel );
48
-
49
- }
50
-
51
- function deactivate() {
52
-
53
- _domElement.removeEventListener( 'pointermove', onPointerMove );
54
- _domElement.removeEventListener( 'pointerdown', onPointerDown );
55
- _domElement.removeEventListener( 'pointerup', onPointerCancel );
56
- _domElement.removeEventListener( 'pointerleave', onPointerCancel );
57
-
58
- _domElement.style.cursor = '';
59
-
60
- }
61
-
62
- function dispose() {
63
-
64
- deactivate();
65
-
66
- }
67
-
68
- function getObjects() {
69
-
70
- return _objects;
71
-
72
- }
73
-
74
- function getRaycaster() {
75
-
76
- return _raycaster;
77
-
78
- }
79
-
80
- function onPointerMove( event ) {
81
-
82
- if ( scope.enabled === false ) return;
83
-
84
- updatePointer( event );
85
-
86
- _raycaster.setFromCamera( _pointer, _camera );
87
-
88
- if ( _selected ) {
89
-
90
- if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
91
-
92
- _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
93
-
94
- }
95
-
96
- scope.dispatchEvent( { type: 'drag', object: _selected } );
97
-
98
- return;
99
-
100
- }
101
-
102
- // hover support
103
-
104
- if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
105
-
106
- _intersections.length = 0;
107
-
108
- _raycaster.setFromCamera( _pointer, _camera );
109
- _raycaster.intersectObjects( _objects, true, _intersections );
110
-
111
- if ( _intersections.length > 0 ) {
112
-
113
- const object = _intersections[ 0 ].object;
114
-
115
- _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
116
-
117
- if ( _hovered !== object && _hovered !== null ) {
118
-
119
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
120
-
121
- _domElement.style.cursor = 'auto';
122
- _hovered = null;
123
-
124
- }
125
-
126
- if ( _hovered !== object ) {
127
-
128
- scope.dispatchEvent( { type: 'hoveron', object: object } );
129
-
130
- _domElement.style.cursor = 'pointer';
131
- _hovered = object;
132
-
133
- }
134
-
135
- } else {
136
-
137
- if ( _hovered !== null ) {
138
-
139
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
140
-
141
- _domElement.style.cursor = 'auto';
142
- _hovered = null;
143
-
144
- }
145
-
146
- }
147
-
148
- }
149
-
150
- }
151
-
152
- function onPointerDown( event ) {
153
-
154
- if ( scope.enabled === false ) return;
155
-
156
- updatePointer( event );
157
-
158
- _intersections.length = 0;
159
-
160
- _raycaster.setFromCamera( _pointer, _camera );
161
- _raycaster.intersectObjects( _objects, true, _intersections );
162
-
163
- if ( _intersections.length > 0 ) {
164
-
165
- _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
166
-
167
- _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
168
-
169
- if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
170
-
171
- _inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
172
- _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
173
-
174
- }
175
-
176
- _domElement.style.cursor = 'move';
177
-
178
- scope.dispatchEvent( { type: 'dragstart', object: _selected } );
179
-
180
- }
181
-
182
-
183
- }
184
-
185
- function onPointerCancel() {
186
-
187
- if ( scope.enabled === false ) return;
188
-
189
- if ( _selected ) {
190
-
191
- scope.dispatchEvent( { type: 'dragend', object: _selected } );
192
-
193
- _selected = null;
194
-
195
- }
196
-
197
- _domElement.style.cursor = _hovered ? 'pointer' : 'auto';
198
-
199
- }
200
-
201
- function updatePointer( event ) {
202
-
203
- const rect = _domElement.getBoundingClientRect();
204
-
205
- _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
206
- _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
207
-
208
- }
209
-
210
- activate();
211
-
212
- // API
213
-
214
- this.enabled = true;
215
- this.transformGroup = false;
216
-
217
- this.activate = activate;
218
- this.deactivate = deactivate;
219
- this.dispose = dispose;
220
- this.getObjects = getObjects;
221
- this.getRaycaster = getRaycaster;
222
- this.onPointerDown = onPointerDown;
223
-
224
- }
225
-
226
- }
227
-
228
- export { DragControls };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/LICENSE/THREE.MeshLine DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2016 Jaume Sanchez
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/LICENSE/es-module-shims DELETED
@@ -1,10 +0,0 @@
1
- MIT License
2
- -----------
3
-
4
- Copyright (C) 2018-2021 Guy Bedford
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
-
8
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
-
10
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
posex/js/LICENSE/three DELETED
@@ -1,21 +0,0 @@
1
- The MIT License
2
-
3
- Copyright © 2010-2023 three.js authors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/THREE.MeshLine.Module.min.js DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * Minified by jsDelivr using Terser v5.15.1.
3
- * Original file: /npm/three.meshline.module@1.0.0/src/THREE.MeshLine.Module.js
4
- *
5
- * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
- */
7
- async function _import() {
8
- if (!globalThis.posex || !globalThis.posex.import) {
9
- return await import('three');
10
- } else {
11
- return await globalThis.posex.imports.three();
12
- }
13
- }
14
- const THREE=await _import();class MeshLine extends THREE.BufferGeometry{constructor(){super(),this.isMeshLine=!0,this.type="MeshLine",this.positions=[],this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[],this.counters=[],this._points=[],this._geom=null,this.widthCallback=null,this.matrixWorld=new THREE.Matrix4,Object.defineProperties(this,{geometry:{enumerable:!0,get:function(){return this}},geom:{enumerable:!0,get:function(){return this._geom},set:function(t){this.setGeometry(t,this.widthCallback)}},points:{enumerable:!0,get:function(){return this._points},set:function(t){this.setPoints(t,this.widthCallback)}}})}}function MeshLineRaycast(t,e){var i=new THREE.Matrix4,s=new THREE.Ray,r=new THREE.Sphere,a=new THREE.Vector3,n=this.geometry;if(n.boundingSphere||n.computeBoundingSphere(),r.copy(n.boundingSphere),r.applyMatrix4(this.matrixWorld),!1!==t.ray.intersectSphere(r,a)){i.copy(this.matrixWorld).invert(),s.copy(t.ray).applyMatrix4(i);var o=new THREE.Vector3,u=new THREE.Vector3,h=new THREE.Vector3,l=this instanceof THREE.LineSegments?2:1,p=n.index,c=n.attributes;if(null!==p)for(var f=p.array,v=c.position.array,d=c.width.array,y=0,m=f.length-1;y<m;y+=l){var b=f[y],x=f[y+1];o.fromArray(v,3*b),u.fromArray(v,3*x);var E=void 0!==d[Math.floor(y/3)]?d[Math.floor(y/3)]:1,g=t.params.Line.threshold+this.material.lineWidth*E/2,A=g*g;if(!(s.distanceSqToSegment(o,u,a,h)>A)){a.applyMatrix4(this.matrixWorld);var M=t.ray.origin.distanceTo(a);M<t.near||M>t.far||(e.push({distance:M,point:h.clone().applyMatrix4(this.matrixWorld),index:y,face:null,faceIndex:null,object:this}),y=m)}}}}function memcpy(t,e,i,s,r){var a;if(t=t.subarray||t.slice?t:t.buffer,i=i.subarray||i.slice?i:i.buffer,t=e?t.subarray?t.subarray(e,r&&e+r):t.slice(e,r&&e+r):t,i.set)i.set(t,s);else for(a=0;a<t.length;a++)i[a+s]=t[a];return i}MeshLine.prototype.setMatrixWorld=function(t){this.matrixWorld=t},MeshLine.prototype.setGeometry=function(t,e){this._geometry=t,this.setPoints(t.getAttribute("position").array,e)},MeshLine.prototype.setPoints=function(t,e){if(t instanceof Float32Array||t instanceof Array){if(this._points=t,this.widthCallback=e,this.positions=[],this.counters=[],t.length&&t[0]instanceof THREE.Vector3)for(var i=0;i<t.length;i++){var s=t[i],r=i/t.length;this.positions.push(s.x,s.y,s.z),this.positions.push(s.x,s.y,s.z),this.counters.push(r),this.counters.push(r)}else for(i=0;i<t.length;i+=3){r=i/t.length;this.positions.push(t[i],t[i+1],t[i+2]),this.positions.push(t[i],t[i+1],t[i+2]),this.counters.push(r),this.counters.push(r)}this.process()}else console.error("ERROR: The BufferArray of points is not instancied correctly.")},MeshLine.prototype.raycast=MeshLineRaycast,MeshLine.prototype.compareV3=function(t,e){var i=6*t,s=6*e;return this.positions[i]===this.positions[s]&&this.positions[i+1]===this.positions[s+1]&&this.positions[i+2]===this.positions[s+2]},MeshLine.prototype.copyV3=function(t){var e=6*t;return[this.positions[e],this.positions[e+1],this.positions[e+2]]},MeshLine.prototype.process=function(){var t,e,i=this.positions.length/6;this.previous=[],this.next=[],this.side=[],this.width=[],this.indices_array=[],this.uvs=[],e=this.compareV3(0,i-1)?this.copyV3(i-2):this.copyV3(0),this.previous.push(e[0],e[1],e[2]),this.previous.push(e[0],e[1],e[2]);for(var s=0;s<i;s++){if(this.side.push(1),this.side.push(-1),t=this.widthCallback?this.widthCallback(s/(i-1)):1,this.width.push(t),this.width.push(t),this.uvs.push(s/(i-1),0),this.uvs.push(s/(i-1),1),s<i-1){e=this.copyV3(s),this.previous.push(e[0],e[1],e[2]),this.previous.push(e[0],e[1],e[2]);var r=2*s;this.indices_array.push(r,r+1,r+2),this.indices_array.push(r+2,r+1,r+3)}s>0&&(e=this.copyV3(s),this.next.push(e[0],e[1],e[2]),this.next.push(e[0],e[1],e[2]))}e=this.compareV3(i-1,0)?this.copyV3(1):this.copyV3(i-1),this.next.push(e[0],e[1],e[2]),this.next.push(e[0],e[1],e[2]),this._attributes&&this._attributes.position.count===this.positions.length?(this._attributes.position.copyArray(new Float32Array(this.positions)),this._attributes.position.needsUpdate=!0,this._attributes.previous.copyArray(new Float32Array(this.previous)),this._attributes.previous.needsUpdate=!0,this._attributes.next.copyArray(new Float32Array(this.next)),this._attributes.next.needsUpdate=!0,this._attributes.side.copyArray(new Float32Array(this.side)),this._attributes.side.needsUpdate=!0,this._attributes.width.copyArray(new Float32Array(this.width)),this._attributes.width.needsUpdate=!0,this._attributes.uv.copyArray(new Float32Array(this.uvs)),this._attributes.uv.needsUpdate=!0,this._attributes.index.copyArray(new Uint16Array(this.indices_array)),this._attributes.index.needsUpdate=!0):this._attributes={position:new THREE.BufferAttribute(new Float32Array(this.positions),3),previous:new THREE.BufferAttribute(new Float32Array(this.previous),3),next:new THREE.BufferAttribute(new Float32Array(this.next),3),side:new THREE.BufferAttribute(new Float32Array(this.side),1),width:new THREE.BufferAttribute(new Float32Array(this.width),1),uv:new THREE.BufferAttribute(new Float32Array(this.uvs),2),index:new THREE.BufferAttribute(new Uint16Array(this.indices_array),1),counters:new THREE.BufferAttribute(new Float32Array(this.counters),1)},this.setAttribute("position",this._attributes.position),this.setAttribute("previous",this._attributes.previous),this.setAttribute("next",this._attributes.next),this.setAttribute("side",this._attributes.side),this.setAttribute("width",this._attributes.width),this.setAttribute("uv",this._attributes.uv),this.setAttribute("counters",this._attributes.counters),this.setIndex(this._attributes.index),this.computeBoundingSphere(),this.computeBoundingBox()},MeshLine.prototype.advance=function(t){var e=this._attributes.position.array,i=this._attributes.previous.array,s=this._attributes.next.array,r=e.length;memcpy(e,0,i,0,r),memcpy(e,6,e,0,r-6),e[r-6]=t.x,e[r-5]=t.y,e[r-4]=t.z,e[r-3]=t.x,e[r-2]=t.y,e[r-1]=t.z,memcpy(e,6,s,0,r-6),s[r-6]=t.x,s[r-5]=t.y,s[r-4]=t.z,s[r-3]=t.x,s[r-2]=t.y,s[r-1]=t.z,this._attributes.position.needsUpdate=!0,this._attributes.previous.needsUpdate=!0,this._attributes.next.needsUpdate=!0},THREE.ShaderChunk.meshline_vert=["",THREE.ShaderChunk.logdepthbuf_pars_vertex,THREE.ShaderChunk.fog_pars_vertex,"","attribute vec3 previous;","attribute vec3 next;","attribute float side;","attribute float width;","attribute float counters;","","uniform vec2 resolution;","uniform float lineWidth;","uniform vec3 color;","uniform float opacity;","uniform float sizeAttenuation;","","varying vec2 vUV;","varying vec4 vColor;","varying float vCounters;","","vec2 fix( vec4 i, float aspect ) {",""," vec2 res = i.xy / i.w;"," res.x *= aspect;","\t vCounters = counters;"," return res;","","}","","void main() {",""," float aspect = resolution.x / resolution.y;",""," vColor = vec4( color, opacity );"," vUV = uv;",""," mat4 m = projectionMatrix * modelViewMatrix;"," vec4 finalPosition = m * vec4( position, 1.0 );"," vec4 prevPos = m * vec4( previous, 1.0 );"," vec4 nextPos = m * vec4( next, 1.0 );",""," vec2 currentP = fix( finalPosition, aspect );"," vec2 prevP = fix( prevPos, aspect );"," vec2 nextP = fix( nextPos, aspect );",""," float w = lineWidth * width;",""," vec2 dir;"," if( nextP == currentP ) dir = normalize( currentP - prevP );"," else if( prevP == currentP ) dir = normalize( nextP - currentP );"," else {"," vec2 dir1 = normalize( currentP - prevP );"," vec2 dir2 = normalize( nextP - currentP );"," dir = normalize( dir1 + dir2 );",""," vec2 perp = vec2( -dir1.y, dir1.x );"," vec2 miter = vec2( -dir.y, dir.x );"," //w = clamp( w / dot( miter, perp ), 0., 4. * lineWidth * width );",""," }",""," //vec2 normal = ( cross( vec3( dir, 0. ), vec3( 0., 0., 1. ) ) ).xy;"," vec4 normal = vec4( -dir.y, dir.x, 0., 1. );"," normal.xy *= .5 * w;"," normal *= projectionMatrix;"," if( sizeAttenuation == 0. ) {"," normal.xy *= finalPosition.w;"," normal.xy /= ( vec4( resolution, 0., 1. ) * projectionMatrix ).xy;"," }",""," finalPosition.xy += normal.xy * side;",""," gl_Position = finalPosition;","",THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.fog_vertex&&" vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.fog_vertex,"}"].join("\n"),THREE.ShaderChunk.meshline_frag=["",THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"","uniform sampler2D map;","uniform sampler2D alphaMap;","uniform float useMap;","uniform float useAlphaMap;","uniform float useDash;","uniform float dashArray;","uniform float dashOffset;","uniform float dashRatio;","uniform float visibility;","uniform float alphaTest;","uniform vec2 repeat;","","varying vec2 vUV;","varying vec4 vColor;","varying float vCounters;","","void main() {","",THREE.ShaderChunk.logdepthbuf_fragment,""," vec4 c = vColor;"," if( useMap == 1. ) c *= texture2D( map, vUV * repeat );"," if( useAlphaMap == 1. ) c.a *= texture2D( alphaMap, vUV * repeat ).a;"," if( c.a < alphaTest ) discard;"," if( useDash == 1. ){"," c.a *= ceil(mod(vCounters + dashOffset, dashArray) - (dashArray * dashRatio));"," }"," gl_FragColor = c;"," gl_FragColor.a *= step(vCounters, visibility);","",THREE.ShaderChunk.fog_fragment,"}"].join("\n");class MeshLineMaterial extends THREE.ShaderMaterial{constructor(t){super({uniforms:Object.assign({},THREE.UniformsLib.fog,{lineWidth:{value:1},map:{value:null},useMap:{value:0},alphaMap:{value:null},useAlphaMap:{value:0},color:{value:new THREE.Color(16777215)},opacity:{value:1},resolution:{value:new THREE.Vector2(1,1)},sizeAttenuation:{value:1},dashArray:{value:0},dashOffset:{value:0},dashRatio:{value:.5},useDash:{value:0},visibility:{value:1},alphaTest:{value:0},repeat:{value:new THREE.Vector2(1,1)}}),vertexShader:THREE.ShaderChunk.meshline_vert,fragmentShader:THREE.ShaderChunk.meshline_frag}),this.isMeshLineMaterial=!0,this.type="MeshLineMaterial",Object.defineProperties(this,{lineWidth:{enumerable:!0,get:function(){return this.uniforms.lineWidth.value},set:function(t){this.uniforms.lineWidth.value=t}},map:{enumerable:!0,get:function(){return this.uniforms.map.value},set:function(t){this.uniforms.map.value=t}},useMap:{enumerable:!0,get:function(){return this.uniforms.useMap.value},set:function(t){this.uniforms.useMap.value=t}},alphaMap:{enumerable:!0,get:function(){return this.uniforms.alphaMap.value},set:function(t){this.uniforms.alphaMap.value=t}},useAlphaMap:{enumerable:!0,get:function(){return this.uniforms.useAlphaMap.value},set:function(t){this.uniforms.useAlphaMap.value=t}},color:{enumerable:!0,get:function(){return this.uniforms.color.value},set:function(t){this.uniforms.color.value=t}},opacity:{enumerable:!0,get:function(){return this.uniforms.opacity.value},set:function(t){this.uniforms.opacity.value=t}},resolution:{enumerable:!0,get:function(){return this.uniforms.resolution.value},set:function(t){this.uniforms.resolution.value.copy(t)}},sizeAttenuation:{enumerable:!0,get:function(){return this.uniforms.sizeAttenuation.value},set:function(t){this.uniforms.sizeAttenuation.value=t}},dashArray:{enumerable:!0,get:function(){return this.uniforms.dashArray.value},set:function(t){this.uniforms.dashArray.value=t,this.useDash=0!==t?1:0}},dashOffset:{enumerable:!0,get:function(){return this.uniforms.dashOffset.value},set:function(t){this.uniforms.dashOffset.value=t}},dashRatio:{enumerable:!0,get:function(){return this.uniforms.dashRatio.value},set:function(t){this.uniforms.dashRatio.value=t}},useDash:{enumerable:!0,get:function(){return this.uniforms.useDash.value},set:function(t){this.uniforms.useDash.value=t}},visibility:{enumerable:!0,get:function(){return this.uniforms.visibility.value},set:function(t){this.uniforms.visibility.value=t}},alphaTest:{enumerable:!0,get:function(){return this.uniforms.alphaTest.value},set:function(t){this.uniforms.alphaTest.value=t}},repeat:{enumerable:!0,get:function(){return this.uniforms.repeat.value},set:function(t){this.uniforms.repeat.value.copy(t)}}}),this.setValues(t)}}MeshLineMaterial.prototype.copy=function(t){return THREE.ShaderMaterial.prototype.copy.call(this,t),this.lineWidth=t.lineWidth,this.map=t.map,this.useMap=t.useMap,this.alphaMap=t.alphaMap,this.useAlphaMap=t.useAlphaMap,this.color.copy(t.color),this.opacity=t.opacity,this.resolution.copy(t.resolution),this.sizeAttenuation=t.sizeAttenuation,this.dashArray.copy(t.dashArray),this.dashOffset.copy(t.dashOffset),this.dashRatio.copy(t.dashRatio),this.useDash=t.useDash,this.visibility=t.visibility,this.alphaTest=t.alphaTest,this.repeat.copy(t.repeat),this};export{MeshLine,MeshLineMaterial,MeshLineRaycast};
15
- //# sourceMappingURL=/sm/a10f0fbff9ef9e01c8548236b6b20610cf5d5cba1f631d8ebab539add9c04974.map
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/TrackballControls.js DELETED
@@ -1,821 +0,0 @@
1
- async function _import() {
2
- if (!globalThis.posex || !globalThis.posex.import) {
3
- return await import('three');
4
- } else {
5
- return await globalThis.posex.imports.three();
6
- }
7
- }
8
- const {
9
- EventDispatcher,
10
- MOUSE,
11
- Quaternion,
12
- Vector2,
13
- Vector3
14
- } = await _import();
15
-
16
- const _changeEvent = { type: 'change' };
17
- const _startEvent = { type: 'start' };
18
- const _endEvent = { type: 'end' };
19
-
20
- class TrackballControls extends EventDispatcher {
21
-
22
- constructor( object, domElement ) {
23
-
24
- super();
25
-
26
- const scope = this;
27
- const STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
28
-
29
- this.object = object;
30
- this.domElement = domElement;
31
- this.domElement.style.touchAction = 'none'; // disable touch scroll
32
-
33
- // API
34
-
35
- this.enabled = true;
36
-
37
- this.screen = { left: 0, top: 0, width: 0, height: 0 };
38
-
39
- this.rotateSpeed = 1.0;
40
- this.zoomSpeed = 1.2;
41
- this.panSpeed = 0.3;
42
-
43
- this.noRotate = false;
44
- this.noZoom = false;
45
- this.noPan = false;
46
-
47
- this.staticMoving = false;
48
- this.dynamicDampingFactor = 0.2;
49
-
50
- this.minDistance = 0;
51
- this.maxDistance = Infinity;
52
-
53
- this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/ ];
54
-
55
- this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
56
-
57
- // internals
58
-
59
- this.target = new Vector3();
60
-
61
- const EPS = 0.000001;
62
-
63
- const lastPosition = new Vector3();
64
- let lastZoom = 1;
65
-
66
- let _state = STATE.NONE,
67
- _keyState = STATE.NONE,
68
-
69
- _touchZoomDistanceStart = 0,
70
- _touchZoomDistanceEnd = 0,
71
-
72
- _lastAngle = 0;
73
-
74
- const _eye = new Vector3(),
75
-
76
- _movePrev = new Vector2(),
77
- _moveCurr = new Vector2(),
78
-
79
- _lastAxis = new Vector3(),
80
-
81
- _zoomStart = new Vector2(),
82
- _zoomEnd = new Vector2(),
83
-
84
- _panStart = new Vector2(),
85
- _panEnd = new Vector2(),
86
-
87
- _pointers = [],
88
- _pointerPositions = {};
89
-
90
- // for reset
91
-
92
- this.target0 = this.target.clone();
93
- this.position0 = this.object.position.clone();
94
- this.up0 = this.object.up.clone();
95
- this.zoom0 = this.object.zoom;
96
-
97
- // methods
98
-
99
- this.handleResize = function () {
100
-
101
- const box = scope.domElement.getBoundingClientRect();
102
- // adjustments come from similar code in the jquery offset() function
103
- const d = scope.domElement.ownerDocument.documentElement;
104
- scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
105
- scope.screen.top = box.top + window.pageYOffset - d.clientTop;
106
- scope.screen.width = box.width;
107
- scope.screen.height = box.height;
108
-
109
- };
110
-
111
- const getMouseOnScreen = ( function () {
112
-
113
- const vector = new Vector2();
114
-
115
- return function getMouseOnScreen( pageX, pageY ) {
116
-
117
- vector.set(
118
- ( pageX - scope.screen.left ) / scope.screen.width,
119
- ( pageY - scope.screen.top ) / scope.screen.height
120
- );
121
-
122
- return vector;
123
-
124
- };
125
-
126
- }() );
127
-
128
- const getMouseOnCircle = ( function () {
129
-
130
- const vector = new Vector2();
131
-
132
- return function getMouseOnCircle( pageX, pageY ) {
133
-
134
- vector.set(
135
- ( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ) ),
136
- ( ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width ) // screen.width intentional
137
- );
138
-
139
- return vector;
140
-
141
- };
142
-
143
- }() );
144
-
145
- this.rotateCamera = ( function () {
146
-
147
- const axis = new Vector3(),
148
- quaternion = new Quaternion(),
149
- eyeDirection = new Vector3(),
150
- objectUpDirection = new Vector3(),
151
- objectSidewaysDirection = new Vector3(),
152
- moveDirection = new Vector3();
153
-
154
- return function rotateCamera() {
155
-
156
- moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
157
- let angle = moveDirection.length();
158
-
159
- if ( angle ) {
160
-
161
- _eye.copy( scope.object.position ).sub( scope.target );
162
-
163
- eyeDirection.copy( _eye ).normalize();
164
- objectUpDirection.copy( scope.object.up ).normalize();
165
- objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
166
-
167
- objectUpDirection.setLength( _moveCurr.y - _movePrev.y );
168
- objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );
169
-
170
- moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );
171
-
172
- axis.crossVectors( moveDirection, _eye ).normalize();
173
-
174
- angle *= scope.rotateSpeed;
175
- quaternion.setFromAxisAngle( axis, angle );
176
-
177
- _eye.applyQuaternion( quaternion );
178
- scope.object.up.applyQuaternion( quaternion );
179
-
180
- _lastAxis.copy( axis );
181
- _lastAngle = angle;
182
-
183
- } else if ( ! scope.staticMoving && _lastAngle ) {
184
-
185
- _lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
186
- _eye.copy( scope.object.position ).sub( scope.target );
187
- quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
188
- _eye.applyQuaternion( quaternion );
189
- scope.object.up.applyQuaternion( quaternion );
190
-
191
- }
192
-
193
- _movePrev.copy( _moveCurr );
194
-
195
- };
196
-
197
- }() );
198
-
199
-
200
- this.zoomCamera = function () {
201
-
202
- let factor;
203
-
204
- if ( _state === STATE.TOUCH_ZOOM_PAN ) {
205
-
206
- factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
207
- _touchZoomDistanceStart = _touchZoomDistanceEnd;
208
-
209
- if ( scope.object.isPerspectiveCamera ) {
210
-
211
- _eye.multiplyScalar( factor );
212
-
213
- } else if ( scope.object.isOrthographicCamera ) {
214
-
215
- scope.object.zoom /= factor;
216
- scope.object.updateProjectionMatrix();
217
-
218
- } else {
219
-
220
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
221
-
222
- }
223
-
224
- } else {
225
-
226
- factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
227
-
228
- if ( factor !== 1.0 && factor > 0.0 ) {
229
-
230
- if ( scope.object.isPerspectiveCamera ) {
231
-
232
- _eye.multiplyScalar( factor );
233
-
234
- } else if ( scope.object.isOrthographicCamera ) {
235
-
236
- scope.object.zoom /= factor;
237
- scope.object.updateProjectionMatrix();
238
-
239
- } else {
240
-
241
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
242
-
243
- }
244
-
245
- }
246
-
247
- if ( scope.staticMoving ) {
248
-
249
- _zoomStart.copy( _zoomEnd );
250
-
251
- } else {
252
-
253
- _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
254
-
255
- }
256
-
257
- }
258
-
259
- };
260
-
261
- this.panCamera = ( function () {
262
-
263
- const mouseChange = new Vector2(),
264
- objectUp = new Vector3(),
265
- pan = new Vector3();
266
-
267
- return function panCamera() {
268
-
269
- mouseChange.copy( _panEnd ).sub( _panStart );
270
-
271
- if ( mouseChange.lengthSq() ) {
272
-
273
- if ( scope.object.isOrthographicCamera ) {
274
-
275
- const scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth;
276
- const scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth;
277
-
278
- mouseChange.x *= scale_x;
279
- mouseChange.y *= scale_y;
280
-
281
- }
282
-
283
- mouseChange.multiplyScalar( _eye.length() * scope.panSpeed );
284
-
285
- pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x );
286
- pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
287
-
288
- scope.object.position.add( pan );
289
- scope.target.add( pan );
290
-
291
- if ( scope.staticMoving ) {
292
-
293
- _panStart.copy( _panEnd );
294
-
295
- } else {
296
-
297
- _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) );
298
-
299
- }
300
-
301
- }
302
-
303
- };
304
-
305
- }() );
306
-
307
- this.checkDistances = function () {
308
-
309
- if ( ! scope.noZoom || ! scope.noPan ) {
310
-
311
- if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
312
-
313
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
314
- _zoomStart.copy( _zoomEnd );
315
-
316
- }
317
-
318
- if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
319
-
320
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
321
- _zoomStart.copy( _zoomEnd );
322
-
323
- }
324
-
325
- }
326
-
327
- };
328
-
329
- this.update = function () {
330
-
331
- _eye.subVectors( scope.object.position, scope.target );
332
-
333
- if ( ! scope.noRotate ) {
334
-
335
- scope.rotateCamera();
336
-
337
- }
338
-
339
- if ( ! scope.noZoom ) {
340
-
341
- scope.zoomCamera();
342
-
343
- }
344
-
345
- if ( ! scope.noPan ) {
346
-
347
- scope.panCamera();
348
-
349
- }
350
-
351
- scope.object.position.addVectors( scope.target, _eye );
352
-
353
- if ( scope.object.isPerspectiveCamera ) {
354
-
355
- scope.checkDistances();
356
-
357
- scope.object.lookAt( scope.target );
358
-
359
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
360
-
361
- scope.dispatchEvent( _changeEvent );
362
-
363
- lastPosition.copy( scope.object.position );
364
-
365
- }
366
-
367
- } else if ( scope.object.isOrthographicCamera ) {
368
-
369
- scope.object.lookAt( scope.target );
370
-
371
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
372
-
373
- scope.dispatchEvent( _changeEvent );
374
-
375
- lastPosition.copy( scope.object.position );
376
- lastZoom = scope.object.zoom;
377
-
378
- }
379
-
380
- } else {
381
-
382
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
383
-
384
- }
385
-
386
- };
387
-
388
- this.reset = function () {
389
-
390
- _state = STATE.NONE;
391
- _keyState = STATE.NONE;
392
-
393
- scope.target.copy( scope.target0 );
394
- scope.object.position.copy( scope.position0 );
395
- scope.object.up.copy( scope.up0 );
396
- scope.object.zoom = scope.zoom0;
397
-
398
- scope.object.updateProjectionMatrix();
399
-
400
- _eye.subVectors( scope.object.position, scope.target );
401
-
402
- scope.object.lookAt( scope.target );
403
-
404
- scope.dispatchEvent( _changeEvent );
405
-
406
- lastPosition.copy( scope.object.position );
407
- lastZoom = scope.object.zoom;
408
-
409
- };
410
-
411
- // listeners
412
-
413
- function onPointerDown( event ) {
414
-
415
- if ( scope.enabled === false ) return;
416
-
417
- if ( _pointers.length === 0 ) {
418
-
419
- scope.domElement.setPointerCapture( event.pointerId );
420
-
421
- scope.domElement.addEventListener( 'pointermove', onPointerMove );
422
- scope.domElement.addEventListener( 'pointerup', onPointerUp );
423
-
424
- }
425
-
426
- //
427
-
428
- addPointer( event );
429
-
430
- if ( event.pointerType === 'touch' ) {
431
-
432
- onTouchStart( event );
433
-
434
- } else {
435
-
436
- onMouseDown( event );
437
-
438
- }
439
-
440
- }
441
-
442
- function onPointerMove( event ) {
443
-
444
- if ( scope.enabled === false ) return;
445
-
446
- if ( event.pointerType === 'touch' ) {
447
-
448
- onTouchMove( event );
449
-
450
- } else {
451
-
452
- onMouseMove( event );
453
-
454
- }
455
-
456
- }
457
-
458
- function onPointerUp( event ) {
459
-
460
- if ( scope.enabled === false ) return;
461
-
462
- if ( event.pointerType === 'touch' ) {
463
-
464
- onTouchEnd( event );
465
-
466
- } else {
467
-
468
- onMouseUp();
469
-
470
- }
471
-
472
- //
473
-
474
- removePointer( event );
475
-
476
- if ( _pointers.length === 0 ) {
477
-
478
- scope.domElement.releasePointerCapture( event.pointerId );
479
-
480
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
481
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
482
-
483
- }
484
-
485
-
486
- }
487
-
488
- function onPointerCancel( event ) {
489
-
490
- removePointer( event );
491
-
492
- }
493
-
494
- function keydown( event ) {
495
-
496
- if ( scope.enabled === false ) return;
497
-
498
- window.removeEventListener( 'keydown', keydown );
499
-
500
- if ( _keyState !== STATE.NONE ) {
501
-
502
- return;
503
-
504
- } else if ( event.code === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) {
505
-
506
- _keyState = STATE.ROTATE;
507
-
508
- } else if ( event.code === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) {
509
-
510
- _keyState = STATE.ZOOM;
511
-
512
- } else if ( event.code === scope.keys[ STATE.PAN ] && ! scope.noPan ) {
513
-
514
- _keyState = STATE.PAN;
515
-
516
- }
517
-
518
- }
519
-
520
- function keyup() {
521
-
522
- if ( scope.enabled === false ) return;
523
-
524
- _keyState = STATE.NONE;
525
-
526
- window.addEventListener( 'keydown', keydown );
527
-
528
- }
529
-
530
- function onMouseDown( event ) {
531
-
532
- if ( _state === STATE.NONE ) {
533
-
534
- switch ( event.button ) {
535
-
536
- case scope.mouseButtons.LEFT:
537
- _state = STATE.ROTATE;
538
- break;
539
-
540
- case scope.mouseButtons.MIDDLE:
541
- _state = STATE.ZOOM;
542
- break;
543
-
544
- case scope.mouseButtons.RIGHT:
545
- _state = STATE.PAN;
546
- break;
547
-
548
- }
549
-
550
- }
551
-
552
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
553
-
554
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
555
-
556
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
557
- _movePrev.copy( _moveCurr );
558
-
559
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
560
-
561
- _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
562
- _zoomEnd.copy( _zoomStart );
563
-
564
- } else if ( state === STATE.PAN && ! scope.noPan ) {
565
-
566
- _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
567
- _panEnd.copy( _panStart );
568
-
569
- }
570
-
571
- scope.dispatchEvent( _startEvent );
572
-
573
- }
574
-
575
- function onMouseMove( event ) {
576
-
577
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
578
-
579
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
580
-
581
- _movePrev.copy( _moveCurr );
582
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
583
-
584
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
585
-
586
- _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
587
-
588
- } else if ( state === STATE.PAN && ! scope.noPan ) {
589
-
590
- _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
591
-
592
- }
593
-
594
- }
595
-
596
- function onMouseUp() {
597
-
598
- _state = STATE.NONE;
599
-
600
- scope.dispatchEvent( _endEvent );
601
-
602
- }
603
-
604
- function onMouseWheel( event ) {
605
-
606
- if ( scope.enabled === false ) return;
607
-
608
- if ( scope.noZoom === true ) return;
609
-
610
- event.preventDefault();
611
-
612
- switch ( event.deltaMode ) {
613
-
614
- case 2:
615
- // Zoom in pages
616
- _zoomStart.y -= event.deltaY * 0.025;
617
- break;
618
-
619
- case 1:
620
- // Zoom in lines
621
- _zoomStart.y -= event.deltaY * 0.01;
622
- break;
623
-
624
- default:
625
- // undefined, 0, assume pixels
626
- _zoomStart.y -= event.deltaY * 0.00025;
627
- break;
628
-
629
- }
630
-
631
- scope.dispatchEvent( _startEvent );
632
- scope.dispatchEvent( _endEvent );
633
-
634
- }
635
-
636
- function onTouchStart( event ) {
637
-
638
- trackPointer( event );
639
-
640
- switch ( _pointers.length ) {
641
-
642
- case 1:
643
- _state = STATE.TOUCH_ROTATE;
644
- _moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );
645
- _movePrev.copy( _moveCurr );
646
- break;
647
-
648
- default: // 2 or more
649
- _state = STATE.TOUCH_ZOOM_PAN;
650
- const dx = _pointers[ 0 ].pageX - _pointers[ 1 ].pageX;
651
- const dy = _pointers[ 0 ].pageY - _pointers[ 1 ].pageY;
652
- _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
653
-
654
- const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;
655
- const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;
656
- _panStart.copy( getMouseOnScreen( x, y ) );
657
- _panEnd.copy( _panStart );
658
- break;
659
-
660
- }
661
-
662
- scope.dispatchEvent( _startEvent );
663
-
664
- }
665
-
666
- function onTouchMove( event ) {
667
-
668
- trackPointer( event );
669
-
670
- switch ( _pointers.length ) {
671
-
672
- case 1:
673
- _movePrev.copy( _moveCurr );
674
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
675
- break;
676
-
677
- default: // 2 or more
678
-
679
- const position = getSecondPointerPosition( event );
680
-
681
- const dx = event.pageX - position.x;
682
- const dy = event.pageY - position.y;
683
- _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
684
-
685
- const x = ( event.pageX + position.x ) / 2;
686
- const y = ( event.pageY + position.y ) / 2;
687
- _panEnd.copy( getMouseOnScreen( x, y ) );
688
- break;
689
-
690
- }
691
-
692
- }
693
-
694
- function onTouchEnd( event ) {
695
-
696
- switch ( _pointers.length ) {
697
-
698
- case 0:
699
- _state = STATE.NONE;
700
- break;
701
-
702
- case 1:
703
- _state = STATE.TOUCH_ROTATE;
704
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
705
- _movePrev.copy( _moveCurr );
706
- break;
707
-
708
- case 2:
709
- _state = STATE.TOUCH_ZOOM_PAN;
710
-
711
- for ( let i = 0; i < _pointers.length; i ++ ) {
712
-
713
- if ( _pointers[ i ].pointerId !== event.pointerId ) {
714
-
715
- const position = _pointerPositions[ _pointers[ i ].pointerId ];
716
- _moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
717
- _movePrev.copy( _moveCurr );
718
- break;
719
-
720
- }
721
-
722
- }
723
-
724
- break;
725
-
726
- }
727
-
728
- scope.dispatchEvent( _endEvent );
729
-
730
- }
731
-
732
- function contextmenu( event ) {
733
-
734
- if ( scope.enabled === false ) return;
735
-
736
- event.preventDefault();
737
-
738
- }
739
-
740
- function addPointer( event ) {
741
-
742
- _pointers.push( event );
743
-
744
- }
745
-
746
- function removePointer( event ) {
747
-
748
- delete _pointerPositions[ event.pointerId ];
749
-
750
- for ( let i = 0; i < _pointers.length; i ++ ) {
751
-
752
- if ( _pointers[ i ].pointerId == event.pointerId ) {
753
-
754
- _pointers.splice( i, 1 );
755
- return;
756
-
757
- }
758
-
759
- }
760
-
761
- }
762
-
763
- function trackPointer( event ) {
764
-
765
- let position = _pointerPositions[ event.pointerId ];
766
-
767
- if ( position === undefined ) {
768
-
769
- position = new Vector2();
770
- _pointerPositions[ event.pointerId ] = position;
771
-
772
- }
773
-
774
- position.set( event.pageX, event.pageY );
775
-
776
- }
777
-
778
- function getSecondPointerPosition( event ) {
779
-
780
- const pointer = ( event.pointerId === _pointers[ 0 ].pointerId ) ? _pointers[ 1 ] : _pointers[ 0 ];
781
-
782
- return _pointerPositions[ pointer.pointerId ];
783
-
784
- }
785
-
786
- this.dispose = function () {
787
-
788
- scope.domElement.removeEventListener( 'contextmenu', contextmenu );
789
-
790
- scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
791
- scope.domElement.removeEventListener( 'pointercancel', onPointerCancel );
792
- scope.domElement.removeEventListener( 'wheel', onMouseWheel );
793
-
794
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
795
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
796
-
797
- window.removeEventListener( 'keydown', keydown );
798
- window.removeEventListener( 'keyup', keyup );
799
-
800
- };
801
-
802
- this.domElement.addEventListener( 'contextmenu', contextmenu );
803
-
804
- this.domElement.addEventListener( 'pointerdown', onPointerDown );
805
- this.domElement.addEventListener( 'pointercancel', onPointerCancel );
806
- this.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
807
-
808
-
809
- window.addEventListener( 'keydown', keydown );
810
- window.addEventListener( 'keyup', keyup );
811
-
812
- this.handleResize();
813
-
814
- // force an update at start
815
- this.update();
816
-
817
- }
818
-
819
- }
820
-
821
- export { TrackballControls };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/app.js DELETED
@@ -1,145 +0,0 @@
1
- const POSES = new Map();
2
-
3
- function notify(str, type) {
4
- if (type === undefined) type = 'success';
5
-
6
- switch (type) {
7
- case 'success': console.log(str); break;
8
- case 'info': console.log(str); break;
9
- case 'warn': console.warn(str); break;
10
- case 'error': console.error(str); break;
11
- }
12
-
13
- const p = document.createElement('p');
14
- p.textContent = str;
15
- p.classList.add('item', type);
16
- const cont = document.querySelector('#notifications');
17
- cont.appendChild(p);
18
- setTimeout(() => cont.removeChild(p), 3000);
19
- }
20
-
21
- async function save_pose(obj) {
22
- const res = await fetch('/pose/save', {
23
- method: 'POST',
24
- headers: { 'Content-Type': 'application/json' },
25
- body: JSON.stringify(obj),
26
- });
27
- const result = await res.json();
28
- if (result.ok) reload_poses();
29
- return result;
30
- }
31
-
32
- async function delete_pose(name) {
33
- const res = await fetch('/pose/delete', {
34
- method: 'POST',
35
- headers: { 'Content-Type': 'application/json' },
36
- body: JSON.stringify({ name }),
37
- });
38
- const result = await res.json();
39
- notify(result.result, result.ok ? 'success' : 'error');
40
- if (result.ok) reload_poses();
41
- return result;
42
- }
43
-
44
- async function reload_poses() {
45
- POSES.clear();
46
-
47
- const res = await fetch('/pose/all');
48
- const cont = document.querySelector('#saved_poses');
49
- cont.innerHTML = '';
50
- const df = document.createDocumentFragment();
51
- for (let data of await res.json()) {
52
- POSES.set(data.name, data);
53
-
54
- const fig = document.createElement('figure')
55
- const img = document.createElement('img');
56
- const cap = document.createElement('figcaption');
57
- const clo = document.createElement('div');
58
- const clo2 = document.createElement('span');
59
- fig.dataset.poseName = data.name;
60
- cap.textContent = data.name;
61
- clo.textContent = 'x';
62
- clo.classList.add('close');
63
- clo2.classList.add('close2');
64
- clo2.textContent = 'delete';
65
- clo.appendChild(clo2);
66
-
67
- img.src = 'data:image/png;base64,' + data.image;
68
- img.title = data.name;
69
- fig.append(clo, img, cap);
70
-
71
- df.appendChild(fig);
72
- }
73
- cont.appendChild(df);
74
- }
75
-
76
- document.addEventListener('DOMContentLoaded', async () => {
77
-
78
- const ui = {
79
- container: document.querySelector('#cont'),
80
- canvas: document.querySelector('#main_canvas'),
81
- notation: document.querySelector('#notation'),
82
- indicator1: document.querySelector('#body_indicator1'),
83
- indicator2: document.querySelector('#body_indicator2'),
84
- all_reset: document.querySelector('#all_reset'),
85
- reset_camera: document.querySelector('#reset_camera'),
86
- reset_pose: document.querySelector('#reset_pose'),
87
- fixed_roll: document.querySelector('#fixed_roll'),
88
- add_body: document.querySelector('#add_body'),
89
- remove_body: document.querySelector('#remove_body'),
90
- canvas_width: document.querySelector('#canvas_width'),
91
- canvas_height: document.querySelector('#canvas_height'),
92
- bg: document.querySelector('#bg_file'),
93
- reset_bg: document.querySelector('#reset_bg'),
94
- elliptic_limbs: document.querySelector('#elliptic_limbs'),
95
- //joint_radius: document.querySelector('#joint_radius'),
96
- limb_width: document.querySelector('#limb_width'),
97
- low_fps: document.querySelector('#low_fps'),
98
- save: document.querySelector('#save_button'),
99
- copy: document.querySelector('#copy_button'),
100
- save_pose: document.querySelector('#save_pose'),
101
- save_pose_callback: save_pose,
102
- notify: notify,
103
- };
104
-
105
- document.addEventListener('poseload', e => {
106
- const obj = POSES.get(e.detail.name);
107
- if (obj) ui.loadPose(obj);
108
- }, false);
109
-
110
- const { init, init_3d } = await import('posex');
111
-
112
- init(ui);
113
- const animate = init_3d(ui);
114
- animate();
115
-
116
- await reload_poses();
117
-
118
- }, false);
119
-
120
- document.addEventListener('DOMContentLoaded', () => {
121
- const get_name = ele => {
122
- while (ele && ele !== document) {
123
- if (ele.dataset && ele.dataset.poseName !== undefined)
124
- return ele.dataset.poseName;
125
- ele = ele.parentNode;
126
- }
127
- return '';
128
- };
129
-
130
- document.querySelector('#saved_poses').addEventListener('click', e => {
131
- let target = e.target;
132
- if (target.tagName === 'IMG') target = target.parentNode;
133
- if (target.classList.contains('close2')) target = target.parentNode;
134
- if (target.tagName === 'FIGURE') {
135
- const name = get_name(target);
136
- const ev = new CustomEvent('poseload', { bubbles: true, detail: { name } });
137
- target.dispatchEvent(ev);
138
- } else if (target.classList.contains('close')) {
139
- const name = get_name(target);
140
- if (name.length != 0) {
141
- delete_pose(name);
142
- }
143
- }
144
- }, false);
145
- }, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/es-module-shims.js DELETED
@@ -1,790 +0,0 @@
1
- // https://github.com/guybedford/es-module-shims
2
-
3
- /* ES Module Shims 1.3.6 */
4
- (function () {
5
-
6
- const edge = navigator.userAgent.match(/Edge\/\d\d\.\d+$/);
7
-
8
- let baseUrl;
9
-
10
- function createBlob(source, type = 'text/javascript') {
11
- return URL.createObjectURL(new Blob([source], { type }));
12
- }
13
-
14
- const noop = () => { };
15
-
16
- const baseEl = document.querySelector('base[href]');
17
- if (baseEl)
18
- baseUrl = baseEl.href;
19
-
20
- if (!baseUrl && typeof location !== 'undefined') {
21
- baseUrl = location.href.split('#')[0].split('?')[0];
22
- const lastSepIndex = baseUrl.lastIndexOf('/');
23
- if (lastSepIndex !== -1)
24
- baseUrl = baseUrl.slice(0, lastSepIndex + 1);
25
- }
26
-
27
- function isURL(url) {
28
- try {
29
- new URL(url);
30
- return true;
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
-
37
- const backslashRegEx = /\\/g;
38
- function resolveIfNotPlainOrUrl(relUrl, parentUrl) {
39
- // strip off any trailing query params or hashes
40
- parentUrl = parentUrl && parentUrl.split('#')[0].split('?')[0];
41
- if (relUrl.indexOf('\\') !== -1)
42
- relUrl = relUrl.replace(backslashRegEx, '/');
43
- // protocol-relative
44
- if (relUrl[0] === '/' && relUrl[1] === '/') {
45
- return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl;
46
- }
47
- // relative-url
48
- else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) ||
49
- relUrl.length === 1 && (relUrl += '/')) ||
50
- relUrl[0] === '/') {
51
- const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1);
52
- // Disabled, but these cases will give inconsistent results for deep backtracking
53
- //if (parentUrl[parentProtocol.length] !== '/')
54
- // throw new Error('Cannot resolve');
55
- // read pathname from parent URL
56
- // pathname taken to be part after leading "/"
57
- let pathname;
58
- if (parentUrl[parentProtocol.length + 1] === '/') {
59
- // resolving to a :// so we need to read out the auth and host
60
- if (parentProtocol !== 'file:') {
61
- pathname = parentUrl.slice(parentProtocol.length + 2);
62
- pathname = pathname.slice(pathname.indexOf('/') + 1);
63
- }
64
- else {
65
- pathname = parentUrl.slice(8);
66
- }
67
- }
68
- else {
69
- // resolving to :/ so pathname is the /... part
70
- pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/'));
71
- }
72
-
73
- if (relUrl[0] === '/')
74
- return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl;
75
-
76
- // join together and split for removal of .. and . segments
77
- // looping the string instead of anything fancy for perf reasons
78
- // '../../../../../z' resolved to 'x/y' is just 'z'
79
- const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl;
80
-
81
- const output = [];
82
- let segmentIndex = -1;
83
- for (let i = 0; i < segmented.length; i++) {
84
- // busy reading a segment - only terminate on '/'
85
- if (segmentIndex !== -1) {
86
- if (segmented[i] === '/') {
87
- output.push(segmented.slice(segmentIndex, i + 1));
88
- segmentIndex = -1;
89
- }
90
- }
91
-
92
- // new segment - check if it is relative
93
- else if (segmented[i] === '.') {
94
- // ../ segment
95
- if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) {
96
- output.pop();
97
- i += 2;
98
- }
99
- // ./ segment
100
- else if (segmented[i + 1] === '/' || i + 1 === segmented.length) {
101
- i += 1;
102
- }
103
- else {
104
- // the start of a new segment as below
105
- segmentIndex = i;
106
- }
107
- }
108
- // it is the start of a new segment
109
- else {
110
- segmentIndex = i;
111
- }
112
- }
113
- // finish reading out the last segment
114
- if (segmentIndex !== -1)
115
- output.push(segmented.slice(segmentIndex));
116
- return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join('');
117
- }
118
- }
119
-
120
- /*
121
- * Import maps implementation
122
- *
123
- * To make lookups fast we pre-resolve the entire import map
124
- * and then match based on backtracked hash lookups
125
- *
126
- */
127
- function resolveUrl(relUrl, parentUrl) {
128
- return resolveIfNotPlainOrUrl(relUrl, parentUrl) || (relUrl.indexOf(':') !== -1 ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl));
129
- }
130
-
131
- function resolveAndComposePackages(packages, outPackages, baseUrl, parentMap) {
132
- for (let p in packages) {
133
- const resolvedLhs = resolveIfNotPlainOrUrl(p, baseUrl) || p;
134
- if (outPackages[resolvedLhs]) {
135
- throw new Error(`Dynamic import map rejected: Overrides entry "${resolvedLhs}" from ${outPackages[resolvedLhs]} to ${packages[resolvedLhs]}.`);
136
- }
137
- let target = packages[p];
138
- if (typeof target !== 'string')
139
- continue;
140
- const mapped = resolveImportMap(parentMap, resolveIfNotPlainOrUrl(target, baseUrl) || target, baseUrl);
141
- if (mapped) {
142
- outPackages[resolvedLhs] = mapped;
143
- continue;
144
- }
145
- targetWarning(p, packages[p], 'bare specifier did not resolve');
146
- }
147
- }
148
-
149
- function resolveAndComposeImportMap(json, baseUrl, parentMap) {
150
- const outMap = { imports: Object.assign({}, parentMap.imports), scopes: Object.assign({}, parentMap.scopes) };
151
-
152
- if (json.imports)
153
- resolveAndComposePackages(json.imports, outMap.imports, baseUrl, parentMap);
154
-
155
- if (json.scopes)
156
- for (let s in json.scopes) {
157
- const resolvedScope = resolveUrl(s, baseUrl);
158
- resolveAndComposePackages(json.scopes[s], outMap.scopes[resolvedScope] || (outMap.scopes[resolvedScope] = {}), baseUrl, parentMap);
159
- }
160
-
161
- return outMap;
162
- }
163
-
164
- function getMatch(path, matchObj) {
165
- if (matchObj[path])
166
- return path;
167
- let sepIndex = path.length;
168
- do {
169
- const segment = path.slice(0, sepIndex + 1);
170
- if (segment in matchObj)
171
- return segment;
172
- } while ((sepIndex = path.lastIndexOf('/', sepIndex - 1)) !== -1)
173
- }
174
-
175
- function applyPackages(id, packages) {
176
- const pkgName = getMatch(id, packages);
177
- if (pkgName) {
178
- const pkg = packages[pkgName];
179
- if (pkg === null) return;
180
- if (id.length > pkgName.length && pkg[pkg.length - 1] !== '/')
181
- targetWarning(pkgName, pkg, "should have a trailing '/'");
182
- else
183
- return pkg + id.slice(pkgName.length);
184
- }
185
- }
186
-
187
- function targetWarning(match, target, msg) {
188
- console.warn("Package target " + msg + ", resolving target '" + target + "' for " + match);
189
- }
190
-
191
- function resolveImportMap(importMap, resolvedOrPlain, parentUrl) {
192
- let scopeUrl = parentUrl && getMatch(parentUrl, importMap.scopes);
193
- while (scopeUrl) {
194
- const packageResolution = applyPackages(resolvedOrPlain, importMap.scopes[scopeUrl]);
195
- if (packageResolution)
196
- return packageResolution;
197
- scopeUrl = getMatch(scopeUrl.slice(0, scopeUrl.lastIndexOf('/')), importMap.scopes);
198
- }
199
- return applyPackages(resolvedOrPlain, importMap.imports) || resolvedOrPlain.indexOf(':') !== -1 && resolvedOrPlain;
200
- }
201
-
202
- const optionsScript = document.querySelector('script[type=esms-options]');
203
-
204
- const esmsInitOptions = optionsScript ? JSON.parse(optionsScript.innerHTML) : self.esmsInitOptions ? self.esmsInitOptions : {};
205
-
206
- let shimMode = !!esmsInitOptions.shimMode;
207
- const resolveHook = globalHook(shimMode && esmsInitOptions.resolve);
208
-
209
- const skip = esmsInitOptions.skip ? new RegExp(esmsInitOptions.skip) : null;
210
-
211
- let nonce = esmsInitOptions.nonce;
212
-
213
- if (!nonce) {
214
- const nonceElement = document.querySelector('script[nonce]');
215
- if (nonceElement)
216
- nonce = nonceElement.nonce || nonceElement.getAttribute('nonce');
217
- }
218
-
219
- const onerror = globalHook(esmsInitOptions.onerror || noop);
220
- const onpolyfill = globalHook(esmsInitOptions.onpolyfill || noop);
221
-
222
- const { revokeBlobURLs, noLoadEventRetriggers } = esmsInitOptions;
223
-
224
- const fetchHook = esmsInitOptions.fetch ? globalHook(esmsInitOptions.fetch) : fetch;
225
-
226
- function globalHook(name) {
227
- return typeof name === 'string' ? self[name] : name;
228
- }
229
-
230
- const enable = Array.isArray(esmsInitOptions.polyfillEnable) ? esmsInitOptions.polyfillEnable : [];
231
- const cssModulesEnabled = enable.includes('css-modules');
232
- const jsonModulesEnabled = enable.includes('json-modules');
233
-
234
- function setShimMode() {
235
- shimMode = true;
236
- }
237
-
238
- let err;
239
- window.addEventListener('error', _err => err = _err);
240
- function dynamicImportScript(url, { errUrl = url } = {}) {
241
- err = undefined;
242
- const src = createBlob(`import*as m from'${url}';self._esmsi=m`);
243
- const s = Object.assign(document.createElement('script'), { type: 'module', src });
244
- s.setAttribute('nonce', nonce);
245
- s.setAttribute('noshim', '');
246
- const p = new Promise((resolve, reject) => {
247
- // Safari is unique in supporting module script error events
248
- s.addEventListener('error', cb);
249
- s.addEventListener('load', cb);
250
-
251
- function cb(_err) {
252
- document.head.removeChild(s);
253
- if (self._esmsi) {
254
- resolve(self._esmsi, baseUrl);
255
- self._esmsi = undefined;
256
- }
257
- else {
258
- reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${src}).`));
259
- err = undefined;
260
- }
261
- }
262
- });
263
- document.head.appendChild(s);
264
- return p;
265
- }
266
-
267
- let dynamicImport = dynamicImportScript;
268
-
269
- const supportsDynamicImportCheck = dynamicImportScript(createBlob('export default u=>import(u)')).then(_dynamicImport => {
270
- if (_dynamicImport)
271
- dynamicImport = _dynamicImport.default;
272
- return !!_dynamicImport;
273
- }, noop);
274
-
275
- // support browsers without dynamic import support (eg Firefox 6x)
276
- let supportsJsonAssertions = false;
277
- let supportsCssAssertions = false;
278
-
279
- let supportsImportMeta = false;
280
- let supportsImportMaps = false;
281
-
282
- let supportsDynamicImport = false;
283
-
284
- const featureDetectionPromise = Promise.resolve(supportsDynamicImportCheck).then(_supportsDynamicImport => {
285
- if (!_supportsDynamicImport)
286
- return;
287
- supportsDynamicImport = true;
288
-
289
- return Promise.all([
290
- dynamicImport(createBlob('import.meta')).then(() => supportsImportMeta = true, noop),
291
- cssModulesEnabled && dynamicImport(createBlob('import"data:text/css,{}"assert{type:"css"}')).then(() => supportsCssAssertions = true, noop),
292
- jsonModulesEnabled && dynamicImport(createBlob('import"data:text/json,{}"assert{type:"json"}')).then(() => supportsJsonAssertions = true, noop),
293
- new Promise(resolve => {
294
- self._$s = v => {
295
- document.head.removeChild(iframe);
296
- if (v) supportsImportMaps = true;
297
- delete self._$s;
298
- resolve();
299
- };
300
- const iframe = document.createElement('iframe');
301
- iframe.style.display = 'none';
302
- document.head.appendChild(iframe);
303
- iframe.src = createBlob(`<script type=importmap nonce="${nonce}">{"imports":{"x":"data:text/javascript,"}}<${''}/script><script nonce="${nonce}">import('x').then(()=>1,()=>0).then(v=>parent._$s(v))<${''}/script>`, 'text/html');
304
- })
305
- ]);
306
- });
307
-
308
- let e, r, a, i = 4194304; const s = 1 === new Uint8Array(new Uint16Array([1]).buffer)[0]; let t, f, c$1; function parse(k, l = "@") { if (t = k, f = l, t.length > i || !e) { for (; t.length > i;)i *= 2; r = new ArrayBuffer(4 * i), e = function (e, r, a) { "use asm"; var i = new e.Int8Array(a), s = new e.Int16Array(a), t = new e.Int32Array(a), f = new e.Uint8Array(a), c = new e.Uint16Array(a), n = 816; function b(e) { e = e | 0; var r = 0, a = 0, f = 0, b = 0, l = 0; l = n; n = n + 14336 | 0; b = l; i[589] = 1; s[291] = 0; s[292] = 0; s[293] = -1; t[15] = t[2]; i[590] = 0; t[14] = 0; i[588] = 0; t[16] = l + 10240; t[17] = l + 2048; i[591] = 0; e = (t[3] | 0) + -2 | 0; t[18] = e; r = e + (t[12] << 1) | 0; t[19] = r; e: while (1) { a = e + 2 | 0; t[18] = a; if (e >>> 0 >= r >>> 0) { f = 18; break } r: do { switch (s[a >> 1] | 0) { case 9: case 10: case 11: case 12: case 13: case 32: break; case 101: { if ((((s[292] | 0) == 0 ? R(a) | 0 : 0) ? B(e + 4 | 0, 120, 112, 111, 114, 116) | 0 : 0) ? (u(), (i[589] | 0) == 0) : 0) { f = 9; break e } else f = 17; break } case 105: { if (R(a) | 0 ? B(e + 4 | 0, 109, 112, 111, 114, 116) | 0 : 0) { k(); f = 17; } else f = 17; break } case 59: { f = 17; break } case 47: switch (s[e + 4 >> 1] | 0) { case 47: { G(); break r } case 42: { p(1); break r } default: { f = 16; break e } }default: { f = 16; break e } } } while (0); if ((f | 0) == 17) { f = 0; t[15] = t[18]; } e = t[18] | 0; r = t[19] | 0; } if ((f | 0) == 9) { e = t[18] | 0; t[15] = e; f = 19; } else if ((f | 0) == 16) { i[589] = 0; t[18] = e; f = 19; } else if ((f | 0) == 18) if (!(i[588] | 0)) { e = a; f = 19; } else e = 0; do { if ((f | 0) == 19) { e: while (1) { r = e + 2 | 0; t[18] = r; a = r; if (e >>> 0 >= (t[19] | 0) >>> 0) { f = 75; break } r: do { switch (s[r >> 1] | 0) { case 9: case 10: case 11: case 12: case 13: case 32: break; case 101: { if (((s[292] | 0) == 0 ? R(r) | 0 : 0) ? B(e + 4 | 0, 120, 112, 111, 114, 116) | 0 : 0) { u(); f = 74; } else f = 74; break } case 105: { if (R(r) | 0 ? B(e + 4 | 0, 109, 112, 111, 114, 116) | 0 : 0) { k(); f = 74; } else f = 74; break } case 99: { if ((R(r) | 0 ? z(e + 4 | 0, 108, 97, 115, 115) | 0 : 0) ? Z(s[e + 12 >> 1] | 0) | 0 : 0) { i[591] = 1; f = 74; } else f = 74; break } case 40: { r = t[15] | 0; a = t[17] | 0; f = s[292] | 0; s[292] = f + 1 << 16 >> 16; t[a + ((f & 65535) << 2) >> 2] = r; f = 74; break } case 41: { e = s[292] | 0; if (!(e << 16 >> 16)) { f = 36; break e } f = e + -1 << 16 >> 16; s[292] = f; e = t[11] | 0; if ((e | 0) != 0 ? (t[e + 20 >> 2] | 0) == (t[(t[17] | 0) + ((f & 65535) << 2) >> 2] | 0) : 0) { r = e + 4 | 0; if (!(t[r >> 2] | 0)) t[r >> 2] = a; t[e + 12 >> 2] = a; t[11] = 0; f = 74; } else f = 74; break } case 123: { f = t[15] | 0; a = t[8] | 0; e = f; do { if ((s[f >> 1] | 0) == 41 & (a | 0) != 0 ? (t[a + 4 >> 2] | 0) == (f | 0) : 0) { r = t[9] | 0; t[8] = r; if (!r) { t[4] = 0; break } else { t[r + 28 >> 2] = 0; break } } } while (0); r = s[292] | 0; f = r & 65535; i[b + f >> 0] = i[591] | 0; i[591] = 0; a = t[17] | 0; s[292] = r + 1 << 16 >> 16; t[a + (f << 2) >> 2] = e; f = 74; break } case 125: { e = s[292] | 0; if (!(e << 16 >> 16)) { f = 49; break e } a = e + -1 << 16 >> 16; s[292] = a; r = s[293] | 0; if (e << 16 >> 16 != r << 16 >> 16) if (r << 16 >> 16 != -1 & (a & 65535) < (r & 65535)) { f = 53; break e } else { f = 74; break r } else { a = t[16] | 0; f = (s[291] | 0) + -1 << 16 >> 16; s[291] = f; s[293] = s[a + ((f & 65535) << 1) >> 1] | 0; h(); f = 74; break r } } case 39: { d(39); f = 74; break } case 34: { d(34); f = 74; break } case 47: switch (s[e + 4 >> 1] | 0) { case 47: { G(); break r } case 42: { p(1); break r } default: { r = t[15] | 0; a = s[r >> 1] | 0; a: do { if (!(x(a) | 0)) { switch (a << 16 >> 16) { case 41: if (L(t[(t[17] | 0) + (c[292] << 2) >> 2] | 0) | 0) { f = 71; break a } else { f = 68; break a } case 125: break; default: { f = 68; break a } }e = c[292] | 0; if (!(y(t[(t[17] | 0) + (e << 2) >> 2] | 0) | 0) ? (i[b + e >> 0] | 0) == 0 : 0) f = 68; else f = 71; } else switch (a << 16 >> 16) { case 46: if (((s[r + -2 >> 1] | 0) + -48 & 65535) < 10) { f = 68; break a } else { f = 71; break a } case 43: if ((s[r + -2 >> 1] | 0) == 43) { f = 68; break a } else { f = 71; break a } case 45: if ((s[r + -2 >> 1] | 0) == 45) { f = 68; break a } else { f = 71; break a } default: { f = 71; break a } } } while (0); a: do { if ((f | 0) == 68) { f = 0; if (!(o(r) | 0)) { switch (a << 16 >> 16) { case 0: { f = 71; break a } case 47: break; default: { e = 1; break a } }if (!(i[590] | 0)) e = 1; else f = 71; } else f = 71; } } while (0); if ((f | 0) == 71) { I(); e = 0; } i[590] = e; f = 74; break r } }case 96: { h(); f = 74; break } default: f = 74; } } while (0); if ((f | 0) == 74) { f = 0; t[15] = t[18]; } e = t[18] | 0; } if ((f | 0) == 36) { Y(); e = 0; break } else if ((f | 0) == 49) { Y(); e = 0; break } else if ((f | 0) == 53) { Y(); e = 0; break } else if ((f | 0) == 75) { e = (s[293] | 0) == -1 & (s[292] | 0) == 0 & (i[588] | 0) == 0; break } } } while (0); n = l; return e | 0 } function u() { var e = 0, r = 0, a = 0, f = 0, c = 0, n = 0; c = t[18] | 0; n = c + 12 | 0; t[18] = n; r = w(1) | 0; e = t[18] | 0; if (!((e | 0) == (n | 0) ? !(S(r) | 0) : 0)) f = 3; e: do { if ((f | 0) == 3) { r: do { switch (r << 16 >> 16) { case 100: { J(e, e + 14 | 0); break e } case 97: { t[18] = e + 10; w(1) | 0; e = t[18] | 0; f = 6; break } case 102: { f = 6; break } case 99: { if (z(e + 2 | 0, 108, 97, 115, 115) | 0 ? (a = e + 10 | 0, F(s[a >> 1] | 0) | 0) : 0) { t[18] = a; c = w(1) | 0; n = t[18] | 0; H(c) | 0; J(n, t[18] | 0); t[18] = (t[18] | 0) + -2; break e } e = e + 4 | 0; t[18] = e; f = 13; break } case 108: case 118: { f = 13; break } case 123: { t[18] = e + 2; e = w(1) | 0; a = t[18] | 0; while (1) { if (_(e) | 0) { d(e); e = (t[18] | 0) + 2 | 0; t[18] = e; } else { H(e) | 0; e = t[18] | 0; } w(1) | 0; e = g(a, e) | 0; if (e << 16 >> 16 == 44) { t[18] = (t[18] | 0) + 2; e = w(1) | 0; } r = a; a = t[18] | 0; if (e << 16 >> 16 == 125) { f = 32; break } if ((a | 0) == (r | 0)) { f = 29; break } if (a >>> 0 > (t[19] | 0) >>> 0) { f = 31; break } } if ((f | 0) == 29) { Y(); break e } else if ((f | 0) == 31) { Y(); break e } else if ((f | 0) == 32) { t[18] = a + 2; f = 34; break r } break } case 42: { t[18] = e + 2; w(1) | 0; f = t[18] | 0; g(f, f) | 0; f = 34; break } default: { } } } while (0); if ((f | 0) == 6) { t[18] = e + 16; e = w(1) | 0; if (e << 16 >> 16 == 42) { t[18] = (t[18] | 0) + 2; e = w(1) | 0; } n = t[18] | 0; H(e) | 0; J(n, t[18] | 0); t[18] = (t[18] | 0) + -2; break } else if ((f | 0) == 13) { e = e + 4 | 0; t[18] = e; i[589] = 0; r: while (1) { t[18] = e + 2; n = w(1) | 0; e = t[18] | 0; switch ((H(n) | 0) << 16 >> 16) { case 91: case 123: { f = 15; break r } default: { } }r = t[18] | 0; if ((r | 0) == (e | 0)) break e; J(e, r); switch ((w(1) | 0) << 16 >> 16) { case 61: { f = 19; break r } case 44: break; default: { f = 20; break r } }e = t[18] | 0; } if ((f | 0) == 15) { t[18] = (t[18] | 0) + -2; break } else if ((f | 0) == 19) { t[18] = (t[18] | 0) + -2; break } else if ((f | 0) == 20) { t[18] = (t[18] | 0) + -2; break } } else if ((f | 0) == 34) r = w(1) | 0; e = t[18] | 0; if (r << 16 >> 16 == 102 ? K(e + 2 | 0, 114, 111, 109) | 0 : 0) { t[18] = e + 8; l(c, w(1) | 0); break } t[18] = e + -2; } } while (0); return } function k() { var e = 0, r = 0, a = 0, f = 0, c = 0; c = t[18] | 0; r = c + 12 | 0; t[18] = r; e: do { switch ((w(1) | 0) << 16 >> 16) { case 40: { r = t[17] | 0; a = s[292] | 0; s[292] = a + 1 << 16 >> 16; t[r + ((a & 65535) << 2) >> 2] = c; if ((s[t[15] >> 1] | 0) != 46) { v(c, (t[18] | 0) + 2 | 0, 0, c); t[11] = t[8]; t[18] = (t[18] | 0) + 2; switch ((w(1) | 0) << 16 >> 16) { case 39: { d(39); break } case 34: { d(34); break } default: { t[18] = (t[18] | 0) + -2; break e } }t[18] = (t[18] | 0) + 2; switch ((w(1) | 0) << 16 >> 16) { case 44: { c = t[18] | 0; t[(t[8] | 0) + 4 >> 2] = c; t[18] = c + 2; w(1) | 0; c = t[18] | 0; a = t[8] | 0; t[a + 16 >> 2] = c; i[a + 24 >> 0] = 1; t[18] = c + -2; break e } case 41: { s[292] = (s[292] | 0) + -1 << 16 >> 16; a = t[18] | 0; c = t[8] | 0; t[c + 4 >> 2] = a; t[c + 12 >> 2] = a; i[c + 24 >> 0] = 1; break e } default: { t[18] = (t[18] | 0) + -2; break e } } } break } case 46: { t[18] = (t[18] | 0) + 2; if (((w(1) | 0) << 16 >> 16 == 109 ? (e = t[18] | 0, K(e + 2 | 0, 101, 116, 97) | 0) : 0) ? (s[t[15] >> 1] | 0) != 46 : 0) v(c, c, e + 8 | 0, 2); break } case 42: case 39: case 34: { f = 16; break } case 123: { e = t[18] | 0; if (s[292] | 0) { t[18] = e + -2; break e } while (1) { if (e >>> 0 >= (t[19] | 0) >>> 0) break; e = w(1) | 0; if (!(_(e) | 0)) { if (e << 16 >> 16 == 125) { f = 31; break } } else d(e); e = (t[18] | 0) + 2 | 0; t[18] = e; } if ((f | 0) == 31) t[18] = (t[18] | 0) + 2; w(1) | 0; e = t[18] | 0; if (!(z(e, 102, 114, 111, 109) | 0)) { Y(); break e } t[18] = e + 8; e = w(1) | 0; if (_(e) | 0) { l(c, e); break e } else { Y(); break e } } default: if ((t[18] | 0) != (r | 0)) f = 16; } } while (0); do { if ((f | 0) == 16) { if (s[292] | 0) { t[18] = (t[18] | 0) + -2; break } e = t[19] | 0; r = t[18] | 0; while (1) { if (r >>> 0 >= e >>> 0) { f = 23; break } a = s[r >> 1] | 0; if (_(a) | 0) { f = 21; break } f = r + 2 | 0; t[18] = f; r = f; } if ((f | 0) == 21) { l(c, a); break } else if ((f | 0) == 23) { Y(); break } } } while (0); return } function l(e, r) { e = e | 0; r = r | 0; var a = 0, i = 0; a = (t[18] | 0) + 2 | 0; switch (r << 16 >> 16) { case 39: { d(39); i = 5; break } case 34: { d(34); i = 5; break } default: Y(); }do { if ((i | 0) == 5) { v(e, a, t[18] | 0, 1); t[18] = (t[18] | 0) + 2; i = (w(0) | 0) << 16 >> 16 == 97; r = t[18] | 0; if (i ? B(r + 2 | 0, 115, 115, 101, 114, 116) | 0 : 0) { t[18] = r + 12; if ((w(1) | 0) << 16 >> 16 != 123) { t[18] = r; break } e = t[18] | 0; a = e; e: while (1) { t[18] = a + 2; a = w(1) | 0; switch (a << 16 >> 16) { case 39: { d(39); t[18] = (t[18] | 0) + 2; a = w(1) | 0; break } case 34: { d(34); t[18] = (t[18] | 0) + 2; a = w(1) | 0; break } default: a = H(a) | 0; }if (a << 16 >> 16 != 58) { i = 16; break } t[18] = (t[18] | 0) + 2; switch ((w(1) | 0) << 16 >> 16) { case 39: { d(39); break } case 34: { d(34); break } default: { i = 20; break e } }t[18] = (t[18] | 0) + 2; switch ((w(1) | 0) << 16 >> 16) { case 125: { i = 25; break e } case 44: break; default: { i = 24; break e } }t[18] = (t[18] | 0) + 2; if ((w(1) | 0) << 16 >> 16 == 125) { i = 25; break } a = t[18] | 0; } if ((i | 0) == 16) { t[18] = r; break } else if ((i | 0) == 20) { t[18] = r; break } else if ((i | 0) == 24) { t[18] = r; break } else if ((i | 0) == 25) { i = t[8] | 0; t[i + 16 >> 2] = e; t[i + 12 >> 2] = (t[18] | 0) + 2; break } } t[18] = r + -2; } } while (0); return } function o(e) { e = e | 0; e: do { switch (s[e >> 1] | 0) { case 100: switch (s[e + -2 >> 1] | 0) { case 105: { e = q(e + -4 | 0, 118, 111) | 0; break e } case 108: { e = P(e + -4 | 0, 121, 105, 101) | 0; break e } default: { e = 0; break e } }case 101: { switch (s[e + -2 >> 1] | 0) { case 115: break; case 116: { e = E(e + -4 | 0, 100, 101, 108, 101) | 0; break e } default: { e = 0; break e } }switch (s[e + -4 >> 1] | 0) { case 108: { e = D(e + -6 | 0, 101) | 0; break e } case 97: { e = D(e + -6 | 0, 99) | 0; break e } default: { e = 0; break e } } } case 102: { if ((s[e + -2 >> 1] | 0) == 111 ? (s[e + -4 >> 1] | 0) == 101 : 0) switch (s[e + -6 >> 1] | 0) { case 99: { e = O(e + -8 | 0, 105, 110, 115, 116, 97, 110) | 0; break e } case 112: { e = q(e + -8 | 0, 116, 121) | 0; break e } default: { e = 0; break e } } else e = 0; break } case 110: { e = e + -2 | 0; if (D(e, 105) | 0) e = 1; else e = $(e, 114, 101, 116, 117, 114) | 0; break } case 111: { e = D(e + -2 | 0, 100) | 0; break } case 114: { e = m(e + -2 | 0, 100, 101, 98, 117, 103, 103, 101) | 0; break } case 116: { e = E(e + -2 | 0, 97, 119, 97, 105) | 0; break } case 119: switch (s[e + -2 >> 1] | 0) { case 101: { e = D(e + -4 | 0, 110) | 0; break e } case 111: { e = P(e + -4 | 0, 116, 104, 114) | 0; break e } default: { e = 0; break e } }default: e = 0; } } while (0); return e | 0 } function h() { var e = 0, r = 0, a = 0; r = t[19] | 0; a = t[18] | 0; e: while (1) { e = a + 2 | 0; if (a >>> 0 >= r >>> 0) { r = 8; break } switch (s[e >> 1] | 0) { case 96: { r = 9; break e } case 36: { if ((s[a + 4 >> 1] | 0) == 123) { r = 6; break e } break } case 92: { e = a + 4 | 0; break } default: { } }a = e; } if ((r | 0) == 6) { t[18] = a + 4; e = s[293] | 0; r = t[16] | 0; a = s[291] | 0; s[291] = a + 1 << 16 >> 16; s[r + ((a & 65535) << 1) >> 1] = e; a = (s[292] | 0) + 1 << 16 >> 16; s[292] = a; s[293] = a; } else if ((r | 0) == 8) { t[18] = e; Y(); } else if ((r | 0) == 9) t[18] = e; return } function w(e) { e = e | 0; var r = 0, a = 0, i = 0; a = t[18] | 0; e: do { r = s[a >> 1] | 0; r: do { if (r << 16 >> 16 != 47) if (e) if (Z(r) | 0) break; else break e; else if (Q(r) | 0) break; else break e; else switch (s[a + 2 >> 1] | 0) { case 47: { G(); break r } case 42: { p(e); break r } default: { r = 47; break e } } } while (0); i = t[18] | 0; a = i + 2 | 0; t[18] = a; } while (i >>> 0 < (t[19] | 0) >>> 0); return r | 0 } function d(e) { e = e | 0; var r = 0, a = 0, i = 0, f = 0; f = t[19] | 0; r = t[18] | 0; while (1) { i = r + 2 | 0; if (r >>> 0 >= f >>> 0) { r = 9; break } a = s[i >> 1] | 0; if (a << 16 >> 16 == e << 16 >> 16) { r = 10; break } if (a << 16 >> 16 == 92) { a = r + 4 | 0; if ((s[a >> 1] | 0) == 13) { r = r + 6 | 0; r = (s[r >> 1] | 0) == 10 ? r : a; } else r = a; } else if (ae(a) | 0) { r = 9; break } else r = i; } if ((r | 0) == 9) { t[18] = i; Y(); } else if ((r | 0) == 10) t[18] = i; return } function v(e, r, a, s) { e = e | 0; r = r | 0; a = a | 0; s = s | 0; var f = 0, c = 0; f = t[13] | 0; t[13] = f + 32; c = t[8] | 0; t[((c | 0) == 0 ? 16 : c + 28 | 0) >> 2] = f; t[9] = c; t[8] = f; t[f + 8 >> 2] = e; do { if (2 != (s | 0)) if (1 == (s | 0)) { t[f + 12 >> 2] = a + 2; break } else { t[f + 12 >> 2] = t[3]; break } else t[f + 12 >> 2] = a; } while (0); t[f >> 2] = r; t[f + 4 >> 2] = a; t[f + 16 >> 2] = 0; t[f + 20 >> 2] = s; i[f + 24 >> 0] = 1 == (s | 0) & 1; t[f + 28 >> 2] = 0; return } function A() { var e = 0, r = 0, a = 0; a = t[19] | 0; r = t[18] | 0; e: while (1) { e = r + 2 | 0; if (r >>> 0 >= a >>> 0) { r = 6; break } switch (s[e >> 1] | 0) { case 13: case 10: { r = 6; break e } case 93: { r = 7; break e } case 92: { e = r + 4 | 0; break } default: { } }r = e; } if ((r | 0) == 6) { t[18] = e; Y(); e = 0; } else if ((r | 0) == 7) { t[18] = e; e = 93; } return e | 0 } function C(e, r, a, i, t, f, c, n) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; t = t | 0; f = f | 0; c = c | 0; n = n | 0; if ((((((s[e + 12 >> 1] | 0) == n << 16 >> 16 ? (s[e + 10 >> 1] | 0) == c << 16 >> 16 : 0) ? (s[e + 8 >> 1] | 0) == f << 16 >> 16 : 0) ? (s[e + 6 >> 1] | 0) == t << 16 >> 16 : 0) ? (s[e + 4 >> 1] | 0) == i << 16 >> 16 : 0) ? (s[e + 2 >> 1] | 0) == a << 16 >> 16 : 0) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function y(e) { e = e | 0; switch (s[e >> 1] | 0) { case 62: { e = (s[e + -2 >> 1] | 0) == 61; break } case 41: case 59: { e = 1; break } case 104: { e = E(e + -2 | 0, 99, 97, 116, 99) | 0; break } case 121: { e = O(e + -2 | 0, 102, 105, 110, 97, 108, 108) | 0; break } case 101: { e = P(e + -2 | 0, 101, 108, 115) | 0; break } default: e = 0; }return e | 0 } function g(e, r) { e = e | 0; r = r | 0; var a = 0, i = 0; a = t[18] | 0; i = s[a >> 1] | 0; if (i << 16 >> 16 == 97) { t[18] = a + 4; a = w(1) | 0; e = t[18] | 0; if (_(a) | 0) { d(a); r = (t[18] | 0) + 2 | 0; t[18] = r; } else { H(a) | 0; r = t[18] | 0; } i = w(1) | 0; a = t[18] | 0; } if ((a | 0) != (e | 0)) J(e, r); return i | 0 } function I() { var e = 0, r = 0, a = 0; e: while (1) { e = t[18] | 0; r = e + 2 | 0; t[18] = r; if (e >>> 0 >= (t[19] | 0) >>> 0) { a = 7; break } switch (s[r >> 1] | 0) { case 13: case 10: { a = 7; break e } case 47: break e; case 91: { A() | 0; break } case 92: { t[18] = e + 4; break } default: { } } } if ((a | 0) == 7) Y(); return } function p(e) { e = e | 0; var r = 0, a = 0, i = 0, f = 0, c = 0; f = (t[18] | 0) + 2 | 0; t[18] = f; a = t[19] | 0; while (1) { r = f + 2 | 0; if (f >>> 0 >= a >>> 0) break; i = s[r >> 1] | 0; if (!e ? ae(i) | 0 : 0) break; if (i << 16 >> 16 == 42 ? (s[f + 4 >> 1] | 0) == 47 : 0) { c = 8; break } f = r; } if ((c | 0) == 8) { t[18] = r; r = f + 4 | 0; } t[18] = r; return } function U(e, r, a, i, t, f, c) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; t = t | 0; f = f | 0; c = c | 0; if (((((s[e + 10 >> 1] | 0) == c << 16 >> 16 ? (s[e + 8 >> 1] | 0) == f << 16 >> 16 : 0) ? (s[e + 6 >> 1] | 0) == t << 16 >> 16 : 0) ? (s[e + 4 >> 1] | 0) == i << 16 >> 16 : 0) ? (s[e + 2 >> 1] | 0) == a << 16 >> 16 : 0) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function m(e, r, a, i, f, c, n, b) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; f = f | 0; c = c | 0; n = n | 0; b = b | 0; var u = 0, k = 0; k = e + -12 | 0; u = t[3] | 0; if (k >>> 0 >= u >>> 0 ? C(k, r, a, i, f, c, n, b) | 0 : 0) if ((k | 0) == (u | 0)) u = 1; else u = F(s[e + -14 >> 1] | 0) | 0; else u = 0; return u | 0 } function S(e) { e = e | 0; e: do { switch (e << 16 >> 16) { case 38: case 37: case 33: { e = 1; break } default: if ((e & -8) << 16 >> 16 == 40 | (e + -58 & 65535) < 6) e = 1; else { switch (e << 16 >> 16) { case 91: case 93: case 94: { e = 1; break e } default: { } }e = (e + -123 & 65535) < 4; } } } while (0); return e | 0 } function x(e) { e = e | 0; e: do { switch (e << 16 >> 16) { case 38: case 37: case 33: break; default: if (!((e + -58 & 65535) < 6 | (e + -40 & 65535) < 7 & e << 16 >> 16 != 41)) { switch (e << 16 >> 16) { case 91: case 94: break e; default: { } }return e << 16 >> 16 != 125 & (e + -123 & 65535) < 4 | 0 } } } while (0); return 1 } function O(e, r, a, i, f, c, n) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; f = f | 0; c = c | 0; n = n | 0; var b = 0, u = 0; u = e + -10 | 0; b = t[3] | 0; if (u >>> 0 >= b >>> 0 ? U(u, r, a, i, f, c, n) | 0 : 0) if ((u | 0) == (b | 0)) b = 1; else b = F(s[e + -12 >> 1] | 0) | 0; else b = 0; return b | 0 } function $(e, r, a, i, f, c) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; f = f | 0; c = c | 0; var n = 0, b = 0; b = e + -8 | 0; n = t[3] | 0; if (b >>> 0 >= n >>> 0 ? B(b, r, a, i, f, c) | 0 : 0) if ((b | 0) == (n | 0)) n = 1; else n = F(s[e + -10 >> 1] | 0) | 0; else n = 0; return n | 0 } function j(e) { e = e | 0; var r = 0, a = 0, i = 0, f = 0; a = n; n = n + 16 | 0; i = a; t[i >> 2] = 0; t[12] = e; r = t[3] | 0; f = r + (e << 1) | 0; e = f + 2 | 0; s[f >> 1] = 0; t[i >> 2] = e; t[13] = e; t[4] = 0; t[8] = 0; t[6] = 0; t[5] = 0; t[10] = 0; t[7] = 0; n = a; return r | 0 } function B(e, r, a, i, t, f) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; t = t | 0; f = f | 0; if ((((s[e + 8 >> 1] | 0) == f << 16 >> 16 ? (s[e + 6 >> 1] | 0) == t << 16 >> 16 : 0) ? (s[e + 4 >> 1] | 0) == i << 16 >> 16 : 0) ? (s[e + 2 >> 1] | 0) == a << 16 >> 16 : 0) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function E(e, r, a, i, f) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; f = f | 0; var c = 0, n = 0; n = e + -6 | 0; c = t[3] | 0; if (n >>> 0 >= c >>> 0 ? z(n, r, a, i, f) | 0 : 0) if ((n | 0) == (c | 0)) c = 1; else c = F(s[e + -8 >> 1] | 0) | 0; else c = 0; return c | 0 } function P(e, r, a, i) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; var f = 0, c = 0; c = e + -4 | 0; f = t[3] | 0; if (c >>> 0 >= f >>> 0 ? K(c, r, a, i) | 0 : 0) if ((c | 0) == (f | 0)) f = 1; else f = F(s[e + -6 >> 1] | 0) | 0; else f = 0; return f | 0 } function q(e, r, a) { e = e | 0; r = r | 0; a = a | 0; var i = 0, f = 0; f = e + -2 | 0; i = t[3] | 0; if (f >>> 0 >= i >>> 0 ? N(f, r, a) | 0 : 0) if ((f | 0) == (i | 0)) i = 1; else i = F(s[e + -4 >> 1] | 0) | 0; else i = 0; return i | 0 } function z(e, r, a, i, t) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; t = t | 0; if (((s[e + 6 >> 1] | 0) == t << 16 >> 16 ? (s[e + 4 >> 1] | 0) == i << 16 >> 16 : 0) ? (s[e + 2 >> 1] | 0) == a << 16 >> 16 : 0) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function D(e, r) { e = e | 0; r = r | 0; var a = 0; a = t[3] | 0; if (a >>> 0 <= e >>> 0 ? (s[e >> 1] | 0) == r << 16 >> 16 : 0) if ((a | 0) == (e | 0)) a = 1; else a = F(s[e + -2 >> 1] | 0) | 0; else a = 0; return a | 0 } function F(e) { e = e | 0; e: do { if ((e + -9 & 65535) < 5) e = 1; else { switch (e << 16 >> 16) { case 32: case 160: { e = 1; break e } default: { } }e = e << 16 >> 16 != 46 & (S(e) | 0); } } while (0); return e | 0 } function G() { var e = 0, r = 0, a = 0; e = t[19] | 0; a = t[18] | 0; e: while (1) { r = a + 2 | 0; if (a >>> 0 >= e >>> 0) break; switch (s[r >> 1] | 0) { case 13: case 10: break e; default: a = r; } } t[18] = r; return } function H(e) { e = e | 0; while (1) { if (Z(e) | 0) break; if (S(e) | 0) break; e = (t[18] | 0) + 2 | 0; t[18] = e; e = s[e >> 1] | 0; if (!(e << 16 >> 16)) { e = 0; break } } return e | 0 } function J(e, r) { e = e | 0; r = r | 0; var a = 0, i = 0; a = t[13] | 0; t[13] = a + 12; i = t[10] | 0; t[((i | 0) == 0 ? 20 : i + 8 | 0) >> 2] = a; t[10] = a; t[a >> 2] = e; t[a + 4 >> 2] = r; t[a + 8 >> 2] = 0; return } function K(e, r, a, i) { e = e | 0; r = r | 0; a = a | 0; i = i | 0; if ((s[e + 4 >> 1] | 0) == i << 16 >> 16 ? (s[e + 2 >> 1] | 0) == a << 16 >> 16 : 0) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function L(e) { e = e | 0; if (!($(e, 119, 104, 105, 108, 101) | 0) ? !(P(e, 102, 111, 114) | 0) : 0) e = q(e, 105, 102) | 0; else e = 1; return e | 0 } function M() { var e = 0; e = t[(t[6] | 0) + 20 >> 2] | 0; switch (e | 0) { case 1: { e = -1; break } case 2: { e = -2; break } default: e = e - (t[3] | 0) >> 1; }return e | 0 } function N(e, r, a) { e = e | 0; r = r | 0; a = a | 0; if ((s[e + 2 >> 1] | 0) == a << 16 >> 16) r = (s[e >> 1] | 0) == r << 16 >> 16; else r = 0; return r | 0 } function Q(e) { e = e | 0; switch (e << 16 >> 16) { case 160: case 32: case 12: case 11: case 9: { e = 1; break } default: e = 0; }return e | 0 } function R(e) { e = e | 0; if ((t[3] | 0) == (e | 0)) e = 1; else e = F(s[e + -2 >> 1] | 0) | 0; return e | 0 } function T() { var e = 0; e = t[(t[6] | 0) + 16 >> 2] | 0; if (!e) e = -1; else e = e - (t[3] | 0) >> 1; return e | 0 } function V() { var e = 0; e = t[6] | 0; e = t[((e | 0) == 0 ? 16 : e + 28 | 0) >> 2] | 0; t[6] = e; return (e | 0) != 0 | 0 } function W() { var e = 0; e = t[7] | 0; e = t[((e | 0) == 0 ? 20 : e + 8 | 0) >> 2] | 0; t[7] = e; return (e | 0) != 0 | 0 } function X(e) { e = e | 0; var r = 0; r = n; n = n + e | 0; n = n + 15 & -16; return r | 0 } function Y() { i[588] = 1; t[14] = (t[18] | 0) - (t[3] | 0) >> 1; t[18] = (t[19] | 0) + 2; return } function Z(e) { e = e | 0; return (e | 128) << 16 >> 16 == 160 | (e + -9 & 65535) < 5 | 0 } function _(e) { e = e | 0; return e << 16 >> 16 == 39 | e << 16 >> 16 == 34 | 0 } function ee() { return (t[(t[6] | 0) + 12 >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function re() { return (t[(t[6] | 0) + 8 >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function ae(e) { e = e | 0; return e << 16 >> 16 == 13 | e << 16 >> 16 == 10 | 0 } function ie() { return (t[(t[6] | 0) + 4 >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function se() { return (t[(t[7] | 0) + 4 >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function te() { return (t[t[6] >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function fe() { return (t[t[7] >> 2] | 0) - (t[3] | 0) >> 1 | 0 } function ce() { return f[(t[6] | 0) + 24 >> 0] | 0 | 0 } function ne(e) { e = e | 0; t[3] = e; return } function be() { return (i[589] | 0) != 0 | 0 } function ue() { return t[14] | 0 } return { ai: T, e: ue, ee: se, es: fe, f: be, id: M, ie: ie, ip: ce, is: te, p: b, re: W, ri: V, sa: j, se: ee, ses: ne, ss: re, sta: X } }({ Int8Array: Int8Array, Int16Array: Int16Array, Int32Array: Int32Array, Uint8Array: Uint8Array, Uint16Array: Uint16Array }, {}, r), a = e.sta(2 * i); } const o = t.length + 1; e.ses(a), e.sa(o - 1), (s ? b : n)(t, new Uint16Array(r, a, o)), e.p() || (c$1 = e.e(), h()); const w = [], d = []; for (; e.ri();) { const r = e.is(), a = e.ie(), i = e.ai(), s = e.id(), f = e.ss(), c = e.se(); let n; e.ip() && (n = u(-1 === s ? r : r + 1, t.charCodeAt(-1 === s ? r - 1 : r))), w.push({ n: n, s: r, e: a, ss: f, se: c, d: s, a: i }); } for (; e.re();) { const r = e.es(), a = t.charCodeAt(r); d.push(34 === a || 39 === a ? u(r + 1, a) : t.slice(e.es(), e.ee())); } return [w, d, !!e.f()] } function n(e, r) { const a = e.length; let i = 0; for (; i < a;) { const a = e.charCodeAt(i); r[i++] = (255 & a) << 8 | a >>> 8; } } function b(e, r) { const a = e.length; let i = 0; for (; i < a;)r[i] = e.charCodeAt(i++); } function u(e, r) { c$1 = e; let a = "", i = c$1; for (; ;) { c$1 >= t.length && h(); const e = t.charCodeAt(c$1); if (e === r) break; 92 === e ? (a += t.slice(i, c$1), a += k(), i = c$1) : (8232 === e || 8233 === e || o(e) && h(), ++c$1); } return a += t.slice(i, c$1++), a } function k() { let e = t.charCodeAt(++c$1); switch (++c$1, e) { case 110: return "\n"; case 114: return "\r"; case 120: return String.fromCharCode(l(2)); case 117: return function () { let e; 123 === t.charCodeAt(c$1) ? (++c$1, e = l(t.indexOf("}", c$1) - c$1), ++c$1, e > 1114111 && h()) : e = l(4); return e <= 65535 ? String.fromCharCode(e) : (e -= 65536, String.fromCharCode(55296 + (e >> 10), 56320 + (1023 & e))) }(); case 116: return "\t"; case 98: return "\b"; case 118: return "\v"; case 102: return "\f"; case 13: 10 === t.charCodeAt(c$1) && ++c$1; case 10: return ""; case 56: case 57: h(); default: if (e >= 48 && e <= 55) { let r = t.substr(c$1 - 1, 3).match(/^[0-7]+/)[0], a = parseInt(r, 8); return a > 255 && (r = r.slice(0, -1), a = parseInt(r, 8)), c$1 += r.length - 1, e = t.charCodeAt(c$1), "0" === r && 56 !== e && 57 !== e || h(), String.fromCharCode(a) } return o(e) ? "" : String.fromCharCode(e) } } function l(e) { const r = c$1; let a = 0, i = 0; for (let r = 0; r < e; ++r, ++c$1) { let e, s = t.charCodeAt(c$1); if (95 !== s) { if (s >= 97) e = s - 97 + 10; else if (s >= 65) e = s - 65 + 10; else { if (!(s >= 48 && s <= 57)) break; e = s - 48; } if (e >= 16) break; i = s, a = 16 * a + e; } else 95 !== i && 0 !== r || h(), i = s; } return 95 !== i && c$1 - r === e || h(), a } function o(e) { return 13 === e || 10 === e } function h() { throw Object.assign(new Error(`Parse error ${f}:${t.slice(0, c$1).split("\n").length}:${c$1 - t.lastIndexOf("\n", c$1 - 1)}`), { idx: c$1 }) }
309
-
310
- async function defaultResolve(id, parentUrl) {
311
- return resolveImportMap(importMap, resolveIfNotPlainOrUrl(id, parentUrl) || id, parentUrl);
312
- }
313
-
314
- async function _resolve(id, parentUrl) {
315
- const urlResolved = resolveIfNotPlainOrUrl(id, parentUrl);
316
- return {
317
- r: resolveImportMap(importMap, urlResolved || id, parentUrl),
318
- // b = bare specifier
319
- b: !urlResolved && !isURL(id)
320
- };
321
- }
322
-
323
- const resolve = resolveHook ? async (id, parentUrl) => ({ r: await resolveHook(id, parentUrl, defaultResolve), b: false }) : _resolve;
324
-
325
- let id = 0;
326
- const registry = {};
327
-
328
- async function loadAll(load, seen) {
329
- if (load.b || seen[load.u])
330
- return;
331
- seen[load.u] = 1;
332
- await load.L;
333
- await Promise.all(load.d.map(dep => loadAll(dep, seen)));
334
- if (!load.n)
335
- load.n = load.d.some(dep => dep.n);
336
- }
337
-
338
- let importMap = { imports: {}, scopes: {} };
339
- let importMapSrcOrLazy = false;
340
- let baselinePassthrough;
341
-
342
- const initPromise = featureDetectionPromise.then(() => {
343
- // shim mode is determined on initialization, no late shim mode
344
- if (!shimMode) {
345
- let seenScript = false;
346
- for (const script of document.querySelectorAll('script[type="module-shim"],script[type="importmap-shim"],script[type="module"],script[type="importmap"]')) {
347
- if (!seenScript && script.type === 'module')
348
- seenScript = true;
349
- if (script.type.endsWith('-shim')) {
350
- setShimMode();
351
- break;
352
- }
353
- if (seenScript && script.type === 'importmap') {
354
- importMapSrcOrLazy = true;
355
- break;
356
- }
357
- }
358
- }
359
- baselinePassthrough = supportsDynamicImport && supportsImportMeta && supportsImportMaps && (!jsonModulesEnabled || supportsJsonAssertions) && (!cssModulesEnabled || supportsCssAssertions) && !importMapSrcOrLazy && !false;
360
- if (!baselinePassthrough) onpolyfill();
361
- if (shimMode || !baselinePassthrough) {
362
- new MutationObserver(mutations => {
363
- for (const mutation of mutations) {
364
- if (mutation.type !== 'childList') continue;
365
- for (const node of mutation.addedNodes) {
366
- if (node.tagName === 'SCRIPT') {
367
- if (!shimMode && node.type === 'module' || shimMode && node.type === 'module-shim')
368
- processScript(node);
369
- if (!shimMode && node.type === 'importmap' || shimMode && node.type === 'importmap-shim')
370
- processImportMap(node);
371
- }
372
- else if (node.tagName === 'LINK' && node.rel === 'modulepreload')
373
- processPreload(node);
374
- }
375
- }
376
- }).observe(document, { childList: true, subtree: true });
377
- processImportMaps();
378
- processScriptsAndPreloads();
379
- return undefined;
380
- }
381
- });
382
- let importMapPromise = initPromise;
383
-
384
- let acceptingImportMaps = true;
385
- async function topLevelLoad(url, fetchOpts, source, nativelyLoaded, lastStaticLoadPromise) {
386
- if (!shimMode)
387
- acceptingImportMaps = false;
388
- await importMapPromise;
389
- // early analysis opt-out - no need to even fetch if we have feature support
390
- if (!shimMode && baselinePassthrough) {
391
- // for polyfill case, only dynamic import needs a return value here, and dynamic import will never pass nativelyLoaded
392
- if (nativelyLoaded)
393
- return null;
394
- await lastStaticLoadPromise;
395
- return dynamicImport(source ? createBlob(source) : url, { errUrl: url || source });
396
- }
397
- const load = getOrCreateLoad(url, fetchOpts, source);
398
- const seen = {};
399
- await loadAll(load, seen);
400
- lastLoad = undefined;
401
- resolveDeps(load, seen);
402
- await lastStaticLoadPromise;
403
- if (source && !shimMode && !load.n && !false) {
404
- const module = await dynamicImport(createBlob(source), { errUrl: source });
405
- if (revokeBlobURLs) revokeObjectURLs(Object.keys(seen));
406
- return module;
407
- }
408
- const module = await dynamicImport(!shimMode && !load.n && nativelyLoaded ? load.u : load.b, { errUrl: load.u });
409
- // if the top-level load is a shell, run its update function
410
- if (load.s)
411
- (await dynamicImport(load.s)).u$_(module);
412
- if (revokeBlobURLs) revokeObjectURLs(Object.keys(seen));
413
- // when tla is supported, this should return the tla promise as an actual handle
414
- // so readystate can still correspond to the sync subgraph exec completions
415
- return module;
416
- }
417
-
418
- function revokeObjectURLs(registryKeys) {
419
- let batch = 0;
420
- const keysLength = registryKeys.length;
421
- const schedule = self.requestIdleCallback ? self.requestIdleCallback : self.requestAnimationFrame;
422
- schedule(cleanup);
423
- function cleanup() {
424
- const batchStartIndex = batch * 100;
425
- if (batchStartIndex > keysLength) return
426
- for (const key of registryKeys.slice(batchStartIndex, batchStartIndex + 100)) {
427
- const load = registry[key];
428
- if (load) URL.revokeObjectURL(load.b);
429
- }
430
- batch++;
431
- schedule(cleanup);
432
- }
433
- }
434
-
435
- async function importShim(id, parentUrl = baseUrl, _assertion) {
436
- // needed for shim check
437
- await initPromise;
438
- if (acceptingImportMaps || shimMode || !baselinePassthrough) {
439
- processImportMaps();
440
- if (!shimMode)
441
- acceptingImportMaps = false;
442
- }
443
- await importMapPromise;
444
- return topLevelLoad((await resolve(id, parentUrl)).r || throwUnresolved(id, parentUrl), { credentials: 'same-origin' });
445
- }
446
-
447
- self.importShim = importShim;
448
-
449
- if (shimMode) {
450
- importShim.getImportMap = () => JSON.parse(JSON.stringify(importMap));
451
- }
452
-
453
- const meta = {};
454
-
455
- async function importMetaResolve(id, parentUrl = this.url) {
456
- return (await resolve(id, `${parentUrl}`)).r || throwUnresolved(id, parentUrl);
457
- }
458
-
459
- self._esmsm = meta;
460
-
461
- function urlJsString(url) {
462
- return `'${url.replace(/'/g, "\\'")}'`;
463
- }
464
-
465
- let lastLoad;
466
- function resolveDeps(load, seen) {
467
- if (load.b || !seen[load.u])
468
- return;
469
- seen[load.u] = 0;
470
-
471
- for (const dep of load.d)
472
- resolveDeps(dep, seen);
473
-
474
- const [imports] = load.a;
475
-
476
- // "execution"
477
- const source = load.S;
478
-
479
- // edge doesnt execute sibling in order, so we fix this up by ensuring all previous executions are explicit dependencies
480
- let resolvedSource = edge && lastLoad ? `import '${lastLoad}';` : '';
481
-
482
- if (!imports.length) {
483
- resolvedSource += source;
484
- }
485
- else {
486
- // once all deps have loaded we can inline the dependency resolution blobs
487
- // and define this blob
488
- let lastIndex = 0, depIndex = 0;
489
- for (const { s: start, se: end, d: dynamicImportIndex } of imports) {
490
- // dependency source replacements
491
- if (dynamicImportIndex === -1) {
492
- const depLoad = load.d[depIndex++];
493
- let blobUrl = depLoad.b;
494
- if (!blobUrl) {
495
- // circular shell creation
496
- if (!(blobUrl = depLoad.s)) {
497
- blobUrl = depLoad.s = createBlob(`export function u$_(m){${depLoad.a[1].map(
498
- name => name === 'default' ? `$_default=m.default` : `${name}=m.${name}`
499
- ).join(',')
500
- }}${depLoad.a[1].map(name =>
501
- name === 'default' ? `let $_default;export{$_default as default}` : `export let ${name}`
502
- ).join(';')
503
- }\n//# sourceURL=${depLoad.r}?cycle`);
504
- }
505
- }
506
- // circular shell execution
507
- else if (depLoad.s) {
508
- resolvedSource += `${source.slice(lastIndex, start - 1)}/*${source.slice(start - 1, end)}*/${urlJsString(blobUrl)};import*as m$_${depIndex} from'${depLoad.b}';import{u$_ as u$_${depIndex}}from'${depLoad.s}';u$_${depIndex}(m$_${depIndex})`;
509
- lastIndex = end;
510
- depLoad.s = undefined;
511
- continue;
512
- }
513
- resolvedSource += `${source.slice(lastIndex, start - 1)}/*${source.slice(start - 1, end)}*/${urlJsString(blobUrl)}`;
514
- lastIndex = end;
515
- }
516
- // import.meta
517
- else if (dynamicImportIndex === -2) {
518
- meta[load.r] = { url: load.r, resolve: importMetaResolve };
519
- resolvedSource += `${source.slice(lastIndex, start)}self._esmsm[${urlJsString(load.r)}]`;
520
- lastIndex = end;
521
- }
522
- // dynamic import
523
- else {
524
- resolvedSource += `${source.slice(lastIndex, dynamicImportIndex + 6)}Shim(${source.slice(start, end)}, ${load.r && urlJsString(load.r)}`;
525
- lastIndex = end;
526
- }
527
- }
528
-
529
- resolvedSource += source.slice(lastIndex);
530
- }
531
-
532
- // ; and // trailer support added for Ruby 7 source maps compatibility
533
- let hasSourceURL = false;
534
- resolvedSource = resolvedSource.replace(sourceMapURLRegEx, (match, isMapping, url) => (hasSourceURL = !isMapping, match.replace(url, () => new URL(url, load.r))));
535
- if (!hasSourceURL)
536
- resolvedSource += '\n//# sourceURL=' + load.r;
537
-
538
- load.b = lastLoad = createBlob(resolvedSource);
539
- load.S = undefined;
540
- }
541
-
542
- const sourceMapURLRegEx = /\n\/\/# source(Mapping)?URL=([^\n]+)\s*((;|\/\/[^#][^\n]*)\s*)*$/;
543
-
544
- const jsContentType = /^(text|application)\/(x-)?javascript(;|$)/;
545
- const jsonContentType = /^(text|application)\/json(;|$)/;
546
- const cssContentType = /^(text|application)\/css(;|$)/;
547
- const wasmContentType = /^application\/wasm(;|$)/;
548
-
549
- const cssUrlRegEx = /url\(\s*(?:(["'])((?:\\.|[^\n\\"'])+)\1|((?:\\.|[^\s,"'()\\])+))\s*\)/g;
550
-
551
- // restrict in-flight fetches to a pool of 100
552
- let p = [];
553
- let c = 0;
554
- function pushFetchPool() {
555
- if (++c > 100)
556
- return new Promise(r => p.push(r));
557
- }
558
- function popFetchPool() {
559
- c--;
560
- if (p.length)
561
- p.shift()();
562
- }
563
-
564
- async function doFetch(url, fetchOpts) {
565
- const poolQueue = pushFetchPool();
566
- if (poolQueue) await poolQueue;
567
- try {
568
- var res = await fetchHook(url, fetchOpts);
569
- }
570
- finally {
571
- popFetchPool();
572
- }
573
- if (!res.ok)
574
- throw new Error(`${res.status} ${res.statusText} ${res.url}`);
575
- const contentType = res.headers.get('content-type');
576
- if (jsContentType.test(contentType))
577
- return { r: res.url, s: await res.text(), t: 'js' };
578
- else if (jsonContentType.test(contentType))
579
- return { r: res.url, s: `export default ${await res.text()}`, t: 'json' };
580
- else if (cssContentType.test(contentType))
581
- return {
582
- r: res.url, s: `var s=new CSSStyleSheet();s.replaceSync(${JSON.stringify((await res.text()).replace(cssUrlRegEx, (_match, quotes, relUrl1, relUrl2) => `url(${quotes}${resolveUrl(relUrl1 || relUrl2, url)}${quotes})`))
583
- });export default s;`, t: 'css'
584
- };
585
- else if (wasmContentType.test(contentType))
586
- throw new Error('WASM modules not supported');
587
- else
588
- throw new Error(`Unknown Content-Type "${contentType}"`);
589
- }
590
-
591
- function getOrCreateLoad(url, fetchOpts, source) {
592
- let load = registry[url];
593
- if (load)
594
- return load;
595
-
596
- load = registry[url] = {
597
- // url
598
- u: url,
599
- // response url
600
- r: undefined,
601
- // fetchPromise
602
- f: undefined,
603
- // source
604
- S: undefined,
605
- // linkPromise
606
- L: undefined,
607
- // analysis
608
- a: undefined,
609
- // deps
610
- d: undefined,
611
- // blobUrl
612
- b: undefined,
613
- // shellUrl
614
- s: undefined,
615
- // needsShim
616
- n: false,
617
- // type
618
- t: null
619
- };
620
-
621
- load.f = (async () => {
622
- if (!source) {
623
- // preload fetch options override fetch options (race)
624
- let t;
625
- ({ r: load.r, s: source, t } = await (fetchCache[url] || doFetch(url, fetchOpts)));
626
- if (t && !shimMode) {
627
- if (t === 'css' && !cssModulesEnabled || t === 'json' && !jsonModulesEnabled)
628
- throw new Error(`${t}-modules require <script type="esms-options">{ "polyfillEnable": ["${t}-modules"] }<${''}/script>`);
629
- if (t === 'css' && !supportsCssAssertions || t === 'json' && !supportsJsonAssertions)
630
- load.n = true;
631
- }
632
- }
633
- try {
634
- load.a = parse(source, load.u);
635
- }
636
- catch (e) {
637
- console.warn(e);
638
- load.a = [[], []];
639
- }
640
- load.S = source;
641
- return load;
642
- })();
643
-
644
- load.L = load.f.then(async () => {
645
- let childFetchOpts = fetchOpts;
646
- load.d = (await Promise.all(load.a[0].map(async ({ n, d }) => {
647
- if (d >= 0 && !supportsDynamicImport || d === 2 && !supportsImportMeta)
648
- load.n = true;
649
- if (!n) return;
650
- const { r, b } = await resolve(n, load.r || load.u);
651
- if (b && (!supportsImportMaps || importMapSrcOrLazy))
652
- load.n = true;
653
- if (d !== -1) return;
654
- if (!r)
655
- throwUnresolved(n, load.r || load.u);
656
- if (skip && skip.test(r)) return { b: r };
657
- if (childFetchOpts.integrity)
658
- childFetchOpts = Object.assign({}, childFetchOpts, { integrity: undefined });
659
- return getOrCreateLoad(r, childFetchOpts).f;
660
- }))).filter(l => l);
661
- });
662
-
663
- return load;
664
- }
665
-
666
- function processScriptsAndPreloads() {
667
- for (const script of document.querySelectorAll(shimMode ? 'script[type="module-shim"]' : 'script[type="module"]'))
668
- processScript(script);
669
- for (const link of document.querySelectorAll('link[rel="modulepreload"]'))
670
- processPreload(link);
671
- }
672
-
673
- function processImportMaps() {
674
- for (const script of document.querySelectorAll(shimMode ? 'script[type="importmap-shim"]' : 'script[type="importmap"]'))
675
- processImportMap(script);
676
- }
677
-
678
- function getFetchOpts(script) {
679
- const fetchOpts = {};
680
- if (script.integrity)
681
- fetchOpts.integrity = script.integrity;
682
- if (script.referrerpolicy)
683
- fetchOpts.referrerPolicy = script.referrerpolicy;
684
- if (script.crossorigin === 'use-credentials')
685
- fetchOpts.credentials = 'include';
686
- else if (script.crossorigin === 'anonymous')
687
- fetchOpts.credentials = 'omit';
688
- else
689
- fetchOpts.credentials = 'same-origin';
690
- return fetchOpts;
691
- }
692
-
693
- let lastStaticLoadPromise = Promise.resolve();
694
-
695
- let domContentLoadedCnt = 1;
696
- function domContentLoadedCheck() {
697
- if (--domContentLoadedCnt === 0 && !noLoadEventRetriggers)
698
- document.dispatchEvent(new Event('DOMContentLoaded'));
699
- }
700
- // this should always trigger because we assume es-module-shims is itself a domcontentloaded requirement
701
- document.addEventListener('DOMContentLoaded', async () => {
702
- await initPromise;
703
- domContentLoadedCheck();
704
- if (shimMode || !baselinePassthrough) {
705
- processImportMaps();
706
- processScriptsAndPreloads();
707
- }
708
- });
709
-
710
- let readyStateCompleteCnt = 1;
711
- if (document.readyState === 'complete') {
712
- readyStateCompleteCheck();
713
- }
714
- else {
715
- document.addEventListener('readystatechange', async () => {
716
- processImportMaps();
717
- await initPromise;
718
- readyStateCompleteCheck();
719
- });
720
- }
721
- function readyStateCompleteCheck() {
722
- if (--readyStateCompleteCnt === 0 && !noLoadEventRetriggers)
723
- document.dispatchEvent(new Event('readystatechange'));
724
- }
725
-
726
- function processImportMap(script) {
727
- if (script.ep) // ep marker = script processed
728
- return;
729
- // empty inline scripts sometimes show before domready
730
- if (!script.src && !script.innerHTML)
731
- return;
732
- script.ep = true;
733
- // we dont currently support multiple, external or dynamic imports maps in polyfill mode to match native
734
- if (script.src) {
735
- if (!shimMode)
736
- return;
737
- importMapSrcOrLazy = true;
738
- }
739
- if (acceptingImportMaps) {
740
- importMapPromise = importMapPromise
741
- .then(async () => {
742
- importMap = resolveAndComposeImportMap(script.src ? await (await fetchHook(script.src)).json() : JSON.parse(script.innerHTML), script.src || baseUrl, importMap);
743
- })
744
- .catch(error => setTimeout(() => { throw error }));
745
- if (!shimMode)
746
- acceptingImportMaps = false;
747
- }
748
- }
749
-
750
- function processScript(script) {
751
- if (script.ep) // ep marker = script processed
752
- return;
753
- if (script.getAttribute('noshim') !== null)
754
- return;
755
- // empty inline scripts sometimes show before domready
756
- if (!script.src && !script.innerHTML)
757
- return;
758
- script.ep = true;
759
- // does this load block readystate complete
760
- const isReadyScript = readyStateCompleteCnt > 0;
761
- // does this load block DOMContentLoaded
762
- const isDomContentLoadedScript = domContentLoadedCnt > 0;
763
- if (isReadyScript) readyStateCompleteCnt++;
764
- if (isDomContentLoadedScript) domContentLoadedCnt++;
765
- const blocks = script.getAttribute('async') === null && isReadyScript;
766
- const loadPromise = topLevelLoad(script.src || `${baseUrl}?${id++}`, getFetchOpts(script), !script.src && script.innerHTML, !shimMode, blocks && lastStaticLoadPromise).catch(e => {
767
- setTimeout(() => { throw e });
768
- onerror(e);
769
- });
770
- if (blocks)
771
- lastStaticLoadPromise = loadPromise.then(readyStateCompleteCheck);
772
- if (isDomContentLoadedScript)
773
- loadPromise.then(domContentLoadedCheck);
774
- }
775
-
776
- const fetchCache = {};
777
- function processPreload(link) {
778
- if (link.ep) // ep marker = processed
779
- return;
780
- link.ep = true;
781
- if (fetchCache[link.href])
782
- return;
783
- fetchCache[link.href] = doFetch(link.href, getFetchOpts(link));
784
- }
785
-
786
- function throwUnresolved(id, parentUrl) {
787
- throw Error("Unable to resolve specifier '" + id + (parentUrl ? "' from " + parentUrl : "'"));
788
- }
789
-
790
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/posex.js DELETED
@@ -1,844 +0,0 @@
1
- async function _import() {
2
- if (!globalThis.posex || !globalThis.posex.import) {
3
- const THREE = await import('three');
4
- const { TrackballControls } = await import('three-trackballcontrols');
5
- const { DragControls } = await import('three-dragcontrols');
6
- const { MeshLine, MeshLineMaterial } = await import('three-meshline');
7
- return { THREE, TrackballControls, DragControls, MeshLine, MeshLineMaterial };
8
- } else {
9
- return await globalThis.posex.import();
10
- }
11
- }
12
- const { THREE, TrackballControls, DragControls, MeshLine, MeshLineMaterial } = await _import();
13
-
14
- const JOINT_RADIUS = 4.0;
15
- const LIMB_SIZE = 4.0;
16
- const LIMB_N = 64;
17
-
18
- const joint_names = [
19
- 'nose',
20
- 'neck',
21
- 'right shoulder',
22
- 'right elbow',
23
- 'right wrist',
24
- 'left shoulder',
25
- 'left elbow',
26
- 'left wrist',
27
- 'right hip',
28
- 'right knee',
29
- 'right ancle',
30
- 'left hip',
31
- 'left knee',
32
- 'left ancle',
33
- 'right eye',
34
- 'left eye',
35
- 'right ear',
36
- 'left ear'
37
- ];
38
-
39
- const joint_colors = [
40
- // r g b
41
- [255, 0, 0], // 0: nose
42
- [255, 85, 0], // 1: neck
43
- [255, 170, 0], // 2: right shoulder
44
- [255, 255, 0], // 3: right elbow
45
- [170, 255, 0], // 4: right wrist
46
- [85, 255, 0], // 5: left shoulder
47
- [0, 255, 0], // 6: left elbow
48
- [0, 255, 85], // 7: left wrist
49
- [0, 255, 170], // 8: right hip
50
- [0, 255, 255], // 9: right knee
51
- [0, 170, 255], // 10: right ancle
52
- [0, 85, 255], // 11: left hip
53
- [0, 0, 255], // 12: left knee
54
- [85, 0, 255], // 13: left ancle
55
- [170, 0, 255], // 14: right eye
56
- [255, 0, 255], // 15: left eye
57
- [255, 0, 170], // 16: right ear
58
- [255, 0, 85] // 17: left ear
59
- ];
60
-
61
- const limb_pairs = [
62
- [1, 2], // 0: right shoulder
63
- [1, 5], // 1: left shoulder
64
- [2, 3], // 2: right upper arm
65
- [3, 4], // 3: right forearm
66
- [5, 6], // 4: left upper arm
67
- [6, 7], // 5: left forearm
68
- [1, 8], // 6: right hip
69
- [8, 9], // 7: right upper leg
70
- [9, 10], // 8: right lower leg
71
- [1, 11], // 9: left hip
72
- [11, 12], // 10: left upper leg
73
- [12, 13], // 11: left lower leg
74
- [1, 0], // 12: neck
75
- [0, 14], // 13: right eye
76
- [14, 16], // 14: right ear
77
- [0, 15], // 15: left eye
78
- [15, 17], // 16: left ear
79
- ];
80
-
81
- const standard_pose = [
82
- // x y z ∈ [0,1]
83
- [0.500, 0.820, 0.000], // 0: nose
84
- [0.500, 0.750, 0.000], // 1: neck
85
- [0.416, 0.750, 0.000], // 2: right shoulder
86
- [0.305, 0.750, 0.000], // 3: right elbow
87
- [0.188, 0.750, 0.000], // 4: right wrist
88
- [0.584, 0.750, 0.000], // 5: left shoulder
89
- [0.695, 0.750, 0.000], // 6: left elbow
90
- [0.812, 0.750, 0.000], // 7: left wrist
91
- [0.447, 0.511, 0.000], // 8: right hip
92
- [0.453, 0.295, 0.000], // 9: right knee
93
- [0.445, 0.109, 0.000], // 10: right ancle
94
- [0.553, 0.511, 0.000], // 11: left hip
95
- [0.547, 0.295, 0.000], // 12: left knee
96
- [0.555, 0.109, 0.000], // 13: left ancle
97
- [0.480, 0.848, 0.000], // 14: right eye
98
- [0.520, 0.848, 0.000], // 15: left eye
99
- [0.450, 0.834, 0.000], // 16: right ear
100
- [0.550, 0.834, 0.000] // 17: left ear
101
- ]
102
-
103
- for (let xyz of standard_pose) {
104
- xyz[0] = xyz[0] - 0.5; // [0,1] -> [-0.5,0.5]
105
- xyz[1] = xyz[1] - 0.5; // [0,1] -> [-0.5,0.5]
106
- //xyz[2] = xyz[2] * 2 - 1.0;
107
- }
108
-
109
- function create_body(unit, x0, y0, z0) {
110
- const joints = [];
111
- const limbs = [];
112
-
113
- for (let i = 0; i < standard_pose.length; ++i) {
114
- const [x, y, z] = standard_pose[i];
115
- const [r, g, b] = joint_colors[i];
116
- const color = (r << 16) | (g << 8) | (b << 0);
117
- const geom = new THREE.SphereGeometry(JOINT_RADIUS, 32, 32);
118
- const mat = new THREE.MeshBasicMaterial({ color: color });
119
- const joint = new THREE.Mesh(geom, mat);
120
- joint.name = joint_names[i];
121
- joint.position.x = x * unit + x0;
122
- joint.position.y = y * unit + y0;
123
- joint.position.z = z + z0;
124
- joint.dirty = true; // update limbs in next frame
125
- joints.push(joint);
126
- }
127
-
128
- for (let i = 0; i < limb_pairs.length; ++i) {
129
- const [r, g, b] = joint_colors[i];
130
- const color = (r << 16) | (g << 8) | (b << 0);
131
- const line = new MeshLine();
132
- const mat = new MeshLineMaterial({ color: color, opacity: 0.6, transparent: true });
133
- limbs.push(new THREE.Mesh(line, mat));
134
- }
135
-
136
- return [joints, limbs];
137
- }
138
-
139
- function init_3d(ui) {
140
- const
141
- container = ui.container,
142
- canvas = ui.canvas,
143
- notation = ui.notation,
144
- indicator1 = ui.indicator1,
145
- indicator2 = ui.indicator2,
146
- width = () => canvas.width,
147
- height = () => canvas.height,
148
- unit = () => Math.min(width(), height()),
149
- unit_max = () => Math.max(width(), height());
150
-
151
- canvas.addEventListener('contextmenu', e => {
152
- e.preventDefault();
153
- }, false);
154
-
155
- const scene = new THREE.Scene();
156
- const default_bg = () => new THREE.Color(0x000000);
157
- scene.background = default_bg();
158
- const camera = new THREE.OrthographicCamera(width() / -2, width() / 2, height() / 2, height() / -2, 1, width() * 4);
159
- camera.fixed_roll = ui.fixed_roll ? !!ui.fixed_roll.checked : false;
160
- camera.position.z = unit_max() * 2;
161
-
162
- const renderer = new THREE.WebGLRenderer({
163
- canvas: canvas,
164
- antialias: true,
165
- alpha: true,
166
- preserveDrawingBuffer: true,
167
- });
168
- renderer.setSize(width(), height());
169
-
170
- function set_bg(image_path, dont_dispose) {
171
- const old_tex = scene.background;
172
- if (image_path === null) {
173
- scene.background = default_bg();
174
- if (old_tex && old_tex.dispose && !dont_dispose) old_tex.dispose();
175
- return;
176
- }
177
- const tex = (image_path.isTexture || image_path.isColor) ? image_path : new THREE.TextureLoader().load(image_path);
178
- scene.background = tex;
179
- if (old_tex && old_tex.dispose && !dont_dispose) old_tex.dispose();
180
- }
181
-
182
- const bodies = new Map();
183
- let selected_body = null;
184
- let touched_body = null;
185
- const touchable_objects = [];
186
- const touchable_bodies = [];
187
- const object_to_body = new Map();
188
-
189
- function remove(mesh) {
190
- if (mesh instanceof Array) {
191
- for (let m of mesh) remove(m);
192
- } else {
193
- mesh.material.dispose();
194
- mesh.geometry.dispose();
195
- object_to_body.delete(mesh);
196
- }
197
- };
198
- const add_body = (name, x0, y0, z0) => {
199
- remove_body(name);
200
- const [joints, limbs] = create_body(unit(), x0, y0, z0);
201
- const group = new THREE.Group(); // for DragControls
202
-
203
- const dispose = () => {
204
- for (let joint of joints) {
205
- array_remove(touchable_objects, joint);
206
- remove(joint);
207
- }
208
- for (let limb of limbs) {
209
- remove(limb);
210
- scene.remove(limb);
211
- }
212
- array_remove(touchable_bodies, group);
213
- scene.remove(group);
214
- };
215
-
216
- const reset = (dx, dy, dz) => {
217
- if (dx === undefined) dx = x0;
218
- if (dy === undefined) dy = y0;
219
- if (dz === undefined) dz = z0;
220
- for (let i = 0; i < standard_pose.length; ++i) {
221
- const [x, y, z] = standard_pose[i];
222
- joints[i].position.set(x * unit() + dx, y * unit() + dy, z + dz);
223
- joints[i].dirty = true;
224
- }
225
- group.position.set(0, 0, 0);
226
- body.dirty = true;
227
- };
228
-
229
- const body = {
230
- name,
231
- group,
232
- joints,
233
- limbs,
234
- x0, y0, z0,
235
- dispose,
236
- reset,
237
- dirty: true, // update limbs in next frame
238
- };
239
-
240
- for (let joint of joints) {
241
- touchable_objects.push(joint);
242
- object_to_body.set(joint, body);
243
- group.add(joint);
244
- }
245
- for (let limb of limbs) {
246
- scene.add(limb);
247
- object_to_body.set(limb, body);
248
- }
249
- object_to_body.set(group, body);
250
-
251
- bodies.set(name, body);
252
- scene.add(group);
253
- touchable_bodies.push(group);
254
-
255
- return body;
256
- };
257
-
258
- const remove_body = name => {
259
- if (!bodies.get(name)) return;
260
- bodies.get(name).dispose();
261
- bodies.delete(name);
262
- };
263
-
264
- const get_body_rect = body => {
265
- const v = new THREE.Vector3();
266
- let xmin = Infinity, xmax = -Infinity, ymin = Infinity, ymax = -Infinity;
267
- for (let joint of body.joints) {
268
- const wpos = joint.getWorldPosition(v);
269
- const spos = wpos.project(camera);
270
- if (spos.x < xmin) xmin = spos.x;
271
- if (xmax < spos.x) xmax = spos.x;
272
- if (spos.y < ymin) ymin = spos.y;
273
- if (ymax < spos.y) ymax = spos.y;
274
- }
275
- return [xmin, ymin, xmax, ymax];
276
- };
277
-
278
- const default_body = add_body('defualt', 0, 0, 0);
279
-
280
- const controls = new TrackballControls(camera, renderer.domElement);
281
- const dragger_joint = new DragControls(touchable_objects, camera, renderer.domElement);
282
- const dragger_body = new DragControls([], camera, renderer.domElement);
283
- dragger_body.transformGroup = true;
284
-
285
- dragger_joint.addEventListener('dragstart', () => { controls.enabled = false; });
286
- dragger_joint.addEventListener('dragend', () => { controls.enabled = true; });
287
- dragger_joint.addEventListener('drag', e => {
288
- e.object.dirty = true;
289
- object_to_body.get(e.object).dirty = true;
290
- });
291
-
292
- dragger_body.addEventListener('dragstart', () => { controls.enabled = false; });
293
- dragger_body.addEventListener('dragend', () => { controls.enabled = true; });
294
- dragger_body.addEventListener('drag', e => {
295
- const body = object_to_body.get(e.object);
296
- body.dirty = true;
297
- for (let i = 0; i < body.joints.length; ++i) {
298
- body.joints[i].dirty = true;
299
- }
300
- });
301
-
302
- renderer.domElement.addEventListener('pointerdown', e => {
303
- dragger_joint.enabled = e.button === 0;
304
- dragger_body.enabled = e.button === 2;
305
- }, true);
306
-
307
- const rc = new THREE.Raycaster();
308
- const m = new THREE.Vector2();
309
- renderer.domElement.addEventListener('pointermove', e => {
310
- e.preventDefault();
311
- m.x = (e.offsetX / width()) * 2 - 1;
312
- m.y = (1 - e.offsetY / height()) * 2 - 1;
313
- rc.setFromCamera(m, camera);
314
- const touched = rc.intersectObjects(touchable_objects);
315
-
316
- // show label
317
- if (touched.length != 0) {
318
- const [dx, dy] = get_relative_offset(renderer.domElement, container);
319
- notation.textContent = touched[0].object.name;
320
- notation.style.left = `${e.offsetX + dx}px`;
321
- notation.style.top = `${e.offsetY + dy - 32}px`;
322
- notation.style.display = 'block';
323
- } else {
324
- notation.textContent = '';
325
- notation.style.display = 'none';
326
- }
327
-
328
- // show temporary selection
329
- if (touched.length != 0) {
330
- touched_body = object_to_body.get(touched[0].object);
331
- } else {
332
- touched_body = null;
333
- }
334
- }, false);
335
-
336
- renderer.domElement.addEventListener('pointerdown', e => {
337
- e.preventDefault();
338
- m.x = (e.offsetX / width()) * 2 - 1;
339
- m.y = (1 - e.offsetY / height()) * 2 - 1;
340
- rc.setFromCamera(m, camera);
341
- const touched = rc.intersectObjects(touchable_objects);
342
-
343
- // show selection
344
- if (touched.length != 0) {
345
- selected_body = object_to_body.get(touched[0].object);
346
- const objs = dragger_body.getObjects();
347
- objs.length = 0;
348
- objs.push(selected_body.group);
349
- dragger_body.onPointerDown(e);
350
- } else {
351
- selected_body = null;
352
- dragger_body.getObjects().length = 0;
353
- }
354
- }, false);
355
-
356
- if (ui.all_reset)
357
- ui.all_reset.addEventListener('click', () => {
358
- touched_body = null;
359
- selected_body = null;
360
- camera.position.set(0, 0, unit_max() * 2);
361
- camera.rotation.set(0, 0, 0);
362
- controls.reset();
363
- for (let name of Array.from(bodies.keys()).slice(1)) {
364
- remove_body(name);
365
- }
366
- for (let body of bodies.values()) {
367
- body.reset(0, 0, 0);
368
- }
369
- }, false);
370
-
371
- if (ui.reset_camera)
372
- ui.reset_camera.addEventListener('click', () => {
373
- camera.position.set(0, 0, unit_max() * 2);
374
- camera.rotation.set(0, 0, 0);
375
- controls.reset();
376
- }, false);
377
-
378
- if (ui.reset_pose)
379
- ui.reset_pose.addEventListener('click', () => {
380
- if (selected_body) {
381
- selected_body.reset();
382
- } else {
383
- for (let [name, body] of bodies) {
384
- body.reset();
385
- }
386
- }
387
- }, false);
388
-
389
- if (ui.fixed_roll)
390
- ui.fixed_roll.addEventListener('change', () => {
391
- camera.fixed_roll = !!ui.fixed_roll.checked;
392
- }, false);
393
-
394
- let body_num = 1;
395
- if (ui.add_body)
396
- ui.add_body.addEventListener('click', () => {
397
- const last_body = selected_body ?? Array.from(bodies.values()).at(-1);
398
- const base = last_body.joints[0].getWorldPosition(new THREE.Vector3());
399
- const
400
- dx = base.x - standard_pose[0][0] * unit(),
401
- dy = base.y - standard_pose[0][1] * unit(),
402
- dz = base.z - standard_pose[0][2];
403
- add_body(`body_${body_num++}`, dx + 32, dy, dz);
404
- }, false);
405
-
406
- if (ui.remove_body)
407
- ui.remove_body.addEventListener('click', () => {
408
- if (!selected_body) {
409
- ui.notify('No body is selected.', 'error');
410
- return;
411
- }
412
- if (bodies.size <= 1) {
413
- ui.notify('No body is not allowed.', 'error');
414
- return;
415
- }
416
- remove_body(selected_body.name);
417
- touched_body = null;
418
- selected_body = null;
419
- }, false);
420
-
421
- const get_client_boundary = body => {
422
- let [xmin, ymin, xmax, ymax] = get_body_rect(body);
423
-
424
- // [-1,1] -> [0,width]
425
- xmin = (xmin + 1) * width() / 2;
426
- xmax = (xmax + 1) * width() / 2;
427
- ymin = height() - (ymin + 1) * height() / 2;
428
- ymax = height() - (ymax + 1) * height() / 2;
429
- [ymin, ymax] = [ymax, ymin];
430
-
431
- // add margin
432
- xmin = xmin - 5 + renderer.domElement.offsetLeft;
433
- xmax = xmax + 5 + renderer.domElement.offsetLeft;
434
- ymin = ymin - 5 + renderer.domElement.offsetTop;
435
- ymax = ymax + 5 + renderer.domElement.offsetTop;
436
-
437
- return [xmin, ymin, xmax, ymax];
438
- }
439
-
440
- const size_change = (w, h) => {
441
- if (w < 64 || h < 64) return;
442
- canvas.width = w;
443
- canvas.height = h;
444
- renderer.setSize(w, h);
445
- // update camera
446
- camera.left = w / -2;
447
- camera.right = w / 2;
448
- camera.top = h / 2;
449
- camera.bottom = h / -2;
450
- camera.near = 1;
451
- camera.far = w * 4;
452
- camera.position.z = unit_max() * 2;
453
- camera.updateProjectionMatrix();
454
- controls.handleResize();
455
- };
456
-
457
- const width_input = ui.canvas_width, height_input = ui.canvas_height;
458
- if (width_input && height_input) {
459
- width_input.addEventListener('change', () => {
460
- const w = +width_input.value;
461
- const h = +height_input.value;
462
- size_change(w, h);
463
- }, false);
464
- height_input.addEventListener('change', () => {
465
- const w = +width_input.value;
466
- const h = +height_input.value;
467
- size_change(w, h);
468
- }, false);
469
- }
470
-
471
- if (ui.bg)
472
- ui.bg.addEventListener('change', e => {
473
- const files = ui.bg.files;
474
- if (files.length != 0) {
475
- const file = files[0];
476
- const r = new FileReader();
477
- r.onload = () => set_bg(r.result);
478
- r.readAsDataURL(file);
479
- }
480
- ui.bg.value = '';
481
- }, false);
482
-
483
- if (ui.reset_bg)
484
- ui.reset_bg.addEventListener('click', () => set_bg(null), false);
485
-
486
- function get_pose_dict(obj3d) {
487
- return {
488
- position: obj3d.position.toArray(),
489
- rotation: obj3d.rotation.toArray(),
490
- scale: obj3d.scale.toArray(),
491
- up: obj3d.up.toArray(),
492
- };
493
- }
494
-
495
- function set_pose_dict(obj3d, dict) {
496
- obj3d.position.set(...dict.position);
497
- obj3d.rotation.set(...dict.rotation);
498
- obj3d.scale.set(...dict.scale);
499
- obj3d.up.set(...dict.up);
500
- }
501
-
502
- if (ui.save_pose && ui.save_pose_callback)
503
- ui.save_pose.addEventListener('click', async () => {
504
- const name = prompt('Input pose name.');
505
- if (name === undefined || name === null || name === '') return;
506
-
507
- const screen = {
508
- width: width(),
509
- height: height(),
510
- }
511
-
512
- const camera_ = get_pose_dict(camera);
513
- camera_.zoom = camera.zoom;
514
-
515
- const joints = [];
516
- for (let [name, body] of bodies) {
517
- joints.push({
518
- name,
519
- joints: body.joints.map(j => get_pose_dict(j)),
520
- group: get_pose_dict(body.group),
521
- x0: body.x0,
522
- y0: body.y0,
523
- z0: body.z0,
524
- });
525
- }
526
-
527
- const image = await ui.getDataURL();
528
-
529
- const data = { name, image, screen, camera: camera_, joints };
530
- const result = await ui.save_pose_callback(data);
531
- ui.notify(result.result, result.ok ? 'success' : 'error');
532
- }, false);
533
-
534
- const onAnimateEndOneshot = [];
535
-
536
- // joint and limb update
537
- let elliptic_limbs = ui.elliptic_limbs ? !!ui.elliptic_limbs.checked : true;
538
- //let joint_size_m = ui.joint_radius ? +ui.joint_radius.value / JOINT_RADIUS : 1.0;
539
- let limb_size_m = ui.limb_width ? +ui.limb_width.value / LIMB_SIZE : 1.0;
540
- if (ui.elliptic_limbs)
541
- ui.elliptic_limbs.addEventListener('change', () => {
542
- const b = !!ui.elliptic_limbs.checked;
543
- if (elliptic_limbs !== b) {
544
- elliptic_limbs = b;
545
- for (let body of bodies.values()) {
546
- body.dirty = true;
547
- for (let i = 0; i < body.joints.length; ++i) {
548
- body.joints[i].dirty = true;
549
- }
550
- }
551
- }
552
- }, false);
553
-
554
- //if (ui.joint_radius)
555
- // ui.joint_radius.addEventListener('input', () => {
556
- // const new_val = +ui.joint_radius.value / JOINT_RADIUS;
557
- // if (joint_size_m !== new_val) {
558
- // joint_size_m = new_val;
559
- // for (let body of bodies.values()) {
560
- // body.dirty = true;
561
- // for (let i = 0; i < body.joints.length; ++i) {
562
- // body.joints[i].dirty = true;
563
- // }
564
- // }
565
- // }
566
- // }, false);
567
-
568
- if (ui.limb_width)
569
- ui.limb_width.addEventListener('input', () => {
570
- const new_val = +ui.limb_width.value / LIMB_SIZE;
571
- if (limb_size_m !== new_val) {
572
- limb_size_m = new_val;
573
- for (let body of bodies.values()) {
574
- body.dirty = true;
575
- for (let i = 0; i < body.joints.length; ++i) {
576
- body.joints[i].dirty = true;
577
- }
578
- }
579
- }
580
- }, false);
581
-
582
- const limb_vecs = Array.from(Array(LIMB_N)).map(x => new THREE.Vector3());
583
- function elliptic_limb_width(p) {
584
- // draw limb ellipse
585
- // x^2 / a^2 + y^2 / b^2 = 1
586
- // a := half of distance between two joints
587
- // b := 2 * LIMB_SIZE / camera.zoom
588
- // {a(2p-1)}^2 / a^2 + y^2 / b^2 = 1
589
- // y^2 = b^2 { 1 - (2p-1)^2 }
590
- const b = 2 * LIMB_SIZE * limb_size_m / camera.zoom;
591
- const pp = 2 * p - 1;
592
- return b * Math.sqrt(1 - pp * pp);
593
- }
594
- function stick_limb_width(p) {
595
- // half width of ellipse
596
- return LIMB_SIZE * limb_size_m / camera.zoom;
597
- }
598
- function create_limb(mesh, from, to) {
599
- const s0 = limb_vecs[0];
600
- const s1 = limb_vecs[LIMB_N - 1];
601
- from.getWorldPosition(s0);
602
- to.getWorldPosition(s1);
603
- const N = LIMB_N - 1;
604
- for (let i = 1; i < limb_vecs.length - 1; ++i) {
605
- limb_vecs[i].lerpVectors(s0, s1, i / N);
606
- }
607
- mesh.geometry.setPoints(limb_vecs, elliptic_limbs ? elliptic_limb_width : stick_limb_width);
608
- }
609
-
610
- let low_fps = ui.low_fps ? !!ui.low_fps.checked : false;
611
- if (ui.low_fps)
612
- ui.low_fps.addEventListener('change', () => {
613
- low_fps = !!ui.low_fps.checked;
614
- }, false);
615
-
616
- let last_zoom = camera.zoom;
617
- let running = true;
618
- //const frames = [0,0,0,0,0,0,0,0,0,0], frame_index = 0;
619
- let last_tick = globalThis.performance.now();
620
- const animate = () => {
621
- const t0 = globalThis.performance.now();
622
- //frames[(frame_index++)%frames.length] = t0 - last_tick;
623
- //last_tick = t0;
624
- //console.log(frames.reduce((acc, cur) => acc + cur) / frames.length);
625
-
626
- requestAnimationFrame(animate);
627
- if (!running) return;
628
-
629
- if (controls.enabled) {
630
- if (controls.screen.width === 0 && controls.screen.height === 0) {
631
- controls.handleResize();
632
- }
633
- }
634
- controls.update();
635
-
636
- if (low_fps && t0 - last_tick < 30) return; // nearly 30fps
637
- last_tick = t0;
638
-
639
- for (let [name, body] of bodies) {
640
- const { joints, limbs, group } = body;
641
-
642
- // update joint size
643
- for (let joint of joints) {
644
- joint.scale.setScalar(1 / camera.zoom);
645
- }
646
-
647
- // show limbs
648
- const zoom_changed = last_zoom !== camera.zoom;
649
- if (body.dirty || zoom_changed) {
650
- for (let i = 0; i < limb_pairs.length; ++i) {
651
- const [from_index, to_index] = limb_pairs[i];
652
- const [from, to] = [joints[from_index], joints[to_index]];
653
- if (from.dirty || to.dirty || zoom_changed) {
654
- create_limb(limbs[i], from, to);
655
- }
656
- }
657
-
658
- for (let i = 0; i < joints.length; ++i) {
659
- joints[i].dirty = false;
660
- }
661
- body.dirty = false;
662
- }
663
- }
664
-
665
- last_zoom = camera.zoom;
666
-
667
- // show selection
668
- if (touched_body) {
669
- let [xmin, ymin, xmax, ymax] = get_client_boundary(touched_body);
670
- const st = indicator2.style;
671
- st.display = 'block';
672
- st.left = `${xmin}px`;
673
- st.top = `${ymin}px`;
674
- st.width = `${xmax - xmin}px`;
675
- st.height = `${ymax - ymin}px`;
676
- } else {
677
- indicator2.style.display = 'none';
678
- }
679
-
680
- if (selected_body) {
681
- let [xmin, ymin, xmax, ymax] = get_client_boundary(selected_body);
682
- const st = indicator1.style;
683
- st.display = 'block';
684
- st.left = `${xmin}px`;
685
- st.top = `${ymin}px`;
686
- st.width = `${xmax - xmin}px`;
687
- st.height = `${ymax - ymin}px`;
688
- } else {
689
- indicator1.style.display = 'none';
690
- }
691
-
692
- if (camera.fixed_roll) camera.up.set(0, 1, 0);
693
- renderer.render(scene, camera);
694
-
695
- for (let fn of onAnimateEndOneshot) {
696
- fn();
697
- }
698
- onAnimateEndOneshot.length = 0;
699
- };
700
-
701
- ui.loadPose = function (data) {
702
- selected_body = null;
703
- touched_body = null;
704
- touchable_objects.length = 0;
705
- touchable_bodies.length = 0;
706
- object_to_body.clear();
707
- for (let name of bodies.keys()) {
708
- remove_body(name);
709
- }
710
-
711
- // screen
712
- size_change(data.screen.width, data.screen.height);
713
- if (width_input) width_input.value = data.screen.width;
714
- if (height_input) height_input.value = data.screen.height;
715
-
716
- // camera
717
- set_pose_dict(camera, data.camera);
718
- camera.zoom = data.camera.zoom;
719
- camera.updateProjectionMatrix();
720
-
721
- // bodies
722
-
723
- // update `body_num`
724
- const body_names = data.joints.map(x => {
725
- const m = /^body_(\d+)$/.exec(x.name);
726
- return m ? +m[1] : -1;
727
- }).filter(x => 0 <= x);
728
- if (body_names.length == 0) {
729
- body_num = 0;
730
- } else {
731
- body_num = Math.max(...body_names) + 1;
732
- }
733
-
734
- for (let dict of data.joints) {
735
- const body = add_body(dict.name, dict.x0, dict.y0, dict.z0);
736
- for (let i = 0, e = Math.min(body.joints.length, dict.joints.length); i < e; ++i) {
737
- set_pose_dict(body.joints[i], dict.joints[i]);
738
- }
739
- set_pose_dict(body.group, dict.group);
740
- }
741
- };
742
-
743
- ui.getDataURL = async function () {
744
- const pr = new Promise(resolve => {
745
- const current_bg = scene.background;
746
- set_bg(null, true);
747
- onAnimateEndOneshot.push(() => {
748
- resolve(renderer.domElement.toDataURL('image/png'));
749
- set_bg(current_bg);
750
- });
751
- });
752
- return await pr;
753
- };
754
-
755
- ui.getBlob = async function () {
756
- const pr = new Promise(resolve => {
757
- const current_bg = scene.background;
758
- set_bg(null, true);
759
- onAnimateEndOneshot.push(() => {
760
- renderer.domElement.toBlob(blob => {
761
- resolve(blob);
762
- set_bg(current_bg);
763
- });
764
- });
765
- });
766
- return await pr;
767
- };
768
-
769
- ui.stop = function () {
770
- running = false;
771
- dragger_joint.deactivate();
772
- dragger_joint.enabled = false;
773
- dragger_body.deactivate();
774
- dragger_body.enabled = false;
775
- controls.enabled = false;
776
- };
777
-
778
- ui.play = function () {
779
- running = true;
780
- dragger_joint.activate();
781
- dragger_joint.enabled = true;
782
- dragger_body.activate();
783
- dragger_body.enabled = true;
784
- controls.enabled = true;
785
- controls.handleResize();
786
- };
787
-
788
- return animate;
789
- }
790
-
791
- function init(ui) {
792
- if (ui.save)
793
- ui.save.addEventListener('click', async () => {
794
- const a = document.createElement('a');
795
- if (ui.getDataURL) {
796
- a.href = await ui.getDataURL('image/png');
797
- } else {
798
- a.href = ui.canvas.toDataURL('image/png');
799
- }
800
- a.download = 'download.png';
801
- a.click();
802
- ui.notify('save success');
803
- }, false);
804
-
805
- if (ui.copy)
806
- ui.copy.addEventListener('click', async () => {
807
- if (globalThis.ClipboardItem === undefined) {
808
- alert('`ClipboardItem` is not defined. If you are in Firefox, change about:config -> dom.events.asyncClipboard.clipboardItem to `true`.')
809
- return;
810
- }
811
-
812
- async function get_blob() {
813
- if (ui.getBlob) {
814
- return await ui.getBlob();
815
- } else {
816
- return await new Promise(resolve => ui.canvas.toBlob(blob => resolve(blob)));
817
- }
818
- }
819
- try {
820
- const blob = await get_blob();
821
- const data = new ClipboardItem({ [blob.type]: blob });
822
- navigator.clipboard.write([data]);
823
- ui.notify('copy success');
824
- } catch (e) {
825
- ui.notify(`failed to copy data: ${e.message}`, 'error');
826
- }
827
- }, false);
828
- }
829
-
830
- function array_remove(array, item) {
831
- let index = array.indexOf(item);
832
- while (0 <= index) {
833
- array.splice(index, 1);
834
- index = array.indexOf(item);
835
- }
836
- }
837
-
838
- function get_relative_offset(target, origin) {
839
- const r0 = origin.getBoundingClientRect();
840
- const r1 = target.getBoundingClientRect();
841
- return [r1.left - r0.left, r1.top - r0.top];
842
- }
843
-
844
- export { init, init_3d };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/js/three.module.js DELETED
The diff for this file is too large to render. See raw diff
 
posex/requirements.txt DELETED
@@ -1,2 +0,0 @@
1
- flask
2
- pillow
 
 
 
posex/saved_poses/bridge.png DELETED
Binary file (7.56 kB)
 
posex/saved_poses/sample.png DELETED
Binary file (9.32 kB)
 
posex/scripts/__pycache__/posex.cpython-310.pyc DELETED
Binary file (6.78 kB)
 
posex/scripts/posex.py DELETED
@@ -1,184 +0,0 @@
1
- import os
2
- import io
3
- import base64
4
- import json
5
- from typing import Callable, Any
6
- from PIL import Image
7
- import gradio as gr
8
- from modules import scripts
9
- from modules.processing import StableDiffusionProcessing
10
- from modules.shared import opts
11
- from modules import extensions
12
-
13
- from common import posex_utils as posex
14
-
15
- if '__file__' in globals():
16
- posex.set_save_dir(os.path.join(os.path.dirname(__file__), '..', 'saved_poses'))
17
- else:
18
- # cf. https://stackoverflow.com/a/53293924
19
- import inspect
20
- posex.set_save_dir(os.path.join(os.path.dirname(inspect.getfile(lambda: None)), '..', 'saved_poses'))
21
-
22
- class Script(scripts.Script):
23
-
24
- def title(self):
25
- return 'Posex'
26
-
27
- def show(self, is_img2img):
28
- return scripts.AlwaysVisible
29
-
30
- def ui(self, is_img2img):
31
- id = lambda s: f'posex-{["t2i", "i2i"][is_img2img]}-{s}'
32
- js = lambda s: f'globalThis["{id(s)}"]'
33
-
34
- ext = get_self_extension()
35
- if ext is None:
36
- return []
37
- js_ = [f'{x.path}?{os.path.getmtime(x.path)}' for x in ext.list_files('javascript/lazyload', '.js')]
38
- js_.insert(0, ext.path)
39
-
40
- with gr.Accordion('Posex', open=False, elem_id=id('accordion')):
41
- with gr.Row():
42
- enabled = gr.Checkbox(value=False, label='Send this image to ControlNet.', elem_id=id('enabled'))
43
- cn_num = gr.Number(value=0, precision=0, label='Target ControlNet number', visible=self.max_cn_num()!=1)
44
-
45
- gr.HTML(value='\n'.join(js_), elem_id=id('js'), visible=False)
46
-
47
- gr.HTML(value='', elem_id=id('html'))
48
-
49
- with gr.Group(visible=False):
50
- sink = gr.HTML(value='', visible=False) # to suppress error in javascript
51
- base64 = js2py('base64', id, js, sink)
52
- py2js('allposes', all_pose, id, js, sink)
53
- jscall('delpose', delete_pose, id, js, sink)
54
- jscall('savepose', save_pose, id, js, sink)
55
- jscall('loadpose', load_pose, id, js, sink)
56
-
57
- return [enabled, base64, cn_num]
58
-
59
- def process(self, p: StableDiffusionProcessing, enabled: bool = False, b64: str = '', cn_num: int = 0):
60
- if not enabled or b64 is None or len(b64) == 0:
61
- return
62
-
63
- cn_num = int(cn_num)
64
- max_cn_num = self.max_cn_num()
65
- if max_cn_num != 1:
66
- v = (cn_num + max_cn_num) % max_cn_num
67
- if v < 0:
68
- raise ValueError(f'[posex] invalid ControlNet number: {cn_num}')
69
- cn_num = v
70
- else:
71
- cn_num = 0
72
-
73
- binary = io.BytesIO(base64.b64decode(b64[len('data:image/png;base64,'):]))
74
- image = Image.open(binary)
75
-
76
- opts.control_net_allow_script_control = True
77
- self.set_p_value(p, 'control_net_enabled', cn_num, True)
78
- self.set_p_value(p, 'control_net_input_image', cn_num, image)
79
-
80
- def postprocess(self, p, processed, enabled: bool = False, b64: str = '', cn_num: int = 0):
81
- if not enabled or b64 is None or len(b64) == 0:
82
- return
83
-
84
- opts.control_net_allow_script_control = False
85
-
86
- def set_p_value(self, p: StableDiffusionProcessing, attr: str, idx: int, v: Any):
87
- value = getattr(p, attr, None)
88
- if isinstance(value, list):
89
- value[idx] = v
90
- else:
91
- # if value is None, ControlNet uses default value
92
- value = [value] * self.max_cn_num()
93
- value[idx] = v
94
- setattr(p, attr, value)
95
-
96
- def max_cn_num(self):
97
- if opts.data is None:
98
- return 1
99
- return int(opts.data.get('control_net_max_models_num', 1))
100
-
101
-
102
- def js2py(
103
- name: str,
104
- id: Callable[[str], str],
105
- js: Callable[[str], str],
106
- sink: gr.components.IOComponent,
107
- ) -> gr.Textbox:
108
-
109
- v_set = gr.Button(elem_id=id(f'{name}_set'))
110
- v = gr.Textbox(elem_id=id(name))
111
- v_sink = gr.Textbox()
112
- v_set.click(fn=None, _js=js(name), outputs=[v, v_sink])
113
- v_sink.change(fn=None, _js=js(f'{name}_after'), outputs=[sink])
114
- return v
115
-
116
- def py2js(
117
- name: str,
118
- fn: Callable[[], str],
119
- id: Callable[[str], str],
120
- js: Callable[[str], str],
121
- sink: gr.components.IOComponent,
122
- ) -> None:
123
-
124
- v_fire = gr.Button(elem_id=id(f'{name}_get'))
125
- v_sink = gr.Textbox()
126
- v_sink2 = gr.Textbox()
127
- v_fire.click(fn=wrap_api(fn), outputs=[v_sink, v_sink2])
128
- v_sink2.change(fn=None, _js=js(name), inputs=[v_sink], outputs=[sink])
129
-
130
- def jscall(
131
- name: str,
132
- fn: Callable[[str], str],
133
- id: Callable[[str], str],
134
- js: Callable[[str], str],
135
- sink: gr.components.IOComponent,
136
- ) -> None:
137
-
138
- v_args_set = gr.Button(elem_id=id(f'{name}_args_set'))
139
- v_args = gr.Textbox(elem_id=id(f'{name}_args'))
140
- v_args_sink = gr.Textbox()
141
- v_args_set.click(fn=None, _js=js(f'{name}_args'), outputs=[v_args, v_args_sink])
142
- v_args_sink.change(fn=None, _js=js(f'{name}_args_after'), outputs=[sink])
143
-
144
- v_fire = gr.Button(elem_id=id(f'{name}_get'))
145
- v_sink = gr.Textbox()
146
- v_sink2 = gr.Textbox()
147
- v_fire.click(fn=wrap_api(fn), inputs=[v_args], outputs=[v_sink, v_sink2])
148
- v_sink2.change(fn=None, _js=js(name), inputs=[v_sink], outputs=[sink])
149
-
150
-
151
- def get_self_extension():
152
- if '__file__' in globals():
153
- filepath = __file__
154
- else:
155
- import inspect
156
- filepath = inspect.getfile(lambda: None)
157
- for ext in extensions.active():
158
- if ext.path in filepath:
159
- return ext
160
-
161
- # APIs
162
-
163
- def wrap_api(fn):
164
- _r = 0
165
- def f(*args, **kwargs):
166
- nonlocal _r
167
- _r += 1
168
- v = fn(*args, **kwargs)
169
- return v, str(_r)
170
- return f
171
-
172
- def all_pose():
173
- return json.dumps(list(posex.all_poses()))
174
-
175
- def delete_pose(args):
176
- posex.delete_pose(json.loads(args)[0])
177
- return ''
178
-
179
- def save_pose(args):
180
- posex.save_pose(json.loads(args)[0])
181
- return ''
182
-
183
- def load_pose(args):
184
- return json.dumps(posex.load_pose(json.loads(args)[0]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posex/style.css DELETED
@@ -1,159 +0,0 @@
1
- /*
2
- * CSS for WebUI
3
- **/
4
-
5
- .posex_cont {
6
- display: flex;
7
- flex-flow: column;
8
- gap: 0.5em 0;
9
- width: max-content;
10
- overflow: auto !important;
11
- max-width: 100%;
12
- }
13
-
14
- .posex_cont input[type=checkbox] {
15
- appearance: auto;
16
- }
17
-
18
- .posex_reset_cont {
19
- display: flex;
20
- flex-direction: row;
21
- gap: 0 0.5em;
22
- }
23
-
24
- .posex_box {
25
- display: block;
26
- border: 1px solid gray;
27
- padding: 0.5em 0;
28
- text-decoration: none;
29
- text-align: center;
30
- }
31
-
32
- .posex_reset_cont .posex_box {
33
- flex: 1 1 0;
34
- }
35
-
36
- .posex_canvas_cont {
37
- display: flex;
38
- flex-direction: row;
39
- }
40
-
41
- .posex_canvas_size {
42
- background-color: transparent !important;
43
- }
44
-
45
- .posex_setting_cont {
46
- margin-left: 1em;
47
- display: flex;
48
- flex-direction: column;
49
- gap: 0.25em;
50
- }
51
-
52
- .posex_body {
53
- width: max-content;
54
- min-width: 100%;
55
- text-align: left;
56
- border: 1px solid gray;
57
- padding: 0.5em;
58
- }
59
-
60
- .posex_bg_cont {
61
- display: flex;
62
- flex-direction: row;
63
- gap: 0 0.25em;
64
- }
65
-
66
- .posex_bg {
67
- flex: 0 0 0;
68
- border: 1px solid gray;
69
- padding: 0.25em 1em;
70
- min-width: 5em;
71
- }
72
-
73
- .posex_notation {
74
- display: none;
75
- position: absolute;
76
- color: black;
77
- background-color: rgba(255, 255, 255, 0.75);
78
- padding: 0.1em 0.25em;
79
- pointer-events: none;
80
- font-size: small;
81
- }
82
-
83
- .posex_indicator1 {
84
- display: none;
85
- position: absolute;
86
- outline: 1px solid white;
87
- pointer-events: none;
88
- }
89
-
90
- .posex_indicator2 {
91
- display: none;
92
- position: absolute;
93
- outline: 1px solid gray;
94
- pointer-events: none;
95
- }
96
-
97
- .posex_misc_cont {
98
- display: flex;
99
- flex-flow: row;
100
- gap: 0 0.5em;
101
- }
102
-
103
- .posex_misc {
104
- flex: 1 1 0;
105
- }
106
-
107
- .posex_saved_poses {
108
- display: flex;
109
- flex-direction: row;
110
- gap: 0.25em;
111
- font-size: small;
112
- }
113
-
114
- .posex_saved_poses > * {
115
- margin: 0;
116
- outline: 1px solid gray;
117
- max-width: 128px;
118
- }
119
-
120
- .posex_saved_poses img {
121
- max-width: 128px;
122
- max-height: 128px;
123
- }
124
-
125
- .posex_saved_poses figcaption {
126
- padding: 0 0.25em;
127
- overflow-wrap: anywhere; /* Opera Android may not be able to interpret `anywhere` keyword. */
128
- }
129
-
130
- .posex_saved_poses .close {
131
- position: absolute;
132
- cursor: pointer;
133
- background-color: white;
134
- opacity: 0.5 !important;
135
- width: 16px;
136
- height: 16px;
137
- text-align: center;
138
- vertical-align: middle;
139
- margin: 0;
140
- padding: 0;
141
- font-family: monospace;
142
- }
143
-
144
- .posex_saved_poses .close:hover {
145
- opacity: 1.0 !important;
146
- }
147
-
148
- .posex_saved_poses .close2 {
149
- display: none;
150
- position: absolute;
151
- left: 1.5em;
152
- top: 0;
153
- }
154
-
155
- .posex_saved_poses .close:hover .close2 {
156
- display: block;
157
- color: white;
158
- pointer-events: none;
159
- }