Changes for page Demo for Smart Office, Factory
Last modified by Hera Guo on 2024/11/11 17:08
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Attachments (0 modified, 34 added, 0 removed)
- 1730709382428-730.png
- 1730709409941-536.png
- 1730709424998-915.png
- 1730709442773-502.png
- 1730709461297-207.png
- 1730709479828-595.png
- 1730709511861-439.png
- 1730709527720-418.png
- 1730709542597-321.png
- 1730709555797-383.png
- 1730710271230-716.png
- 1730710395303-672.png
- 1730710693066-349.png
- 1730710850458-781.png
- 1730710875401-848.png
- 1730710949358-671.png
- 1730710990334-601.png
- 1730712335338-750.png
- 1730712473941-913.png
- 1730712539209-554.png
- 1730770392454-317.png
- 1730770636230-829.png
- 1730770875793-351.png
- 1730771103096-522.png
- 1730771199343-553.png
- 1730771228766-212.png
- 1730771256045-238.png
- 1730771318657-502.png
- 1730771386258-676.png
- 1730771441589-122.png
- 1730771504586-433.png
- 1730857191863-514.png
- 1730857537965-184.png
- 1730857750749-240.png
Details
- Page properties
-
- Content
-
... ... @@ -57,7 +57,7 @@ 57 57 58 58 **device:**This section displays the specific information collected by the device, and different types of sensors have different display interfaces 59 59 60 -[[image: 1730699212334-960.png]]60 +[[image:屏幕截图 2024-11-04 134645.png]] 61 61 62 62 First floor: 63 63 ... ... @@ -82,8 +82,9 @@ 82 82 83 83 High Temperature、Low Temperature、High humidity、Low humidity、Low voltage、Device Disconnected 84 84 85 -[[image:1730 699566023-958.png]]85 +[[image:1730854677036-426.png]] 86 86 87 + 87 87 = 4.configuration details = 88 88 89 89 After understanding the architecture and layering of the complete project, we can start configuring it ... ... @@ -90,15 +90,592 @@ 90 90 91 91 == 4.1 Dashboard configuration details == 92 92 93 -1 、Configurethe interface of the third layerDavies.94 +=== 4.1.1.Data source (Entity aliases) === 94 94 96 +detail:Obtain data based on dashboard status 95 95 96 - 2、Configurethenterfaceof the secondlayer asset98 +[[image:1730709424998-915.png||height="729" width="1436"]] 97 97 100 +Alarm:Obtain alarm information 98 98 99 - 3、Configurethefirstlayer menuinterface102 +[[image:1730709479828-595.png||height="696" width="1435"]] 100 100 104 +Dragino&GXHL,Ltd:Obtain data through asset types 101 101 106 +[[image:1730709511861-439.png||height="714" width="1435"]] 107 + 108 +Selected Supermarket:Retrieve devices by device type 109 + 110 +[[image:1730709527720-418.png||height="751" width="1433"]] 111 + 112 +Supermarket Devices:Obtain data through device type 113 + 114 +[[image:1730709555797-383.png||height="726" width="1434"]] 115 + 116 +LHT65N Device:Obtain data based on device type 117 + 118 +[[image:1730857191863-514.png||height="725" width="1433"]] 119 + 120 +=== 4.1.2.Page Configuration === 121 + 122 +==== 4.1.2.1、Configure the interface of the third layer Davies. ==== 123 + 124 + 125 +==== 4.1.2.2、Configure the interface of the second layer asset ==== 126 + 127 +===== 4.1.2.2.1 Equipment distribution diagram: ===== 128 + 129 +**Data:** 130 + 131 +[[image:1730770392454-317.png||height="745" width="1439"]] 132 + 133 +**Appearannce:**In this module, we need to arrange our devices in the corresponding positions and use icons to display our devices. Therefore, in the Appearance interface, we need to configure them 134 + 135 +**Tooltip function:**This module displays the current information of the device 136 + 137 +[[image:1730857537965-184.png]] 138 + 139 +{{code language="none"}} 140 +var msg = data 141 +if(msg.Label=="gateway" && msg.type == "gateway"){ 142 + var stauts 143 + if (msg.gatewaystauts=="true"){ 144 + stauts = "Connect" 145 + } 146 + else{ 147 + stauts = "Disconnected" 148 + } 149 + var str = "<b>"+msg.entityName+"</b><br/><b>"+stauts+"</b><br/>" 150 + return str 151 +} 152 +else if(msg.type=="gxhl01" && msg.Label!="gateway"){ 153 + var str = "<b>"+msg.entityName+"</b><br/><b>"+msg.Label+"</b><br/><b>Bat:</b>"+msg.BatV+"V<br/><b>Temperature:</b>"+ msg.TempC_SHT+ "°C<br/><b>Humidity:</b>"+msg.Hum_SHT+"%" 154 + return str 155 +} 156 +else{ 157 + var str = "<b>"+msg.entityName+"</b><br/><b>"+msg.Label+"</b><br/><b>Bat:</b>"+msg.BatV+"V<br/><b>Temperature:</b>"+ msg.temperature+ "°C<br/><b>Humidity:"+msg.humidity+"%"+"</b><br/>"+ 158 + "<b>Co2:"+msg.co2+"</b></br><b>Air_Pressure:"+msg.air_pressure 159 + 160 + return str 161 +} 162 +{{/code}} 163 + 164 +(% class="wikigeneratedid" id="HMarkerimagefunctionFF1A" %) 165 +**Marker image function:**This module can display different icons based on different types of sensors and their status to achieve its functionality 166 + 167 +(% class="wikigeneratedid" %) 168 +[[image:1730857750749-240.png]] 169 + 170 +{{code language="none"}} 171 +var res 172 +var msg = data 173 +if(msg.Label=="gateway" && msg.type=="gateway"){ 174 + if (msg.gatewaystauts == "true"){ 175 + res = { 176 + url: images[3], 177 + size: 40 178 +} 179 +} 180 +else{ 181 + res = { 182 + url: images[2], 183 + size: 40 184 +} 185 +}} 186 +else if(msg.Label!="gateway" && msg.type=="gxhl01" ){ 187 + if (msg.active=="false"){ 188 + res = { 189 + url: images[1], 190 + size: 40 191 +}} 192 +else{ 193 + res = { 194 + url: images[0], 195 + size: 40 196 +} 197 +} 198 +} 199 +else if(msg.type=="LWL02"){ 200 + if (msg.WATER_LEAK_STATUS=="0"){ 201 + res = { 202 + url: images[6], 203 + size: 40 204 +}} 205 +else{ 206 + res = { 207 + url: images[7], 208 + size: 40 209 +} 210 +} 211 +} 212 +else if(msg.type=="LDS02"){ 213 + if (msg.DOOR_OPEN_STATUS=="0"){ 214 + res = { 215 + url: images[5], 216 + size: 40 217 +}} 218 +else{ 219 + res = { 220 + url: images[8], 221 + size: 40 222 +} 223 +} 224 +} 225 +else if(msg.type=="LDS12"){ 226 + res = { 227 + url: images[10], 228 + size: 40 229 +}} 230 +else if(msg.type=="SE01"){ 231 + res = { 232 + url: images[9], 233 + size: 40 234 +}} 235 +else if(msg.type=="PB01"){ 236 + res = { 237 + url: images[11], 238 + size: 40 239 +}} 240 +else if(msg.type=="S31b"){ 241 + res = { 242 + url: images[12], 243 + size: 40 244 +}} 245 +else if(msg.type=="LHT65N"){ 246 + res = { 247 + url: images[13], 248 + size: 40 249 +}} 250 +else{ 251 + res = { 252 + url: images[4], 253 + size: 40 254 +} 255 +} 256 +return res; 257 +{{/code}} 258 + 259 +==== [[image:1730770875793-351.png]] ==== 260 + 261 +(% class="wikigeneratedid" id="HActions" %) 262 +**Actions:**We need to implement the function of entering the details interface through the corresponding device icon, so in this module, we need to add actions to achieve redirection 263 + 264 +{{code language="none"}} 265 +var entitySubType; 266 +var $injector = widgetContext.$scope.$injector; 267 +$injector.get(widgetContext.servicesMap.get('entityService')).getEntity(entityId.entityType, entityId.id) 268 + .subscribe(function(data) { 269 + entitySubType = data.type; 270 + console.log(entitySubType) 271 + if (entitySubType == 'gateway') { 272 + openDashboardStates('gateway_detail'); 273 + } else if (entitySubType == 'gxhl01') { 274 + openDashboardStates('detail'); 275 + } 276 + else if(entitySubType == 'AQS01-dragino-office'){ 277 + openDashboardStates("aqs01_detail") 278 + } 279 + else if (entitySubType == 'LDS12') { 280 + openDashboardStates('lds12_detail'); 281 + } 282 + else if (entitySubType == 'LDS02') { 283 + openDashboardStates('lds02_detail'); 284 + } 285 + else if (entitySubType == 'SE01') { 286 + openDashboardStates('se01_detail'); 287 + } 288 + else if (entitySubType == 'PB01') { 289 + openDashboardStates('pb01_detail'); 290 + } 291 + else if (entitySubType == 'LWL02') { 292 + openDashboardStates('lwl02_detail'); 293 + } 294 + else if (entitySubType == 'LPS8N') { 295 + openDashboardStates('lps8n_detail'); 296 + } 297 + else if (entitySubType == 'LHT65N') { 298 + openDashboardStates('lht65n_detail'); 299 + } 300 + else if (entitySubType == 'S31b') { 301 + openDashboardStates('s31b_detail'); 302 + } 303 + }); 304 + 305 +function openDashboardStates(statedId) { 306 + var stateParams = widgetContext.stateController.getStateParams(); 307 + var params = { 308 + entityId: entityId, 309 + entityName: entityName 310 + }; 311 + 312 + if (stateParams.city) { 313 + params.city = stateParams.city; 314 + } 315 + 316 + widgetContext.stateController.openState(statedId, params, false); 317 +} 318 + 319 +{{/code}} 320 + 321 +[[image:1730771103096-522.png]] 322 + 323 +===== 4.1.2.2.2 Device List ===== 324 + 325 +**Data:** 326 + 327 +[[image:1730771199343-553.png]] 328 + 329 +**Actions:**Equipment distribution diagram: In this module, functions need to be implemented such as adding devices, editing devices, deleting devices, and jumping to the device details page. Therefore, the following actions need to be added: 330 + 331 +[[image:1730771228766-212.png]] 332 + 333 +(% class="wikigeneratedid" id="HEditdeviceFF1A" %) 334 +Edit device:Implementation function: Device editing 335 + 336 +[[image:1730771256045-238.png]] 337 + 338 +{{code language="none"}} 339 +let $injector = widgetContext.$scope.$injector; 340 +let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); 341 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 342 +let attributeService = $injector.get(widgetContext.servicesMap.get('attributeService')); 343 + 344 +openEditDeviceDialog(); 345 + 346 +function openEditDeviceDialog() { 347 + customDialog.customDialog(htmlTemplate, EditDeviceDialogController).subscribe(); 348 +} 349 + 350 +function EditDeviceDialogController(instance) { 351 + let vm = instance; 352 + 353 + vm.device = null; 354 + vm.attributes = {}; 355 + 356 + vm.editDeviceFormGroup = vm.fb.group({ 357 + deviceName: ['', [vm.validators.required]], 358 + deviceType: ['', [vm.validators.required]], 359 + deviceLabel: [''], 360 + attributes: vm.fb.group({ 361 + latitude: [null], 362 + longitude: [null] 363 + }) 364 + }); 365 + 366 + vm.cancel = function() { 367 + vm.dialogRef.close(null); 368 + }; 369 + 370 + vm.save = function() { 371 + vm.editDeviceFormGroup.markAsPristine(); 372 + if (vm.editDeviceFormGroup.get('deviceType').value !== vm.device.type) { 373 + delete vm.device.deviceProfileId; 374 + } 375 + vm.device.name = vm.editDeviceFormGroup.get('deviceName').value, 376 + vm.device.type = vm.editDeviceFormGroup.get('deviceType').value, 377 + vm.device.label = vm.editDeviceFormGroup.get('deviceLabel').value 378 + deviceService.saveDevice(vm.device).subscribe( 379 + function () { 380 + saveAttributes().subscribe( 381 + function () { 382 + widgetContext.updateAliases(); 383 + vm.dialogRef.close(null); 384 + } 385 + ); 386 + } 387 + ); 388 + }; 389 + 390 + getEntityInfo(); 391 + 392 + function getEntityInfo() { 393 + deviceService.getDevice(entityId.id).subscribe( 394 + function (device) { 395 + attributeService.getEntityAttributes(entityId, 'SERVER_SCOPE', 396 + ['latitude', 'longitude']).subscribe( 397 + function (attributes) { 398 + for (let i = 0; i < attributes.length; i++) { 399 + vm.attributes[attributes[i].key] = attributes[i].value; 400 + } 401 + vm.device = device; 402 + vm.editDeviceFormGroup.patchValue( 403 + { 404 + deviceName: vm.device.name, 405 + deviceType: vm.device.type, 406 + deviceLabel: vm.device.label, 407 + attributes: { 408 + latitude: vm.attributes.latitude, 409 + longitude: vm.attributes.longitude 410 + } 411 + }, {emitEvent: false} 412 + ); 413 + } 414 + ); 415 + } 416 + ); 417 + } 418 + 419 + function saveAttributes() { 420 + let attributes = vm.editDeviceFormGroup.get('attributes').value; 421 + let attributesArray = []; 422 + for (let key in attributes) { 423 + attributesArray.push({key: key, value: attributes[key]}); 424 + } 425 + if (attributesArray.length > 0) { 426 + return attributeService.saveEntityAttributes(entityId, 'SERVER_SCOPE', attributesArray); 427 + } else { 428 + return widgetContext.rxjs.of([]); 429 + } 430 + } 431 +} 432 +{{/code}} 433 + 434 +==== ==== 435 + 436 +Delete device:Implementation function: Device deletion 437 + 438 +[[image:1730771318657-502.png]] 439 + 440 +{{code language="none"}} 441 +let $injector = widgetContext.$scope.$injector; 442 +let dialogs = $injector.get(widgetContext.servicesMap.get('dialogs')); 443 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 444 + 445 +openDeleteDeviceDialog(); 446 + 447 +function openDeleteDeviceDialog() { 448 + let title = "Are you sure you want to delete the device " + entityName + "?"; 449 + let content = "Be careful, after the confirmation, the device and all related data will become unrecoverable!"; 450 + dialogs.confirm(title, content, 'Cancel', 'Delete').subscribe( 451 + function (result) { 452 + if (result) { 453 + deleteDevice(); 454 + } 455 + } 456 + ); 457 +} 458 + 459 +function deleteDevice() { 460 + deviceService.deleteDevice(entityId.id).subscribe( 461 + function () { 462 + widgetContext.updateAliases(); 463 + } 464 + ); 465 +} 466 + 467 +{{/code}} 468 + 469 + 470 +jump:Implementation function: Jump to the device details page 471 + 472 +[[image:1730771386258-676.png]] 473 + 474 +{{code language="none"}} 475 +console.log(entityName) 476 +var entitySubType; 477 +var $injector = widgetContext.$scope.$injector; 478 +//console.log($injector) 479 +$injector.get(widgetContext.servicesMap.get('entityService')).getEntity(entityId.entityType, entityId.id) 480 + .subscribe(function(data) { 481 + console.log(data) 482 + entitySubType = data.type; 483 + console.log(entitySubType) 484 + if (entitySubType == 'AQS01-dragino-office') { 485 + openDashboardStates('aqs01_detail'); 486 + }else if (entitySubType == 'gateway') { 487 + openDashboardStates('gateway_detail'); 488 + } else if (entitySubType == 'gxhl01') { 489 + openDashboardStates('detail'); 490 + 491 + } else if (entitySubType == 'tank-type1') { 492 + openDashboardStates('test1'); 493 + } 494 + else if (entitySubType == 'LDS12') { 495 + openDashboardStates('lds12_detail'); 496 + } 497 + else if (entitySubType == 'LDS02') { 498 + openDashboardStates('lds02_detail'); 499 + } 500 + else if (entitySubType == 'SE01') { 501 + openDashboardStates('se01_detail'); 502 + } 503 + else if (entitySubType == 'PB01') { 504 + openDashboardStates('pb01_detail'); 505 + } 506 + else if (entitySubType == 'LWL02') { 507 + openDashboardStates('lwl02_detail'); 508 + } 509 + else if (entitySubType == 'LPS8N') { 510 + openDashboardStates('lps8n_detail'); 511 + } 512 + else if (entitySubType == 'LHT65N') { 513 + openDashboardStates('lht65n_detail'); 514 + } 515 + else if (entitySubType == 'S31b') { 516 + openDashboardStates('s31b_detail'); 517 + } 518 + }); 519 + 520 +function openDashboardStates(statedId) { 521 + var stateParams = widgetContext.stateController.getStateParams(); 522 + //console.log(stateParams) 523 + var params = { 524 + entityId: entityId, 525 + entityName: entityName 526 + }; 527 + widgetContext.stateController.updateState(statedId, params, false); 528 +} 529 +{{/code}} 530 + 531 +==== ==== 532 + 533 +Add device:Implementation function: Add device 534 + 535 +[[image:1730771441589-122.png]] 536 + 537 +{{code language="none"}} 538 +let $injector = widgetContext.$scope.$injector; 539 +let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); 540 +let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); 541 +let attributeService = $injector.get(widgetContext.servicesMap.get('attributeService')); 542 + 543 +openAddDeviceDialog(); 544 + 545 +function openAddDeviceDialog() { 546 + customDialog.customDialog(htmlTemplate, AddDeviceDialogController).subscribe(); 547 +} 548 + 549 +function AddDeviceDialogController(instance) { 550 + let vm = instance; 551 + 552 + vm.addDeviceFormGroup = vm.fb.group({ 553 + deviceName: ['', [vm.validators.required]], 554 + deviceType: ['', [vm.validators.required]], 555 + deviceLabel: [''], 556 + attributes: vm.fb.group({ 557 + latitude: [null], 558 + longitude: [null] 559 + }) 560 + }); 561 + 562 + vm.cancel = function() { 563 + vm.dialogRef.close(null); 564 + }; 565 + 566 + vm.save = function() { 567 + vm.addDeviceFormGroup.markAsPristine(); 568 + let device = { 569 + name: vm.addDeviceFormGroup.get('deviceName').value, 570 + type: vm.addDeviceFormGroup.get('deviceType').value, 571 + label: vm.addDeviceFormGroup.get('deviceLabel').value 572 + }; 573 + deviceService.saveDevice(device).subscribe( 574 + function (device) { 575 + saveAttributes(device.id).subscribe( 576 + function () { 577 + widgetContext.updateAliases(); 578 + vm.dialogRef.close(null); 579 + } 580 + ); 581 + } 582 + ); 583 + }; 584 + 585 + function saveAttributes(entityId) { 586 + let attributes = vm.addDeviceFormGroup.get('attributes').value; 587 + let attributesArray = []; 588 + for (let key in attributes) { 589 + attributesArray.push({key: key, value: attributes[key]}); 590 + } 591 + if (attributesArray.length > 0) { 592 + return attributeService.saveEntityAttributes(entityId, "SERVER_SCOPE", attributesArray); 593 + } else { 594 + return widgetContext.rxjs.of([]); 595 + } 596 + } 597 +} 598 +{{/code}} 599 + 600 +==== ==== 601 + 602 +===== **4.1.2.2.2 Asset Alarm:** ===== 603 + 604 +**Data:** 605 + 606 +[[image:1730771504586-433.png]] 607 + 608 +==== 4.1.2.3、Configure the first layer menu interface ==== 609 + 610 +===== 4.1.2.3.1 **Map:** ===== 611 + 612 +**Data:** 613 + 614 +[[image:1730710271230-716.png||height="729" width="1427"]] 615 + 616 +Actions:The map interface has two actions, among which Select supermarket can refresh the device list and related alarms on the right side to enter the location, and Supermarket_detail can jump to the second level physical interface to view the details of the location based on the selected location 617 + 618 +[[image:1730710850458-781.png||height="770" width="1429"]] 619 + 620 +Select supermarket:Implementation function: Refresh the side page 621 + 622 +{{code language="none"}} 623 +var params = widgetContext.stateController.getStateParams(); 624 +var selectedSupermarket = params['selectedSupermarket']; 625 +if (selectedSupermarket && selectedSupermarket.entityId.id === entityId.id) { 626 + params['selectedSupermarket'] = null; 627 +} else { 628 + params['selectedSupermarket'] = { entityId: entityId, entityName: entityName, entityLabel: entityLabel }; 629 +} 630 +widgetContext.stateController.updateState(null, params); 631 +{{/code}} 632 + 633 +[[image:1730710875401-848.png||height="767" width="1429"]] 634 + 635 +Supermarket_detail:Implementation function: Jump to the asset details page 636 + 637 +{{code language="none"}} 638 +var params = JSON.parse(JSON.stringify(widgetContext.stateController.getStateParams())); 639 +params['selectedSupermarket'] = { 640 + entityId: entityId, 641 + entityName: entityName, 642 + entityLabel: entityLabel, 643 +}; 644 +params['targetEntityParamName'] = 'selectedSupermarket'; 645 +params['selectedDevice'] = null; 646 + 647 +widgetContext.stateController.openState('svgmap', params); 648 +{{/code}} 649 + 650 +[[image:1730710990334-601.png||height="772" width="1433"]] 651 + 652 +* In this demo, exclusive map icons were set as follows: 653 + 654 +{{code language="none"}} 655 +var res = { 656 + url: images[0], 657 + size: 66 658 +}; 659 +return res; 660 +{{/code}} 661 + 662 +[[image:1730710395303-672.png||height="771" width="1438"]] 663 + 664 +===== 4.1.2.3.1 Asset List: ===== 665 + 666 +**Data:** 667 + 668 +[[image:1730710693066-349.png||height="772" width="1439"]] 669 + 670 +Actions:The Assets List interface has an action, which is the same as the Supermarket_details in the Map. You can jump to the second level entity interface to view the details of the selected location based on its location 671 + 672 +[[image:1730712335338-750.png||height="751" width="1423"]] 673 + 674 +[[image:1730712473941-913.png||height="781" width="1422"]] 675 + 676 +All Alarms: 677 + 678 +[[image:1730712539209-554.png||height="764" width="1424"]] 679 + 102 102 == 4.2 Alarm configuration details == 103 103 104 104 == 4.3 Rule chain configuration details ==
- 1730709382428-730.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +480.8 KB - Content
- 1730709409941-536.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +451.5 KB - Content
- 1730709424998-915.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +443.4 KB - Content
- 1730709442773-502.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +448.3 KB - Content
- 1730709461297-207.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +458.2 KB - Content
- 1730709479828-595.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +450.7 KB - Content
- 1730709511861-439.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +470.0 KB - Content
- 1730709527720-418.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +475.8 KB - Content
- 1730709542597-321.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +474.8 KB - Content
- 1730709555797-383.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +463.2 KB - Content
- 1730710271230-716.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.5 MB - Content
- 1730710395303-672.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.6 MB - Content
- 1730710693066-349.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +94.4 KB - Content
- 1730710850458-781.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.5 MB - Content
- 1730710875401-848.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730710949358-671.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730710990334-601.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +1.0 MB - Content
- 1730712335338-750.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +77.1 KB - Content
- 1730712473941-913.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +135.9 KB - Content
- 1730712539209-554.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +131.0 KB - Content
- 1730770392454-317.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +195.6 KB - Content
- 1730770636230-829.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +290.6 KB - Content
- 1730770875793-351.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +305.2 KB - Content
- 1730771103096-522.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +197.9 KB - Content
- 1730771199343-553.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +108.5 KB - Content
- 1730771228766-212.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +46.8 KB - Content
- 1730771256045-238.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +69.1 KB - Content
- 1730771318657-502.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +60.4 KB - Content
- 1730771386258-676.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +46.4 KB - Content
- 1730771441589-122.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +57.6 KB - Content
- 1730771504586-433.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +151.2 KB - Content
- 1730857191863-514.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +354.7 KB - Content
- 1730857537965-184.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +455.1 KB - Content
- 1730857750749-240.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.hera - Size
-
... ... @@ -1,0 +1,1 @@ 1 +285.9 KB - Content