Commit 8c5efa1f167485cfcdef33d23308c6cbe6d1e3b2

Authored by fengtao
Committed by xp.Huang
1 parent d90e70ca

perf(src/packages): 调整3D模型布局和新增保存缩略图

@@ -35,8 +35,6 @@ @@ -35,8 +35,6 @@
35 <script type="module" src="./js/libs/ternjs/doc_comment.js"></script> 35 <script type="module" src="./js/libs/ternjs/doc_comment.js"></script>
36 <script type="module" src="./js/libs/tern-threejs/threejs.js"></script> 36 <script type="module" src="./js/libs/tern-threejs/threejs.js"></script>
37 <script type="module" src="./js/libs/signals.min.js"></script> 37 <script type="module" src="./js/libs/signals.min.js"></script>
38 - <script type="module" src="./js/libs/axios.min.js"></script>  
39 - <script type="module" src="./js/libs/http/config.js"></script>  
40 <script type="module" src="./main.js"></script> 38 <script type="module" src="./main.js"></script>
41 </body> 39 </body>
42 </html> 40 </html>
1 import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js' 1 import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js'
2 import useMessage from './MessageDialog.js' 2 import useMessage from './MessageDialog.js'
3 import { saveOrUpdateThreeJsModel } from './libs/http/api.js' 3 import { saveOrUpdateThreeJsModel } from './libs/http/api.js'
  4 +import html2canvas from 'html2canvas'
  5 +import { fetchRouteParamsLocation } from '@/utils'
  6 +import { uploadFile } from '@/api/external/contentSave/content'
  7 +import { base64toFile } from '../utils/Base64ToFile.js'
4 8
5 function MenubarFile(editor) { 9 function MenubarFile(editor) {
6 const strings = editor.strings 10 const strings = editor.strings
@@ -137,16 +141,34 @@ function MenubarFile(editor) { @@ -137,16 +141,34 @@ function MenubarFile(editor) {
137 /** 141 /**
138 * THINGS_KIT 修改 142 * THINGS_KIT 修改
139 */ 143 */
  144 +
140 option = new UIRow() 145 option = new UIRow()
141 .addClass('option') 146 .addClass('option')
142 .setTextContent(strings.getKey('menubar/file/save')) 147 .setTextContent(strings.getKey('menubar/file/save'))
143 .onClick(async function () { 148 .onClick(async function () {
  149 + // 获取缩略图片
  150 + const range = document.querySelector('#viewport').children[3]
  151 + // 生成图片
  152 + const canvasImage = await html2canvas(range, {
  153 + backgroundColor: null,
  154 + allowTaint: true,
  155 + useCORS: true,
  156 + logging: false
  157 + })
  158 + // 上传预览图
  159 + const uploadParams = new FormData()
  160 + uploadParams.append(
  161 + 'file',
  162 + base64toFile(canvasImage.toDataURL(), `${fetchRouteParamsLocation()}_index_preview.png`)
  163 + )
  164 + const uploadRes = await uploadFile(uploadParams)
144 const file_json = editor.toJSON() 165 const file_json = editor.toJSON()
145 const paramsStr = window.location.search 166 const paramsStr = window.location.search
146 const params = new URLSearchParams(paramsStr) 167 const params = new URLSearchParams(paramsStr)
147 const file_uuid = params.get('three_file_uuid') 168 const file_uuid = params.get('three_file_uuid')
148 await saveOrUpdateThreeJsModel({ 169 await saveOrUpdateThreeJsModel({
149 id: file_uuid, 170 id: file_uuid,
  171 + imageUrl: uploadRes?.fileDownloadUri,
150 data: file_json 172 data: file_json
151 }) 173 })
152 const { success } = useMessage() 174 const { success } = useMessage()
1 -import * as THREE from 'three'; 1 +import * as THREE from 'three'
2 2
3 -import { UIBreak, UIButton, UIInteger, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js'; 3 +import { UIBreak, UIButton, UIInteger, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js'
4 4
5 -import { ViewportPathtracer } from './Viewport.Pathtracer.js'; 5 +import { ViewportPathtracer } from './Viewport.Pathtracer.js'
6 6
7 -function SidebarProjectImage( editor ) { 7 +function SidebarProjectImage(editor) {
  8 + const strings = editor.strings
8 9
9 - const strings = editor.strings; 10 + const container = new UIPanel()
  11 + container.setId('render')
10 12
11 - const container = new UIPanel();  
12 - container.setId( 'render' ); 13 + // Image
13 14
14 - // Image 15 + container.add(new UIText(strings.getKey('sidebar/project/image')).setTextTransform('uppercase'))
  16 + container.add(new UIBreak(), new UIBreak())
15 17
16 - container.add( new UIText( strings.getKey( 'sidebar/project/image' ) ).setTextTransform( 'uppercase' ) );  
17 - container.add( new UIBreak(), new UIBreak() ); 18 + // Shading
18 19
19 - // Shading 20 + const shadingRow = new UIRow()
  21 + container.add(shadingRow)
20 22
21 - const shadingRow = new UIRow();  
22 - container.add( shadingRow ); 23 + shadingRow.add(new UIText(strings.getKey('sidebar/project/shading')).setClass('Label'))
23 24
24 - shadingRow.add( new UIText( strings.getKey( 'sidebar/project/shading' ) ).setClass( 'Label' ) ); 25 + const shadingTypeSelect = new UISelect()
  26 + .setOptions({
  27 + solid: 'SOLID',
  28 + realistic: 'REALISTIC'
  29 + })
  30 + .setWidth('170px')
  31 + .onChange(refreshShadingRow)
  32 + .setValue('solid')
  33 + shadingRow.add(shadingTypeSelect)
25 34
26 - const shadingTypeSelect = new UISelect().setOptions( {  
27 - 'solid': 'SOLID',  
28 - 'realistic': 'REALISTIC'  
29 - } ).setWidth( '170px' ).onChange( refreshShadingRow ).setValue( 'solid' );  
30 - shadingRow.add( shadingTypeSelect ); 35 + const pathTracerMinSamples = 3
  36 + const pathTracerMaxSamples = 65536
  37 + const samplesNumber = new UIInteger(16).setRange(pathTracerMinSamples, pathTracerMaxSamples)
31 38
32 - const pathTracerMinSamples = 3;  
33 - const pathTracerMaxSamples = 65536;  
34 - const samplesNumber = new UIInteger( 16 ).setRange( pathTracerMinSamples, pathTracerMaxSamples ); 39 + const samplesRow = new UIRow()
  40 + samplesRow.add(new UIText(strings.getKey('sidebar/project/image/samples')).setClass('Label'))
  41 + samplesRow.add(samplesNumber)
35 42
36 - const samplesRow = new UIRow();  
37 - samplesRow.add( new UIText( strings.getKey( 'sidebar/project/image/samples' ) ).setClass( 'Label' ) );  
38 - samplesRow.add( samplesNumber ); 43 + container.add(samplesRow)
39 44
40 - container.add( samplesRow ); 45 + function refreshShadingRow() {
  46 + samplesRow.setHidden(shadingTypeSelect.getValue() !== 'realistic')
  47 + }
41 48
42 - function refreshShadingRow() { 49 + refreshShadingRow()
43 50
44 - samplesRow.setHidden( shadingTypeSelect.getValue() !== 'realistic' ); 51 + // Resolution
45 52
46 - } 53 + const resolutionRow = new UIRow()
  54 + container.add(resolutionRow)
47 55
48 - refreshShadingRow(); 56 + resolutionRow.add(new UIText(strings.getKey('sidebar/project/resolution')).setClass('Label'))
49 57
50 - // Resolution 58 + const imageWidth = new UIInteger(1024).setTextAlign('center').setWidth('28px')
  59 + resolutionRow.add(imageWidth)
51 60
52 - const resolutionRow = new UIRow();  
53 - container.add( resolutionRow ); 61 + resolutionRow.add(new UIText('×').setTextAlign('center').setFontSize('12px').setWidth('12px'))
54 62
55 - resolutionRow.add( new UIText( strings.getKey( 'sidebar/project/resolution' ) ).setClass( 'Label' ) ); 63 + const imageHeight = new UIInteger(1024).setTextAlign('center').setWidth('28px')
  64 + resolutionRow.add(imageHeight)
56 65
57 - const imageWidth = new UIInteger( 1024 ).setTextAlign( 'center' ).setWidth( '28px' );  
58 - resolutionRow.add( imageWidth ); 66 + // Render
59 67
60 - resolutionRow.add( new UIText( '×' ).setTextAlign( 'center' ).setFontSize( '12px' ).setWidth( '12px' ) ); 68 + const renderButton = new UIButton(strings.getKey('sidebar/project/render'))
  69 + renderButton.setWidth('170px')
  70 + renderButton.setMarginLeft('120px')
  71 + renderButton.onClick(async () => {
  72 + if (shadingTypeSelect.getValue() === 'realistic') {
  73 + let isMaterialsValid = true
61 74
62 - const imageHeight = new UIInteger( 1024 ).setTextAlign( 'center' ).setWidth( '28px' );  
63 - resolutionRow.add( imageHeight ); 75 + editor.scene.traverseVisible(object => {
  76 + if (object.isMesh) {
  77 + const materials = Array.isArray(object.material) ? object.material : [object.material]
64 78
65 - // Render 79 + for (let i = 0; i < materials.length; i++) {
  80 + const material = materials[i]
66 81
67 - const renderButton = new UIButton( strings.getKey( 'sidebar/project/render' ) );  
68 - renderButton.setWidth( '170px' );  
69 - renderButton.setMarginLeft( '120px' );  
70 - renderButton.onClick( async () => { 82 + if (!material.isMeshStandardMaterial) {
  83 + isMaterialsValid = false
  84 + return
  85 + }
  86 + }
  87 + }
  88 + })
71 89
72 - if ( shadingTypeSelect.getValue() === 'realistic' ) { 90 + if (isMaterialsValid === false) {
  91 + alert(strings.getKey('prompt/rendering/realistic/unsupportedMaterial'))
  92 + return
  93 + }
  94 + }
73 95
74 - let isMaterialsValid = true; 96 + //
75 97
76 - editor.scene.traverseVisible( ( object ) => { 98 + const json = editor.toJSON()
  99 + const project = json.project
77 100
78 - if ( object.isMesh ) { 101 + //
79 102
80 - const materials = Array.isArray( object.material ) ? object.material : [ object.material ]; 103 + const loader = new THREE.ObjectLoader()
81 104
82 - for ( let i = 0; i < materials.length; i ++ ) { 105 + const camera = loader.parse(json.camera)
  106 + camera.aspect = imageWidth.getValue() / imageHeight.getValue()
  107 + camera.updateProjectionMatrix()
  108 + camera.updateMatrixWorld()
83 109
84 - const material = materials[ i ]; 110 + const scene = loader.parse(json.scene)
85 111
86 - if ( ! material.isMeshStandardMaterial ) { 112 + const renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true })
  113 + renderer.setSize(imageWidth.getValue(), imageHeight.getValue())
87 114
88 - isMaterialsValid = false;  
89 - return; 115 + if (project.shadows !== undefined) renderer.shadowMap.enabled = project.shadows
  116 + if (project.shadowType !== undefined) renderer.shadowMap.type = project.shadowType
  117 + if (project.toneMapping !== undefined) renderer.toneMapping = project.toneMapping
  118 + if (project.toneMappingExposure !== undefined) renderer.toneMappingExposure = project.toneMappingExposure
90 119
91 - } 120 + // popup
92 121
93 - } 122 + const width = imageWidth.getValue() / window.devicePixelRatio
  123 + const height = imageHeight.getValue() / window.devicePixelRatio
94 124
95 - } 125 + const left = (screen.width - width) / 2
  126 + const top = (screen.height - height) / 2
96 127
97 - } ); 128 + const output = window.open('', '_blank', `location=no,left=${left},top=${top},width=${width},height=${height}`)
98 129
99 - if ( isMaterialsValid === false ) { 130 + const meta = document.createElement('meta')
  131 + meta.name = 'viewport'
  132 + meta.content = 'width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0'
  133 + output.document.head.appendChild(meta)
100 134
101 - alert( strings.getKey( 'prompt/rendering/realistic/unsupportedMaterial' ) );  
102 - return; 135 + output.document.body.style.background = '#000'
  136 + output.document.body.style.margin = '0px'
  137 + output.document.body.style.overflow = 'hidden'
103 138
104 - } 139 + const canvas = renderer.domElement
  140 + canvas.style.width = width + 'px'
  141 + canvas.style.height = height + 'px'
  142 + output.document.body.appendChild(canvas)
105 143
106 - } 144 + //
107 145
108 - // 146 + switch (shadingTypeSelect.getValue()) {
  147 + case 'solid':
  148 + renderer.render(scene, camera)
  149 + renderer.dispose()
109 150
110 - const json = editor.toJSON();  
111 - const project = json.project; 151 + break
112 152
113 - // 153 + case 'realistic':
  154 + const status = document.createElement('div')
  155 + status.style.position = 'absolute'
  156 + status.style.top = '10px'
  157 + status.style.left = '10px'
  158 + status.style.color = 'white'
  159 + status.style.fontFamily = 'system-ui'
  160 + status.style.fontSize = '12px'
  161 + output.document.body.appendChild(status)
114 162
115 - const loader = new THREE.ObjectLoader(); 163 + const pathTracer = new ViewportPathtracer(renderer)
  164 + pathTracer.init(scene, camera)
  165 + pathTracer.setSize(imageWidth.getValue(), imageHeight.getValue())
116 166
117 - const camera = loader.parse( json.camera );  
118 - camera.aspect = imageWidth.getValue() / imageHeight.getValue();  
119 - camera.updateProjectionMatrix();  
120 - camera.updateMatrixWorld(); 167 + const maxSamples = Math.max(pathTracerMinSamples, Math.min(pathTracerMaxSamples, samplesNumber.getValue()))
121 168
122 - const scene = loader.parse( json.scene ); 169 + function animate() {
  170 + if (output.closed === true) return
123 171
124 - const renderer = new THREE.WebGLRenderer( { antialias: true } );  
125 - renderer.setSize( imageWidth.getValue(), imageHeight.getValue() ); 172 + const samples = Math.floor(pathTracer.getSamples()) + 1
126 173
127 - if ( project.shadows !== undefined ) renderer.shadowMap.enabled = project.shadows;  
128 - if ( project.shadowType !== undefined ) renderer.shadowMap.type = project.shadowType;  
129 - if ( project.toneMapping !== undefined ) renderer.toneMapping = project.toneMapping;  
130 - if ( project.toneMappingExposure !== undefined ) renderer.toneMappingExposure = project.toneMappingExposure; 174 + if (samples < maxSamples) {
  175 + requestAnimationFrame(animate)
  176 + }
131 177
132 - // popup 178 + pathTracer.update()
133 179
134 - const width = imageWidth.getValue() / window.devicePixelRatio;  
135 - const height = imageHeight.getValue() / window.devicePixelRatio; 180 + const progress = Math.floor((samples / maxSamples) * 100)
136 181
137 - const left = ( screen.width - width ) / 2;  
138 - const top = ( screen.height - height ) / 2; 182 + status.textContent = `${samples} / ${maxSamples} ( ${progress}% )`
139 183
140 - const output = window.open( '', '_blank', `location=no,left=${left},top=${top},width=${width},height=${height}` ); 184 + if (progress === 100) {
  185 + status.textContent += ' ✓'
  186 + }
  187 + }
141 188
142 - const meta = document.createElement( 'meta' );  
143 - meta.name = 'viewport';  
144 - meta.content = 'width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0';  
145 - output.document.head.appendChild( meta ); 189 + animate()
146 190
147 - output.document.body.style.background = '#000';  
148 - output.document.body.style.margin = '0px';  
149 - output.document.body.style.overflow = 'hidden'; 191 + break
  192 + }
  193 + })
  194 + container.add(renderButton)
150 195
151 - const canvas = renderer.domElement;  
152 - canvas.style.width = width + 'px';  
153 - canvas.style.height = height + 'px';  
154 - output.document.body.appendChild( canvas );  
155 -  
156 - //  
157 -  
158 - switch ( shadingTypeSelect.getValue() ) {  
159 -  
160 - case 'solid':  
161 -  
162 - renderer.render( scene, camera );  
163 - renderer.dispose();  
164 -  
165 - break;  
166 -  
167 - case 'realistic':  
168 -  
169 - const status = document.createElement( 'div' );  
170 - status.style.position = 'absolute';  
171 - status.style.top = '10px';  
172 - status.style.left = '10px';  
173 - status.style.color = 'white';  
174 - status.style.fontFamily = 'system-ui';  
175 - status.style.fontSize = '12px';  
176 - output.document.body.appendChild( status );  
177 -  
178 - const pathTracer = new ViewportPathtracer( renderer );  
179 - pathTracer.init( scene, camera );  
180 - pathTracer.setSize( imageWidth.getValue(), imageHeight.getValue() );  
181 -  
182 - const maxSamples = Math.max( pathTracerMinSamples, Math.min( pathTracerMaxSamples, samplesNumber.getValue() ) );  
183 -  
184 - function animate() {  
185 -  
186 - if ( output.closed === true ) return;  
187 -  
188 - const samples = Math.floor( pathTracer.getSamples() ) + 1;  
189 -  
190 - if ( samples < maxSamples ) {  
191 -  
192 - requestAnimationFrame( animate );  
193 -  
194 - }  
195 -  
196 - pathTracer.update();  
197 -  
198 - const progress = Math.floor( samples / maxSamples * 100 );  
199 -  
200 - status.textContent = `${ samples } / ${ maxSamples } ( ${ progress }% )`;  
201 -  
202 - if ( progress === 100 ) {  
203 -  
204 - status.textContent += ' ✓';  
205 -  
206 - }  
207 -  
208 - }  
209 -  
210 - animate();  
211 -  
212 - break;  
213 -  
214 - }  
215 -  
216 - } );  
217 - container.add( renderButton );  
218 -  
219 - //  
220 -  
221 - return container; 196 + //
222 197
  198 + return container
223 } 199 }
224 200
225 -export { SidebarProjectImage }; 201 +export { SidebarProjectImage }
1 -import * as THREE from 'three'; 1 +import * as THREE from 'three'
2 2
3 -import { UINumber, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js';  
4 -import { UIBoolean } from './libs/ui.three.js'; 3 +import { UINumber, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js'
  4 +import { UIBoolean } from './libs/ui.three.js'
5 5
6 -function SidebarProjectRenderer( editor ) { 6 +function SidebarProjectRenderer(editor) {
  7 + const config = editor.config
  8 + const signals = editor.signals
  9 + const strings = editor.strings
7 10
8 - const config = editor.config;  
9 - const signals = editor.signals;  
10 - const strings = editor.strings; 11 + let currentRenderer = null
11 12
12 - let currentRenderer = null; 13 + const container = new UIPanel()
  14 + container.setBorderTop('0px')
13 15
14 - const container = new UIPanel();  
15 - container.setBorderTop( '0px' ); 16 + // Antialias
16 17
17 - // Antialias 18 + const antialiasRow = new UIRow()
  19 + container.add(antialiasRow)
18 20
19 - const antialiasRow = new UIRow();  
20 - container.add( antialiasRow ); 21 + antialiasRow.add(new UIText(strings.getKey('sidebar/project/antialias')).setClass('Label'))
21 22
22 - antialiasRow.add( new UIText( strings.getKey( 'sidebar/project/antialias' ) ).setClass( 'Label' ) ); 23 + const antialiasBoolean = new UIBoolean(config.getKey('project/renderer/antialias')).onChange(createRenderer)
  24 + antialiasRow.add(antialiasBoolean)
23 25
24 - const antialiasBoolean = new UIBoolean( config.getKey( 'project/renderer/antialias' ) ).onChange( createRenderer );  
25 - antialiasRow.add( antialiasBoolean );  
26 -  
27 - // Shadows  
28 -  
29 - const shadowsRow = new UIRow();  
30 - container.add( shadowsRow );  
31 -  
32 - shadowsRow.add( new UIText( strings.getKey( 'sidebar/project/shadows' ) ).setClass( 'Label' ) );  
33 -  
34 - const shadowsBoolean = new UIBoolean( config.getKey( 'project/renderer/shadows' ) ).onChange( updateShadows );  
35 - shadowsRow.add( shadowsBoolean );  
36 -  
37 - const shadowTypeSelect = new UISelect().setOptions( {  
38 - 0: 'Basic',  
39 - 1: 'PCF',  
40 - 2: 'PCF Soft',  
41 - // 3: 'VSM'  
42 - } ).setWidth( '125px' ).onChange( updateShadows );  
43 - shadowTypeSelect.setValue( config.getKey( 'project/renderer/shadowType' ) );  
44 - shadowsRow.add( shadowTypeSelect );  
45 -  
46 - function updateShadows() {  
47 -  
48 - currentRenderer.shadowMap.enabled = shadowsBoolean.getValue();  
49 - currentRenderer.shadowMap.type = parseFloat( shadowTypeSelect.getValue() );  
50 -  
51 - signals.rendererUpdated.dispatch();  
52 -  
53 - }  
54 -  
55 - // Tonemapping  
56 -  
57 - const toneMappingRow = new UIRow();  
58 - container.add( toneMappingRow );  
59 -  
60 - toneMappingRow.add( new UIText( strings.getKey( 'sidebar/project/toneMapping' ) ).setClass( 'Label' ) );  
61 -  
62 - const toneMappingSelect = new UISelect().setOptions( {  
63 - 0: 'No',  
64 - 1: 'Linear',  
65 - 2: 'Reinhard',  
66 - 3: 'Cineon',  
67 - 4: 'ACESFilmic',  
68 - 6: 'AgX',  
69 - 7: 'Neutral'  
70 - } ).setWidth( '120px' ).onChange( updateToneMapping );  
71 - toneMappingSelect.setValue( config.getKey( 'project/renderer/toneMapping' ) );  
72 - toneMappingRow.add( toneMappingSelect );  
73 -  
74 - const toneMappingExposure = new UINumber( config.getKey( 'project/renderer/toneMappingExposure' ) );  
75 - toneMappingExposure.setDisplay( toneMappingSelect.getValue() === '0' ? 'none' : '' );  
76 - toneMappingExposure.setWidth( '30px' ).setMarginLeft( '10px' );  
77 - toneMappingExposure.setRange( 0, 10 );  
78 - toneMappingExposure.onChange( updateToneMapping );  
79 - toneMappingRow.add( toneMappingExposure );  
80 -  
81 - function updateToneMapping() {  
82 -  
83 - toneMappingExposure.setDisplay( toneMappingSelect.getValue() === '0' ? 'none' : '' );  
84 -  
85 - currentRenderer.toneMapping = parseFloat( toneMappingSelect.getValue() );  
86 - currentRenderer.toneMappingExposure = toneMappingExposure.getValue();  
87 - signals.rendererUpdated.dispatch();  
88 -  
89 - }  
90 -  
91 - //  
92 -  
93 - function createRenderer() {  
94 -  
95 - currentRenderer = new THREE.WebGLRenderer( { antialias: antialiasBoolean.getValue() } );  
96 - currentRenderer.shadowMap.enabled = shadowsBoolean.getValue();  
97 - currentRenderer.shadowMap.type = parseFloat( shadowTypeSelect.getValue() );  
98 - currentRenderer.toneMapping = parseFloat( toneMappingSelect.getValue() );  
99 - currentRenderer.toneMappingExposure = toneMappingExposure.getValue();  
100 -  
101 - signals.rendererCreated.dispatch( currentRenderer );  
102 - signals.rendererUpdated.dispatch();  
103 -  
104 - }  
105 -  
106 - createRenderer();  
107 -  
108 -  
109 - // Signals  
110 -  
111 - signals.editorCleared.add( function () {  
112 -  
113 - currentRenderer.shadowMap.enabled = true;  
114 - currentRenderer.shadowMap.type = THREE.PCFShadowMap;  
115 - currentRenderer.toneMapping = THREE.NoToneMapping;  
116 - currentRenderer.toneMappingExposure = 1;  
117 -  
118 - shadowsBoolean.setValue( currentRenderer.shadowMap.enabled );  
119 - shadowTypeSelect.setValue( currentRenderer.shadowMap.type );  
120 - toneMappingSelect.setValue( currentRenderer.toneMapping );  
121 - toneMappingExposure.setValue( currentRenderer.toneMappingExposure );  
122 - toneMappingExposure.setDisplay( currentRenderer.toneMapping === 0 ? 'none' : '' );  
123 -  
124 - signals.rendererUpdated.dispatch();  
125 -  
126 - } );  
127 -  
128 - signals.rendererUpdated.add( function () {  
129 -  
130 - config.setKey(  
131 - 'project/renderer/antialias', antialiasBoolean.getValue(),  
132 - 'project/renderer/shadows', shadowsBoolean.getValue(),  
133 - 'project/renderer/shadowType', parseFloat( shadowTypeSelect.getValue() ),  
134 - 'project/renderer/toneMapping', parseFloat( toneMappingSelect.getValue() ),  
135 - 'project/renderer/toneMappingExposure', toneMappingExposure.getValue()  
136 - );  
137 -  
138 - } );  
139 -  
140 - return container; 26 + // Shadows
141 27
  28 + const shadowsRow = new UIRow()
  29 + container.add(shadowsRow)
  30 +
  31 + shadowsRow.add(new UIText(strings.getKey('sidebar/project/shadows')).setClass('Label'))
  32 +
  33 + const shadowsBoolean = new UIBoolean(config.getKey('project/renderer/shadows')).onChange(updateShadows)
  34 + shadowsRow.add(shadowsBoolean)
  35 +
  36 + const shadowTypeSelect = new UISelect()
  37 + .setOptions({
  38 + 0: 'Basic',
  39 + 1: 'PCF',
  40 + 2: 'PCF Soft'
  41 + // 3: 'VSM'
  42 + })
  43 + .setWidth('125px')
  44 + .onChange(updateShadows)
  45 + shadowTypeSelect.setValue(config.getKey('project/renderer/shadowType'))
  46 + shadowsRow.add(shadowTypeSelect)
  47 +
  48 + function updateShadows() {
  49 + currentRenderer.shadowMap.enabled = shadowsBoolean.getValue()
  50 + currentRenderer.shadowMap.type = parseFloat(shadowTypeSelect.getValue())
  51 +
  52 + signals.rendererUpdated.dispatch()
  53 + }
  54 +
  55 + // Tonemapping
  56 +
  57 + const toneMappingRow = new UIRow()
  58 + container.add(toneMappingRow)
  59 +
  60 + toneMappingRow.add(new UIText(strings.getKey('sidebar/project/toneMapping')).setClass('Label'))
  61 +
  62 + const toneMappingSelect = new UISelect()
  63 + .setOptions({
  64 + 0: 'No',
  65 + 1: 'Linear',
  66 + 2: 'Reinhard',
  67 + 3: 'Cineon',
  68 + 4: 'ACESFilmic',
  69 + 6: 'AgX',
  70 + 7: 'Neutral'
  71 + })
  72 + .setWidth('120px')
  73 + .onChange(updateToneMapping)
  74 + toneMappingSelect.setValue(config.getKey('project/renderer/toneMapping'))
  75 + toneMappingRow.add(toneMappingSelect)
  76 +
  77 + const toneMappingExposure = new UINumber(config.getKey('project/renderer/toneMappingExposure'))
  78 + toneMappingExposure.setDisplay(toneMappingSelect.getValue() === '0' ? 'none' : '')
  79 + toneMappingExposure.setWidth('30px').setMarginLeft('10px')
  80 + toneMappingExposure.setRange(0, 10)
  81 + toneMappingExposure.onChange(updateToneMapping)
  82 + toneMappingRow.add(toneMappingExposure)
  83 +
  84 + function updateToneMapping() {
  85 + toneMappingExposure.setDisplay(toneMappingSelect.getValue() === '0' ? 'none' : '')
  86 +
  87 + currentRenderer.toneMapping = parseFloat(toneMappingSelect.getValue())
  88 + currentRenderer.toneMappingExposure = toneMappingExposure.getValue()
  89 + signals.rendererUpdated.dispatch()
  90 + }
  91 +
  92 + //
  93 +
  94 + function createRenderer() {
  95 + currentRenderer = new THREE.WebGLRenderer({ antialias: antialiasBoolean.getValue(), preserveDrawingBuffer: true })
  96 + currentRenderer.shadowMap.enabled = shadowsBoolean.getValue()
  97 + currentRenderer.shadowMap.type = parseFloat(shadowTypeSelect.getValue())
  98 + currentRenderer.toneMapping = parseFloat(toneMappingSelect.getValue())
  99 + currentRenderer.toneMappingExposure = toneMappingExposure.getValue()
  100 +
  101 + signals.rendererCreated.dispatch(currentRenderer)
  102 + signals.rendererUpdated.dispatch()
  103 + }
  104 +
  105 + createRenderer()
  106 +
  107 + // Signals
  108 +
  109 + signals.editorCleared.add(function () {
  110 + currentRenderer.shadowMap.enabled = true
  111 + currentRenderer.shadowMap.type = THREE.PCFShadowMap
  112 + currentRenderer.toneMapping = THREE.NoToneMapping
  113 + currentRenderer.toneMappingExposure = 1
  114 +
  115 + shadowsBoolean.setValue(currentRenderer.shadowMap.enabled)
  116 + shadowTypeSelect.setValue(currentRenderer.shadowMap.type)
  117 + toneMappingSelect.setValue(currentRenderer.toneMapping)
  118 + toneMappingExposure.setValue(currentRenderer.toneMappingExposure)
  119 + toneMappingExposure.setDisplay(currentRenderer.toneMapping === 0 ? 'none' : '')
  120 +
  121 + signals.rendererUpdated.dispatch()
  122 + })
  123 +
  124 + signals.rendererUpdated.add(function () {
  125 + config.setKey(
  126 + 'project/renderer/antialias',
  127 + antialiasBoolean.getValue(),
  128 + 'project/renderer/shadows',
  129 + shadowsBoolean.getValue(),
  130 + 'project/renderer/shadowType',
  131 + parseFloat(shadowTypeSelect.getValue()),
  132 + 'project/renderer/toneMapping',
  133 + parseFloat(toneMappingSelect.getValue()),
  134 + 'project/renderer/toneMappingExposure',
  135 + toneMappingExposure.getValue()
  136 + )
  137 + })
  138 +
  139 + return container
142 } 140 }
143 141
144 -export { SidebarProjectRenderer }; 142 +export { SidebarProjectRenderer }
1 var APP = { 1 var APP = {
  2 + Player: function () {
  3 + var renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true })
  4 + renderer.setPixelRatio(window.devicePixelRatio) // TODO: Use player.setPixelRatio()
2 5
3 - Player: function () { 6 + var loader = new THREE.ObjectLoader()
  7 + var camera, scene
4 8
5 - var renderer = new THREE.WebGLRenderer( { antialias: true } );  
6 - renderer.setPixelRatio( window.devicePixelRatio ); // TODO: Use player.setPixelRatio() 9 + var events = {}
7 10
8 - var loader = new THREE.ObjectLoader();  
9 - var camera, scene; 11 + var dom = document.createElement('div')
  12 + dom.appendChild(renderer.domElement)
10 13
11 - var events = {}; 14 + this.dom = dom
  15 + this.canvas = renderer.domElement
12 16
13 - var dom = document.createElement( 'div' );  
14 - dom.appendChild( renderer.domElement ); 17 + this.width = 500
  18 + this.height = 500
15 19
16 - this.dom = dom;  
17 - this.canvas = renderer.domElement; 20 + this.load = function (json) {
  21 + var project = json.project
18 22
19 - this.width = 500;  
20 - this.height = 500; 23 + if (project.shadows !== undefined) renderer.shadowMap.enabled = project.shadows
  24 + if (project.shadowType !== undefined) renderer.shadowMap.type = project.shadowType
  25 + if (project.toneMapping !== undefined) renderer.toneMapping = project.toneMapping
  26 + if (project.toneMappingExposure !== undefined) renderer.toneMappingExposure = project.toneMappingExposure
21 27
22 - this.load = function ( json ) { 28 + this.setScene(loader.parse(json.scene))
  29 + this.setCamera(loader.parse(json.camera))
23 30
24 - var project = json.project; 31 + events = {
  32 + init: [],
  33 + start: [],
  34 + stop: [],
  35 + keydown: [],
  36 + keyup: [],
  37 + pointerdown: [],
  38 + pointerup: [],
  39 + pointermove: [],
  40 + update: []
  41 + }
25 42
26 - if ( project.shadows !== undefined ) renderer.shadowMap.enabled = project.shadows;  
27 - if ( project.shadowType !== undefined ) renderer.shadowMap.type = project.shadowType;  
28 - if ( project.toneMapping !== undefined ) renderer.toneMapping = project.toneMapping;  
29 - if ( project.toneMappingExposure !== undefined ) renderer.toneMappingExposure = project.toneMappingExposure; 43 + var scriptWrapParams = 'player,renderer,scene,camera'
  44 + var scriptWrapResultObj = {}
30 45
31 - this.setScene( loader.parse( json.scene ) );  
32 - this.setCamera( loader.parse( json.camera ) ); 46 + for (var eventKey in events) {
  47 + scriptWrapParams += ',' + eventKey
  48 + scriptWrapResultObj[eventKey] = eventKey
  49 + }
33 50
34 - events = {  
35 - init: [],  
36 - start: [],  
37 - stop: [],  
38 - keydown: [],  
39 - keyup: [],  
40 - pointerdown: [],  
41 - pointerup: [],  
42 - pointermove: [],  
43 - update: []  
44 - }; 51 + var scriptWrapResult = JSON.stringify(scriptWrapResultObj).replace(/\"/g, '')
45 52
46 - var scriptWrapParams = 'player,renderer,scene,camera';  
47 - var scriptWrapResultObj = {}; 53 + for (var uuid in json.scripts) {
  54 + var object = scene.getObjectByProperty('uuid', uuid, true)
48 55
49 - for ( var eventKey in events ) { 56 + if (object === undefined) {
  57 + console.warn('APP.Player: Script without object.', uuid)
  58 + continue
  59 + }
50 60
51 - scriptWrapParams += ',' + eventKey;  
52 - scriptWrapResultObj[ eventKey ] = eventKey; 61 + var scripts = json.scripts[uuid]
53 62
54 - } 63 + for (var i = 0; i < scripts.length; i++) {
  64 + var script = scripts[i]
55 65
56 - var scriptWrapResult = JSON.stringify( scriptWrapResultObj ).replace( /\"/g, '' ); 66 + var functions = new Function(scriptWrapParams, script.source + '\nreturn ' + scriptWrapResult + ';').bind(
  67 + object
  68 + )(this, renderer, scene, camera)
57 69
58 - for ( var uuid in json.scripts ) { 70 + for (var name in functions) {
  71 + if (functions[name] === undefined) continue
59 72
60 - var object = scene.getObjectByProperty( 'uuid', uuid, true ); 73 + if (events[name] === undefined) {
  74 + console.warn('APP.Player: Event type not supported (', name, ')')
  75 + continue
  76 + }
61 77
62 - if ( object === undefined ) { 78 + events[name].push(functions[name].bind(object))
  79 + }
  80 + }
  81 + }
63 82
64 - console.warn( 'APP.Player: Script without object.', uuid );  
65 - continue; 83 + dispatch(events.init, arguments)
  84 + }
66 85
67 - } 86 + this.setCamera = function (value) {
  87 + camera = value
  88 + camera.aspect = this.width / this.height
  89 + camera.updateProjectionMatrix()
  90 + }
68 91
69 - var scripts = json.scripts[ uuid ]; 92 + this.setScene = function (value) {
  93 + scene = value
  94 + }
70 95
71 - for ( var i = 0; i < scripts.length; i ++ ) { 96 + this.setPixelRatio = function (pixelRatio) {
  97 + renderer.setPixelRatio(pixelRatio)
  98 + }
72 99
73 - var script = scripts[ i ]; 100 + this.setSize = function (width, height) {
  101 + this.width = width
  102 + this.height = height
74 103
75 - var functions = ( new Function( scriptWrapParams, script.source + '\nreturn ' + scriptWrapResult + ';' ).bind( object ) )( this, renderer, scene, camera ); 104 + if (camera) {
  105 + camera.aspect = this.width / this.height
  106 + camera.updateProjectionMatrix()
  107 + }
76 108
77 - for ( var name in functions ) { 109 + renderer.setSize(width, height)
  110 + }
78 111
79 - if ( functions[ name ] === undefined ) continue; 112 + function dispatch(array, event) {
  113 + for (var i = 0, l = array.length; i < l; i++) {
  114 + array[i](event)
  115 + }
  116 + }
80 117
81 - if ( events[ name ] === undefined ) { 118 + var time, startTime, prevTime
82 119
83 - console.warn( 'APP.Player: Event type not supported (', name, ')' );  
84 - continue; 120 + function animate() {
  121 + time = performance.now()
85 122
86 - } 123 + try {
  124 + dispatch(events.update, { time: time - startTime, delta: time - prevTime })
  125 + } catch (e) {
  126 + console.error(e.message || e, e.stack || '')
  127 + }
87 128
88 - events[ name ].push( functions[ name ].bind( object ) ); 129 + renderer.render(scene, camera)
89 130
90 - } 131 + prevTime = time
  132 + }
91 133
92 - } 134 + this.play = function () {
  135 + startTime = prevTime = performance.now()
93 136
94 - } 137 + document.addEventListener('keydown', onKeyDown)
  138 + document.addEventListener('keyup', onKeyUp)
  139 + document.addEventListener('pointerdown', onPointerDown)
  140 + document.addEventListener('pointerup', onPointerUp)
  141 + document.addEventListener('pointermove', onPointerMove)
95 142
96 - dispatch( events.init, arguments ); 143 + dispatch(events.start, arguments)
97 144
98 - }; 145 + renderer.setAnimationLoop(animate)
  146 + }
99 147
100 - this.setCamera = function ( value ) { 148 + this.stop = function () {
  149 + document.removeEventListener('keydown', onKeyDown)
  150 + document.removeEventListener('keyup', onKeyUp)
  151 + document.removeEventListener('pointerdown', onPointerDown)
  152 + document.removeEventListener('pointerup', onPointerUp)
  153 + document.removeEventListener('pointermove', onPointerMove)
101 154
102 - camera = value;  
103 - camera.aspect = this.width / this.height;  
104 - camera.updateProjectionMatrix(); 155 + dispatch(events.stop, arguments)
105 156
106 - }; 157 + renderer.setAnimationLoop(null)
  158 + }
107 159
108 - this.setScene = function ( value ) { 160 + this.render = function (time) {
  161 + dispatch(events.update, { time: time * 1000, delta: 0 /* TODO */ })
109 162
110 - scene = value; 163 + renderer.render(scene, camera)
  164 + }
111 165
112 - }; 166 + this.dispose = function () {
  167 + renderer.dispose()
113 168
114 - this.setPixelRatio = function ( pixelRatio ) { 169 + camera = undefined
  170 + scene = undefined
  171 + }
115 172
116 - renderer.setPixelRatio( pixelRatio ); 173 + //
117 174
118 - }; 175 + function onKeyDown(event) {
  176 + dispatch(events.keydown, event)
  177 + }
119 178
120 - this.setSize = function ( width, height ) { 179 + function onKeyUp(event) {
  180 + dispatch(events.keyup, event)
  181 + }
121 182
122 - this.width = width;  
123 - this.height = height; 183 + function onPointerDown(event) {
  184 + dispatch(events.pointerdown, event)
  185 + }
124 186
125 - if ( camera ) { 187 + function onPointerUp(event) {
  188 + dispatch(events.pointerup, event)
  189 + }
126 190
127 - camera.aspect = this.width / this.height;  
128 - camera.updateProjectionMatrix(); 191 + function onPointerMove(event) {
  192 + dispatch(events.pointermove, event)
  193 + }
  194 + }
  195 +}
129 196
130 - }  
131 -  
132 - renderer.setSize( width, height );  
133 -  
134 - };  
135 -  
136 - function dispatch( array, event ) {  
137 -  
138 - for ( var i = 0, l = array.length; i < l; i ++ ) {  
139 -  
140 - array[ i ]( event );  
141 -  
142 - }  
143 -  
144 - }  
145 -  
146 - var time, startTime, prevTime;  
147 -  
148 - function animate() {  
149 -  
150 - time = performance.now();  
151 -  
152 - try {  
153 -  
154 - dispatch( events.update, { time: time - startTime, delta: time - prevTime } );  
155 -  
156 - } catch ( e ) {  
157 -  
158 - console.error( ( e.message || e ), ( e.stack || '' ) );  
159 -  
160 - }  
161 -  
162 - renderer.render( scene, camera );  
163 -  
164 - prevTime = time;  
165 -  
166 - }  
167 -  
168 - this.play = function () {  
169 -  
170 - startTime = prevTime = performance.now();  
171 -  
172 - document.addEventListener( 'keydown', onKeyDown );  
173 - document.addEventListener( 'keyup', onKeyUp );  
174 - document.addEventListener( 'pointerdown', onPointerDown );  
175 - document.addEventListener( 'pointerup', onPointerUp );  
176 - document.addEventListener( 'pointermove', onPointerMove );  
177 -  
178 - dispatch( events.start, arguments );  
179 -  
180 - renderer.setAnimationLoop( animate );  
181 -  
182 - };  
183 -  
184 - this.stop = function () {  
185 -  
186 - document.removeEventListener( 'keydown', onKeyDown );  
187 - document.removeEventListener( 'keyup', onKeyUp );  
188 - document.removeEventListener( 'pointerdown', onPointerDown );  
189 - document.removeEventListener( 'pointerup', onPointerUp );  
190 - document.removeEventListener( 'pointermove', onPointerMove );  
191 -  
192 - dispatch( events.stop, arguments );  
193 -  
194 - renderer.setAnimationLoop( null );  
195 -  
196 - };  
197 -  
198 - this.render = function ( time ) {  
199 -  
200 - dispatch( events.update, { time: time * 1000, delta: 0 /* TODO */ } );  
201 -  
202 - renderer.render( scene, camera );  
203 -  
204 - };  
205 -  
206 - this.dispose = function () {  
207 -  
208 - renderer.dispose();  
209 -  
210 - camera = undefined;  
211 - scene = undefined;  
212 -  
213 - };  
214 -  
215 - //  
216 -  
217 - function onKeyDown( event ) {  
218 -  
219 - dispatch( events.keydown, event );  
220 -  
221 - }  
222 -  
223 - function onKeyUp( event ) {  
224 -  
225 - dispatch( events.keyup, event );  
226 -  
227 - }  
228 -  
229 - function onPointerDown( event ) {  
230 -  
231 - dispatch( events.pointerdown, event );  
232 -  
233 - }  
234 -  
235 - function onPointerUp( event ) {  
236 -  
237 - dispatch( events.pointerup, event );  
238 -  
239 - }  
240 -  
241 - function onPointerMove( event ) {  
242 -  
243 - dispatch( events.pointermove, event );  
244 -  
245 - }  
246 -  
247 - }  
248 -  
249 -};  
250 -  
251 -export { APP }; 197 +export { APP }
1 -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).axios=t()}(this,(function(){"use strict";function e(e){var r,n;function o(r,n){try{var a=e[r](n),u=a.value,s=u instanceof t;Promise.resolve(s?u.v:u).then((function(t){if(s){var n="return"===r?"return":"next";if(!u.k||t.done)return o(n,t);t=e[n](t).value}i(a.done?"return":"normal",t)}),(function(e){o("throw",e)}))}catch(e){i("throw",e)}}function i(e,t){switch(e){case"return":r.resolve({value:t,done:!0});break;case"throw":r.reject(t);break;default:r.resolve({value:t,done:!1})}(r=r.next)?o(r.key,r.arg):n=null}this._invoke=function(e,t){return new Promise((function(i,a){var u={key:e,arg:t,resolve:i,reject:a,next:null};n?n=n.next=u:(r=n=u,o(e,t))}))},"function"!=typeof e.return&&(this.return=void 0)}function t(e,t){this.v=e,this.k=t}function r(e){var r={},n=!1;function o(r,o){return n=!0,o=new Promise((function(t){t(e[r](o))})),{done:!1,value:new t(o,1)}}return r["undefined"!=typeof Symbol&&Symbol.iterator||"@@iterator"]=function(){return this},r.next=function(e){return n?(n=!1,e):o("next",e)},"function"==typeof e.throw&&(r.throw=function(e){if(n)throw n=!1,e;return o("throw",e)}),"function"==typeof e.return&&(r.return=function(e){return n?(n=!1,e):o("return",e)}),r}function n(e){var t,r,n,i=2;for("undefined"!=typeof Symbol&&(r=Symbol.asyncIterator,n=Symbol.iterator);i--;){if(r&&null!=(t=e[r]))return t.call(e);if(n&&null!=(t=e[n]))return new o(t.call(e));r="@@asyncIterator",n="@@iterator"}throw new TypeError("Object is not async iterable")}function o(e){function t(e){if(Object(e)!==e)return Promise.reject(new TypeError(e+" is not an object."));var t=e.done;return Promise.resolve(e.value).then((function(e){return{value:e,done:t}}))}return o=function(e){this.s=e,this.n=e.next},o.prototype={s:null,n:null,next:function(){return t(this.n.apply(this.s,arguments))},return:function(e){var r=this.s.return;return void 0===r?Promise.resolve({value:e,done:!0}):t(r.apply(this.s,arguments))},throw:function(e){var r=this.s.return;return void 0===r?Promise.reject(e):t(r.apply(this.s,arguments))}},new o(e)}function i(e){return new t(e,0)}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function u(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){m(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(){s=function(){return t};var e,t={},r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(e,t,r){e[t]=r.value},i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",u=i.asyncIterator||"@@asyncIterator",c=i.toStringTag||"@@toStringTag";function f(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{f({},"")}catch(e){f=function(e,t,r){return e[t]=r}}function l(e,t,r,n){var i=t&&t.prototype instanceof m?t:m,a=Object.create(i.prototype),u=new P(n||[]);return o(a,"_invoke",{value:T(e,r,u)}),a}function h(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}t.wrap=l;var p="suspendedStart",d="executing",v="completed",y={};function m(){}function b(){}function g(){}var w={};f(w,a,(function(){return this}));var E=Object.getPrototypeOf,O=E&&E(E(L([])));O&&O!==r&&n.call(O,a)&&(w=O);var S=g.prototype=m.prototype=Object.create(w);function x(e){["next","throw","return"].forEach((function(t){f(e,t,(function(e){return this._invoke(t,e)}))}))}function R(e,t){function r(o,i,a,u){var s=h(e[o],e,i);if("throw"!==s.type){var c=s.arg,f=c.value;return f&&"object"==typeof f&&n.call(f,"__await")?t.resolve(f.__await).then((function(e){r("next",e,a,u)}),(function(e){r("throw",e,a,u)})):t.resolve(f).then((function(e){c.value=e,a(c)}),(function(e){return r("throw",e,a,u)}))}u(s.arg)}var i;o(this,"_invoke",{value:function(e,n){function o(){return new t((function(t,o){r(e,n,t,o)}))}return i=i?i.then(o,o):o()}})}function T(t,r,n){var o=p;return function(i,a){if(o===d)throw new Error("Generator is already running");if(o===v){if("throw"===i)throw a;return{value:e,done:!0}}for(n.method=i,n.arg=a;;){var u=n.delegate;if(u){var s=k(u,n);if(s){if(s===y)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===p)throw o=v,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=h(t,r,n);if("normal"===c.type){if(o=n.done?v:"suspendedYield",c.arg===y)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=v,n.method="throw",n.arg=c.arg)}}}function k(t,r){var n=r.method,o=t.iterator[n];if(o===e)return r.delegate=null,"throw"===n&&t.iterator.return&&(r.method="return",r.arg=e,k(t,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),y;var i=h(o,t.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,y;var a=i.arg;return a?a.done?(r[t.resultName]=a.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=e),r.delegate=null,y):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,y)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function j(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function P(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function L(t){if(t||""===t){var r=t[a];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var o=-1,i=function r(){for(;++o<t.length;)if(n.call(t,o))return r.value=t[o],r.done=!1,r;return r.value=e,r.done=!0,r};return i.next=i}}throw new TypeError(typeof t+" is not iterable")}return b.prototype=g,o(S,"constructor",{value:g,configurable:!0}),o(g,"constructor",{value:b,configurable:!0}),b.displayName=f(g,c,"GeneratorFunction"),t.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===b||"GeneratorFunction"===(t.displayName||t.name))},t.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,g):(e.__proto__=g,f(e,c,"GeneratorFunction")),e.prototype=Object.create(S),e},t.awrap=function(e){return{__await:e}},x(R.prototype),f(R.prototype,u,(function(){return this})),t.AsyncIterator=R,t.async=function(e,r,n,o,i){void 0===i&&(i=Promise);var a=new R(l(e,r,n,o),i);return t.isGeneratorFunction(r)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},x(S),f(S,c,"Generator"),f(S,a,(function(){return this})),f(S,"toString",(function(){return"[object Generator]"})),t.keys=function(e){var t=Object(e),r=[];for(var n in t)r.push(n);return r.reverse(),function e(){for(;r.length;){var n=r.pop();if(n in t)return e.value=n,e.done=!1,e}return e.done=!0,e}},t.values=L,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=e)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function o(n,o){return u.type="throw",u.arg=t,r.next=n,o&&(r.method="next",r.arg=e),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],u=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var s=n.call(a,"catchLoc"),c=n.call(a,"finallyLoc");if(s&&c){if(this.prev<a.catchLoc)return o(a.catchLoc,!0);if(this.prev<a.finallyLoc)return o(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return o(a.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return o(a.finallyLoc)}}}},abrupt:function(e,t){for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,y):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),y},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),j(r),y}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;j(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:L(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),y}},t}function c(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}function f(e){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(e)}function l(t){return function(){return new e(t.apply(this,arguments))}}function h(e,t,r,n,o,i,a){try{var u=e[i](a),s=u.value}catch(e){return void r(e)}u.done?t(s):Promise.resolve(s).then(n,o)}function p(e){return function(){var t=this,r=arguments;return new Promise((function(n,o){var i=e.apply(t,r);function a(e){h(i,n,o,a,u,"next",e)}function u(e){h(i,n,o,a,u,"throw",e)}a(void 0)}))}}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,c(n.key),n)}}function y(e,t,r){return t&&v(e.prototype,t),r&&v(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function m(e,t,r){return(t=c(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function b(e,t){return w(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,u=[],s=!0,c=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(u.push(n.value),u.length!==t);s=!0);}catch(e){c=!0,o=e}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return u}}(e,t)||O(e,t)||x()}function g(e){return function(e){if(Array.isArray(e))return S(e)}(e)||E(e)||O(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function w(e){if(Array.isArray(e))return e}function E(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function O(e,t){if(e){if("string"==typeof e)return S(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?S(e,t):void 0}}function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function x(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function R(e,t){return function(){return e.apply(t,arguments)}}e.prototype["function"==typeof Symbol&&Symbol.asyncIterator||"@@asyncIterator"]=function(){return this},e.prototype.next=function(e){return this._invoke("next",e)},e.prototype.throw=function(e){return this._invoke("throw",e)},e.prototype.return=function(e){return this._invoke("return",e)};var T,k=Object.prototype.toString,A=Object.getPrototypeOf,j=(T=Object.create(null),function(e){var t=k.call(e);return T[t]||(T[t]=t.slice(8,-1).toLowerCase())}),P=function(e){return e=e.toLowerCase(),function(t){return j(t)===e}},L=function(e){return function(t){return f(t)===e}},N=Array.isArray,_=L("undefined");var C=P("ArrayBuffer");var F=L("string"),U=L("function"),B=L("number"),D=function(e){return null!==e&&"object"===f(e)},I=function(e){if("object"!==j(e))return!1;var t=A(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},q=P("Date"),M=P("File"),z=P("Blob"),H=P("FileList"),J=P("URLSearchParams"),W=b(["ReadableStream","Request","Response","Headers"].map(P),4),G=W[0],K=W[1],V=W[2],X=W[3];function $(e,t){var r,n,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=o.allOwnKeys,a=void 0!==i&&i;if(null!=e)if("object"!==f(e)&&(e=[e]),N(e))for(r=0,n=e.length;r<n;r++)t.call(null,e[r],r,e);else{var u,s=a?Object.getOwnPropertyNames(e):Object.keys(e),c=s.length;for(r=0;r<c;r++)u=s[r],t.call(null,e[u],u,e)}}function Y(e,t){t=t.toLowerCase();for(var r,n=Object.keys(e),o=n.length;o-- >0;)if(t===(r=n[o]).toLowerCase())return r;return null}var Q="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,Z=function(e){return!_(e)&&e!==Q};var ee,te=(ee="undefined"!=typeof Uint8Array&&A(Uint8Array),function(e){return ee&&e instanceof ee}),re=P("HTMLFormElement"),ne=function(e){var t=Object.prototype.hasOwnProperty;return function(e,r){return t.call(e,r)}}(),oe=P("RegExp"),ie=function(e,t){var r=Object.getOwnPropertyDescriptors(e),n={};$(r,(function(r,o){var i;!1!==(i=t(r,o,e))&&(n[o]=i||r)})),Object.defineProperties(e,n)},ae="abcdefghijklmnopqrstuvwxyz",ue="0123456789",se={DIGIT:ue,ALPHA:ae,ALPHA_DIGIT:ae+ae.toUpperCase()+ue};var ce,fe,le,he,pe=P("AsyncFunction"),de=(ce="function"==typeof setImmediate,fe=U(Q.postMessage),ce?setImmediate:fe?(le="axios@".concat(Math.random()),he=[],Q.addEventListener("message",(function(e){var t=e.source,r=e.data;t===Q&&r===le&&he.length&&he.shift()()}),!1),function(e){he.push(e),Q.postMessage(le,"*")}):function(e){return setTimeout(e)}),ve="undefined"!=typeof queueMicrotask?queueMicrotask.bind(Q):"undefined"!=typeof process&&process.nextTick||de,ye={isArray:N,isArrayBuffer:C,isBuffer:function(e){return null!==e&&!_(e)&&null!==e.constructor&&!_(e.constructor)&&U(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:function(e){var t;return e&&("function"==typeof FormData&&e instanceof FormData||U(e.append)&&("formdata"===(t=j(e))||"object"===t&&U(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&C(e.buffer)},isString:F,isNumber:B,isBoolean:function(e){return!0===e||!1===e},isObject:D,isPlainObject:I,isReadableStream:G,isRequest:K,isResponse:V,isHeaders:X,isUndefined:_,isDate:q,isFile:M,isBlob:z,isRegExp:oe,isFunction:U,isStream:function(e){return D(e)&&U(e.pipe)},isURLSearchParams:J,isTypedArray:te,isFileList:H,forEach:$,merge:function e(){for(var t=Z(this)&&this||{},r=t.caseless,n={},o=function(t,o){var i=r&&Y(n,o)||o;I(n[i])&&I(t)?n[i]=e(n[i],t):I(t)?n[i]=e({},t):N(t)?n[i]=t.slice():n[i]=t},i=0,a=arguments.length;i<a;i++)arguments[i]&&$(arguments[i],o);return n},extend:function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=n.allOwnKeys;return $(t,(function(t,n){r&&U(t)?e[n]=R(t,r):e[n]=t}),{allOwnKeys:o}),e},trim:function(e){return e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},stripBOM:function(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e},inherits:function(e,t,r,n){e.prototype=Object.create(t.prototype,n),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),r&&Object.assign(e.prototype,r)},toFlatObject:function(e,t,r,n){var o,i,a,u={};if(t=t||{},null==e)return t;do{for(i=(o=Object.getOwnPropertyNames(e)).length;i-- >0;)a=o[i],n&&!n(a,e,t)||u[a]||(t[a]=e[a],u[a]=!0);e=!1!==r&&A(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},kindOf:j,kindOfTest:P,endsWith:function(e,t,r){e=String(e),(void 0===r||r>e.length)&&(r=e.length),r-=t.length;var n=e.indexOf(t,r);return-1!==n&&n===r},toArray:function(e){if(!e)return null;if(N(e))return e;var t=e.length;if(!B(t))return null;for(var r=new Array(t);t-- >0;)r[t]=e[t];return r},forEachEntry:function(e,t){for(var r,n=(e&&e[Symbol.iterator]).call(e);(r=n.next())&&!r.done;){var o=r.value;t.call(e,o[0],o[1])}},matchAll:function(e,t){for(var r,n=[];null!==(r=e.exec(t));)n.push(r);return n},isHTMLForm:re,hasOwnProperty:ne,hasOwnProp:ne,reduceDescriptors:ie,freezeMethods:function(e){ie(e,(function(t,r){if(U(e)&&-1!==["arguments","caller","callee"].indexOf(r))return!1;var n=e[r];U(n)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=function(){throw Error("Can not rewrite read-only method '"+r+"'")}))}))},toObjectSet:function(e,t){var r={},n=function(e){e.forEach((function(e){r[e]=!0}))};return N(e)?n(e):n(String(e).split(t)),r},toCamelCase:function(e){return e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))},noop:function(){},toFiniteNumber:function(e,t){return null!=e&&Number.isFinite(e=+e)?e:t},findKey:Y,global:Q,isContextDefined:Z,ALPHABET:se,generateString:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:16,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:se.ALPHA_DIGIT,r="",n=t.length;e--;)r+=t[Math.random()*n|0];return r},isSpecCompliantForm:function(e){return!!(e&&U(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:function(e){var t=new Array(10);return function e(r,n){if(D(r)){if(t.indexOf(r)>=0)return;if(!("toJSON"in r)){t[n]=r;var o=N(r)?[]:{};return $(r,(function(t,r){var i=e(t,n+1);!_(i)&&(o[r]=i)})),t[n]=void 0,o}}return r}(e,0)},isAsyncFn:pe,isThenable:function(e){return e&&(D(e)||U(e))&&U(e.then)&&U(e.catch)},setImmediate:de,asap:ve};function me(e,t,r,n,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),r&&(this.config=r),n&&(this.request=n),o&&(this.response=o,this.status=o.status?o.status:null)}ye.inherits(me,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ye.toJSONObject(this.config),code:this.code,status:this.status}}});var be=me.prototype,ge={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((function(e){ge[e]={value:e}})),Object.defineProperties(me,ge),Object.defineProperty(be,"isAxiosError",{value:!0}),me.from=function(e,t,r,n,o,i){var a=Object.create(be);return ye.toFlatObject(e,a,(function(e){return e!==Error.prototype}),(function(e){return"isAxiosError"!==e})),me.call(a,e.message,t,r,n,o),a.cause=e,a.name=e.name,i&&Object.assign(a,i),a};function we(e){return ye.isPlainObject(e)||ye.isArray(e)}function Ee(e){return ye.endsWith(e,"[]")?e.slice(0,-2):e}function Oe(e,t,r){return e?e.concat(t).map((function(e,t){return e=Ee(e),!r&&t?"["+e+"]":e})).join(r?".":""):t}var Se=ye.toFlatObject(ye,{},null,(function(e){return/^is[A-Z]/.test(e)}));function xe(e,t,r){if(!ye.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;var n=(r=ye.toFlatObject(r,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!ye.isUndefined(t[e])}))).metaTokens,o=r.visitor||c,i=r.dots,a=r.indexes,u=(r.Blob||"undefined"!=typeof Blob&&Blob)&&ye.isSpecCompliantForm(t);if(!ye.isFunction(o))throw new TypeError("visitor must be a function");function s(e){if(null===e)return"";if(ye.isDate(e))return e.toISOString();if(!u&&ye.isBlob(e))throw new me("Blob is not supported. Use a Buffer instead.");return ye.isArrayBuffer(e)||ye.isTypedArray(e)?u&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function c(e,r,o){var u=e;if(e&&!o&&"object"===f(e))if(ye.endsWith(r,"{}"))r=n?r:r.slice(0,-2),e=JSON.stringify(e);else if(ye.isArray(e)&&function(e){return ye.isArray(e)&&!e.some(we)}(e)||(ye.isFileList(e)||ye.endsWith(r,"[]"))&&(u=ye.toArray(e)))return r=Ee(r),u.forEach((function(e,n){!ye.isUndefined(e)&&null!==e&&t.append(!0===a?Oe([r],n,i):null===a?r:r+"[]",s(e))})),!1;return!!we(e)||(t.append(Oe(o,r,i),s(e)),!1)}var l=[],h=Object.assign(Se,{defaultVisitor:c,convertValue:s,isVisitable:we});if(!ye.isObject(e))throw new TypeError("data must be an object");return function e(r,n){if(!ye.isUndefined(r)){if(-1!==l.indexOf(r))throw Error("Circular reference detected in "+n.join("."));l.push(r),ye.forEach(r,(function(r,i){!0===(!(ye.isUndefined(r)||null===r)&&o.call(t,r,ye.isString(i)?i.trim():i,n,h))&&e(r,n?n.concat(i):[i])})),l.pop()}}(e),t}function Re(e){var t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function Te(e,t){this._pairs=[],e&&xe(e,this,t)}var ke=Te.prototype;function Ae(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function je(e,t,r){if(!t)return e;var n,o=r&&r.encode||Ae,i=r&&r.serialize;if(n=i?i(t,r):ye.isURLSearchParams(t)?t.toString():new Te(t,r).toString(o)){var a=e.indexOf("#");-1!==a&&(e=e.slice(0,a)),e+=(-1===e.indexOf("?")?"?":"&")+n}return e}ke.append=function(e,t){this._pairs.push([e,t])},ke.toString=function(e){var t=e?function(t){return e.call(this,t,Re)}:Re;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};var Pe=function(){function e(){d(this,e),this.handlers=[]}return y(e,[{key:"use",value:function(e,t,r){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!r&&r.synchronous,runWhen:r?r.runWhen:null}),this.handlers.length-1}},{key:"eject",value:function(e){this.handlers[e]&&(this.handlers[e]=null)}},{key:"clear",value:function(){this.handlers&&(this.handlers=[])}},{key:"forEach",value:function(e){ye.forEach(this.handlers,(function(t){null!==t&&e(t)}))}}]),e}(),Le={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Ne={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:Te,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},_e="undefined"!=typeof window&&"undefined"!=typeof document,Ce="object"===("undefined"==typeof navigator?"undefined":f(navigator))&&navigator||void 0,Fe=_e&&(!Ce||["ReactNative","NativeScript","NS"].indexOf(Ce.product)<0),Ue="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,Be=_e&&window.location.href||"http://localhost",De=u(u({},Object.freeze({__proto__:null,hasBrowserEnv:_e,hasStandardBrowserWebWorkerEnv:Ue,hasStandardBrowserEnv:Fe,navigator:Ce,origin:Be})),Ne);function Ie(e){function t(e,r,n,o){var i=e[o++];if("__proto__"===i)return!0;var a=Number.isFinite(+i),u=o>=e.length;return i=!i&&ye.isArray(n)?n.length:i,u?(ye.hasOwnProp(n,i)?n[i]=[n[i],r]:n[i]=r,!a):(n[i]&&ye.isObject(n[i])||(n[i]=[]),t(e,r,n[i],o)&&ye.isArray(n[i])&&(n[i]=function(e){var t,r,n={},o=Object.keys(e),i=o.length;for(t=0;t<i;t++)n[r=o[t]]=e[r];return n}(n[i])),!a)}if(ye.isFormData(e)&&ye.isFunction(e.entries)){var r={};return ye.forEachEntry(e,(function(e,n){t(function(e){return ye.matchAll(/\w+|\[(\w*)]/g,e).map((function(e){return"[]"===e[0]?"":e[1]||e[0]}))}(e),n,r,0)})),r}return null}var qe={transitional:Le,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){var r,n=t.getContentType()||"",o=n.indexOf("application/json")>-1,i=ye.isObject(e);if(i&&ye.isHTMLForm(e)&&(e=new FormData(e)),ye.isFormData(e))return o?JSON.stringify(Ie(e)):e;if(ye.isArrayBuffer(e)||ye.isBuffer(e)||ye.isStream(e)||ye.isFile(e)||ye.isBlob(e)||ye.isReadableStream(e))return e;if(ye.isArrayBufferView(e))return e.buffer;if(ye.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return xe(e,new De.classes.URLSearchParams,Object.assign({visitor:function(e,t,r,n){return De.isNode&&ye.isBuffer(e)?(this.append(t,e.toString("base64")),!1):n.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((r=ye.isFileList(e))||n.indexOf("multipart/form-data")>-1){var a=this.env&&this.env.FormData;return xe(r?{"files[]":e}:e,a&&new a,this.formSerializer)}}return i||o?(t.setContentType("application/json",!1),function(e,t,r){if(ye.isString(e))try{return(t||JSON.parse)(e),ye.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(r||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){var t=this.transitional||qe.transitional,r=t&&t.forcedJSONParsing,n="json"===this.responseType;if(ye.isResponse(e)||ye.isReadableStream(e))return e;if(e&&ye.isString(e)&&(r&&!this.responseType||n)){var o=!(t&&t.silentJSONParsing)&&n;try{return JSON.parse(e)}catch(e){if(o){if("SyntaxError"===e.name)throw me.from(e,me.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:De.classes.FormData,Blob:De.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};ye.forEach(["delete","get","head","post","put","patch"],(function(e){qe.headers[e]={}}));var Me=qe,ze=ye.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),He=Symbol("internals");function Je(e){return e&&String(e).trim().toLowerCase()}function We(e){return!1===e||null==e?e:ye.isArray(e)?e.map(We):String(e)}function Ge(e,t,r,n,o){return ye.isFunction(n)?n.call(this,t,r):(o&&(t=r),ye.isString(t)?ye.isString(n)?-1!==t.indexOf(n):ye.isRegExp(n)?n.test(t):void 0:void 0)}var Ke=function(e,t){function r(e){d(this,r),e&&this.set(e)}return y(r,[{key:"set",value:function(e,t,r){var n=this;function o(e,t,r){var o=Je(t);if(!o)throw new Error("header name must be a non-empty string");var i=ye.findKey(n,o);(!i||void 0===n[i]||!0===r||void 0===r&&!1!==n[i])&&(n[i||t]=We(e))}var i=function(e,t){return ye.forEach(e,(function(e,r){return o(e,r,t)}))};if(ye.isPlainObject(e)||e instanceof this.constructor)i(e,t);else if(ye.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))i(function(e){var t,r,n,o={};return e&&e.split("\n").forEach((function(e){n=e.indexOf(":"),t=e.substring(0,n).trim().toLowerCase(),r=e.substring(n+1).trim(),!t||o[t]&&ze[t]||("set-cookie"===t?o[t]?o[t].push(r):o[t]=[r]:o[t]=o[t]?o[t]+", "+r:r)})),o}(e),t);else if(ye.isHeaders(e)){var a,u=function(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=O(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return a=e.done,e},e:function(e){u=!0,i=e},f:function(){try{a||null==r.return||r.return()}finally{if(u)throw i}}}}(e.entries());try{for(u.s();!(a=u.n()).done;){var s=b(a.value,2),c=s[0];o(s[1],c,r)}}catch(e){u.e(e)}finally{u.f()}}else null!=e&&o(t,e,r);return this}},{key:"get",value:function(e,t){if(e=Je(e)){var r=ye.findKey(this,e);if(r){var n=this[r];if(!t)return n;if(!0===t)return function(e){for(var t,r=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;t=n.exec(e);)r[t[1]]=t[2];return r}(n);if(ye.isFunction(t))return t.call(this,n,r);if(ye.isRegExp(t))return t.exec(n);throw new TypeError("parser must be boolean|regexp|function")}}}},{key:"has",value:function(e,t){if(e=Je(e)){var r=ye.findKey(this,e);return!(!r||void 0===this[r]||t&&!Ge(0,this[r],r,t))}return!1}},{key:"delete",value:function(e,t){var r=this,n=!1;function o(e){if(e=Je(e)){var o=ye.findKey(r,e);!o||t&&!Ge(0,r[o],o,t)||(delete r[o],n=!0)}}return ye.isArray(e)?e.forEach(o):o(e),n}},{key:"clear",value:function(e){for(var t=Object.keys(this),r=t.length,n=!1;r--;){var o=t[r];e&&!Ge(0,this[o],o,e,!0)||(delete this[o],n=!0)}return n}},{key:"normalize",value:function(e){var t=this,r={};return ye.forEach(this,(function(n,o){var i=ye.findKey(r,o);if(i)return t[i]=We(n),void delete t[o];var a=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))}(o):String(o).trim();a!==o&&delete t[o],t[a]=We(n),r[a]=!0})),this}},{key:"concat",value:function(){for(var e,t=arguments.length,r=new Array(t),n=0;n<t;n++)r[n]=arguments[n];return(e=this.constructor).concat.apply(e,[this].concat(r))}},{key:"toJSON",value:function(e){var t=Object.create(null);return ye.forEach(this,(function(r,n){null!=r&&!1!==r&&(t[n]=e&&ye.isArray(r)?r.join(", "):r)})),t}},{key:Symbol.iterator,value:function(){return Object.entries(this.toJSON())[Symbol.iterator]()}},{key:"toString",value:function(){return Object.entries(this.toJSON()).map((function(e){var t=b(e,2);return t[0]+": "+t[1]})).join("\n")}},{key:Symbol.toStringTag,get:function(){return"AxiosHeaders"}}],[{key:"from",value:function(e){return e instanceof this?e:new this(e)}},{key:"concat",value:function(e){for(var t=new this(e),r=arguments.length,n=new Array(r>1?r-1:0),o=1;o<r;o++)n[o-1]=arguments[o];return n.forEach((function(e){return t.set(e)})),t}},{key:"accessor",value:function(e){var t=(this[He]=this[He]={accessors:{}}).accessors,r=this.prototype;function n(e){var n=Je(e);t[n]||(!function(e,t){var r=ye.toCamelCase(" "+t);["get","set","has"].forEach((function(n){Object.defineProperty(e,n+r,{value:function(e,r,o){return this[n].call(this,t,e,r,o)},configurable:!0})}))}(r,e),t[n]=!0)}return ye.isArray(e)?e.forEach(n):n(e),this}}]),r}();Ke.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),ye.reduceDescriptors(Ke.prototype,(function(e,t){var r=e.value,n=t[0].toUpperCase()+t.slice(1);return{get:function(){return r},set:function(e){this[n]=e}}})),ye.freezeMethods(Ke);var Ve=Ke;function Xe(e,t){var r=this||Me,n=t||r,o=Ve.from(n.headers),i=n.data;return ye.forEach(e,(function(e){i=e.call(r,i,o.normalize(),t?t.status:void 0)})),o.normalize(),i}function $e(e){return!(!e||!e.__CANCEL__)}function Ye(e,t,r){me.call(this,null==e?"canceled":e,me.ERR_CANCELED,t,r),this.name="CanceledError"}function Qe(e,t,r){var n=r.config.validateStatus;r.status&&n&&!n(r.status)?t(new me("Request failed with status code "+r.status,[me.ERR_BAD_REQUEST,me.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r)):e(r)}function Ze(e,t){e=e||10;var r,n=new Array(e),o=new Array(e),i=0,a=0;return t=void 0!==t?t:1e3,function(u){var s=Date.now(),c=o[a];r||(r=s),n[i]=u,o[i]=s;for(var f=a,l=0;f!==i;)l+=n[f++],f%=e;if((i=(i+1)%e)===a&&(a=(a+1)%e),!(s-r<t)){var h=c&&s-c;return h?Math.round(1e3*l/h):void 0}}}function et(e,t){var r,n,o=0,i=1e3/t,a=function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Date.now();o=i,r=null,n&&(clearTimeout(n),n=null),e.apply(null,t)};return[function(){for(var e=Date.now(),t=e-o,u=arguments.length,s=new Array(u),c=0;c<u;c++)s[c]=arguments[c];t>=i?a(s,e):(r=s,n||(n=setTimeout((function(){n=null,a(r)}),i-t)))},function(){return r&&a(r)}]}ye.inherits(Ye,me,{__CANCEL__:!0});var tt=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3,n=0,o=Ze(50,250);return et((function(r){var i=r.loaded,a=r.lengthComputable?r.total:void 0,u=i-n,s=o(u);n=i;var c=m({loaded:i,total:a,progress:a?i/a:void 0,bytes:u,rate:s||void 0,estimated:s&&a&&i<=a?(a-i)/s:void 0,event:r,lengthComputable:null!=a},t?"download":"upload",!0);e(c)}),r)},rt=function(e,t){var r=null!=e;return[function(n){return t[0]({lengthComputable:r,total:e,loaded:n})},t[1]]},nt=function(e){return function(){for(var t=arguments.length,r=new Array(t),n=0;n<t;n++)r[n]=arguments[n];return ye.asap((function(){return e.apply(void 0,r)}))}},ot=De.hasStandardBrowserEnv?function(){var e,t=De.navigator&&/(msie|trident)/i.test(De.navigator.userAgent),r=document.createElement("a");function n(e){var n=e;return t&&(r.setAttribute("href",n),n=r.href),r.setAttribute("href",n),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:r.port,pathname:"/"===r.pathname.charAt(0)?r.pathname:"/"+r.pathname}}return e=n(window.location.href),function(t){var r=ye.isString(t)?n(t):t;return r.protocol===e.protocol&&r.host===e.host}}():function(){return!0},it=De.hasStandardBrowserEnv?{write:function(e,t,r,n,o,i){var a=[e+"="+encodeURIComponent(t)];ye.isNumber(r)&&a.push("expires="+new Date(r).toGMTString()),ye.isString(n)&&a.push("path="+n),ye.isString(o)&&a.push("domain="+o),!0===i&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}};function at(e,t){return e&&!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}var ut=function(e){return e instanceof Ve?u({},e):e};function st(e,t){t=t||{};var r={};function n(e,t,r){return ye.isPlainObject(e)&&ye.isPlainObject(t)?ye.merge.call({caseless:r},e,t):ye.isPlainObject(t)?ye.merge({},t):ye.isArray(t)?t.slice():t}function o(e,t,r){return ye.isUndefined(t)?ye.isUndefined(e)?void 0:n(void 0,e,r):n(e,t,r)}function i(e,t){if(!ye.isUndefined(t))return n(void 0,t)}function a(e,t){return ye.isUndefined(t)?ye.isUndefined(e)?void 0:n(void 0,e):n(void 0,t)}function u(r,o,i){return i in t?n(r,o):i in e?n(void 0,r):void 0}var s={url:i,method:i,data:i,baseURL:a,transformRequest:a,transformResponse:a,paramsSerializer:a,timeout:a,timeoutMessage:a,withCredentials:a,withXSRFToken:a,adapter:a,responseType:a,xsrfCookieName:a,xsrfHeaderName:a,onUploadProgress:a,onDownloadProgress:a,decompress:a,maxContentLength:a,maxBodyLength:a,beforeRedirect:a,transport:a,httpAgent:a,httpsAgent:a,cancelToken:a,socketPath:a,responseEncoding:a,validateStatus:u,headers:function(e,t){return o(ut(e),ut(t),!0)}};return ye.forEach(Object.keys(Object.assign({},e,t)),(function(n){var i=s[n]||o,a=i(e[n],t[n],n);ye.isUndefined(a)&&i!==u||(r[n]=a)})),r}var ct,ft,lt=function(e){var t,r,n=st({},e),o=n.data,i=n.withXSRFToken,a=n.xsrfHeaderName,u=n.xsrfCookieName,s=n.headers,c=n.auth;if(n.headers=s=Ve.from(s),n.url=je(at(n.baseURL,n.url),e.params,e.paramsSerializer),c&&s.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),ye.isFormData(o))if(De.hasStandardBrowserEnv||De.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if(!1!==(t=s.getContentType())){var f=t?t.split(";").map((function(e){return e.trim()})).filter(Boolean):[],l=w(r=f)||E(r)||O(r)||x(),h=l[0],p=l.slice(1);s.setContentType([h||"multipart/form-data"].concat(g(p)).join("; "))}if(De.hasStandardBrowserEnv&&(i&&ye.isFunction(i)&&(i=i(n)),i||!1!==i&&ot(n.url))){var d=a&&u&&it.read(u);d&&s.set(a,d)}return n},ht="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,r){var n,o,i,a,u,s=lt(e),c=s.data,f=Ve.from(s.headers).normalize(),l=s.responseType,h=s.onUploadProgress,p=s.onDownloadProgress;function d(){a&&a(),u&&u(),s.cancelToken&&s.cancelToken.unsubscribe(n),s.signal&&s.signal.removeEventListener("abort",n)}var v=new XMLHttpRequest;function y(){if(v){var n=Ve.from("getAllResponseHeaders"in v&&v.getAllResponseHeaders());Qe((function(e){t(e),d()}),(function(e){r(e),d()}),{data:l&&"text"!==l&&"json"!==l?v.response:v.responseText,status:v.status,statusText:v.statusText,headers:n,config:e,request:v}),v=null}}if(v.open(s.method.toUpperCase(),s.url,!0),v.timeout=s.timeout,"onloadend"in v?v.onloadend=y:v.onreadystatechange=function(){v&&4===v.readyState&&(0!==v.status||v.responseURL&&0===v.responseURL.indexOf("file:"))&&setTimeout(y)},v.onabort=function(){v&&(r(new me("Request aborted",me.ECONNABORTED,e,v)),v=null)},v.onerror=function(){r(new me("Network Error",me.ERR_NETWORK,e,v)),v=null},v.ontimeout=function(){var t=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded",n=s.transitional||Le;s.timeoutErrorMessage&&(t=s.timeoutErrorMessage),r(new me(t,n.clarifyTimeoutError?me.ETIMEDOUT:me.ECONNABORTED,e,v)),v=null},void 0===c&&f.setContentType(null),"setRequestHeader"in v&&ye.forEach(f.toJSON(),(function(e,t){v.setRequestHeader(t,e)})),ye.isUndefined(s.withCredentials)||(v.withCredentials=!!s.withCredentials),l&&"json"!==l&&(v.responseType=s.responseType),p){var m=b(tt(p,!0),2);i=m[0],u=m[1],v.addEventListener("progress",i)}if(h&&v.upload){var g=b(tt(h),2);o=g[0],a=g[1],v.upload.addEventListener("progress",o),v.upload.addEventListener("loadend",a)}(s.cancelToken||s.signal)&&(n=function(t){v&&(r(!t||t.type?new Ye(null,e,v):t),v.abort(),v=null)},s.cancelToken&&s.cancelToken.subscribe(n),s.signal&&(s.signal.aborted?n():s.signal.addEventListener("abort",n)));var w,E,O=(w=s.url,(E=/^([-+\w]{1,25})(:?\/\/|:)/.exec(w))&&E[1]||"");O&&-1===De.protocols.indexOf(O)?r(new me("Unsupported protocol "+O+":",me.ERR_BAD_REQUEST,e)):v.send(c||null)}))},pt=function(e,t){var r=(e=e?e.filter(Boolean):[]).length;if(t||r){var n,o=new AbortController,i=function(e){if(!n){n=!0,u();var t=e instanceof Error?e:this.reason;o.abort(t instanceof me?t:new Ye(t instanceof Error?t.message:t))}},a=t&&setTimeout((function(){a=null,i(new me("timeout ".concat(t," of ms exceeded"),me.ETIMEDOUT))}),t),u=function(){e&&(a&&clearTimeout(a),a=null,e.forEach((function(e){e.unsubscribe?e.unsubscribe(i):e.removeEventListener("abort",i)})),e=null)};e.forEach((function(e){return e.addEventListener("abort",i)}));var s=o.signal;return s.unsubscribe=function(){return ye.asap(u)},s}},dt=s().mark((function e(t,r){var n,o,i;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n=t.byteLength,r&&!(n<r)){e.next=5;break}return e.next=4,t;case 4:return e.abrupt("return");case 5:o=0;case 6:if(!(o<n)){e.next=13;break}return i=o+r,e.next=10,t.slice(o,i);case 10:o=i,e.next=6;break;case 13:case"end":return e.stop()}}),e)})),vt=function(){var e=l(s().mark((function e(t,o){var a,u,c,f,l,h;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:a=!1,u=!1,e.prev=2,f=n(yt(t));case 4:return e.next=6,i(f.next());case 6:if(!(a=!(l=e.sent).done)){e.next=12;break}return h=l.value,e.delegateYield(r(n(dt(h,o))),"t0",9);case 9:a=!1,e.next=4;break;case 12:e.next=18;break;case 14:e.prev=14,e.t1=e.catch(2),u=!0,c=e.t1;case 18:if(e.prev=18,e.prev=19,!a||null==f.return){e.next=23;break}return e.next=23,i(f.return());case 23:if(e.prev=23,!u){e.next=26;break}throw c;case 26:return e.finish(23);case 27:return e.finish(18);case 28:case"end":return e.stop()}}),e,null,[[2,14,18,28],[19,,23,27]])})));return function(t,r){return e.apply(this,arguments)}}(),yt=function(){var e=l(s().mark((function e(t){var o,a,u,c;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!t[Symbol.asyncIterator]){e.next=3;break}return e.delegateYield(r(n(t)),"t0",2);case 2:return e.abrupt("return");case 3:o=t.getReader(),e.prev=4;case 5:return e.next=7,i(o.read());case 7:if(a=e.sent,u=a.done,c=a.value,!u){e.next=12;break}return e.abrupt("break",16);case 12:return e.next=14,c;case 14:e.next=5;break;case 16:return e.prev=16,e.next=19,i(o.cancel());case 19:return e.finish(16);case 20:case"end":return e.stop()}}),e,null,[[4,,16,20]])})));return function(t){return e.apply(this,arguments)}}(),mt=function(e,t,r,n){var o,i=vt(e,t),a=0,u=function(e){o||(o=!0,n&&n(e))};return new ReadableStream({pull:function(e){return p(s().mark((function t(){var n,o,c,f,l;return s().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,t.next=3,i.next();case 3:if(n=t.sent,o=n.done,c=n.value,!o){t.next=10;break}return u(),e.close(),t.abrupt("return");case 10:f=c.byteLength,r&&(l=a+=f,r(l)),e.enqueue(new Uint8Array(c)),t.next=19;break;case 15:throw t.prev=15,t.t0=t.catch(0),u(t.t0),t.t0;case 19:case"end":return t.stop()}}),t,null,[[0,15]])})))()},cancel:function(e){return u(e),i.return()}},{highWaterMark:2})},bt="function"==typeof fetch&&"function"==typeof Request&&"function"==typeof Response,gt=bt&&"function"==typeof ReadableStream,wt=bt&&("function"==typeof TextEncoder?(ct=new TextEncoder,function(e){return ct.encode(e)}):function(){var e=p(s().mark((function e(t){return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.t0=Uint8Array,e.next=3,new Response(t).arrayBuffer();case 3:return e.t1=e.sent,e.abrupt("return",new e.t0(e.t1));case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Et=function(e){try{for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];return!!e.apply(void 0,r)}catch(e){return!1}},Ot=gt&&Et((function(){var e=!1,t=new Request(De.origin,{body:new ReadableStream,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t})),St=gt&&Et((function(){return ye.isReadableStream(new Response("").body)})),xt={stream:St&&function(e){return e.body}};bt&&(ft=new Response,["text","arrayBuffer","blob","formData","stream"].forEach((function(e){!xt[e]&&(xt[e]=ye.isFunction(ft[e])?function(t){return t[e]()}:function(t,r){throw new me("Response type '".concat(e,"' is not supported"),me.ERR_NOT_SUPPORT,r)})})));var Rt=function(){var e=p(s().mark((function e(t){var r;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!=t){e.next=2;break}return e.abrupt("return",0);case 2:if(!ye.isBlob(t)){e.next=4;break}return e.abrupt("return",t.size);case 4:if(!ye.isSpecCompliantForm(t)){e.next=9;break}return r=new Request(De.origin,{method:"POST",body:t}),e.next=8,r.arrayBuffer();case 8:case 15:return e.abrupt("return",e.sent.byteLength);case 9:if(!ye.isArrayBufferView(t)&&!ye.isArrayBuffer(t)){e.next=11;break}return e.abrupt("return",t.byteLength);case 11:if(ye.isURLSearchParams(t)&&(t+=""),!ye.isString(t)){e.next=16;break}return e.next=15,wt(t);case 16:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),Tt=function(){var e=p(s().mark((function e(t,r){var n;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=ye.toFiniteNumber(t.getContentLength()),e.abrupt("return",null==n?Rt(r):n);case 2:case"end":return e.stop()}}),e)})));return function(t,r){return e.apply(this,arguments)}}(),kt=bt&&function(){var e=p(s().mark((function e(t){var r,n,o,i,a,c,f,l,h,p,d,v,y,m,g,w,E,O,S,x,R,T,k,A,j,P,L,N,_,C,F,U,B,D;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=lt(t),n=r.url,o=r.method,i=r.data,a=r.signal,c=r.cancelToken,f=r.timeout,l=r.onDownloadProgress,h=r.onUploadProgress,p=r.responseType,d=r.headers,v=r.withCredentials,y=void 0===v?"same-origin":v,m=r.fetchOptions,p=p?(p+"").toLowerCase():"text",g=pt([a,c&&c.toAbortSignal()],f),E=g&&g.unsubscribe&&function(){g.unsubscribe()},e.prev=4,e.t0=h&&Ot&&"get"!==o&&"head"!==o,!e.t0){e.next=11;break}return e.next=9,Tt(d,i);case 9:e.t1=O=e.sent,e.t0=0!==e.t1;case 11:if(!e.t0){e.next=15;break}S=new Request(n,{method:"POST",body:i,duplex:"half"}),ye.isFormData(i)&&(x=S.headers.get("content-type"))&&d.setContentType(x),S.body&&(R=rt(O,tt(nt(h))),T=b(R,2),k=T[0],A=T[1],i=mt(S.body,65536,k,A));case 15:return ye.isString(y)||(y=y?"include":"omit"),j="credentials"in Request.prototype,w=new Request(n,u(u({},m),{},{signal:g,method:o.toUpperCase(),headers:d.normalize().toJSON(),body:i,duplex:"half",credentials:j?y:void 0})),e.next=20,fetch(w);case 20:return P=e.sent,L=St&&("stream"===p||"response"===p),St&&(l||L&&E)&&(N={},["status","statusText","headers"].forEach((function(e){N[e]=P[e]})),_=ye.toFiniteNumber(P.headers.get("content-length")),C=l&&rt(_,tt(nt(l),!0))||[],F=b(C,2),U=F[0],B=F[1],P=new Response(mt(P.body,65536,U,(function(){B&&B(),E&&E()})),N)),p=p||"text",e.next=26,xt[ye.findKey(xt,p)||"text"](P,t);case 26:return D=e.sent,!L&&E&&E(),e.next=30,new Promise((function(e,r){Qe(e,r,{data:D,headers:Ve.from(P.headers),status:P.status,statusText:P.statusText,config:t,request:w})}));case 30:return e.abrupt("return",e.sent);case 33:if(e.prev=33,e.t2=e.catch(4),E&&E(),!e.t2||"TypeError"!==e.t2.name||!/fetch/i.test(e.t2.message)){e.next=38;break}throw Object.assign(new me("Network Error",me.ERR_NETWORK,t,w),{cause:e.t2.cause||e.t2});case 38:throw me.from(e.t2,e.t2&&e.t2.code,t,w);case 39:case"end":return e.stop()}}),e,null,[[4,33]])})));return function(t){return e.apply(this,arguments)}}(),At={http:null,xhr:ht,fetch:kt};ye.forEach(At,(function(e,t){if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));var jt=function(e){return"- ".concat(e)},Pt=function(e){return ye.isFunction(e)||null===e||!1===e},Lt=function(e){for(var t,r,n=(e=ye.isArray(e)?e:[e]).length,o={},i=0;i<n;i++){var a=void 0;if(r=t=e[i],!Pt(t)&&void 0===(r=At[(a=String(t)).toLowerCase()]))throw new me("Unknown adapter '".concat(a,"'"));if(r)break;o[a||"#"+i]=r}if(!r){var u=Object.entries(o).map((function(e){var t=b(e,2),r=t[0],n=t[1];return"adapter ".concat(r," ")+(!1===n?"is not supported by the environment":"is not available in the build")}));throw new me("There is no suitable adapter to dispatch the request "+(n?u.length>1?"since :\n"+u.map(jt).join("\n"):" "+jt(u[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return r};function Nt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ye(null,e)}function _t(e){return Nt(e),e.headers=Ve.from(e.headers),e.data=Xe.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Lt(e.adapter||Me.adapter)(e).then((function(t){return Nt(e),t.data=Xe.call(e,e.transformResponse,t),t.headers=Ve.from(t.headers),t}),(function(t){return $e(t)||(Nt(e),t&&t.response&&(t.response.data=Xe.call(e,e.transformResponse,t.response),t.response.headers=Ve.from(t.response.headers))),Promise.reject(t)}))}var Ct="1.7.7",Ft={};["object","boolean","number","function","string","symbol"].forEach((function(e,t){Ft[e]=function(r){return f(r)===e||"a"+(t<1?"n ":" ")+e}}));var Ut={};Ft.transitional=function(e,t,r){function n(e,t){return"[Axios v1.7.7] Transitional option '"+e+"'"+t+(r?". "+r:"")}return function(r,o,i){if(!1===e)throw new me(n(o," has been removed"+(t?" in "+t:"")),me.ERR_DEPRECATED);return t&&!Ut[o]&&(Ut[o]=!0,console.warn(n(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(r,o,i)}};var Bt={assertOptions:function(e,t,r){if("object"!==f(e))throw new me("options must be an object",me.ERR_BAD_OPTION_VALUE);for(var n=Object.keys(e),o=n.length;o-- >0;){var i=n[o],a=t[i];if(a){var u=e[i],s=void 0===u||a(u,i,e);if(!0!==s)throw new me("option "+i+" must be "+s,me.ERR_BAD_OPTION_VALUE)}else if(!0!==r)throw new me("Unknown option "+i,me.ERR_BAD_OPTION)}},validators:Ft},Dt=Bt.validators,It=function(){function e(t){d(this,e),this.defaults=t,this.interceptors={request:new Pe,response:new Pe}}var t;return y(e,[{key:"request",value:(t=p(s().mark((function e(t,r){var n,o;return s().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this._request(t,r);case 3:return e.abrupt("return",e.sent);case 6:if(e.prev=6,e.t0=e.catch(0),e.t0 instanceof Error){Error.captureStackTrace?Error.captureStackTrace(n={}):n=new Error,o=n.stack?n.stack.replace(/^.+\n/,""):"";try{e.t0.stack?o&&!String(e.t0.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(e.t0.stack+="\n"+o):e.t0.stack=o}catch(e){}}throw e.t0;case 10:case"end":return e.stop()}}),e,this,[[0,6]])}))),function(e,r){return t.apply(this,arguments)})},{key:"_request",value:function(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{};var r=t=st(this.defaults,t),n=r.transitional,o=r.paramsSerializer,i=r.headers;void 0!==n&&Bt.assertOptions(n,{silentJSONParsing:Dt.transitional(Dt.boolean),forcedJSONParsing:Dt.transitional(Dt.boolean),clarifyTimeoutError:Dt.transitional(Dt.boolean)},!1),null!=o&&(ye.isFunction(o)?t.paramsSerializer={serialize:o}:Bt.assertOptions(o,{encode:Dt.function,serialize:Dt.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();var a=i&&ye.merge(i.common,i[t.method]);i&&ye.forEach(["delete","get","head","post","put","patch","common"],(function(e){delete i[e]})),t.headers=Ve.concat(a,i);var u=[],s=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(s=s&&e.synchronous,u.unshift(e.fulfilled,e.rejected))}));var c,f=[];this.interceptors.response.forEach((function(e){f.push(e.fulfilled,e.rejected)}));var l,h=0;if(!s){var p=[_t.bind(this),void 0];for(p.unshift.apply(p,u),p.push.apply(p,f),l=p.length,c=Promise.resolve(t);h<l;)c=c.then(p[h++],p[h++]);return c}l=u.length;var d=t;for(h=0;h<l;){var v=u[h++],y=u[h++];try{d=v(d)}catch(e){y.call(this,e);break}}try{c=_t.call(this,d)}catch(e){return Promise.reject(e)}for(h=0,l=f.length;h<l;)c=c.then(f[h++],f[h++]);return c}},{key:"getUri",value:function(e){return je(at((e=st(this.defaults,e)).baseURL,e.url),e.params,e.paramsSerializer)}}]),e}();ye.forEach(["delete","get","head","options"],(function(e){It.prototype[e]=function(t,r){return this.request(st(r||{},{method:e,url:t,data:(r||{}).data}))}})),ye.forEach(["post","put","patch"],(function(e){function t(t){return function(r,n,o){return this.request(st(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:r,data:n}))}}It.prototype[e]=t(),It.prototype[e+"Form"]=t(!0)}));var qt=It,Mt=function(){function e(t){if(d(this,e),"function"!=typeof t)throw new TypeError("executor must be a function.");var r;this.promise=new Promise((function(e){r=e}));var n=this;this.promise.then((function(e){if(n._listeners){for(var t=n._listeners.length;t-- >0;)n._listeners[t](e);n._listeners=null}})),this.promise.then=function(e){var t,r=new Promise((function(e){n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},t((function(e,t,o){n.reason||(n.reason=new Ye(e,t,o),r(n.reason))}))}return y(e,[{key:"throwIfRequested",value:function(){if(this.reason)throw this.reason}},{key:"subscribe",value:function(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}},{key:"unsubscribe",value:function(e){if(this._listeners){var t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}}},{key:"toAbortSignal",value:function(){var e=this,t=new AbortController,r=function(e){t.abort(e)};return this.subscribe(r),t.signal.unsubscribe=function(){return e.unsubscribe(r)},t.signal}}],[{key:"source",value:function(){var t;return{token:new e((function(e){t=e})),cancel:t}}}]),e}(),zt=Mt;var Ht={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ht).forEach((function(e){var t=b(e,2),r=t[0],n=t[1];Ht[n]=r}));var Jt=Ht;var Wt=function e(t){var r=new qt(t),n=R(qt.prototype.request,r);return ye.extend(n,qt.prototype,r,{allOwnKeys:!0}),ye.extend(n,r,null,{allOwnKeys:!0}),n.create=function(r){return e(st(t,r))},n}(Me);return Wt.Axios=qt,Wt.CanceledError=Ye,Wt.CancelToken=zt,Wt.isCancel=$e,Wt.VERSION=Ct,Wt.toFormData=xe,Wt.AxiosError=me,Wt.Cancel=Wt.CanceledError,Wt.all=function(e){return Promise.all(e)},Wt.spread=function(e){return function(t){return e.apply(null,t)}},Wt.isAxiosError=function(e){return ye.isObject(e)&&!0===e.isAxiosError},Wt.mergeConfig=st,Wt.AxiosHeaders=Ve,Wt.formToJSON=function(e){return Ie(ye.isHTMLForm(e)?new FormData(e):e)},Wt.getAdapter=Lt,Wt.HttpStatusCode=Jt,Wt.default=Wt,Wt}));  
2 -//# sourceMappingURL=axios.min.js.map  
1 -import request from './axios.js' 1 +import { defHttp } from '@/utils/external/http/axios'
2 2
3 const API = { 3 const API = {
4 - URL: '3d_component/' 4 + URL: '/3d_component'
5 } 5 }
6 6
7 -export function saveOrUpdateThreeJsModel(params = {}) {  
8 - return request({  
9 - url: API['URL'] + params['id'],  
10 - method: 'POST', 7 +/**
  8 + * @description: 3D模型 保存 api
  9 + */
  10 +export function saveOrUpdateThreeJsModel(params) {
  11 + return defHttp.post({
  12 + url: `${API['URL']}?id=${params['id']}&imageUrl=${params['imageUrl']}`,
11 data: params['data'] 13 data: params['data']
12 }) 14 })
13 } 15 }
14 16
  17 +/**
  18 + * @description: 3D模型 获取 api
  19 + */
15 export function getThreeJsModel(id) { 20 export function getThreeJsModel(id) {
16 - return request({  
17 - url: API['URL'] + id,  
18 - method: 'get', 21 + return defHttp.get({
  22 + url: API['URL'] + '/' + id
19 }) 23 })
20 } 24 }
21 -  
1 -import axios from 'axios'  
2 -import { BASE_URL } from './config.js'  
3 -import { getJwtToken } from '@/utils/external/auth'  
4 -  
5 -const service = axios.create({  
6 - baseURL: BASE_URL,  
7 - timeout: 5000  
8 -})  
9 -  
10 -service.interceptors.request.use(  
11 - config => {  
12 - const token = getJwtToken()  
13 - if (token) {  
14 - config.headers['x-authorization'] = `Bearer ${token}`  
15 - }  
16 - return config  
17 - },  
18 - error => {  
19 - return Promise.reject(error)  
20 - }  
21 -)  
22 -  
23 -service.interceptors.response.use(  
24 - response => {  
25 - const { status, data } = response  
26 - if (status === 200) {  
27 - const { code } = data  
28 - switch (code) {  
29 - case 1003:  
30 - return Promise.reject(data)  
31 - default:  
32 - return data  
33 - }  
34 - }  
35 - },  
36 - error => {  
37 - if (error.response) {  
38 - const { status, data } = error.response  
39 - if (status === 2001) {  
40 - }  
41 - }  
42 - return Promise.reject(error)  
43 - }  
44 -)  
45 -  
46 -export default service  
1 -const { host, protocol } = location  
2 -  
3 -let threeFilePath = `${protocol}//${host}`  
4 -  
5 -const VITE_GLOB_API_URL = import.meta.env.VITE_GLOB_API_URL  
6 -  
7 -const VITE_GLOB_API_URL_PREFIX = import.meta.env.VITE_GLOB_API_URL_PREFIX  
8 -  
9 -export const BASE_URL = `${threeFilePath}${VITE_GLOB_API_URL}${VITE_GLOB_API_URL_PREFIX}`  
1 -import * as THREE from 'three'; 1 +import * as THREE from 'three'
2 2
3 -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';  
4 -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';  
5 -import { TGALoader } from 'three/addons/loaders/TGALoader.js';  
6 -import { FullScreenQuad } from 'three/addons/postprocessing/Pass.js'; 3 +import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'
  4 +import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'
  5 +import { TGALoader } from 'three/addons/loaders/TGALoader.js'
  6 +import { FullScreenQuad } from 'three/addons/postprocessing/Pass.js'
7 7
8 -import { UISpan, UIDiv, UIRow, UIButton, UICheckbox, UIText, UINumber } from './ui.js';  
9 -import { MoveObjectCommand } from '../commands/MoveObjectCommand.js'; 8 +import { UISpan, UIDiv, UIRow, UIButton, UICheckbox, UIText, UINumber } from './ui.js'
  9 +import { MoveObjectCommand } from '../commands/MoveObjectCommand.js'
10 10
11 -const cache = new Map(); 11 +const cache = new Map()
12 12
13 class UITexture extends UISpan { 13 class UITexture extends UISpan {
14 -  
15 - constructor( editor ) {  
16 -  
17 - super();  
18 -  
19 - const scope = this;  
20 -  
21 - const form = document.createElement( 'form' );  
22 -  
23 - const input = document.createElement( 'input' );  
24 - input.type = 'file';  
25 - input.addEventListener( 'change', function ( event ) {  
26 -  
27 - loadFile( event.target.files[ 0 ] );  
28 -  
29 - } );  
30 - form.appendChild( input );  
31 -  
32 - const canvas = document.createElement( 'canvas' );  
33 - canvas.width = 32;  
34 - canvas.height = 16;  
35 - canvas.style.cursor = 'pointer';  
36 - canvas.style.marginRight = '5px';  
37 - canvas.style.border = '1px solid #888';  
38 - canvas.addEventListener( 'click', function () {  
39 -  
40 - input.click();  
41 -  
42 - } );  
43 - canvas.addEventListener( 'drop', function ( event ) {  
44 -  
45 - event.preventDefault();  
46 - event.stopPropagation();  
47 - loadFile( event.dataTransfer.files[ 0 ] );  
48 -  
49 - } );  
50 - this.dom.appendChild( canvas );  
51 -  
52 - function loadFile( file ) {  
53 -  
54 - const extension = file.name.split( '.' ).pop().toLowerCase();  
55 - const reader = new FileReader();  
56 -  
57 - const hash = `${file.lastModified}_${file.size}_${file.name}`;  
58 -  
59 - if ( cache.has( hash ) ) {  
60 -  
61 - const texture = cache.get( hash );  
62 -  
63 - scope.setValue( texture );  
64 -  
65 - if ( scope.onChangeCallback ) scope.onChangeCallback( texture );  
66 -  
67 - } else if ( extension === 'hdr' || extension === 'pic' ) {  
68 -  
69 - reader.addEventListener( 'load', function ( event ) {  
70 -  
71 - // assuming RGBE/Radiance HDR image format  
72 -  
73 - const loader = new RGBELoader();  
74 - loader.load( event.target.result, function ( hdrTexture ) {  
75 -  
76 - hdrTexture.sourceFile = file.name;  
77 -  
78 - cache.set( hash, hdrTexture );  
79 -  
80 - scope.setValue( hdrTexture );  
81 -  
82 - if ( scope.onChangeCallback ) scope.onChangeCallback( hdrTexture );  
83 -  
84 - } );  
85 -  
86 - } );  
87 -  
88 - reader.readAsDataURL( file );  
89 -  
90 - } else if ( extension === 'tga' ) {  
91 -  
92 - reader.addEventListener( 'load', function ( event ) {  
93 -  
94 - const loader = new TGALoader();  
95 - loader.load( event.target.result, function ( texture ) {  
96 -  
97 - texture.colorSpace = THREE.SRGBColorSpace;  
98 - texture.sourceFile = file.name;  
99 -  
100 - cache.set( hash, texture );  
101 -  
102 - scope.setValue( texture );  
103 -  
104 - if ( scope.onChangeCallback ) scope.onChangeCallback( texture );  
105 -  
106 -  
107 - } );  
108 -  
109 - }, false );  
110 -  
111 - reader.readAsDataURL( file );  
112 -  
113 - } else if ( extension === 'ktx2' ) {  
114 -  
115 - reader.addEventListener( 'load', function ( event ) {  
116 -  
117 - const arrayBuffer = event.target.result;  
118 - const blobURL = URL.createObjectURL( new Blob( [ arrayBuffer ] ) );  
119 - const ktx2Loader = new KTX2Loader();  
120 - ktx2Loader.setTranscoderPath( '../../examples/jsm/libs/basis/' );  
121 - editor.signals.rendererDetectKTX2Support.dispatch( ktx2Loader );  
122 -  
123 - ktx2Loader.load( blobURL, function ( texture ) {  
124 -  
125 - texture.colorSpace = THREE.SRGBColorSpace;  
126 - texture.sourceFile = file.name;  
127 - texture.needsUpdate = true;  
128 -  
129 - cache.set( hash, texture );  
130 -  
131 - scope.setValue( texture );  
132 -  
133 - if ( scope.onChangeCallback ) scope.onChangeCallback( texture );  
134 - ktx2Loader.dispose();  
135 -  
136 - } );  
137 -  
138 - } );  
139 -  
140 - reader.readAsArrayBuffer( file );  
141 -  
142 - } else if ( file.type.match( 'image.*' ) ) {  
143 -  
144 - reader.addEventListener( 'load', function ( event ) {  
145 -  
146 - const image = document.createElement( 'img' );  
147 - image.addEventListener( 'load', function () {  
148 -  
149 - const texture = new THREE.Texture( this );  
150 - texture.sourceFile = file.name;  
151 - texture.needsUpdate = true;  
152 -  
153 - cache.set( hash, texture );  
154 -  
155 - scope.setValue( texture );  
156 -  
157 - if ( scope.onChangeCallback ) scope.onChangeCallback( texture );  
158 -  
159 - }, false );  
160 -  
161 - image.src = event.target.result;  
162 -  
163 - }, false );  
164 -  
165 - reader.readAsDataURL( file );  
166 -  
167 - }  
168 -  
169 - form.reset();  
170 -  
171 - }  
172 -  
173 - this.texture = null;  
174 - this.onChangeCallback = null;  
175 -  
176 - }  
177 -  
178 - getValue() {  
179 -  
180 - return this.texture;  
181 -  
182 - }  
183 -  
184 - setValue( texture ) {  
185 -  
186 - const canvas = this.dom.children[ 0 ];  
187 - const context = canvas.getContext( '2d' );  
188 -  
189 - // Seems like context can be null if the canvas is not visible  
190 - if ( context ) {  
191 -  
192 - // Always clear the context before set new texture, because new texture may has transparency  
193 - context.clearRect( 0, 0, canvas.width, canvas.height );  
194 -  
195 - }  
196 -  
197 - if ( texture !== null ) {  
198 -  
199 - const image = texture.image;  
200 -  
201 - if ( image !== undefined && image !== null && image.width > 0 ) {  
202 -  
203 - canvas.title = texture.sourceFile;  
204 - const scale = canvas.width / image.width;  
205 -  
206 - if ( texture.isDataTexture || texture.isCompressedTexture ) {  
207 -  
208 - const canvas2 = renderToCanvas( texture );  
209 - context.drawImage( canvas2, 0, 0, image.width * scale, image.height * scale );  
210 -  
211 - } else {  
212 -  
213 - context.drawImage( image, 0, 0, image.width * scale, image.height * scale );  
214 -  
215 - }  
216 -  
217 - } else {  
218 -  
219 - canvas.title = texture.sourceFile + ' (error)';  
220 -  
221 - }  
222 -  
223 - } else {  
224 -  
225 - canvas.title = 'empty';  
226 -  
227 - }  
228 -  
229 - this.texture = texture;  
230 -  
231 - }  
232 -  
233 - setColorSpace( colorSpace ) {  
234 -  
235 - const texture = this.getValue();  
236 -  
237 - if ( texture !== null ) {  
238 -  
239 - texture.colorSpace = colorSpace;  
240 -  
241 - }  
242 -  
243 - return this;  
244 -  
245 - }  
246 -  
247 - onChange( callback ) {  
248 -  
249 - this.onChangeCallback = callback;  
250 -  
251 - return this;  
252 -  
253 - }  
254 - 14 + constructor(editor) {
  15 + super()
  16 +
  17 + const scope = this
  18 +
  19 + const form = document.createElement('form')
  20 +
  21 + const input = document.createElement('input')
  22 + input.type = 'file'
  23 + input.addEventListener('change', function (event) {
  24 + loadFile(event.target.files[0])
  25 + })
  26 + form.appendChild(input)
  27 +
  28 + const canvas = document.createElement('canvas')
  29 + canvas.width = 32
  30 + canvas.height = 16
  31 + canvas.style.cursor = 'pointer'
  32 + canvas.style.marginRight = '5px'
  33 + canvas.style.border = '1px solid #888'
  34 + canvas.addEventListener('click', function () {
  35 + input.click()
  36 + })
  37 + canvas.addEventListener('drop', function (event) {
  38 + event.preventDefault()
  39 + event.stopPropagation()
  40 + loadFile(event.dataTransfer.files[0])
  41 + })
  42 + this.dom.appendChild(canvas)
  43 +
  44 + function loadFile(file) {
  45 + const extension = file.name.split('.').pop().toLowerCase()
  46 + const reader = new FileReader()
  47 +
  48 + const hash = `${file.lastModified}_${file.size}_${file.name}`
  49 +
  50 + if (cache.has(hash)) {
  51 + const texture = cache.get(hash)
  52 +
  53 + scope.setValue(texture)
  54 +
  55 + if (scope.onChangeCallback) scope.onChangeCallback(texture)
  56 + } else if (extension === 'hdr' || extension === 'pic') {
  57 + reader.addEventListener('load', function (event) {
  58 + // assuming RGBE/Radiance HDR image format
  59 +
  60 + const loader = new RGBELoader()
  61 + loader.load(event.target.result, function (hdrTexture) {
  62 + hdrTexture.sourceFile = file.name
  63 +
  64 + cache.set(hash, hdrTexture)
  65 +
  66 + scope.setValue(hdrTexture)
  67 +
  68 + if (scope.onChangeCallback) scope.onChangeCallback(hdrTexture)
  69 + })
  70 + })
  71 +
  72 + reader.readAsDataURL(file)
  73 + } else if (extension === 'tga') {
  74 + reader.addEventListener(
  75 + 'load',
  76 + function (event) {
  77 + const loader = new TGALoader()
  78 + loader.load(event.target.result, function (texture) {
  79 + texture.colorSpace = THREE.SRGBColorSpace
  80 + texture.sourceFile = file.name
  81 +
  82 + cache.set(hash, texture)
  83 +
  84 + scope.setValue(texture)
  85 +
  86 + if (scope.onChangeCallback) scope.onChangeCallback(texture)
  87 + })
  88 + },
  89 + false
  90 + )
  91 +
  92 + reader.readAsDataURL(file)
  93 + } else if (extension === 'ktx2') {
  94 + reader.addEventListener('load', function (event) {
  95 + const arrayBuffer = event.target.result
  96 + const blobURL = URL.createObjectURL(new Blob([arrayBuffer]))
  97 + const ktx2Loader = new KTX2Loader()
  98 + ktx2Loader.setTranscoderPath('../../examples/jsm/libs/basis/')
  99 + editor.signals.rendererDetectKTX2Support.dispatch(ktx2Loader)
  100 +
  101 + ktx2Loader.load(blobURL, function (texture) {
  102 + texture.colorSpace = THREE.SRGBColorSpace
  103 + texture.sourceFile = file.name
  104 + texture.needsUpdate = true
  105 +
  106 + cache.set(hash, texture)
  107 +
  108 + scope.setValue(texture)
  109 +
  110 + if (scope.onChangeCallback) scope.onChangeCallback(texture)
  111 + ktx2Loader.dispose()
  112 + })
  113 + })
  114 +
  115 + reader.readAsArrayBuffer(file)
  116 + } else if (file.type.match('image.*')) {
  117 + reader.addEventListener(
  118 + 'load',
  119 + function (event) {
  120 + const image = document.createElement('img')
  121 + image.addEventListener(
  122 + 'load',
  123 + function () {
  124 + const texture = new THREE.Texture(this)
  125 + texture.sourceFile = file.name
  126 + texture.needsUpdate = true
  127 +
  128 + cache.set(hash, texture)
  129 +
  130 + scope.setValue(texture)
  131 +
  132 + if (scope.onChangeCallback) scope.onChangeCallback(texture)
  133 + },
  134 + false
  135 + )
  136 +
  137 + image.src = event.target.result
  138 + },
  139 + false
  140 + )
  141 +
  142 + reader.readAsDataURL(file)
  143 + }
  144 +
  145 + form.reset()
  146 + }
  147 +
  148 + this.texture = null
  149 + this.onChangeCallback = null
  150 + }
  151 +
  152 + getValue() {
  153 + return this.texture
  154 + }
  155 +
  156 + setValue(texture) {
  157 + const canvas = this.dom.children[0]
  158 + const context = canvas.getContext('2d')
  159 +
  160 + // Seems like context can be null if the canvas is not visible
  161 + if (context) {
  162 + // Always clear the context before set new texture, because new texture may has transparency
  163 + context.clearRect(0, 0, canvas.width, canvas.height)
  164 + }
  165 +
  166 + if (texture !== null) {
  167 + const image = texture.image
  168 +
  169 + if (image !== undefined && image !== null && image.width > 0) {
  170 + canvas.title = texture.sourceFile
  171 + const scale = canvas.width / image.width
  172 +
  173 + if (texture.isDataTexture || texture.isCompressedTexture) {
  174 + const canvas2 = renderToCanvas(texture)
  175 + context.drawImage(canvas2, 0, 0, image.width * scale, image.height * scale)
  176 + } else {
  177 + context.drawImage(image, 0, 0, image.width * scale, image.height * scale)
  178 + }
  179 + } else {
  180 + canvas.title = texture.sourceFile + ' (error)'
  181 + }
  182 + } else {
  183 + canvas.title = 'empty'
  184 + }
  185 +
  186 + this.texture = texture
  187 + }
  188 +
  189 + setColorSpace(colorSpace) {
  190 + const texture = this.getValue()
  191 +
  192 + if (texture !== null) {
  193 + texture.colorSpace = colorSpace
  194 + }
  195 +
  196 + return this
  197 + }
  198 +
  199 + onChange(callback) {
  200 + this.onChangeCallback = callback
  201 +
  202 + return this
  203 + }
255 } 204 }
256 205
257 class UIOutliner extends UIDiv { 206 class UIOutliner extends UIDiv {
  207 + constructor(editor) {
  208 + super()
258 209
259 - constructor( editor ) {  
260 -  
261 - super();  
262 -  
263 - this.dom.className = 'Outliner';  
264 - this.dom.tabIndex = 0; // keyup event is ignored without setting tabIndex  
265 -  
266 - const scope = this;  
267 -  
268 - // hack  
269 - this.scene = editor.scene;  
270 -  
271 - // Prevent native scroll behavior  
272 - this.dom.addEventListener( 'keydown', function ( event ) {  
273 -  
274 - switch ( event.code ) {  
275 -  
276 - case 'ArrowUp':  
277 - case 'ArrowDown':  
278 - event.preventDefault();  
279 - event.stopPropagation();  
280 - break;  
281 -  
282 - }  
283 -  
284 - } );  
285 -  
286 - // Keybindings to support arrow navigation  
287 - this.dom.addEventListener( 'keyup', function ( event ) {  
288 -  
289 - switch ( event.code ) {  
290 -  
291 - case 'ArrowUp':  
292 - scope.selectIndex( scope.selectedIndex - 1 );  
293 - break;  
294 - case 'ArrowDown':  
295 - scope.selectIndex( scope.selectedIndex + 1 );  
296 - break;  
297 -  
298 - }  
299 -  
300 - } );  
301 -  
302 - this.editor = editor;  
303 -  
304 - this.options = [];  
305 - this.selectedIndex = - 1;  
306 - this.selectedValue = null;  
307 -  
308 - }  
309 -  
310 - selectIndex( index ) {  
311 -  
312 - if ( index >= 0 && index < this.options.length ) {  
313 -  
314 - this.setValue( this.options[ index ].value );  
315 -  
316 - const changeEvent = new Event( 'change', { bubbles: true, cancelable: true } );  
317 - this.dom.dispatchEvent( changeEvent ); 210 + this.dom.className = 'Outliner'
  211 + this.dom.tabIndex = 0 // keyup event is ignored without setting tabIndex
318 212
319 - } 213 + const scope = this
320 214
321 - } 215 + // hack
  216 + this.scene = editor.scene
322 217
323 - setOptions( options ) { 218 + // Prevent native scroll behavior
  219 + this.dom.addEventListener('keydown', function (event) {
  220 + switch (event.code) {
  221 + case 'ArrowUp':
  222 + case 'ArrowDown':
  223 + event.preventDefault()
  224 + event.stopPropagation()
  225 + break
  226 + }
  227 + })
324 228
325 - const scope = this; 229 + // Keybindings to support arrow navigation
  230 + this.dom.addEventListener('keyup', function (event) {
  231 + switch (event.code) {
  232 + case 'ArrowUp':
  233 + scope.selectIndex(scope.selectedIndex - 1)
  234 + break
  235 + case 'ArrowDown':
  236 + scope.selectIndex(scope.selectedIndex + 1)
  237 + break
  238 + }
  239 + })
326 240
327 - while ( scope.dom.children.length > 0 ) { 241 + this.editor = editor
  242 +
  243 + this.options = []
  244 + this.selectedIndex = -1
  245 + this.selectedValue = null
  246 + }
328 247
329 - scope.dom.removeChild( scope.dom.firstChild ); 248 + selectIndex(index) {
  249 + if (index >= 0 && index < this.options.length) {
  250 + this.setValue(this.options[index].value)
330 251
331 - } 252 + const changeEvent = new Event('change', { bubbles: true, cancelable: true })
  253 + this.dom.dispatchEvent(changeEvent)
  254 + }
  255 + }
332 256
333 - function onClick() { 257 + setOptions(options) {
  258 + const scope = this
334 259
335 - scope.setValue( this.value ); 260 + while (scope.dom.children.length > 0) {
  261 + scope.dom.removeChild(scope.dom.firstChild)
  262 + }
336 263
337 - const changeEvent = new Event( 'change', { bubbles: true, cancelable: true } );  
338 - scope.dom.dispatchEvent( changeEvent ); 264 + function onClick() {
  265 + scope.setValue(this.value)
339 266
340 - } 267 + const changeEvent = new Event('change', { bubbles: true, cancelable: true })
  268 + scope.dom.dispatchEvent(changeEvent)
  269 + }
341 270
342 - // Drag 271 + // Drag
343 272
344 - let currentDrag; 273 + let currentDrag
345 274
346 - function onDrag() { 275 + function onDrag() {
  276 + currentDrag = this
  277 + }
347 278
348 - currentDrag = this; 279 + function onDragStart(event) {
  280 + event.dataTransfer.setData('text', 'foo')
  281 + }
349 282
350 - } 283 + function onDragOver(event) {
  284 + if (this === currentDrag) return
351 285
352 - function onDragStart( event ) { 286 + const area = event.offsetY / this.clientHeight
353 287
354 - event.dataTransfer.setData( 'text', 'foo' ); 288 + if (area < 0.25) {
  289 + this.className = 'option dragTop'
  290 + } else if (area > 0.75) {
  291 + this.className = 'option dragBottom'
  292 + } else {
  293 + this.className = 'option drag'
  294 + }
  295 + }
355 296
356 - } 297 + function onDragLeave() {
  298 + if (this === currentDrag) return
357 299
358 - function onDragOver( event ) { 300 + this.className = 'option'
  301 + }
359 302
360 - if ( this === currentDrag ) return; 303 + function onDrop(event) {
  304 + if (this === currentDrag || currentDrag === undefined) return
361 305
362 - const area = event.offsetY / this.clientHeight; 306 + this.className = 'option'
363 307
364 - if ( area < 0.25 ) { 308 + const scene = scope.scene
  309 + const object = scene.getObjectById(currentDrag.value)
365 310
366 - this.className = 'option dragTop'; 311 + const area = event.offsetY / this.clientHeight
367 312
368 - } else if ( area > 0.75 ) { 313 + if (area < 0.25) {
  314 + const nextObject = scene.getObjectById(this.value)
  315 + moveObject(object, nextObject.parent, nextObject)
  316 + } else if (area > 0.75) {
  317 + let nextObject, parent
369 318
370 - this.className = 'option dragBottom'; 319 + if (this.nextSibling !== null) {
  320 + nextObject = scene.getObjectById(this.nextSibling.value)
  321 + parent = nextObject.parent
  322 + } else {
  323 + // end of list (no next object)
371 324
372 - } else { 325 + nextObject = null
  326 + parent = scene.getObjectById(this.value).parent
  327 + }
373 328
374 - this.className = 'option drag'; 329 + moveObject(object, parent, nextObject)
  330 + } else {
  331 + const parentObject = scene.getObjectById(this.value)
  332 + moveObject(object, parentObject)
  333 + }
  334 + }
375 335
376 - } 336 + function moveObject(object, newParent, nextObject) {
  337 + if (nextObject === null) nextObject = undefined
377 338
378 - } 339 + let newParentIsChild = false
379 340
380 - function onDragLeave() { 341 + object.traverse(function (child) {
  342 + if (child === newParent) newParentIsChild = true
  343 + })
381 344
382 - if ( this === currentDrag ) return; 345 + if (newParentIsChild) return
383 346
384 - this.className = 'option'; 347 + const editor = scope.editor
  348 + editor.execute(new MoveObjectCommand(editor, object, newParent, nextObject))
385 349
386 - } 350 + const changeEvent = new Event('change', { bubbles: true, cancelable: true })
  351 + scope.dom.dispatchEvent(changeEvent)
  352 + }
387 353
388 - function onDrop( event ) { 354 + //
389 355
390 - if ( this === currentDrag || currentDrag === undefined ) return; 356 + scope.options = []
391 357
392 - this.className = 'option'; 358 + for (let i = 0; i < options.length; i++) {
  359 + const div = options[i]
  360 + div.className = 'option'
  361 + scope.dom.appendChild(div)
393 362
394 - const scene = scope.scene;  
395 - const object = scene.getObjectById( currentDrag.value ); 363 + scope.options.push(div)
396 364
397 - const area = event.offsetY / this.clientHeight; 365 + div.addEventListener('click', onClick)
398 366
399 - if ( area < 0.25 ) { 367 + if (div.draggable === true) {
  368 + div.addEventListener('drag', onDrag)
  369 + div.addEventListener('dragstart', onDragStart) // Firefox needs this
400 370
401 - const nextObject = scene.getObjectById( this.value );  
402 - moveObject( object, nextObject.parent, nextObject ); 371 + div.addEventListener('dragover', onDragOver)
  372 + div.addEventListener('dragleave', onDragLeave)
  373 + div.addEventListener('drop', onDrop)
  374 + }
  375 + }
403 376
404 - } else if ( area > 0.75 ) { 377 + return scope
  378 + }
405 379
406 - let nextObject, parent; 380 + getValue() {
  381 + return this.selectedValue
  382 + }
407 383
408 - if ( this.nextSibling !== null ) { 384 + setValue(value) {
  385 + for (let i = 0; i < this.options.length; i++) {
  386 + const element = this.options[i]
409 387
410 - nextObject = scene.getObjectById( this.nextSibling.value );  
411 - parent = nextObject.parent; 388 + if (element.value === value) {
  389 + element.classList.add('active')
412 390
413 - } else { 391 + // scroll into view
414 392
415 - // end of list (no next object) 393 + const y = element.offsetTop - this.dom.offsetTop
  394 + const bottomY = y + element.offsetHeight
  395 + const minScroll = bottomY - this.dom.offsetHeight
416 396
417 - nextObject = null;  
418 - parent = scene.getObjectById( this.value ).parent; 397 + if (this.dom.scrollTop > y) {
  398 + this.dom.scrollTop = y
  399 + } else if (this.dom.scrollTop < minScroll) {
  400 + this.dom.scrollTop = minScroll
  401 + }
419 402
420 - } 403 + this.selectedIndex = i
  404 + } else {
  405 + element.classList.remove('active')
  406 + }
  407 + }
421 408
422 - moveObject( object, parent, nextObject );  
423 -  
424 - } else {  
425 -  
426 - const parentObject = scene.getObjectById( this.value );  
427 - moveObject( object, parentObject );  
428 -  
429 - }  
430 -  
431 - }  
432 -  
433 - function moveObject( object, newParent, nextObject ) {  
434 -  
435 - if ( nextObject === null ) nextObject = undefined;  
436 -  
437 - let newParentIsChild = false;  
438 -  
439 - object.traverse( function ( child ) {  
440 -  
441 - if ( child === newParent ) newParentIsChild = true;  
442 -  
443 - } );  
444 -  
445 - if ( newParentIsChild ) return;  
446 -  
447 - const editor = scope.editor;  
448 - editor.execute( new MoveObjectCommand( editor, object, newParent, nextObject ) );  
449 -  
450 - const changeEvent = new Event( 'change', { bubbles: true, cancelable: true } );  
451 - scope.dom.dispatchEvent( changeEvent );  
452 -  
453 - }  
454 -  
455 - //  
456 -  
457 - scope.options = [];  
458 -  
459 - for ( let i = 0; i < options.length; i ++ ) {  
460 -  
461 - const div = options[ i ];  
462 - div.className = 'option';  
463 - scope.dom.appendChild( div );  
464 -  
465 - scope.options.push( div );  
466 -  
467 - div.addEventListener( 'click', onClick );  
468 -  
469 - if ( div.draggable === true ) {  
470 -  
471 - div.addEventListener( 'drag', onDrag );  
472 - div.addEventListener( 'dragstart', onDragStart ); // Firefox needs this  
473 -  
474 - div.addEventListener( 'dragover', onDragOver );  
475 - div.addEventListener( 'dragleave', onDragLeave );  
476 - div.addEventListener( 'drop', onDrop );  
477 -  
478 - }  
479 -  
480 -  
481 - }  
482 -  
483 - return scope;  
484 -  
485 - }  
486 -  
487 - getValue() {  
488 -  
489 - return this.selectedValue;  
490 -  
491 - }  
492 -  
493 - setValue( value ) {  
494 -  
495 - for ( let i = 0; i < this.options.length; i ++ ) {  
496 -  
497 - const element = this.options[ i ];  
498 -  
499 - if ( element.value === value ) {  
500 -  
501 - element.classList.add( 'active' );  
502 -  
503 - // scroll into view  
504 -  
505 - const y = element.offsetTop - this.dom.offsetTop;  
506 - const bottomY = y + element.offsetHeight;  
507 - const minScroll = bottomY - this.dom.offsetHeight;  
508 -  
509 - if ( this.dom.scrollTop > y ) {  
510 -  
511 - this.dom.scrollTop = y;  
512 -  
513 - } else if ( this.dom.scrollTop < minScroll ) {  
514 -  
515 - this.dom.scrollTop = minScroll;  
516 -  
517 - }  
518 -  
519 - this.selectedIndex = i;  
520 -  
521 - } else {  
522 -  
523 - element.classList.remove( 'active' );  
524 -  
525 - }  
526 -  
527 - }  
528 -  
529 - this.selectedValue = value;  
530 -  
531 - return this;  
532 -  
533 - } 409 + this.selectedValue = value
534 410
  411 + return this
  412 + }
535 } 413 }
536 414
537 class UIPoints extends UISpan { 415 class UIPoints extends UISpan {
  416 + constructor() {
  417 + super()
538 418
539 - constructor() {  
540 -  
541 - super();  
542 -  
543 - this.dom.style.display = 'inline-block';  
544 -  
545 - this.pointsList = new UIDiv();  
546 - this.add( this.pointsList );  
547 -  
548 - this.pointsUI = [];  
549 - this.lastPointIdx = 0;  
550 - this.onChangeCallback = null;  
551 -  
552 - this.update = () => { // bind lexical this  
553 -  
554 - if ( this.onChangeCallback !== null ) {  
555 -  
556 - this.onChangeCallback();  
557 -  
558 - }  
559 -  
560 - };  
561 -  
562 - }  
563 -  
564 - onChange( callback ) {  
565 -  
566 - this.onChangeCallback = callback; 419 + this.dom.style.display = 'inline-block'
567 420
568 - return this; 421 + this.pointsList = new UIDiv()
  422 + this.add(this.pointsList)
569 423
570 - } 424 + this.pointsUI = []
  425 + this.lastPointIdx = 0
  426 + this.onChangeCallback = null
571 427
572 - clear() { 428 + this.update = () => {
  429 + // bind lexical this
573 430
574 - for ( let i = this.pointsUI.length - 1; i >= 0; -- i ) { 431 + if (this.onChangeCallback !== null) {
  432 + this.onChangeCallback()
  433 + }
  434 + }
  435 + }
575 436
576 - this.deletePointRow( i, false ); 437 + onChange(callback) {
  438 + this.onChangeCallback = callback
577 439
578 - } 440 + return this
  441 + }
579 442
580 - this.lastPointIdx = 0; 443 + clear() {
  444 + for (let i = this.pointsUI.length - 1; i >= 0; --i) {
  445 + this.deletePointRow(i, false)
  446 + }
581 447
582 - } 448 + this.lastPointIdx = 0
  449 + }
583 450
584 - deletePointRow( idx, needsUpdate = true ) { 451 + deletePointRow(idx, needsUpdate = true) {
  452 + if (!this.pointsUI[idx]) return
585 453
586 - if ( ! this.pointsUI[ idx ] ) return; 454 + this.pointsList.remove(this.pointsUI[idx].row)
587 455
588 - this.pointsList.remove( this.pointsUI[ idx ].row ); 456 + this.pointsUI.splice(idx, 1)
589 457
590 - this.pointsUI.splice( idx, 1 );  
591 -  
592 - if ( needsUpdate === true ) {  
593 -  
594 - this.update();  
595 -  
596 - }  
597 -  
598 - this.lastPointIdx --;  
599 -  
600 - } 458 + if (needsUpdate === true) {
  459 + this.update()
  460 + }
601 461
  462 + this.lastPointIdx--
  463 + }
602 } 464 }
603 465
604 class UIPoints2 extends UIPoints { 466 class UIPoints2 extends UIPoints {
  467 + constructor() {
  468 + super()
605 469
606 - constructor() {  
607 -  
608 - super();  
609 -  
610 - const row = new UIRow();  
611 - this.add( row );  
612 -  
613 - const addPointButton = new UIButton( '+' );  
614 - addPointButton.onClick( () => {  
615 -  
616 - if ( this.pointsUI.length === 0 ) {  
617 -  
618 - this.pointsList.add( this.createPointRow( 0, 0 ) );  
619 -  
620 - } else {  
621 -  
622 - const point = this.pointsUI[ this.pointsUI.length - 1 ];  
623 -  
624 - this.pointsList.add( this.createPointRow( point.x.getValue(), point.y.getValue() ) );  
625 -  
626 - }  
627 -  
628 - this.update();  
629 -  
630 - } );  
631 - row.add( addPointButton ); 470 + const row = new UIRow()
  471 + this.add(row)
632 472
633 - } 473 + const addPointButton = new UIButton('+')
  474 + addPointButton.onClick(() => {
  475 + if (this.pointsUI.length === 0) {
  476 + this.pointsList.add(this.createPointRow(0, 0))
  477 + } else {
  478 + const point = this.pointsUI[this.pointsUI.length - 1]
634 479
635 - getValue() { 480 + this.pointsList.add(this.createPointRow(point.x.getValue(), point.y.getValue()))
  481 + }
636 482
637 - const points = []; 483 + this.update()
  484 + })
  485 + row.add(addPointButton)
  486 + }
638 487
639 - let count = 0; 488 + getValue() {
  489 + const points = []
640 490
641 - for ( let i = 0; i < this.pointsUI.length; i ++ ) { 491 + let count = 0
642 492
643 - const pointUI = this.pointsUI[ i ]; 493 + for (let i = 0; i < this.pointsUI.length; i++) {
  494 + const pointUI = this.pointsUI[i]
644 495
645 - if ( ! pointUI ) continue; 496 + if (!pointUI) continue
646 497
647 - points.push( new THREE.Vector2( pointUI.x.getValue(), pointUI.y.getValue() ) );  
648 - ++ count;  
649 - pointUI.lbl.setValue( count ); 498 + points.push(new THREE.Vector2(pointUI.x.getValue(), pointUI.y.getValue()))
  499 + ++count
  500 + pointUI.lbl.setValue(count)
  501 + }
650 502
651 - } 503 + return points
  504 + }
652 505
653 - return points; 506 + setValue(points, needsUpdate = true) {
  507 + this.clear()
654 508
655 - } 509 + for (let i = 0; i < points.length; i++) {
  510 + const point = points[i]
  511 + this.pointsList.add(this.createPointRow(point.x, point.y))
  512 + }
656 513
657 - setValue( points, needsUpdate = true ) { 514 + if (needsUpdate === true) this.update()
658 515
659 - this.clear(); 516 + return this
  517 + }
660 518
661 - for ( let i = 0; i < points.length; i ++ ) { 519 + createPointRow(x, y) {
  520 + const pointRow = new UIDiv()
  521 + const lbl = new UIText(this.lastPointIdx + 1).setWidth('20px')
  522 + const txtX = new UINumber(x).setWidth('30px').onChange(this.update)
  523 + const txtY = new UINumber(y).setWidth('30px').onChange(this.update)
662 524
663 - const point = points[ i ];  
664 - this.pointsList.add( this.createPointRow( point.x, point.y ) ); 525 + const scope = this
  526 + const btn = new UIButton('-').onClick(function () {
  527 + if (scope.isEditing) return
665 528
666 - } 529 + const idx = scope.pointsList.getIndexOfChild(pointRow)
  530 + scope.deletePointRow(idx)
  531 + })
667 532
668 - if ( needsUpdate === true ) this.update();  
669 -  
670 - return this;  
671 -  
672 - }  
673 -  
674 - createPointRow( x, y ) {  
675 -  
676 - const pointRow = new UIDiv();  
677 - const lbl = new UIText( this.lastPointIdx + 1 ).setWidth( '20px' );  
678 - const txtX = new UINumber( x ).setWidth( '30px' ).onChange( this.update );  
679 - const txtY = new UINumber( y ).setWidth( '30px' ).onChange( this.update );  
680 -  
681 - const scope = this;  
682 - const btn = new UIButton( '-' ).onClick( function () {  
683 -  
684 - if ( scope.isEditing ) return;  
685 -  
686 - const idx = scope.pointsList.getIndexOfChild( pointRow );  
687 - scope.deletePointRow( idx );  
688 -  
689 - } );  
690 -  
691 - this.pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY } );  
692 - ++ this.lastPointIdx;  
693 - pointRow.add( lbl, txtX, txtY, btn );  
694 -  
695 - return pointRow;  
696 -  
697 - } 533 + this.pointsUI.push({ row: pointRow, lbl: lbl, x: txtX, y: txtY })
  534 + ++this.lastPointIdx
  535 + pointRow.add(lbl, txtX, txtY, btn)
698 536
  537 + return pointRow
  538 + }
699 } 539 }
700 540
701 class UIPoints3 extends UIPoints { 541 class UIPoints3 extends UIPoints {
  542 + constructor() {
  543 + super()
702 544
703 - constructor() {  
704 -  
705 - super();  
706 -  
707 - const row = new UIRow();  
708 - this.add( row );  
709 -  
710 - const addPointButton = new UIButton( '+' );  
711 - addPointButton.onClick( () => {  
712 -  
713 - if ( this.pointsUI.length === 0 ) {  
714 -  
715 - this.pointsList.add( this.createPointRow( 0, 0, 0 ) ); 545 + const row = new UIRow()
  546 + this.add(row)
716 547
717 - } else { 548 + const addPointButton = new UIButton('+')
  549 + addPointButton.onClick(() => {
  550 + if (this.pointsUI.length === 0) {
  551 + this.pointsList.add(this.createPointRow(0, 0, 0))
  552 + } else {
  553 + const point = this.pointsUI[this.pointsUI.length - 1]
718 554
719 - const point = this.pointsUI[ this.pointsUI.length - 1 ]; 555 + this.pointsList.add(this.createPointRow(point.x.getValue(), point.y.getValue(), point.z.getValue()))
  556 + }
720 557
721 - this.pointsList.add( this.createPointRow( point.x.getValue(), point.y.getValue(), point.z.getValue() ) ); 558 + this.update()
  559 + })
  560 + row.add(addPointButton)
  561 + }
722 562
723 - } 563 + getValue() {
  564 + const points = []
  565 + let count = 0
724 566
725 - this.update(); 567 + for (let i = 0; i < this.pointsUI.length; i++) {
  568 + const pointUI = this.pointsUI[i]
726 569
727 - } );  
728 - row.add( addPointButton ); 570 + if (!pointUI) continue
729 571
730 - } 572 + points.push(new THREE.Vector3(pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue()))
  573 + ++count
  574 + pointUI.lbl.setValue(count)
  575 + }
731 576
732 - getValue() { 577 + return points
  578 + }
733 579
734 - const points = [];  
735 - let count = 0; 580 + setValue(points, needsUpdate = true) {
  581 + this.clear()
736 582
737 - for ( let i = 0; i < this.pointsUI.length; i ++ ) { 583 + for (let i = 0; i < points.length; i++) {
  584 + const point = points[i]
  585 + this.pointsList.add(this.createPointRow(point.x, point.y, point.z))
  586 + }
738 587
739 - const pointUI = this.pointsUI[ i ]; 588 + if (needsUpdate === true) this.update()
740 589
741 - if ( ! pointUI ) continue; 590 + return this
  591 + }
742 592
743 - points.push( new THREE.Vector3( pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue() ) );  
744 - ++ count;  
745 - pointUI.lbl.setValue( count ); 593 + createPointRow(x, y, z) {
  594 + const pointRow = new UIDiv()
  595 + const lbl = new UIText(this.lastPointIdx + 1).setWidth('20px')
  596 + const txtX = new UINumber(x).setWidth('30px').onChange(this.update)
  597 + const txtY = new UINumber(y).setWidth('30px').onChange(this.update)
  598 + const txtZ = new UINumber(z).setWidth('30px').onChange(this.update)
746 599
747 - } 600 + const scope = this
  601 + const btn = new UIButton('-').onClick(function () {
  602 + if (scope.isEditing) return
748 603
749 - return points; 604 + const idx = scope.pointsList.getIndexOfChild(pointRow)
  605 + scope.deletePointRow(idx)
  606 + })
750 607
751 - }  
752 -  
753 - setValue( points, needsUpdate = true ) {  
754 -  
755 - this.clear();  
756 -  
757 - for ( let i = 0; i < points.length; i ++ ) {  
758 -  
759 - const point = points[ i ];  
760 - this.pointsList.add( this.createPointRow( point.x, point.y, point.z ) );  
761 -  
762 - }  
763 -  
764 - if ( needsUpdate === true ) this.update();  
765 -  
766 - return this;  
767 -  
768 - }  
769 -  
770 - createPointRow( x, y, z ) {  
771 -  
772 - const pointRow = new UIDiv();  
773 - const lbl = new UIText( this.lastPointIdx + 1 ).setWidth( '20px' );  
774 - const txtX = new UINumber( x ).setWidth( '30px' ).onChange( this.update );  
775 - const txtY = new UINumber( y ).setWidth( '30px' ).onChange( this.update );  
776 - const txtZ = new UINumber( z ).setWidth( '30px' ).onChange( this.update );  
777 -  
778 - const scope = this;  
779 - const btn = new UIButton( '-' ).onClick( function () {  
780 -  
781 - if ( scope.isEditing ) return;  
782 -  
783 - const idx = scope.pointsList.getIndexOfChild( pointRow );  
784 - scope.deletePointRow( idx );  
785 -  
786 - } );  
787 -  
788 - this.pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ } );  
789 - ++ this.lastPointIdx;  
790 - pointRow.add( lbl, txtX, txtY, txtZ, btn );  
791 -  
792 - return pointRow;  
793 -  
794 - } 608 + this.pointsUI.push({ row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ })
  609 + ++this.lastPointIdx
  610 + pointRow.add(lbl, txtX, txtY, txtZ, btn)
795 611
  612 + return pointRow
  613 + }
796 } 614 }
797 615
798 class UIBoolean extends UISpan { 616 class UIBoolean extends UISpan {
  617 + constructor(boolean, text) {
  618 + super()
799 619
800 - constructor( boolean, text ) {  
801 -  
802 - super();  
803 -  
804 - this.setMarginRight( '4px' );  
805 -  
806 - this.checkbox = new UICheckbox( boolean );  
807 - this.text = new UIText( text ).setMarginLeft( '3px' );  
808 -  
809 - this.add( this.checkbox );  
810 - this.add( this.text );  
811 -  
812 - }  
813 -  
814 - getValue() {  
815 -  
816 - return this.checkbox.getValue(); 620 + this.setMarginRight('4px')
817 621
818 - } 622 + this.checkbox = new UICheckbox(boolean)
  623 + this.text = new UIText(text).setMarginLeft('3px')
819 624
820 - setValue( value ) { 625 + this.add(this.checkbox)
  626 + this.add(this.text)
  627 + }
821 628
822 - return this.checkbox.setValue( value );  
823 -  
824 - } 629 + getValue() {
  630 + return this.checkbox.getValue()
  631 + }
825 632
  633 + setValue(value) {
  634 + return this.checkbox.setValue(value)
  635 + }
826 } 636 }
827 637
828 -let renderer, fsQuad;  
829 -  
830 -function renderToCanvas( texture ) {  
831 -  
832 - if ( renderer === undefined ) {  
833 -  
834 - renderer = new THREE.WebGLRenderer();  
835 -  
836 - }  
837 -  
838 - if ( fsQuad === undefined ) {  
839 -  
840 - fsQuad = new FullScreenQuad( new THREE.MeshBasicMaterial() ); 638 +let renderer, fsQuad
841 639
842 - } 640 +function renderToCanvas(texture) {
  641 + if (renderer === undefined) {
  642 + renderer = new THREE.WebGLRenderer({ preserveDrawingBuffer: true })
  643 + }
843 644
844 - const image = texture.image; 645 + if (fsQuad === undefined) {
  646 + fsQuad = new FullScreenQuad(new THREE.MeshBasicMaterial())
  647 + }
845 648
846 - renderer.setSize( image.width, image.height, false ); 649 + const image = texture.image
847 650
848 - fsQuad.material.map = texture;  
849 - fsQuad.render( renderer ); 651 + renderer.setSize(image.width, image.height, false)
850 652
851 - return renderer.domElement; 653 + fsQuad.material.map = texture
  654 + fsQuad.render(renderer)
852 655
  656 + return renderer.domElement
853 } 657 }
854 658
855 -export { UITexture, UIOutliner, UIPoints, UIPoints2, UIPoints3, UIBoolean }; 659 +export { UITexture, UIOutliner, UIPoints, UIPoints2, UIPoints3, UIBoolean }
  1 +/**
  2 + * * base64转file
  3 + * @param url
  4 + * @param fileName
  5 + * @returns
  6 + */
  7 +export const base64toFile = (url, fileName) => {
  8 + const dataArr = url.split(',')
  9 + const mime = dataArr[0].match(/:(.*?);/)[1]
  10 + const bstr = atob(dataArr[1])
  11 + let n = bstr.length
  12 + const u8arr = new Uint8Array(n)
  13 + while (n--) {
  14 + u8arr[n] = bstr.charCodeAt(n)
  15 + }
  16 + return new File([u8arr], fileName, { type: mime })
  17 +}
@@ -48,6 +48,7 @@ export type ConfigType = { @@ -48,6 +48,7 @@ export type ConfigType = {
48 // 3D模型数据 48 // 3D模型数据
49 threeModelContent?: any 49 threeModelContent?: any
50 threeModelFilePath?: string 50 threeModelFilePath?: string
  51 + threeModelImageUrl?: string
51 } 52 }
52 53
53 // 数据请求 54 // 数据请求
@@ -68,7 +68,8 @@ import { @@ -68,7 +68,8 @@ import {
68 EyeOffOutline as EyeOffOutlineIcon, 68 EyeOffOutline as EyeOffOutlineIcon,
69 Albums as AlbumsIcon, 69 Albums as AlbumsIcon,
70 Analytics as AnalyticsIcon, 70 Analytics as AnalyticsIcon,
71 - AirplaneOutline as AirPlaneOutlineIcon 71 + AirplaneOutline as AirPlaneOutlineIcon,
  72 + Reload as ReloadSearch
72 } from '@vicons/ionicons5' 73 } from '@vicons/ionicons5'
73 74
74 import { 75 import {
@@ -105,6 +106,7 @@ import { @@ -105,6 +106,7 @@ import {
105 } from '@vicons/carbon' 106 } from '@vicons/carbon'
106 107
107 const ionicons5 = { 108 const ionicons5 = {
  109 + ReloadSearch,
108 // 新增 110 // 新增
109 AddIcon, 111 AddIcon,
110 // 帮助(问号) 112 // 帮助(问号)
@@ -27,6 +27,9 @@ @@ -27,6 +27,9 @@
27 </div> 27 </div>
28 <div class="list-center go-flex-center go-transition" draggable="true"> 28 <div class="list-center go-flex-center go-transition" draggable="true">
29 <Icon v-if="item.icon" class="list-img" :icon="item.icon" color="#999" width="48" /> 29 <Icon v-if="item.icon" class="list-img" :icon="item.icon" color="#999" width="48" />
  30 + <div class="list-img" v-else-if="item.threeModelImageUrl">
  31 + <n-image height="100" width="140" object-fit="fill" preview-disabled :src="item.threeModelImageUrl"></n-image>
  32 + </div>
30 <chart-glob-image v-else class="list-img" :chartConfig="item" /> 33 <chart-glob-image v-else class="list-img" :chartConfig="item" />
31 </div> 34 </div>
32 <div class="list-bottom"> 35 <div class="list-bottom">
@@ -75,7 +75,6 @@ const selectValue = ref<string>('all') @@ -75,7 +75,6 @@ const selectValue = ref<string>('all')
75 75
76 const threeJsModels = ref<Recordable[]>([]) 76 const threeJsModels = ref<Recordable[]>([])
77 77
78 -  
79 // 设置初始列表 78 // 设置初始列表
80 const setSelectOptions = (categorys: any) => { 79 const setSelectOptions = (categorys: any) => {
81 for (const val in categorys) { 80 for (const val in categorys) {
@@ -128,18 +127,19 @@ watch( @@ -128,18 +127,19 @@ watch(
128 chartFrame: 'static', 127 chartFrame: 'static',
129 chartKey: 'ExternalVCLoader', 128 chartKey: 'ExternalVCLoader',
130 conKey: 'ExternalVCCLoader', 129 conKey: 'ExternalVCCLoader',
131 - image: 'threeModelDefault.svg', 130 + image: modelItem.imageUrl ? modelItem.imageUrl : 'threeModelDefault.svg',
132 key: 'Loader', 131 key: 'Loader',
133 package: 'Decorates', 132 package: 'Decorates',
134 title: modelItem.name ?? modelItem.id, 133 title: modelItem.name ?? modelItem.id,
135 redirectComponent: 'Decorates/Three/Loader', 134 redirectComponent: 'Decorates/Three/Loader',
136 isThreeModel: true, 135 isThreeModel: true,
137 threeModelContent: modelItem.content, 136 threeModelContent: modelItem.content,
138 - threeModelFilePath: `${threeFilePath}${VITE_GLOB_API_URL}${VITE_GLOB_API_URL_PREFIX}/3d_component/json/${modelItem.id}/scene.json` 137 + threeModelFilePath: `${threeFilePath}${VITE_GLOB_API_URL}${VITE_GLOB_API_URL_PREFIX}/3d_component/json/${modelItem.id}/scene.json`,
  138 + threeModelImageUrl: modelItem.imageUrl
139 } 139 }
140 }) 140 })
141 } 141 }
142 - const mergeList = [...newData.list,...threeJsModels.value] as ConfigType[] 142 + const mergeList = [...newData.list, ...threeJsModels.value] as ConfigType[]
143 mergeList.forEach((e: ConfigType) => { 143 mergeList.forEach((e: ConfigType) => {
144 const value: ConfigType[] = (packages.categorys as Recordable)[e.category] 144 const value: ConfigType[] = (packages.categorys as Recordable)[e.category]
145 packages.categorys[e.category] = value && value.length ? [...value, e] : [e] 145 packages.categorys[e.category] = value && value.length ? [...value, e] : [e]
@@ -54,7 +54,8 @@ const imageInfo = ref('') @@ -54,7 +54,8 @@ const imageInfo = ref('')
54 54
55 // 获取图片 55 // 获取图片
56 const fetchImageUrl = async () => { 56 const fetchImageUrl = async () => {
57 - imageInfo.value = await fetchImages(props.componentData.chartConfig) 57 + const threeModelImageUrl = props.componentData.chartConfig?.threeModelImageUrl
  58 + imageInfo.value = threeModelImageUrl ? threeModelImageUrl : await fetchImages(props.componentData.chartConfig)
58 } 59 }
59 fetchImageUrl() 60 fetchImageUrl()
60 61
@@ -181,7 +181,6 @@ export const useSyncRemote = () => { @@ -181,7 +181,6 @@ export const useSyncRemote = () => {
181 181
182 //thumbnailSyncUpdate 缩略图保存 182 //thumbnailSyncUpdate 缩略图保存
183 const thumbnailSyncUpdate = throttle(async (updateImg = true) => { 183 const thumbnailSyncUpdate = throttle(async (updateImg = true) => {
184 - console.log(projectInfoStore.getProjectInfo, 'projectInfoStore.getProjectInfo')  
185 const { state, organizationId, dataViewName, thumbnail } = projectInfoStore.getProjectInfo 184 const { state, organizationId, dataViewName, thumbnail } = projectInfoStore.getProjectInfo
186 if (updateImg) { 185 if (updateImg) {
187 // 获取缩略图片 186 // 获取缩略图片
1 <template> 1 <template>
2 <div v-if="cardData" class="go-items-list-card"> 2 <div v-if="cardData" class="go-items-list-card">
3 - <n-card hoverable size="small"> 3 + <n-card :hoverable="false" size="small">
4 <div class="list-content"> 4 <div class="list-content">
5 - <!-- 顶部按钮 -->  
6 - <div class="list-content-top">  
7 - <mac-os-control-btn  
8 - class="top-btn"  
9 - :hidden="['remove']"  
10 - @close="deleteHandle"  
11 - @resize="handleLoadThreeModel"  
12 - ></mac-os-control-btn>  
13 - </div>  
14 - <!-- 中间 -->  
15 <div class="list-content-img"> 5 <div class="list-content-img">
16 - <LoadThreeModelImage v-if="showThreeModel" :threeModelPath="cardData.threeModelFilePath" />  
17 <n-image 6 <n-image
18 - object-fit="contain" 7 + object-fit="fill"
19 height="180" 8 height="180"
  9 + width="350"
20 preview-disabled 10 preview-disabled
21 - v-else  
22 - :src="requireUrl('ThreeModelDefault.svg')" 11 + :src="requestImag(cardData.imageUrl)"
  12 + :alt="cardData.name"
23 :fallback-src="requireErrorImg()" 13 :fallback-src="requireErrorImg()"
24 ></n-image> 14 ></n-image>
25 </div> 15 </div>
26 </div> 16 </div>
27 <template #action> 17 <template #action>
28 <div class="go-flex-items-center list-footer" justify="space-between"> 18 <div class="go-flex-items-center list-footer" justify="space-between">
29 - <n-text @click="handleFocus">  
30 - <n-button v-show="!focus" secondary size="tiny">  
31 - <span class="title">  
32 - {{ cardData.name || cardData.id }}  
33 - </span>  
34 - </n-button>  
35 - </n-text>  
36 - <n-input  
37 - v-show="focus"  
38 - ref="inputInstRef"  
39 - size="small"  
40 - type="text"  
41 - maxlength="16"  
42 - show-count  
43 - v-model:value.trim="title"  
44 - @keyup.enter="handleBlur"  
45 - @blur="handleBlur"  
46 - ></n-input> 19 + <div style="display: flex; flex-direction: column; align-items: start">
  20 + <n-text @click="handleFocus">
  21 + <n-button v-show="!focus" secondary size="tiny">
  22 + <span class="title">
  23 + {{ cardData.name || cardData.id }}
  24 + </span>
  25 + </n-button>
  26 + </n-text>
  27 + <n-input
  28 + v-show="focus"
  29 + ref="inputInstRef"
  30 + size="small"
  31 + type="text"
  32 + maxlength="16"
  33 + show-count
  34 + v-model:value.trim="title"
  35 + @keyup.enter="handleBlur"
  36 + @blur="handleBlur"
  37 + ></n-input>
  38 + <n-text style="font-size: 12px; margin-left: 6px">{{ cardData.createTime }}</n-text>
  39 + </div>
47 <!-- 工具 --> 40 <!-- 工具 -->
48 <div class="go-flex-items-center list-footer-ri"> 41 <div class="go-flex-items-center list-footer-ri">
49 <n-space> 42 <n-space>
@@ -97,10 +90,8 @@ @@ -97,10 +90,8 @@
97 import { reactive, ref, PropType, nextTick } from 'vue' 90 import { reactive, ref, PropType, nextTick } from 'vue'
98 import { renderIcon, renderLang, requireErrorImg } from '@/utils' 91 import { renderIcon, renderLang, requireErrorImg } from '@/utils'
99 import { icon } from '@/plugins' 92 import { icon } from '@/plugins'
100 -import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn'  
101 import { ChartType } from '../..' 93 import { ChartType } from '../..'
102 import { updateThreeJsModel } from '@/api/external/contentSave/content' 94 import { updateThreeJsModel } from '@/api/external/contentSave/content'
103 -import LoadThreeModelImage from '../LoadThreeModelImage.vue'  
104 95
105 const { EllipsisHorizontalCircleSharpIcon, TrashIcon, HammerIcon, SendIcon } = icon.ionicons5 96 const { EllipsisHorizontalCircleSharpIcon, TrashIcon, HammerIcon, SendIcon } = icon.ionicons5
106 97
@@ -110,21 +101,17 @@ const props = defineProps({ @@ -110,21 +101,17 @@ const props = defineProps({
110 cardData: Object as PropType<ChartType> 101 cardData: Object as PropType<ChartType>
111 }) 102 })
112 103
  104 +// 处理url获取
  105 +const requireUrl = (name: string) => {
  106 + return new URL(`../../../../../assets/images/${name}`, import.meta.url).href
  107 +}
  108 +
113 const focus = ref<boolean>(false) 109 const focus = ref<boolean>(false)
114 110
115 const inputInstRef = ref(null) 111 const inputInstRef = ref(null)
116 112
117 const title = ref<string>('') 113 const title = ref<string>('')
118 114
119 -const showThreeModel = ref(false)  
120 -  
121 -const handleLoadThreeModel = () => (showThreeModel.value = true)  
122 -  
123 -// 处理url获取  
124 -const requireUrl = (name: string) => {  
125 - return new URL(`../../../../../assets/images/${name}`, import.meta.url).href  
126 -}  
127 -  
128 const fnBtnList = reactive([ 115 const fnBtnList = reactive([
129 { 116 {
130 label: renderLang('global.r_edit'), 117 label: renderLang('global.r_edit'),
@@ -180,11 +167,6 @@ const releaseHandle = () => { @@ -180,11 +167,6 @@ const releaseHandle = () => {
180 emit('release', props.cardData) 167 emit('release', props.cardData)
181 } 168 }
182 169
183 -// // 放大处理  
184 -// const resizeHandle = () => {  
185 -// emit('resize', props.cardData)  
186 -// }  
187 -  
188 const handleFocus = () => { 170 const handleFocus = () => {
189 focus.value = true 171 focus.value = true
190 nextTick(() => { 172 nextTick(() => {
@@ -202,6 +184,10 @@ const handleBlur = async () => { @@ -202,6 +184,10 @@ const handleBlur = async () => {
202 emit('inputUpdateCard') 184 emit('inputUpdateCard')
203 window['$message'].success(window['$t']('common.operationSuccessText')) 185 window['$message'].success(window['$t']('common.operationSuccessText'))
204 } 186 }
  187 +
  188 +const requestImag = (imageUrl: string | undefined) => {
  189 + return !imageUrl ? requireUrl('ThreeModelDefault.svg') : imageUrl
  190 +}
205 </script> 191 </script>
206 192
207 <style lang="scss" scoped> 193 <style lang="scss" scoped>
@@ -215,12 +201,10 @@ $contentHeight: 180px; @@ -215,12 +201,10 @@ $contentHeight: 180px;
215 @include hover-border-color('hover-border-color'); 201 @include hover-border-color('hover-border-color');
216 } 202 }
217 .list-content { 203 .list-content {
218 - margin-top: 20px;  
219 - margin-bottom: 5px;  
220 cursor: pointer; 204 cursor: pointer;
221 border-radius: $--border-radius-base; 205 border-radius: $--border-radius-base;
222 - @include background-image('background-point');  
223 - @extend .go-point-bg; 206 + // @include background-image('background-point');
  207 + // @extend .go-point-bg;
224 &-top { 208 &-top {
225 position: absolute; 209 position: absolute;
226 top: 10px; 210 top: 10px;
@@ -6,14 +6,14 @@ import { getThreeJsModelList, putThreeJsModelRelease, threeJsDeleteApi } from '@ @@ -6,14 +6,14 @@ import { getThreeJsModelList, putThreeJsModelRelease, threeJsDeleteApi } from '@
6 import { PaginationResult } from '/#/external/axios' 6 import { PaginationResult } from '/#/external/axios'
7 7
8 // 数据初始化 8 // 数据初始化
9 -export const useDataListInit = () => { 9 +export const useDataListInit = (formValue: { name: string; state: string | null }) => {
10 const loading = ref(true) 10 const loading = ref(true)
11 11
12 const pagination = reactive({ 12 const pagination = reactive({
13 // 当前页数 13 // 当前页数
14 page: 1, 14 page: 1,
15 // 每页值 15 // 每页值
16 - pageSize: 12, 16 + pageSize: 8,
17 // 总数 17 // 总数
18 count: 10 18 count: 10
19 }) 19 })
@@ -23,9 +23,17 @@ export const useDataListInit = () => { @@ -23,9 +23,17 @@ export const useDataListInit = () => {
23 // 数据请求 23 // 数据请求
24 const fetchList = async () => { 24 const fetchList = async () => {
25 loading.value = true 25 loading.value = true
  26 + const searchParams: Recordable = {}
  27 + if (Reflect.get(formValue, 'name')) {
  28 + searchParams['name'] = formValue.name
  29 + }
  30 + if (Reflect.get(formValue, 'state')) {
  31 + searchParams['state'] = formValue.state === 'yes' ? 1 : 0
  32 + }
26 const res = await getThreeJsModelList({ 33 const res = await getThreeJsModelList({
27 page: pagination.page, 34 page: pagination.page,
28 - pageSize: pagination.pageSize 35 + pageSize: pagination.pageSize,
  36 + ...searchParams
29 }) 37 })
30 if (res) { 38 if (res) {
31 const { host, protocol } = location 39 const { host, protocol } = location
@@ -47,6 +55,8 @@ export const useDataListInit = () => { @@ -47,6 +55,8 @@ export const useDataListInit = () => {
47 55
48 const inputUpdateHandle = () => fetchList() 56 const inputUpdateHandle = () => fetchList()
49 57
  58 + const handleSearchClick = () => fetchList()
  59 +
50 // 修改页数 60 // 修改页数
51 const changePage = (_page: number) => { 61 const changePage = (_page: number) => {
52 pagination.page = _page 62 pagination.page = _page
@@ -106,6 +116,7 @@ export const useDataListInit = () => { @@ -106,6 +116,7 @@ export const useDataListInit = () => {
106 changePage, 116 changePage,
107 deleteHandle, 117 deleteHandle,
108 releaseHandle, 118 releaseHandle,
109 - inputUpdateHandle 119 + inputUpdateHandle,
  120 + handleSearchClick
110 } 121 }
111 } 122 }
1 <template> 1 <template>
2 <div class="go-items-list"> 2 <div class="go-items-list">
  3 + <!-- 搜索区域 -->
  4 + <n-form ref="formRef" label-placement="left" label-width="auto" :model="formValue" :size="formSize">
  5 + <n-grid :cols="24" :x-gap="24">
  6 + <n-grid-item :span="6" label="Input" path="name">
  7 + <n-form-item label="名称" path="name">
  8 + <n-input v-model:value="formValue.name" placeholder="输入名称" />
  9 + </n-form-item>
  10 + </n-grid-item>
  11 + <n-grid-item :span="6" label="Select" path="state">
  12 + <n-form-item label="状态" path="state">
  13 + <n-select v-model:value="formValue.state" placeholder="选择状态" :options="statusOptions" />
  14 + </n-form-item>
  15 + </n-grid-item>
  16 + <n-grid-item :span="8">
  17 + <n-button type="primary" @click="handleSearchClick">
  18 + <template #icon>
  19 + <n-icon>
  20 + <SearchIcon />
  21 + </n-icon>
  22 + </template>
  23 + 查询
  24 + </n-button>
  25 + <n-button style="margin-left: 20px" @click="handleResetClick">
  26 + <template #icon>
  27 + <n-icon>
  28 + <ReloadSearch />
  29 + </n-icon>
  30 + </template>
  31 + 重置
  32 + </n-button>
  33 + </n-grid-item>
  34 + </n-grid>
  35 + </n-form>
3 <div v-show="loading"> 36 <div v-show="loading">
4 <go-loading></go-loading> 37 <go-loading></go-loading>
5 </div> 38 </div>
6 <div v-show="!loading"> 39 <div v-show="!loading">
7 - <n-grid :x-gap="20" :y-gap="20" cols="2 s:2 m:3 l:4 xl:4 xxl:4" responsive="screen"> 40 + <div style="display: flex; flex-direction: row-reverse">
  41 + <n-space>
  42 + <n-button type="primary" @click="handleOpenThreeEditor"> 新增 </n-button>
  43 + <!-- <n-button disabled> 批量操作 </n-button> -->
  44 + </n-space>
  45 + </div>
  46 + <n-grid style="margin-top: 16px" :x-gap="20" :y-gap="20" cols="2 s:2 m:3 l:4 xl:4 xxl:4" responsive="screen">
8 <n-grid-item v-for="(item, index) in list" :key="item.id"> 47 <n-grid-item v-for="(item, index) in list" :key="item.id">
9 <div style="display: none">{{ index }}</div> 48 <div style="display: none">{{ index }}</div>
10 <project-items-card 49 <project-items-card
@@ -23,11 +62,13 @@ @@ -23,11 +62,13 @@
23 :page="pagination.page" 62 :page="pagination.page"
24 :page-size="pagination.pageSize" 63 :page-size="pagination.pageSize"
25 :item-count="pagination.count" 64 :item-count="pagination.count"
26 - :page-sizes="[12, 24, 36, 48]" 65 + :page-sizes="[8, 16, 24, 32]"
27 @update:page="changePage" 66 @update:page="changePage"
28 @update:page-size="changeSize" 67 @update:page-size="changeSize"
29 show-size-picker 68 show-size-picker
30 - /> 69 + >
  70 + <template #prefix> 共 {{ pagination.count }} 条 </template>
  71 + </n-pagination>
31 </div> 72 </div>
32 </div> 73 </div>
33 <project-items-modal-card 74 <project-items-modal-card
@@ -44,10 +85,58 @@ import { ProjectItemsCard } from '../ProjectItemsCard/index' @@ -44,10 +85,58 @@ import { ProjectItemsCard } from '../ProjectItemsCard/index'
44 import { ProjectItemsModalCard } from '../ProjectItemsModalCard/index' 85 import { ProjectItemsModalCard } from '../ProjectItemsModalCard/index'
45 import { useModalDataInit } from './hooks/useModal.hook' 86 import { useModalDataInit } from './hooks/useModal.hook'
46 import { useDataListInit } from './hooks/useData.hook' 87 import { useDataListInit } from './hooks/useData.hook'
  88 +import { ref } from 'vue'
  89 +import type { FormInst } from 'naive-ui'
  90 +import { icon } from '@/plugins'
  91 +import { getUUID } from '@/utils/utils'
  92 +
  93 +const { SearchIcon, ReloadSearch } = icon.ionicons5
47 94
48 const { modalData, modalShow, closeModal, resizeHandle, editHandle } = useModalDataInit() 95 const { modalData, modalShow, closeModal, resizeHandle, editHandle } = useModalDataInit()
49 96
50 -const { loading, pagination, list, changeSize, changePage, deleteHandle, releaseHandle, inputUpdateHandle } = useDataListInit() 97 +const formRef = ref<FormInst | null>(null)
  98 +
  99 +const formSize = ref('medium')
  100 +
  101 +const formValue = ref({
  102 + name: '',
  103 + state: null
  104 +})
  105 +
  106 +const statusOptions = ref([
  107 + {
  108 + label: '已发布',
  109 + value: 'yes'
  110 + },
  111 + {
  112 + label: '未发布',
  113 + value: 'no'
  114 + }
  115 +])
  116 +
  117 +const {
  118 + loading,
  119 + pagination,
  120 + list,
  121 + changeSize,
  122 + changePage,
  123 + deleteHandle,
  124 + releaseHandle,
  125 + inputUpdateHandle,
  126 + handleSearchClick
  127 +} = useDataListInit(formValue.value)
  128 +
  129 +const handleResetClick = () => {
  130 + formValue.value.name = ''
  131 + formValue.value.state = null
  132 + handleSearchClick()
  133 +}
  134 +
  135 +const handleOpenThreeEditor = () => {
  136 + const { host, protocol, pathname } = location
  137 + const randomId = getUUID(32)
  138 + window.open(`${protocol}//${host}${pathname}editor/?three_file_uuid=${randomId}&action_type=create`)
  139 +}
51 </script> 140 </script>
52 141
53 <style lang="scss" scoped> 142 <style lang="scss" scoped>
@@ -55,16 +144,15 @@ $contentHeight: 250px; @@ -55,16 +144,15 @@ $contentHeight: 250px;
55 @include go('items-list') { 144 @include go('items-list') {
56 display: flex; 145 display: flex;
57 flex-direction: column; 146 flex-direction: column;
58 - justify-content: space-between;  
59 min-height: calc(100vh - #{$--header-height} * 2 - 2px); 147 min-height: calc(100vh - #{$--header-height} * 2 - 2px);
60 .list-content { 148 .list-content {
61 position: relative; 149 position: relative;
62 height: $contentHeight; 150 height: $contentHeight;
63 } 151 }
64 .list-pagination { 152 .list-pagination {
65 - display: flex;  
66 - justify-content: flex-end;  
67 - margin-top: 20px; 153 + position: fixed;
  154 + bottom: 30px;
  155 + right: 30px;
68 } 156 }
69 } 157 }
70 </style> 158 </style>
@@ -8,6 +8,7 @@ export type ChartType = { @@ -8,6 +8,7 @@ export type ChartType = {
8 state?: number 8 state?: number
9 name?: string 9 name?: string
10 threeModelFilePath?: string 10 threeModelFilePath?: string
  11 + imageUrl?: string | undefined
11 } 12 }
12 13
13 export type ChartList = ChartType[] 14 export type ChartList = ChartType[]
@@ -13,44 +13,29 @@ @@ -13,44 +13,29 @@
13 > 13 >
14 <div class="go-project-sider-flex"> 14 <div class="go-project-sider-flex">
15 <aside> 15 <aside>
16 - <n-space vertical class="go-project-sider-top">  
17 - <project-layout-create :collapsed="collapsed"></project-layout-create>  
18 - </n-space>  
19 <n-menu 16 <n-menu
20 - :value="menuValue"  
21 :options="menuOptions" 17 :options="menuOptions"
22 :collapsed-width="getAsideCollapsedWidth" 18 :collapsed-width="getAsideCollapsedWidth"
23 :collapsed-icon-size="22" 19 :collapsed-icon-size="22"
24 - :default-expanded-keys="defaultExpandedKeys"  
25 - ></n-menu> 20 + default-value="three-project"
  21 + ></n-menu>
26 </aside> 22 </aside>
27 - <!-- 底部提示 -->  
28 - <!-- <div class="sider-bottom">  
29 - <project-layout-aside-footer :collapsed="collapsed"></project-layout-aside-footer>  
30 - </div> -->  
31 </div> 23 </div>
32 </n-layout-sider> 24 </n-layout-sider>
33 </template> 25 </template>
34 26
35 <script setup lang="ts"> 27 <script setup lang="ts">
36 -import { ref, computed, onMounted, onUnmounted, toRefs } from 'vue'  
37 -import { ProjectLayoutCreate } from '../ProjectLayoutCreate/index'  
38 -import { ProjectLayoutAsideFooter } from '../ProjectLayoutAsideFooter/index' 28 +import { ref, onMounted, onUnmounted, toRefs } from 'vue'
39 import { asideWidth } from '@/settings/designSetting' 29 import { asideWidth } from '@/settings/designSetting'
40 -import { useRoute } from 'vue-router'  
41 import { useSettingStore } from '@/store/modules/settingStore/settingStore' 30 import { useSettingStore } from '@/store/modules/settingStore/settingStore'
42 -import { menuOptionsInit, expandedKeys } from './menu' 31 +import { menuOptionsInit } from './menu'
43 32
44 const collapsed = ref<boolean>(false) 33 const collapsed = ref<boolean>(false)
45 -const { getAsideCollapsedWidth } = toRefs(useSettingStore())  
46 34
47 -const route = useRoute()  
48 -const menuValue = computed(() => route.name) 35 +const { getAsideCollapsedWidth } = toRefs(useSettingStore())
49 36
50 const menuOptions = menuOptionsInit() 37 const menuOptions = menuOptionsInit()
51 38
52 -const defaultExpandedKeys = expandedKeys()  
53 -  
54 const watchWidth = () => { 39 const watchWidth = () => {
55 const Width = document.body.clientWidth 40 const Width = document.body.clientWidth
56 if (Width <= 950) { 41 if (Width <= 950) {
@@ -62,7 +47,7 @@ onMounted(() => { @@ -62,7 +47,7 @@ onMounted(() => {
62 window.addEventListener('resize', watchWidth) 47 window.addEventListener('resize', watchWidth)
63 }) 48 })
64 49
65 -onUnmounted(()=> { 50 +onUnmounted(() => {
66 window.removeEventListener('resize', watchWidth) 51 window.removeEventListener('resize', watchWidth)
67 }) 52 })
68 </script> 53 </script>
1 import { reactive, h } from 'vue' 1 import { reactive, h } from 'vue'
2 import { renderIcon } from '@/utils' 2 import { renderIcon } from '@/utils'
3 -import { RouterLink } from 'vue-router'  
4 -import { PageEnum } from '@/enums/pageEnum'  
5 import { MenuOption, MenuGroupOption } from 'naive-ui' 3 import { MenuOption, MenuGroupOption } from 'naive-ui'
6 import { icon } from '@/plugins' 4 import { icon } from '@/plugins'
7 5
8 -const { TvOutlineIcon } = icon.ionicons5  
9 const { DevicesIcon } = icon.carbon 6 const { DevicesIcon } = icon.carbon
  7 +
10 export const renderMenuLabel = (option: MenuOption | MenuGroupOption) => { 8 export const renderMenuLabel = (option: MenuOption | MenuGroupOption) => {
11 return option.label 9 return option.label
12 } 10 }
13 11
14 -export const expandedKeys = () => ['three-project'] 12 +export const expandedKeys = () => 'three-project'
15 13
16 export const menuOptionsInit = () => { 14 export const menuOptionsInit = () => {
17 const t = window['$t'] 15 const t = window['$t']
18 -  
19 return reactive([ 16 return reactive([
20 { 17 {
21 - key: 'divider-1',  
22 - type: 'divider'  
23 - },  
24 - {  
25 - label: () => h('span', null, { default: () => t('project.project') }), 18 + label: () => h('span', null, { default: () => t('project.three_project') }),
26 key: 'three-project', 19 key: 'three-project',
27 - icon: renderIcon(DevicesIcon),  
28 - children: [  
29 - {  
30 - type: 'group',  
31 - label: () => h('span', null, { default: () => t('project.three_project') }),  
32 - key: 'my-three-project',  
33 - children: [  
34 - {  
35 - label: () =>  
36 - h(  
37 - RouterLink,  
38 - {  
39 - to: {  
40 - name: PageEnum.THREE_HOME_ITEMS_NAME  
41 - }  
42 - },  
43 - { default: () => t('project.all_project') }  
44 - ),  
45 - key: PageEnum.THREE_HOME_ITEMS_NAME,  
46 - icon: renderIcon(TvOutlineIcon)  
47 - }  
48 - ]  
49 - }  
50 - ] 20 + icon: renderIcon(DevicesIcon)
51 } 21 }
52 ]) 22 ])
53 } 23 }