@mapgis/webclient-vue-cesium 10.5.5-1 → 10.5.5-6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +46 -49
  2. package/dist-libs/webclient-vue-cesium.common.js +191087 -0
  3. package/dist-libs/webclient-vue-cesium.css +1 -1
  4. package/dist-libs/webclient-vue-cesium.umd.js +191097 -0
  5. package/dist-libs/webclient-vue-cesium.umd.min.js +204 -194
  6. package/docs/.vuepress/config.js +47 -46
  7. package/docs/README.md +5 -4
  8. package/docs/api/analysis/Aspect.md +236 -0
  9. package/docs/api/analysis/Contour.md +240 -0
  10. package/docs/api/analysis/CutFill.md +306 -0
  11. package/docs/api/analysis/DynamicSection.md +336 -0
  12. package/docs/api/analysis/Excavate.md +3 -11
  13. package/docs/api/analysis/Flood.md +177 -200
  14. package/docs/api/analysis/HeightLimited.md +7 -4
  15. package/docs/api/analysis/ParticleEffects.md +549 -0
  16. package/docs/api/analysis/Profile.md +464 -0
  17. package/docs/api/analysis/Shadow.md +76 -13
  18. package/docs/api/analysis/Sightline.md +66 -13
  19. package/docs/api/analysis/Skyline.md +144 -29
  20. package/docs/api/analysis/Slope.md +236 -0
  21. package/docs/api/analysis/Viewshed.md +100 -21
  22. package/docs/api/layer/IGServer/IgsDocLayer.md +10 -0
  23. package/docs/api/layer/IGServer/IgsFeatureLayer.md +253 -0
  24. package/docs/api/layer/IGServer/IgsTileLayer.md +11 -0
  25. package/docs/api/layer/OGC/CesiumOgcWmsLayer.md +20 -19
  26. package/docs/api/layer/OGC/Wms.png +0 -0
  27. package/docs/api/layer/marker/DynamicMarker.md +81 -0
  28. package/docs/api/layer/marker/dynamicmarker.png +0 -0
  29. package/docs/api/layer/marker/selects.png +0 -0
  30. package/docs/api/layer/vectortile/vectortile.md +10 -0
  31. package/docs/api/m3d/image/layer_control_1.png +0 -0
  32. package/docs/api/m3d/image/layer_control_2.png +0 -0
  33. package/docs/api/m3d/image/layer_control_3.png +0 -0
  34. package/docs/api/m3d/m3d.md +13 -2
  35. package/docs/api/service/comprehensiveQuery/comprehensiveQuery.md +946 -0
  36. package/docs/api/ui/draw.md +68 -40
  37. package/docs/api/ui/link.md +8 -1
  38. package/docs/api/ui/marker.md +19 -1
  39. package/docs/api/ui/measure.md +82 -10
  40. package/docs/api/ui/table.md +6 -6
  41. package/docs/guide/README.md +26 -23
  42. package/docs/guide/basemap.md +35 -33
  43. package/docs/guide/markers&popups.md +46 -53
  44. package/docs/plugin_components/create_storybook.md +241 -0
  45. package/docs/plugin_components/img.png +0 -0
  46. package/docs/plugin_components/img_1.png +0 -0
  47. package/docs/plugin_components/img_10.png +0 -0
  48. package/docs/plugin_components/img_2.png +0 -0
  49. package/docs/plugin_components/img_3.png +0 -0
  50. package/docs/plugin_components/img_4.png +0 -0
  51. package/docs/plugin_components/img_5.png +0 -0
  52. package/docs/plugin_components/img_6.png +0 -0
  53. package/docs/plugin_components/img_7.png +0 -0
  54. package/docs/plugin_components/img_8.png +0 -0
  55. package/docs/version/diff.md +4 -4
  56. package/docs/version/version.md +81 -0
  57. package/package.json +5 -5
  58. package/src/cdn/cdn_component.js +62 -0
  59. package/src/component.js +20 -2
  60. package/src/components/Analysis/Aspect.vue +318 -0
  61. package/src/components/Analysis/Contour.vue +257 -0
  62. package/src/components/Analysis/CutFill.vue +581 -0
  63. package/src/components/Analysis/DynamicCutting.vue +98 -59
  64. package/src/components/Analysis/DynamicSection.vue +494 -0
  65. package/src/components/Analysis/Excavate.vue +133 -87
  66. package/src/components/Analysis/Flood.vue +395 -487
  67. package/src/components/Analysis/Flood.vue-- +630 -0
  68. package/src/components/Analysis/HeightLimited.vue +66 -47
  69. package/src/components/Analysis/ModelFlatten.vue +2 -2
  70. package/src/components/Analysis/Profile.vue +503 -0
  71. package/src/components/Analysis/Shadow.vue +220 -309
  72. package/src/components/Analysis/Sightline.vue +393 -375
  73. package/src/components/Analysis/SkyLine.vue +283 -93
  74. package/src/components/Analysis/Slope.vue +317 -0
  75. package/src/components/Analysis/Viewshed.vue +806 -373
  76. package/src/components/Analysis/skyline2dChartOptions.js +66 -0
  77. package/src/components/DataSource/Geojson/GeoJsonDataSource.vue +201 -3
  78. package/src/components/Layer/GeoJSON/GeoJsonLayer.vue +345 -0
  79. package/src/components/Layer/IGServer/IgsFeatureLayer.vue +227 -0
  80. package/src/components/Layer/Marker/DynamicMarkerLayer.vue +487 -0
  81. package/src/components/Layer/Marker/Marker3dPro.vue +196 -0
  82. package/src/components/Layer/Marker/Marker3dSetPro.vue +67 -0
  83. package/src/components/Layer/VectorTile/VectorTileLayer.vue +117 -33
  84. package/src/components/Layer/VectorTile/VectorTileOptions.js +1 -1
  85. package/src/components/M3D/3DTilesetOptions.js +23 -1
  86. package/src/components/M3D/G3D.vue +150 -0
  87. package/src/components/M3D/M3d.vue +142 -32
  88. package/src/components/M3D/M3dSet.vue +118 -0
  89. package/src/components/M3D/M3dType.js +24 -0
  90. package/src/components/Overlay/Mapv3dLayer.vue +2 -0
  91. package/src/components/Overlay/ParticleEffects.vue +545 -0
  92. package/src/components/Overlay/mapv/MapvBaseLayer.js +351 -172
  93. package/src/components/Overlay/mapv/MapvLayer.js +372 -324
  94. package/src/components/Overlay/mapv/SuperCluster.js +611 -0
  95. package/src/components/Overlay/themeLayer/heater/CesiumHeater.vue +152 -0
  96. package/src/components/Overlay/themeLayer/heater/MapvHeater.vue +161 -0
  97. package/src/components/UI/Controls/Draw/Draw.vue +320 -92
  98. package/src/components/UI/Controls/Legend/Legend.vue +55 -51
  99. package/src/components/UI/Controls/Link/Link.vue +59 -37
  100. package/src/components/UI/Controls/Measure/Measure.vue +75 -33
  101. package/src/components/UI/Controls/Measure/components/MeasureResult.vue +71 -0
  102. package/src/components/UI/Controls/Measure/components/MeasureSetting.vue +63 -0
  103. package/src/components/UI/Controls/Measure/components/MeasureTool.vue +155 -0
  104. package/src/components/UI/Geojson/Popup.vue +101 -0
  105. package/src/components/UI/Marker/Marker.vue +185 -48
  106. package/src/components/UI/Popup/Popup.vue +21 -64
  107. package/src/components/Utils/common/color-util.js +159 -0
  108. package/src/components/Utils/util.js +311 -231
  109. package/src/components/WebGlobe/manager.js +81 -3
  110. package/src/components/WebGlobe/mixins/withPrivateMethods.js +4 -2
  111. package/src/components/WebGlobe/util.js +173 -0
  112. package/src/components/service/comprehensive-query/ComprehensiveQuery.vue +156 -0
  113. package/src/components/service/comprehensive-query/PlaceNameCesium.vue +102 -0
  114. package/src/components/service/comprehensive-query/util/catalog/document.js +626 -0
  115. package/src/components/service/comprehensive-query/util/feature/arcgis-feature-query.js +448 -0
  116. package/src/components/service/comprehensive-query/util/feature/feature-convert.js +408 -0
  117. package/src/components/service/comprehensive-query/util/feature/feature-edit.js +50 -0
  118. package/src/components/service/comprehensive-query/util/feature/feature-geojson.js +100 -0
  119. package/src/components/service/comprehensive-query/util/feature/feature-query.js +723 -0
  120. package/src/components/service/comprehensive-query/util/feature/feature.js +1 -0
  121. package/src/components/service/comprehensive-query/util/feature/index.js +9 -0
  122. package/src/components/service/comprehensive-query/util/objects/geometry.js +58 -0
  123. package/src/components/Overlay/Mapv.vue +0 -142
  124. package/src/components/Overlay/MapvHeater.vue +0 -98
@@ -0,0 +1,494 @@
1
+ <template>
2
+ <div>
3
+ <slot>
4
+ <mapgis-ui-group-tab
5
+ title="模型"
6
+ :has-top-margin="false"
7
+ ></mapgis-ui-group-tab>
8
+ <mapgis-ui-row class="model">
9
+ <mapgis-ui-radio-group v-if="models.length > 0" v-model="model">
10
+ <mapgis-ui-radio
11
+ v-for="(node, index) in models"
12
+ :style="radioStyle"
13
+ :key="`model-${index}`"
14
+ :value="node"
15
+ >
16
+ {{ node.title }}
17
+ </mapgis-ui-radio>
18
+ </mapgis-ui-radio-group>
19
+ <div v-else>暂无数据!</div>
20
+ </mapgis-ui-row>
21
+ <mapgis-ui-group-tab title="坐标轴"> </mapgis-ui-group-tab>
22
+ <mapgis-ui-row class="axisCopy">
23
+ <mapgis-ui-radio-group v-model="axisCopy">
24
+ <mapgis-ui-radio value="X"> X轴 </mapgis-ui-radio>
25
+ <mapgis-ui-radio value="Y"> Y轴 </mapgis-ui-radio>
26
+ <mapgis-ui-radio value="Z"> Z轴 </mapgis-ui-radio>
27
+ </mapgis-ui-radio-group>
28
+ </mapgis-ui-row>
29
+ <mapgis-ui-group-tab title="参数设置"></mapgis-ui-group-tab>
30
+ <mapgis-ui-setting-form :label-width="72">
31
+ <mapgis-ui-form-item label="剖面颜色">
32
+ <mapgis-ui-sketch-color-picker
33
+ :color.sync="colorCopy"
34
+ :disableAlpha="false"
35
+ class="colorCopy-picker"
36
+ >
37
+ </mapgis-ui-sketch-color-picker>
38
+ </mapgis-ui-form-item>
39
+ <mapgis-ui-form-item label="动画时间">
40
+ <mapgis-ui-input-number
41
+ v-model="timeCopy"
42
+ :min="0"
43
+ style="width: 100%"
44
+ />
45
+ </mapgis-ui-form-item>
46
+ <mapgis-ui-form-item label="剖切距离">
47
+ <mapgis-ui-slider
48
+ v-model="distanceCopy"
49
+ :min="min"
50
+ :max="max"
51
+ @change="setDistance"
52
+ :disabled="readonly"
53
+ />
54
+ </mapgis-ui-form-item>
55
+ </mapgis-ui-setting-form>
56
+ <mapgis-ui-setting-footer>
57
+ <mapgis-ui-button type="primary" @click="startClipping">
58
+ 分析
59
+ </mapgis-ui-button>
60
+ <mapgis-ui-button type="primary" @click="animation">
61
+ 动态效果
62
+ </mapgis-ui-button>
63
+ <mapgis-ui-button @click="stopClipping"> 清除 </mapgis-ui-button>
64
+ </mapgis-ui-setting-footer>
65
+ </slot>
66
+ </div>
67
+ </template>
68
+
69
+ <script>
70
+ import { makeColor } from "../Utils/util";
71
+ import BaseLayer from "./BaseLayer";
72
+
73
+ export default {
74
+ name: "mapgis-3d-dynamic-section",
75
+ inject: ["Cesium", "CesiumZondy", "webGlobe"],
76
+ mixins: [BaseLayer],
77
+ props: {
78
+ // 模型集合
79
+ models: {
80
+ type: Array,
81
+ default: () => []
82
+ },
83
+ axis: {
84
+ type: String,
85
+ default: "X"
86
+ },
87
+ color: {
88
+ type: String,
89
+ default: "rgb(200,200,200,0.5)"
90
+ },
91
+ time: {
92
+ type: Number,
93
+ default: 10
94
+ },
95
+ distance: {
96
+ type: Number,
97
+ default: 0
98
+ }
99
+ },
100
+ data() {
101
+ return {
102
+ // 选中模型
103
+ model: null,
104
+
105
+ // 默认坐标轴
106
+ axisCopy: "X",
107
+
108
+ // 默认裁剪边缘颜色
109
+ colorCopy: "rgb(200,200,200,0.5)",
110
+
111
+ // 默认动画时间
112
+ timeCopy: 10,
113
+
114
+ // 默认剖切距离
115
+ distanceCopy: 0,
116
+
117
+ // 最大剖切距离
118
+ max: 10000,
119
+
120
+ // 最小剖切距离
121
+ min: -10000,
122
+
123
+ // 时间轴
124
+ timer: null,
125
+
126
+ // slider滑块是否禁用
127
+ readonly: false,
128
+
129
+ // 组件是否已激活
130
+ isActive: false,
131
+
132
+ // radio样式
133
+ radioStyle: {
134
+ display: "block",
135
+ height: "30px",
136
+ lineHeight: "30px"
137
+ }
138
+ };
139
+ },
140
+ watch: {
141
+ models: {
142
+ handler: function(layers) {
143
+ if (layers && layers.length > 0) {
144
+ this.model = layers[layers.length - 1];
145
+ } else {
146
+ this.model = null;
147
+ }
148
+ },
149
+ deep: true,
150
+ immediate: true
151
+ },
152
+ model: {
153
+ deep: true,
154
+ immediate: true,
155
+ handler: function() {
156
+ this.removeDynaCut();
157
+ this.changeModel();
158
+ }
159
+ },
160
+ axis: {
161
+ immediate: true,
162
+ handler: function() {
163
+ this.axisCopy = this.axis;
164
+ }
165
+ },
166
+ color: {
167
+ immediate: true,
168
+ handler: function() {
169
+ this.colorCopy = this.color;
170
+ }
171
+ },
172
+ time: {
173
+ immediate: true,
174
+ handler: function() {
175
+ this.timeCopy = this.time;
176
+ }
177
+ },
178
+ distance: {
179
+ immediate: true,
180
+ handler: function() {
181
+ this.distanceCopy = this.distance;
182
+ }
183
+ },
184
+ axisCopy: {
185
+ deep: true,
186
+ immediate: true,
187
+ handler: function() {
188
+ this.getMaxMin();
189
+ this.startClipping();
190
+ }
191
+ }
192
+ },
193
+ mounted() {
194
+ this.$emit("mounted", this);
195
+ },
196
+ beforeDestroy() {
197
+ this.$emit("destroyed", this);
198
+ },
199
+ methods: {
200
+ async createCesiumObject() {
201
+ const { baseUrl, options } = this;
202
+ // return new Cesium.GeoJsonDataSource.load(baseUrl, options);
203
+ return new Promise(
204
+ resolve => {
205
+ resolve();
206
+ },
207
+ reject => {}
208
+ );
209
+ },
210
+ mount() {
211
+ const { webGlobe, CesiumZondy, vueKey, vueIndex } = this;
212
+ const { viewer } = webGlobe;
213
+ const vm = this;
214
+ let promise = this.createCesiumObject();
215
+ promise.then(function(dataSource) {
216
+ vm.$emit("load", { component: this });
217
+ CesiumZondy.DynamicSectionAnalysisManager.addSource(
218
+ vueKey,
219
+ vueIndex,
220
+ dataSource,
221
+ {
222
+ dynamicSectionAnalysis: null
223
+ }
224
+ );
225
+ });
226
+ },
227
+ unmount() {
228
+ let { CesiumZondy, vueKey, vueIndex } = this;
229
+ let find = CesiumZondy.DynamicSectionAnalysisManager.findSource(
230
+ vueKey,
231
+ vueIndex
232
+ );
233
+ if (find) {
234
+ this.removeDynaCut();
235
+ }
236
+ CesiumZondy.DynamicSectionAnalysisManager.deleteSource(vueKey, vueIndex);
237
+ this.$emit("unload", this);
238
+ },
239
+
240
+ /**
241
+ * 打开模块
242
+ */
243
+ onOpen() {
244
+ this.isActive = true;
245
+ this.mount();
246
+ this.changeModel();
247
+ },
248
+
249
+ /**
250
+ * 关闭模块
251
+ */
252
+ onClose() {
253
+ this.stopClipping();
254
+ this.isActive = false;
255
+ },
256
+
257
+ changeModel() {
258
+ this.m3dIsReady().then(m3d => {
259
+ const { source } = m3d;
260
+ this.zoomToM3dLayerBySource(source[0]);
261
+ this.getMaxMin();
262
+ // this.startClipping();
263
+ });
264
+ },
265
+
266
+ /**
267
+ * 判断传入的m3d图层是否加载完毕
268
+ */
269
+ m3dIsReady() {
270
+ const { webGlobe, CesiumZondy, vueKey, vueIndex, model, isActive } = this;
271
+ return new Promise((resolve, reject) => {
272
+ if (isActive && model && model.vueIndex) {
273
+ this.$_getM3DByInterval(
274
+ function(m3ds) {
275
+ if (m3ds && m3ds.length > 0) {
276
+ if (
277
+ !m3ds[0] ||
278
+ !m3ds[0].hasOwnProperty("source") ||
279
+ !m3ds[0].source
280
+ ) {
281
+ reject(null);
282
+ } else {
283
+ resolve(m3ds[0]);
284
+ }
285
+ } else {
286
+ reject(null);
287
+ }
288
+ },
289
+ vueKey,
290
+ model.vueIndex
291
+ );
292
+ } else {
293
+ reject(null);
294
+ }
295
+ });
296
+ },
297
+
298
+ /**
299
+ * 剖切方向,Cesium.Cartesian3中第一个参数是左右,第二个参数是前后,第三个参数是上下
300
+ */
301
+ clippingDirection() {
302
+ switch (this.axisCopy) {
303
+ case "X":
304
+ return new this.Cesium.Cartesian3(-1.0, 0.0, 0.0);
305
+ case "Y":
306
+ return new this.Cesium.Cartesian3(0.0, -1.0, 0.0);
307
+ case "Z":
308
+ return new this.Cesium.Cartesian3(0.0, 0.0, -1.0);
309
+ default:
310
+ return new this.Cesium.Cartesian3(-1.0, 0.0, 0.0);
311
+ }
312
+ },
313
+ /**
314
+ * 设置剖切距离
315
+ */
316
+ setDistance(value) {
317
+ let { CesiumZondy, vueKey, vueIndex } = this;
318
+ let find = CesiumZondy.DynamicSectionAnalysisManager.findSource(
319
+ vueKey,
320
+ vueIndex
321
+ );
322
+ let { options } = find;
323
+ let { dynamicSectionAnalysis } = options;
324
+ if (dynamicSectionAnalysis) {
325
+ // 设置剖切面距离
326
+ dynamicSectionAnalysis.distance = value;
327
+ }
328
+ },
329
+ /**
330
+ * 动画设置
331
+ */
332
+ animation() {
333
+ this.m3dIsReady().then(() => {
334
+ if (this.max == undefined || this.min == undefined) {
335
+ return;
336
+ }
337
+ this.clearTimer();
338
+ this.distanceCopy = this.min;
339
+ const self = this;
340
+ this.timer = window.setInterval(() => {
341
+ if (self.readonly === false) {
342
+ self.readonly = true;
343
+ }
344
+ const step = ((self.max - self.min) * 2) / (self.timeCopy * 10);
345
+ self.distanceCopy += step;
346
+ if (self.distanceCopy >= self.max) {
347
+ self.distanceCopy = self.min;
348
+ }
349
+ self.setDistance(self.distanceCopy);
350
+ }, 100);
351
+ });
352
+ },
353
+ /**
354
+ * 结束分析
355
+ */
356
+ stopClipping() {
357
+ this.clearTimer();
358
+ this.removeDynaCut();
359
+ },
360
+
361
+ /**
362
+ * 开始分析分析
363
+ */
364
+ startClipping() {
365
+ this.m3dIsReady().then(m3d => {
366
+ this.clearTimer();
367
+ this.removeDynaCut();
368
+ let { CesiumZondy, vueKey, vueIndex } = this;
369
+ let find = CesiumZondy.DynamicSectionAnalysisManager.findSource(
370
+ vueKey,
371
+ vueIndex
372
+ );
373
+ let { options } = find;
374
+ let { dynamicSectionAnalysis } = options;
375
+ const { viewer } = this.webGlobe;
376
+
377
+ dynamicSectionAnalysis =
378
+ dynamicSectionAnalysis ||
379
+ new this.Cesium.CuttingTool(viewer, m3d.source);
380
+ // 剖切方向
381
+ const direction = this.clippingDirection();
382
+ // 创建剖切对象实例
383
+ dynamicSectionAnalysis.createModelCuttingPlane(direction, {
384
+ distance: this.distanceCopy || 0,
385
+ color: this.edgeColor(),
386
+ // 剖切辅助面的宽高缩放比(基于模型球的半径)
387
+ scaleHeight: 2.0,
388
+ scaleWidth: 2.0
389
+ });
390
+ CesiumZondy.DynamicSectionAnalysisManager.changeOptions(
391
+ vueKey,
392
+ vueIndex,
393
+ "dynamicSectionAnalysis",
394
+ dynamicSectionAnalysis
395
+ );
396
+ });
397
+ },
398
+ /**
399
+ * RGB/RGBA转Cesium内部颜色值
400
+ * @param {string} colorCopy rgb/rgba颜色值
401
+ */
402
+ edgeColor() {
403
+ const { colorCopy } = this;
404
+ return makeColor(colorCopy);
405
+ },
406
+ /**
407
+ * 移除动态剖切对象
408
+ */
409
+ removeDynaCut() {
410
+ let { CesiumZondy, vueKey, vueIndex } = this;
411
+ let find = CesiumZondy.DynamicSectionAnalysisManager.findSource(
412
+ vueKey,
413
+ vueIndex
414
+ );
415
+ let { options } = find || {};
416
+ let { dynamicSectionAnalysis } = options || {};
417
+ if (dynamicSectionAnalysis) {
418
+ dynamicSectionAnalysis.removeAll();
419
+ dynamicSectionAnalysis = null;
420
+ CesiumZondy.DynamicSectionAnalysisManager.changeOptions(
421
+ vueKey,
422
+ vueIndex,
423
+ "dynamicSectionAnalysis",
424
+ dynamicSectionAnalysis
425
+ );
426
+ }
427
+ },
428
+
429
+ /**
430
+ * 清除时间计时器
431
+ */
432
+ clearTimer() {
433
+ if (this.timer) {
434
+ window.clearInterval(this.timer);
435
+ this.timer = null;
436
+ this.readonly = false;
437
+ }
438
+ },
439
+
440
+ /**
441
+ * 获取M3DLayer对象
442
+ * @returns M3DLayer对象
443
+ */
444
+ getM3D() {
445
+ const { CesiumZondy, webGlobe } = this;
446
+ const m3d = new CesiumZondy.Layer.M3DLayer({
447
+ viewer: webGlobe.viewer
448
+ });
449
+ return m3d;
450
+ },
451
+
452
+ /**
453
+ * 跳转到模型范围,视角不变。基于source
454
+ * @param source
455
+ */
456
+ zoomToM3dLayerBySource(source) {
457
+ const m3d = this.getM3D();
458
+ m3d.zoomToM3dLayer(source);
459
+ },
460
+
461
+ /**
462
+ * 获取剖切距离最大最小值
463
+ */
464
+ getMaxMin() {
465
+ let max = 10000;
466
+ let min = -max;
467
+ if (!this.model) return;
468
+ const { range } = this.model;
469
+ const { xmin, ymin, xmax, ymax, zmin, zmax } = range;
470
+ let length = max - min;
471
+ switch (this.axis) {
472
+ case "X":
473
+ max = xmax;
474
+ min = xmin;
475
+ break;
476
+ case "Y":
477
+ max = ymax;
478
+ min = ymin;
479
+ break;
480
+ case "Z":
481
+ max = zmax;
482
+ min = zmin;
483
+ break;
484
+ default:
485
+ break;
486
+ }
487
+ length = (max - min) * 1.5;
488
+ this.distanceCopy = length / 2;
489
+ this.max = length;
490
+ this.min = -length;
491
+ }
492
+ }
493
+ };
494
+ </script>