From 4d562043d5cd6d98f07c5887d579b550f614a214 Mon Sep 17 00:00:00 2001 From: lyd <1419499670@qq.com> Date: Mon, 1 Aug 2022 09:05:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E5=BD=A2=E5=8C=96-=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=9B=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nladmin-system/pom.xml | 10 +- .../logicflow/rest/StageController.java | 88 +++ .../logicflow/rest/StageImageController.java | 73 +++ .../logicflow/service/StageImageService.java | 59 ++ .../logicflow/service/StageService.java | 74 +++ .../logicflow/service/dto/StageDto.java | 63 ++ .../logicflow/service/dto/StageImageDto.java | 68 ++ .../service/impl/StageImageServiceImpl.java | 110 ++++ .../service/impl/StageServiceImpl.java | 132 ++++ .../org/nl/modules/logicflow/wql/device.xls | Bin 0 -> 190976 bytes .../modules/system/rest/ParamController.java | 7 + .../java/org/nl/modules/system/wql/sys.xls | Bin 214528 -> 214528 bytes nladmin-ui/package.json | 3 + nladmin-ui/src/api/logicflow/stage.js | 50 ++ nladmin-ui/src/api/logicflow/stageImage.js | 34 + nladmin-ui/src/api/system/param.js | 10 +- nladmin-ui/src/main.js | 6 + .../logicflow/editor/components/Diagram.vue | 604 ++++++++++++++++++ .../editor/components/DiagramSidebar.vue | 196 ++++++ .../editor/components/DiagramToolbar.vue | 251 ++++++++ .../editor/components/PropertyPanel.vue | 375 +++++++++++ .../editor/components/icon/Actor.vue | 38 ++ .../editor/components/icon/AreaSelect.vue | 15 + .../logicflow/editor/components/icon/Blod.vue | 15 + .../editor/components/icon/Circle.vue | 31 + .../editor/components/icon/ColorFill.vue | 15 + .../editor/components/icon/ColorText.vue | 15 + .../editor/components/icon/Cross.vue | 19 + .../editor/components/icon/Cylinde.vue | 27 + .../editor/components/icon/Diamond.vue | 19 + .../editor/components/icon/Divide.vue | 37 ++ .../editor/components/icon/DownArrow.vue | 18 + .../editor/components/icon/Ellipse.vue | 21 + .../logicflow/editor/components/icon/Font.vue | 15 + .../editor/components/icon/Heptagon.vue | 19 + .../editor/components/icon/Hexagon.vue | 19 + .../components/icon/HorizontalArrow.vue | 18 + .../editor/components/icon/LeftArrow.vue | 18 + .../logicflow/editor/components/icon/Line.vue | 15 + .../editor/components/icon/Minus.vue | 19 + .../editor/components/icon/Parallelogram.vue | 19 + .../editor/components/icon/Pentagon.vue | 19 + .../logicflow/editor/components/icon/Rect.vue | 31 + .../editor/components/icon/RectRadius.vue | 23 + .../editor/components/icon/RightArrow.vue | 18 + .../editor/components/icon/Septagon.vue | 19 + .../editor/components/icon/StepBack.vue | 16 + .../editor/components/icon/StepFoward.vue | 16 + .../editor/components/icon/Table.vue | 158 +++++ .../logicflow/editor/components/icon/Text.vue | 46 ++ .../editor/components/icon/Times.vue | 19 + .../editor/components/icon/Trapezoid.vue | 19 + .../editor/components/icon/Triangle.vue | 19 + .../editor/components/icon/UpArrow.vue | 19 + .../editor/components/icon/VerticalArrow.vue | 18 + .../editor/components/icon/ZoomIn.vue | 16 + .../editor/components/icon/ZoomOut.vue | 16 + .../components/node/arrow/DownArrowNode.js | 49 ++ .../node/arrow/HorizontalArrowNode.js | 56 ++ .../editor/components/node/arrow/LeftArrow.js | 48 ++ .../components/node/arrow/RightArrow.js | 50 ++ .../components/node/arrow/UpArrowNode.js | 49 ++ .../node/arrow/VerticalArrowNode.js | 56 ++ .../editor/components/node/basic/BaseNode.js | 16 + .../components/node/basic/CircleNode.js | 33 + .../components/node/basic/DiamondNode.js | 35 + .../components/node/basic/EllipseNode.js | 19 + .../editor/components/node/basic/RectNode.js | 27 + .../components/node/basic/RectRadiusNode.js | 14 + .../editor/components/node/basic/TextNode.js | 37 ++ .../editor/components/node/edge/Bezier.js | 26 + .../editor/components/node/edge/Line.js | 26 + .../editor/components/node/edge/Polyline.js | 26 + .../components/node/getShapeStyleUtil.js | 70 ++ .../editor/components/node/html/htmlNode.js | 89 +++ .../logicflow/editor/components/node/index.js | 74 +++ .../editor/components/node/path/ActorNode.js | 95 +++ .../editor/components/node/path/CrossNode.js | 65 ++ .../components/node/path/CylindeNode.js | 92 +++ .../editor/components/node/path/DivideNode.js | 83 +++ .../components/node/path/HeptagonNode.js | 61 ++ .../components/node/path/HexagonNode.js | 59 ++ .../editor/components/node/path/MinusNode.js | 57 ++ .../components/node/path/ParallelogramNode.js | 57 ++ .../components/node/path/PentagonNode.js | 58 ++ .../components/node/path/SeptagonNode.js | 60 ++ .../editor/components/node/path/Star.js | 40 ++ .../editor/components/node/path/TimesNode.js | 65 ++ .../components/node/path/TrapezoidNode.js | 57 ++ .../components/node/path/TriangleNode.js | 47 ++ .../system/logicflow/editor/constant/index.js | 69 ++ .../system/logicflow/editor/image/agv.svg | 60 ++ .../logicflow/editor/image/icon_alert.png | Bin 0 -> 1649 bytes .../system/logicflow/editor/image/托盘.svg | 14 + .../views/system/logicflow/editor/index.vue | 34 + .../views/system/logicflow/image/index.vue | 310 +++++++++ .../src/views/system/logicflow/index.vue | 129 ++++ .../system/monitor/device/XJDeviceMonitor.vue | 223 +++++++ .../src/views/system/monitor/device/index.vue | 154 +++++ 99 files changed, 5780 insertions(+), 6 deletions(-) create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageController.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageImageController.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageImageService.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageService.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageDto.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageImageDto.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageImageServiceImpl.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageServiceImpl.java create mode 100644 nladmin-system/src/main/java/org/nl/modules/logicflow/wql/device.xls create mode 100644 nladmin-ui/src/api/logicflow/stage.js create mode 100644 nladmin-ui/src/api/logicflow/stageImage.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/Diagram.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/DiagramSidebar.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/DiagramToolbar.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/PropertyPanel.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Actor.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/AreaSelect.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Blod.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Circle.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorFill.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorText.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Cross.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Cylinde.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Diamond.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Divide.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/DownArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Ellipse.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Font.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Heptagon.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Hexagon.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/HorizontalArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/LeftArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Line.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Minus.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Parallelogram.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Pentagon.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Rect.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/RectRadius.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/RightArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Septagon.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/StepBack.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/StepFoward.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Table.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Text.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Times.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Trapezoid.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/Triangle.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/UpArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/VerticalArrow.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomIn.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomOut.vue create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/DownArrowNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/HorizontalArrowNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/LeftArrow.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/RightArrow.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/UpArrowNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/VerticalArrowNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/BaseNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/CircleNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/DiamondNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/EllipseNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectRadiusNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/basic/TextNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Bezier.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Line.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Polyline.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/getShapeStyleUtil.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/html/htmlNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/index.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/ActorNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/CrossNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/CylindeNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/DivideNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/HeptagonNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/HexagonNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/MinusNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/ParallelogramNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/PentagonNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/SeptagonNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/Star.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/TimesNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/TrapezoidNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/components/node/path/TriangleNode.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/constant/index.js create mode 100644 nladmin-ui/src/views/system/logicflow/editor/image/agv.svg create mode 100644 nladmin-ui/src/views/system/logicflow/editor/image/icon_alert.png create mode 100644 nladmin-ui/src/views/system/logicflow/editor/image/托盘.svg create mode 100644 nladmin-ui/src/views/system/logicflow/editor/index.vue create mode 100644 nladmin-ui/src/views/system/logicflow/image/index.vue create mode 100644 nladmin-ui/src/views/system/logicflow/index.vue create mode 100644 nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue create mode 100644 nladmin-ui/src/views/system/monitor/device/index.vue diff --git a/nladmin-system/pom.xml b/nladmin-system/pom.xml index 073ab9d1b..954dcc2e5 100644 --- a/nladmin-system/pom.xml +++ b/nladmin-system/pom.xml @@ -20,11 +20,11 @@ - - com.alicp.jetcache - jetcache-starter-redis - 2.5.14 - + + + + + diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageController.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageController.java new file mode 100644 index 000000000..708ee82cf --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageController.java @@ -0,0 +1,88 @@ +package org.nl.modules.logicflow.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.annotation.Log; +import org.nl.modules.logicflow.service.StageService; +import org.nl.modules.logicflow.service.dto.StageDto; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: 舞台管理 + * @Date: 2022-07-29 10:49 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "舞台管理") +@RequestMapping("/api/stage") +@Slf4j +public class StageController { + private final StageService stageService; + @GetMapping + @Log("查询舞台") + @ApiOperation("查询舞台") + //@PreAuthorize("@el.check('stage:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page) { + return new ResponseEntity<>(stageService.queryAll(whereJson, page), HttpStatus.OK); + } + + @PostMapping + @Log("新增舞台") + @ApiOperation("新增舞台") + //@PreAuthorize("@el.check('stage:add')") + public ResponseEntity create(@Validated @RequestBody StageDto dto) { + stageService.create(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改舞台") + @ApiOperation("修改舞台") + //@PreAuthorize("@el.check('stage:edit')") + public ResponseEntity update(@Validated @RequestBody StageDto dto) { + stageService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除舞台") + @ApiOperation("删除舞台") + //@PreAuthorize("@el.check('stage:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody String[] ids) { + stageService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @GetMapping("/selectList") + @Log("下拉选舞台") + @ApiOperation("下拉选舞台") + //@PreAuthorize("@el.check('routePlan:list')") + public ResponseEntity selectList() { + return new ResponseEntity<>(stageService.selectList(), HttpStatus.OK); + } + + @PostMapping("/addNewStage") + @Log("保存舞台数据") + @ApiOperation("保存舞台数据") + public ResponseEntity addNewStage(@Validated @RequestBody StageDto dto) { + log.info("dto{}",dto); + stageService.addNewStage(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PostMapping("/getNewStageDataByCode") + @Log("根据stage_code获取舞台数据") + @ApiOperation("根据stage_code获取舞台数据") + public ResponseEntity getNewStageDataByCode(@RequestBody String code) { + return new ResponseEntity<>(stageService.findByCode(code), HttpStatus.CREATED); + } +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageImageController.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageImageController.java new file mode 100644 index 000000000..d75d7650b --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/rest/StageImageController.java @@ -0,0 +1,73 @@ +package org.nl.modules.logicflow.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.annotation.Log; +import org.nl.modules.logicflow.service.StageImageService; +import org.nl.modules.logicflow.service.dto.StageImageDto; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: 舞台图标控制层 + * @Date: 2022-07-29 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "舞台管理") +@RequestMapping("/api/stageImage") +@Slf4j +public class StageImageController { + private final StageImageService stageImageService; + + @GetMapping + @Log("查询舞台") + @ApiOperation("查询舞台") + //@PreAuthorize("@el.check('stageImage:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page) { + return new ResponseEntity<>(stageImageService.queryAll(whereJson, page), HttpStatus.OK); + } + + @PostMapping + @Log("新增舞台") + @ApiOperation("新增舞台") + //@PreAuthorize("@el.check('stageImage:add')") + public ResponseEntity create(@Validated @RequestBody StageImageDto dto) { + stageImageService.create(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改舞台") + @ApiOperation("修改舞台") + //@PreAuthorize("@el.check('stageImage:edit')") + public ResponseEntity update(@Validated @RequestBody StageImageDto dto) { + stageImageService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除舞台") + @ApiOperation("删除舞台") + //@PreAuthorize("@el.check('stageImage:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody String[] ids) { + stageImageService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @GetMapping("/selectList") + @Log("下拉选设备图标") + @ApiOperation("下拉选设备图标") + //@PreAuthorize("@el.check('routePlan:list')") + public ResponseEntity selectList() { + return new ResponseEntity<>(stageImageService.selectList(), HttpStatus.OK); + } +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageImageService.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageImageService.java new file mode 100644 index 000000000..f282923d7 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageImageService.java @@ -0,0 +1,59 @@ +package org.nl.modules.logicflow.service; + +import com.alibaba.fastjson.JSONArray; +import org.nl.modules.logicflow.service.dto.StageImageDto; +import org.springframework.data.domain.Pageable; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: 舞台图标的服务层 + * @Date: 2022-07-29 + */ +public interface StageImageService { + /** + * 查询数据分页 + * + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 创建 + * + * @param dto / + */ + void create(StageImageDto dto); + + /** + * 编辑 + * + * @param dto / + */ + void update(StageImageDto dto); + + /** + * 根据ID查询 + * + * @param image_uuid ID + * @return StageImage + */ + StageImageDto findById(String image_uuid); + + /** + * 多选删除 + * + * @param ids / + */ + void deleteAll(String[] ids); + + /** + * 前端舞台编辑选择设备图标下拉选列表 + * + * @return + */ + JSONArray selectList(); +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageService.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageService.java new file mode 100644 index 000000000..857c476ab --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/StageService.java @@ -0,0 +1,74 @@ +package org.nl.modules.logicflow.service; + +import com.alibaba.fastjson.JSONArray; +import org.nl.modules.logicflow.service.dto.StageDto; +import org.springframework.data.domain.Pageable; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: + * @Date: 2022-07-29 10:50 + */ +public interface StageService { + /** + * 查询数据分页 + * + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 创建 + * + * @param dto / + */ + void create(StageDto dto); + + /** + * 编辑 + * + * @param dto / + */ + void update(StageDto dto); + + /** + * 根据ID查询 + * + * @param stage_uuid ID + * @return Stage + */ + StageDto findById(String stage_uuid); + + /** + * 多选删除 + * + * @param ids / + */ + void deleteAll(String[] ids); + + /** + * 前端舞台下拉选列表 + * + * @return + */ + JSONArray selectList(); + + /** + * 新增舞台信息 + * 将数据保存到remark---保存数据 + * @param dto + */ + void addNewStage(StageDto dto); + + /** + * 根据编码查询 + * + * @param code code + * @return Stage + */ + StageDto findByCode(String code); +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageDto.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageDto.java new file mode 100644 index 000000000..ed7420312 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageDto.java @@ -0,0 +1,63 @@ +package org.nl.modules.logicflow.service.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: lyd + * @Description: 舞台数据的Dto + * @Date: 2022-07-29 13:28 + */ +@Data +public class StageDto implements Serializable { + /** + * 舞台标识 + */ + private String stage_uuid; + + /** + * 舞台编码 + */ + private String stage_code; + + /** + * 舞台名字 + */ + private String stage_name; + + /** + * 舞台数据 + */ + private String stage_data; + + /** + * 是否启用 + */ + private String is_active; + + /** + * 是否删除 + */ + private String is_delete; + + /** + * 创建者 + */ + private String create_by; + + /** + * 创建时间 + */ + private String create_time; + + /** + * 修改者 + */ + private String update_by; + + /** + * 修改时间 + */ + private String update_time; +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageImageDto.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageImageDto.java new file mode 100644 index 000000000..2d6cf493b --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/dto/StageImageDto.java @@ -0,0 +1,68 @@ +package org.nl.modules.logicflow.service.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: lyd + * @Description: 设备图标dto + * @Date: 2022-07-29 + */ +@Data +public class StageImageDto implements Serializable { + /** + * 设备标识 + */ + private String image_uuid; + + /** + * 设备名字 + */ + private String image_name; + + /** + * 适用驱动 + */ + private String driver_code_json; + + /** + * 备注 + */ + private String remark; + + /** + * 是否启用 + */ + private String is_active; + + /** + * 是否删除 + */ + private String is_delete; + + /** + * 创建者 + */ + private String create_by; + + /** + * 创建时间 + */ + private String create_time; + + /** + * 修改者 + */ + private String update_by; + + /** + * 修改时间 + */ + private String update_time; + + /** + * 图标编码 + */ + private String image_code; +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageImageServiceImpl.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageImageServiceImpl.java new file mode 100644 index 000000000..e4a531c88 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageImageServiceImpl.java @@ -0,0 +1,110 @@ +package org.nl.modules.logicflow.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.exception.BadRequestException; +import org.nl.modules.logicflow.service.StageImageService; +import org.nl.modules.logicflow.service.dto.StageImageDto; +import org.nl.utils.SecurityUtils; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: 舞台图标的服务实现 + * @Date: 2022-07-29 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class StageImageServiceImpl implements StageImageService { + @Override + public Map queryAll(Map whereJson, Pageable page) { + String where = "1=1"; + if (whereJson.get("device_type") != null) { + where = "driver_code_json like ('%" + whereJson.get("device_type") + "%')"; + } + WQLObject wo = WQLObject.getWQLObject("stage_image"); + ResultBean rb = wo.pagequery(WqlUtil.getHttpContext(page), where, "update_time desc"); + final JSONObject json = rb.pageResult(); + return json; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(StageImageDto dto) { + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + + dto.setImage_uuid(IdUtil.simpleUUID()); + dto.setCreate_by(currentUsername); + dto.setUpdate_by(currentUsername); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("stage_image"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(StageImageDto dto) { + StageImageDto entity = this.findById(dto.getImage_uuid()); + if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + dto.setUpdate_time(now); + dto.setUpdate_by(currentUsername); + + WQLObject wo = WQLObject.getWQLObject("stage_image"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.update(json); + } + + @Override + public StageImageDto findById(String image_uuid) { + WQLObject wo = WQLObject.getWQLObject("stage_image"); + JSONObject json = wo.query("image_uuid ='" + image_uuid + "'").uniqueResult(0); + final StageImageDto obj = json.toJavaObject(StageImageDto.class); + return obj; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(String[] ids) { + WQLObject wo = WQLObject.getWQLObject("stage_image"); + for (String image_uuid : ids) { + wo.delete("image_uuid = '" + image_uuid + "'"); + } + } + + @Override + public JSONArray selectList() { + //设备基础信息表【acs_stage_image】 + JSONArray arr = WQLObject.getWQLObject("stage_image").query("is_delete= '0' AND is_active= '1'", "update_time desc").getResultJSONArray(0); + JSONArray result = new JSONArray(); + for (int i = 0; i < arr.size(); i++) { + JSONObject obj = arr.getJSONObject(i); + JSONObject json = new JSONObject(); + json.put("image_uuid", obj.getString("image_uuid")); + json.put("image_code", obj.getString("image_code")); + json.put("image_name", obj.getString("image_code").toString().split("-")[0]); + result.add(json); + } + return result; + } +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageServiceImpl.java b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageServiceImpl.java new file mode 100644 index 000000000..fc046af99 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/logicflow/service/impl/StageServiceImpl.java @@ -0,0 +1,132 @@ +package org.nl.modules.logicflow.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.exception.BadRequestException; +import org.nl.modules.logicflow.service.StageService; +import org.nl.modules.logicflow.service.dto.StageDto; +import org.nl.utils.SecurityUtils; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +/** + * @Author: lyd + * @Description: + * @Date: 2022-07-29 10:51 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class StageServiceImpl implements StageService { + @Override + public Map queryAll(Map whereJson, Pageable page) { + log.info("分页查找"); + WQLObject wo = WQLObject.getWQLObject("stage"); + ResultBean rb = wo.pagequery(WqlUtil.getHttpContext(page), "", "update_time desc"); + final JSONObject json = rb.pageResult(); + return json; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(StageDto dto) { + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + + dto.setStage_uuid(IdUtil.simpleUUID()); + dto.setCreate_by(currentUsername); + dto.setUpdate_by(currentUsername); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("stage"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(StageDto dto) { + StageDto entity = this.findById(dto.getStage_uuid()); + if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + dto.setUpdate_time(now); + dto.setUpdate_by(currentUsername); + + WQLObject wo = WQLObject.getWQLObject("stage"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.update(json); + } + + @Override + public StageDto findById(String stage_uuid) { + WQLObject wo = WQLObject.getWQLObject("stage"); + JSONObject json = wo.query("stage_uuid ='" + stage_uuid + "'").uniqueResult(0); + final StageDto obj = json.toJavaObject(StageDto.class); + return obj; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(String[] ids) { + WQLObject wo = WQLObject.getWQLObject("stage"); + for (String stage_uuid : ids) { + wo.delete("stage_uuid = '" + stage_uuid + "'"); + } + } + + @Override + public JSONArray selectList() { + //设备基础信息表【stage】 + JSONArray arr = WQLObject.getWQLObject("stage").query("is_delete= '0' AND is_active= '1'").getResultJSONArray(0); + JSONArray result = new JSONArray(); + for (int i = 0; i < arr.size(); i++) { + JSONObject obj = arr.getJSONObject(i); + JSONObject json = new JSONObject(); + json.put("stage_id", obj.getString("stage_id")); + json.put("stage_code", obj.getString("stage_code")); + json.put("stage_name", obj.getString("stage_name")); + result.add(json); + } + return result; + } + + @Override + public void addNewStage(StageDto dto) { + // 根据dto的code找到数据 + StageDto stageDto = this.findByCode(dto.getStage_code()); + // 设置内容 + stageDto.setStage_data(dto.getStage_data()); + // 获取当前用户与时间 + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + stageDto.setUpdate_time(now); + stageDto.setUpdate_by(currentUsername); + System.out.println(stageDto); + WQLObject wo = WQLObject.getWQLObject("stage"); + JSONObject json = (JSONObject) JSONObject.toJSON(stageDto); + wo.update(json); + } + + @Override + public StageDto findByCode(String code) { + WQLObject wo = WQLObject.getWQLObject("stage"); + JSONObject json = wo.query("stage_code ='" + code + "'").uniqueResult(0); + final StageDto obj = json.toJavaObject(StageDto.class); + return obj; + } +} diff --git a/nladmin-system/src/main/java/org/nl/modules/logicflow/wql/device.xls b/nladmin-system/src/main/java/org/nl/modules/logicflow/wql/device.xls new file mode 100644 index 0000000000000000000000000000000000000000..f15ea83e16435d26ac69e23d10c0c18da53b4e90 GIT binary patch literal 190976 zcmeFa2YeMp_ddS&rrkh72)%O?TEGCIcL-H#D2cQHAtW~>kPt|tOK1WDLXajRO1B|c zQITRr1Q8I$hM)*y1z!~eOMcHYv%7ci-c1DG_y7I8@Bfp%IoX{vXU;iu=1kk2**)=I z==sf0SNlRS9i0^)<*&j(#ovJU!L>~bmsONIaZTJ`g@uJ0dIBy^1ArN z8$eq?J3xCt2S7(aCqQRF7eF+iE1(;oJD>-kC!iOg58x5NN%N70LcIsAO$cUkP1ixOa!o; z(s9lJOaf#ACIhAbvH;nD96&B04=@!l4KN)r127XX3osjSH((ARA20-*GLh1WoKM0z zOQb-=EgqHNF`Ap(kjCk-iTxTnN!z^~wPiUBMfrEdc@S(d5M|vHz7U6Sca$Ydw)i6) zEn*l*!U6PatK*Rg=l{*oP3VwlV_6+SQFXEfp$@l4 zz3z;99jm+#{L8iwwn=fRY1zXvvnGzq%$&Fp$wJZSFd19}|I3U2y9J|H#Q#o+`EAZ` zbCkgg8nhJ+o=s`y6D{bLi~r%`e;NF@DSJhlPXwkJnz*arSvY5<@Sb~M{H5`+1Bw3( zc!%=u6DGqN{ZnvvXar~{k_y2-_QF5*E)_z@-o*wqE=GjUFYUOUiS11A> zYKga@)~o*P!N-PSkTpKg5^u*)O>MP2_!#`tgl|~{eMd{Y4MQy}eK-vBmh0gs2D!!I zb^kQcoAI@LtDvT&TyT*;%21hp_G#%NX} zXcA>ik5Db&Iw%s10gMzTE`qEL2DBKmCOARZ$SK4pI6J68RUbDZym7b)L?<|F`8L6L z7$f2Yr!ie4r!i3@r$>q|7&T-3YZL}0-0an)9yl=Q(#0*bH3r`pX6r&VT3xOiVMZw;^dbSI(6_jT<+X){y332jYN(%6! zm1kjFTRi%SC!LK^qN6cTa$+JA38;g~NfSU629gaiaEV86<-!1;G!Y0DpJo)&oEOt6 zMftT5nbVI$PU2w_;E|VKw21#Ko?NZ?|Nj|pqZ8?ev?nK>!VYYHc=*;9_V>m&E&|`E z2z-+w@YRdJH!T7mSp>dj5%|(Y;EU3yDE=)3A5O?U?Nh4=ywt~=Uh3nGuUiD4W<}sz z3VapZt`PO*H&I&nC(99)+tQyaX!z4&E?--t5B0>C*6`)rcqcB=DoFl1-c%oXv%=Fp zCO<*EJWT$kp;i96zx|td^l#EWCO)@||4->t!l(Fh=Z&;qcuT|NSG)n{=~uFyX{zB* zW8$N9*8RB(`XsA*Q3WFrD}0p3XLV@ky3*@PE54OP{lX|f%3Yn3avdiTWNfr!vzoDJA^*G0VwPP{iU8#f8G?- z@G@VrUB#Ht($3!PQfI;68(*pje7hp>x7)t85`1JmMZdo>G_+FbN+_3V0`Cv~ZM+TJ zHZ(Na8ST{UDe<`FI?WRwP%J%)!$j{V=mp*e{;;#`7bG5XHF^~<x!>lB@I*?<|^6TS2VTOa9c~6VH&)hYhAUWIHD5!@TH2 z@aV**fKNv=y)_;+UDCH@rU{ZiY6|e)ekkqiT~BLh^qOD!N`LdlOFxl#qx~hG*|%{H zrIou~>eCMRKx6x(;@b;)10R1WSK@`9vYx7V-axnU5s{{+nqOcn^Q+@EdbQr66}ldAqsjgJ>S`9psVuhL8V82ntt>*b=+>vG8lt&oOS>ESt+ z`IY<)^-HCv{XN=$4}A>nt%`?+#qdY$G}R9N!A{OMrCjha;dQwtyv|?4tL1{4XepNu zFN8m9^d9zUq+ z!wyw&Ar5IbOvEhlK>`o2GttX-p5@}%e&QLIP=L-OaPtVa^7wYQSqV22{dKXU#n z#})Xm+09qZf8Bg+q0vgTQ}M#{dAb$8Y^cIPk#py_c)q*~a;vnBZ-bV1nQoPD^V^{1-KbmT%R5xJO55r-XnAMqR{8R7 z)veNUAakp;N)6k5BqefxG@wx&;)E?o+>2cMcg0;kH>^bt70l&cG*-bS2vn|ddx zrC;lLEOLy~+k>_cO{mtUdXFXgfYx1}MjLDT7v|gae0rzv?~#6^%PmW@Q{i_T4e8Bg zJOJt4Wh`u<=F7vT>R3qANzj?fSl~=$>}gYT8OK1jEMwZVOP4&|PP*>L9?*5y^fCIE zrjNjx%2?pQmxoryMx1vU4+5pT?Gg#~GB(%4!H6zyoI$JNC~^!rX??`&(I_V-Is)@A}*Hp5tA!j}1k7Kde7f#}kFe^m5k9^qFU#(aTvYQ-L%2n82BQ zOyD4ahj*FY1FYLlp5utdrZ#60Xx(LMq%8ye?Xw-`1dBxi5y{+f`7aNwv?wCM62#hZ z?-ksv6PSy61rnIlS0#97wcs{rSKS8f>f4}QTMVt)dh0-IGB+>=>zR$Qz8L0apWRR- zbGIL&tt_&BK6snyyPAAyBhvfm{g?11VD!uxmB1n#;q%@l`Up}KRr+RYZUJqvu4PWJ zRV45jB>|&r=&j8*#NMhl+i#coj$)Xb{b1*9&^~q>w2$8g?UT1byQ>&lbE!N9T0=3i zW5iy9LU)s5cJ$pMfk!c_35-4_n84Az2M~L1GrhSmo<@3;SE%y6+skK#EUV^E=<4lq zrv!6G`Y6Zxi_*k1VM@)MssJ* zoGGk|fy*oQ8tmkkJDPYAQ&U7Sg%3vT+z-JND{Ugh{r0N35noENHOIKHp5nw_BBv5P zHEW&|kAGGS z1>5?TY~_^K%(lEW+m;q=8(FfIvtu*c3f62}fo(T{(Y8%2*>WPyEf=t@!AYz-qOHQgtfO+wPtJOEq7S5wf2^3)@-f3rKu%bqqiLEzxVUY zUIwXdErQ-+uIw!=Maa7~W+$vcwykf;L!4l1MX7rT3YD!C+mM>pY^^+`t|eQehcs{T z$=cP@AO;b&tVLLPNQ9*bgNGQ{*0yGAiYGo z9MwFDeL@QD3S%T`FcysaN>bTb)iRNnE%X)SjMb9Vb0?t_MVgX?>Pckh6MzX)fNx=! zod-XMo$j{>V;`wdfn9f_fRa8^miwhESh++@Yh)s#pVuAHZ*GSYz+0ypiQJF8ydQJHir6T zVAI%>4eM3$Y*?SX$39J1hoos+D9pJA_uIp;O&cqltRme+p=e2U>$ViB=}FDpCC2Jl zbcq?NpdoY3-8@?hp2cNOQg~-B6x+&m)ksu)iAf48HZ48b6klRwV_jmcJlPaqVq{}g zV!`N<^vck-Skua<3ZDI6D7N70HsQJo)~BNVMp9VWq^&2L;!R67)|H{1C!69;OE%V~ zZSTpZc+--NwP`!JP1~+m)5?c1X47_bYtim+O)Dv^OxwwmP4T8B8*9^c_GDAMY01Xg zv|T*e6mMFxu`;c%5}ohx?o{m#bgB!N|FwF1l5FY&l&dhPpY9mnLWbTpYWND z)}Qd14*O(oJh$DM-eK%2M}3qaxyr-lQx%;GW4ul7t8~xz_3noJe37ETa@!bkU}x1M zKLAutPriNuP=ZwPXbI8Z3EDushX9IfUb=4PD#sYl1olc`%NWjfHU0Sv!=Lv!(Kqsb zyA9hFjUk6eD9|HxzdZymz3@|Phf*(&zbm%;;Et)Q9Ft8#D?>|nJRc!&rbcnww{I6_ z41new&1!1!F@(Rah74(H$dIOn3{j0csm6sR?-Vo`yT}ze-fP%mZv|2Ac&#Y3T(jrs z%{rK}v~Qeb;MsH7?4{AyYq7@U9A8j_KGc8?r5U2V$q-ebfjgf5WGn;C>U@6WFABYH zz7GoBG!*jlfg0Uo2MqKdvU;s7a$luizCS4IddlaoVORhXxH0IX1Ey;%3FB z+{~(;&Wg=Aijy}`@EGgCeIvYB#kyIsIX7pjq0Y+Cl!K|9qXy%xA-YZ2jGHxStS4s^ zu4)3e?DynbUYgwHW<@q;R?T!)9N(#|0u|-@+FmABfp~)p;xDJaQ{e5xrQlSIp$}`# zRUw{)X^zCFSZ*JdAT*D?Pw5 z1(I@coujODQ~`j*aM*B7Fvn?ll8&{J??Q0?{%(ftHruFi>lWhPXrILl``Q+{l2U(J zS|)|KmCPb=lU6q=Ja5G-Xto;Sh+hWp7>eIhHeWUezLl}HUQ6?;&7r)CK)u)PN{VBX zpIkP`RJ0g2WnNv3o4{yBuBPH_d(y7(slgKfawvfk8$Ih4Ul>7j;$R`psZqV>Z?4*4E{CEwrl8s z-f@E~biVTLvi27SC8e$YtwrX>s0O9J38`H0$((H!9&kDuk2|)&9^ba-6LTX@pB$Xp zpo#ymaxX4!-8eG6VNc)2^M)1#PTH0hJGS}z*Uz?@da0RX?uCLYXS0uYD!jhGL$&a% zkP|KacJwJd{E6A&1N#@8U-;wF@OzGR>s)5`ORwLPUgO@@dwV||_OGW>Gaox!XX3&B zU6q&a8$Nz+zpr<1oS!yoRQTD110g5s+4qNy2^|*v!aLi>yxDcol&TfKe05}C>A@S% z1s!eq(Dtq$JhSAX&6~sCey)ps&Km_coA*0auF}i(YE~;h#L+&l>wD>~OCP@$SMjTk z-QRh?>e1DK!#7NSFRsy=>n&?mopMgQ_li z_>PBLJQVYFr?X|=^Z)3jtK+YK@!4bd4^BNBe|%+jtNw4*om%1kXB(tfOa3nZV9JII zw#Hd2-`m!`+m$YN4_~wJ_ovV7-1>Bxh_4ThY(8y*^Fv$BH%0~5s`!4trnwsq&+7bG zXqUXBZ#GC8a>vo?yVssOc5qbTA3y)FqS5dSzkRh=-1~8Q^0OUt%Vqo-?KddUH$Tl8 zboCdXLoK7L?%uWP>4-+3?|sCzF=cF*u}ax>f0$UDN2B$Q+)Ue*7AJdiVVRbH_AJM(epuRQR2aG>j~JCR*t_lLDbwfWwp6zN^7xg2@tu!9aQ=a;wIgf!B?PQqb!E==k8N*U z_t|*(K#dhWuYEP`_@Dk!K|6vbj-2zy`99z7c<=15Oa9t4@rAs71DBrJ^+(lZZyk6j zF#h2US30g=I{fp|jXo>4so#XweIsXVt2AbK)zf*?-(B^|yygy4&9~q0Uv_i(`lZtfnmzcz zj7=4mwBGpOn0E1(zUu$j*FV<(Yx}eX9|gXV67%iWX1~6_sxbJAS8h~)efFsVW2-!B zoA%TS+osyHXU^Q&{^7r3^1khKGtV|_-O9cnuSneGcQgO3f{7@ET$8@7pf<-l zmA0t@HGREP`7zI_bQtSYPUZ>J3y|nk7Ks0jF#`2Vic{GGsTTpY$5+GMVcYceKjyu0 zcaUNmhMO||6{-1wrJI*()7;}W8)v)K@PwEA_-m%vqGaY4$Qu^_{6q>>*3Dg# zyK-^7HlJRQx8v>&@j->eN90Bgk(8WiUtfAWMx*kZbXRQSn81}E#s(G68?kZxohze; zY)%gx?})RnlqrG=uP+UaV?j~M%Q3^_P9)tN+#>h-QhStJqZZKUy@^UpBf(iKK)={K z;#Q2g9&3xDmcemXr^_o_)R<8X#@eE&jV)@ANYcHR zbajO-s?wZ-6)$Aj#(un_8E#}ZiecKI!o0zaV}c5`IHqbJGh>FMFgRx7@IZsbTSBw! z!S}^zlne6AWg<&v#*Au(8keBL)Wz+mUtCJ9+s8~wskV|=L50f)*Ul|FE_HC~;vTqX z(qFmeVh$yp+ZI|$R})-f69x>Cd{~;24@=XrljS14jz0Hh!p!ybIVGn5V*al@g#Jd0mX2AFCriBr! zxXzf-f3eXIT0rpX#NuC2hOE^e}BS)Bin)WxhFWyjr!pEEEb*G<(9RCA|~oA}6( z*()M)BZfUX#5VStD>#PX8}X~h(0*um+M+!QTseI`F3Ia9S4aYG`87?c9|sI+=xe@; z(z|PHZyR2^je+u@e)uPhht!`ND~;$3siTt9L67n7hKYZOkbPJxOo1MjZQ7I*P( z4vQSm8ijV2@4imND|UI~P(ueOwq)E(Y_20j;_0Tu$ah3;g_W!$m_=nL;N{2Zn1Upw zCT2x6YZ$Bq;;v@WhIrBh6-HsHV||n|GtpRSn&O9h{Tl^_p6lCl8wZ7QQ?QG!zdqAM$bV5sMjoG!Yocr_Oso1s;A zfEVtKgJ%Hl*#_WUpxg;TW*Yytx}vZOR^aIDuetn(oSLq&Zw5oQM-jEd|7Q5FF~-f$Vo-J*HJKx2`zU0RUWA*RV1KNt-v>RL5)s|cl_B7Ew;n9x!8#jq^i zoxUKCep+eH^;q0_N5;~Uk}{KB1`e$}IJ9aQVw4+H$nk=#BGU$!kBP`7H)tmN#OuIrH#eS|E{SqnE8VRz<45M!#f4+Nr? z(-drMX3j$UmYtB642#;eq$;UD%Ab3`+!2x|KlD*r6oQ_hIYb*owK8eKa5-dm1VztT zBeQB7SPd!!6)tk6;B1TH3bsBoh4UmPCug~`v(e}oi{ieRsA18=`pm?eI*fT{k!c8_ zpwSA$rlh62+%|)MwQA*ILxv3*V-T&9v9hz6?}}{{v&eM~jXeJc z$K9b^S-v1aG&^W7s(Ly)P0vJKGfL0sgCR#yA+I*YFCEB`Eoyi6ym`E0ay;qCPRP#5 zN}Dtu6;2l2oHflMED}xOyb;w37Y=?YUf3){lDRVj-$vGrwh@TxLK{&Mjbn_ws8h8O zRvB>=_E>u@h66CPqtqzfOIAy>EP;T#$ueKKT$3bnmw95mZwBf+49b*>cc_^K&stP~Q zm2Ml^thvsZwrVCY{!qINYr7{Qo7Q0Drj*-pG^ux@S&PM8MiOYLoUnXLSXHVmOM;z0 z8*Pn7kf0Tlg|jFdZBUMDS`JQ0>6zo;BI%iv#uHPMk zVUozpm6HUoJPgUw@r>1_aA?N`kNy-f321(TKtm$^;T2y^N*sSJ2A8XnR*X?ES$gH? z437s_`7m^HQNu|NU>B_CSeNq{hU7r9Y22ejuDK+BL0zC^>e8 zS6KIFo}bcsWFoivl27ZxYuGQLwPubBawGP8pXVfgdJ1cq=qCQNcWJLzdBtF{xpxa5FW=^j)IVHUUEte zW63!+F65+IjpVEvm)e9Fmvrb0OIGq$j5cY4_O!5^eF3jcwE`4hK8?vv$e5Iv;o{PV zs^XhSz~KngVv{m6Sig#l&z8M{IUdzZa<^iR*OJOe4uZ3D5;G>7lP_0-Ik3k|S53EF z!C-g>_?Q&N93Cjd=7DdRm%Z z&e~Q^3M!P|_0fu^DZF(+*Z*@Rr~FM_wj?7T-ZUW}DbbS$X`KUIgR6~r<8FGSF&%Gd zFb`~e$hYU<*aVjP?{iKry*PU6;Gn_;abqbqVdS9ivyRRn?aE1Vg4__zP76R6zyLrD zU>U${O0^^>C8SNtagBFn6&bH~0OokiHaV4Pno=FJ#A=1`B(3yvbJLQ|)N16Uge=T) ziinhRQAYY3JkD3Los^J0$(+t6qhicSg4862VS_oTu58Zq$zJ;SDt`1a(VU?fG_%*! za!zArY)I=IlDxLaw3?BOS;cxl%H?>}oX)D=8I!7}7-3FVUYcSAj>ZE9H15&EnVQ-@ zBcpwGwwY3`e7Tc33r%1REP^5_%T*MGs-?o*k%GXJ(*jj$J-EO%Y@3nq{b#uZ!nWG(=)xQk?t%st2wEv z)}(~gA}X1x)`6t~BRB{#YppWRa%CiDVZ7m4aRQYf@d`;LEjuAGDJLxt;!$afp-Oh8 zyQri$mFgVHuDrA)SAypEMh7%iQ)85F0^Z;;n?R4$JkDrZ)jnbbmta+6JP5Qd#VEV1 zEV$$>WIszNo-iRhQ?w*TGF^+QDMhwj*$G;tF{N5U_LUL2Q#PPSF`3sxL2J8-I{(+u zfYgB0x0agItLzzVUp`MYAZ=-Wh)N? zEk{P3RdZ11VvNb?VvNaXD`V<8L1oI!DmEvjwM?rOM(SE0{aRhGT-&9G_UdQ09F{N3 z`kOdud^&1neXpc?r=Z?nBL`yvtDS;ZnW$zu>Pla6Y6%|An0!`^p6q(#?$R*Q_LJHNY`SkMq|^t=~_mY;z!%0dwIK5X}4!~zyR8q z(3{xc5*#I&Rq=2sG|`D>0&o1swf{<0G~AQsi-Ks zCMe3=l@w+3L`8W8507`G17Af^wq@YSb5%t-HAzu^sHP~NWa2vt)iK1Gf;B5OF~fIM z0>B{Z0T$}9*3l_wts#c!LH&I2Q6=8D=I39(`8?zxmyFfG0~)BL#CMk^ln{p@UH0fE z(=yVZEI1nTdQ{n-*L(jl|6=358=r}G)ca=M;rkA6nRV#x2kKTj^3gLp@B00E|5I_@ z9(7hqkNmjB^-UcvWbLmV@cirRH}34a`(NGesQX>@J4bIn*Jj|yyM`{ATdhjR#O)#L ze|h=9D-mrL<@Z^#VaWEGmnM(z|4gU*R%X>+x$V@=w)Uf~^6KaRnP2AJ+`*q!`EE%; z+Y3j!pSkGs!k(JLJNwAKhB)m7?S+(({gB><4`To-nN2I@U z_P%HCo7H;Ev6xp2D~$cM%jNR#ADa_D2No&B18h%wZU1oR*N0%I);9T3-h?bydUn$$ z{J&tudlO!d3R-k!;r{t2XAeI0dX;*4O}DS?-gN71<%@_pso~W>t^VDo0}uO`+UHoX z?aKAXI{o$3(i>l_{@Ph-!{h$1f7!ju(bO;UIvt!d@5sV!JL@^(r%k?R>&#D|Pk3d} z$*mpVZB~7I?-!!hlnYt>@xWJxJk>4vcv3 zAO4A~cxQCt^tF}dBct~MY5;OlT^X*XhW`T+ar4EMMGpx&HlWn&&a%;8%-%e8<;QK3 z_C@p@_sr3!_FYrDZ>-k!@FS-l{`Abn3-j9?KUd*{2m1w&h};+ue6Q=>CX4r8ofWyW z`lFxpuJLAM`WJ^QUixNQl_SqBFMqDj+u4I>*ZE-O!d=gwb$zrMeS3 zExmKt<@c{Q{IchFchoOsZ)>gmPk$Wv?s?Sw!>A>!4FC{F7JDCeBIg6g}jNoMlx9_UW)bwCbpHv#vihaa#8`>xMZ#+?nOGcmD9l z(vzl-xF>4a#fqB>DqN~Rs_yVtpIE&1u)VhJ?1IL-PfwV5G;l{+{*aBz#~tnu4DPdM z#L6FglZd`}#l9{n#g1;P&&@u<4K5 z-`Eoub+XKaOO+!t$Hc!?{YLnXm=WrehN*0!tWCs)2c-S6!M&(>@@tLFLdp0CmQ&aN$2PuVe||Fp+9KKk94$#o;fd^@h! z7hxwJ@$GVcOGxiOU)!^#;gDyS^`Gnrd#LG&jaU6&T~oC~g?AQ)y<6ePpcDO{pMSkY z&^OI?UcdR~-rWfuy8}Ai{mUP}oeaT3g4$hfets&e(vRm`KHg;3ufH}pIOj&#%^yA< zwtLg8ONWm(`s?c}oo{|~c;KJWy|=&AqiL5pH;?|jv+2R#emj%7Y1;XC`-;b}h7DNU zWABmBPreSkoDy`QZ%nT*$K7#HvmGB)j8CgO<=$46L;l=!Z_QtRsG9Q8{O`)1nRnfH zb-CJC-}+^4ovY4Du{}Fg$b4&w&u14m=Dv7!p$s2mzeQDgtH-AW)b@{^C zHy^uj?(>%OC-j|NcVDw9Z+w>2_O7(8{fpXfyz$)U^%pfM_l&*8imTmUtI^`~L$M3X z*FF*!GyH?|d-vQsyIYx*@F%~VF=Xz}I_rkXDp_M9}obl1v6JNj6;>n?3e0VDPT>huiH^#Znv|Tv* zi~VhW8WQ^I!tu-24ct+u-xEiU49PiNX5_nTQu4cPe13l5#!X)|J96l|A$!-Z?>V`4 z#YTy*|8*?6^@z^bQ=S-fY{0zspDi1{uW7{hr|0(X{rqxQdiU4+Ukp1m-vw7q@ zV?S^7<=jbQK3<+xdDxrV{;2oZkl+i24>X$5Wp3#uA3S|6+OhYrz0N}of5zny(D|6R9{zpP z_!AMQ2E?>Fx3TZgANRKo`0K~xhwHb9xcFh>`zI<~YudBrhgltJ@B2Km>9x-v51%pa z^ORQiKG}A8)n&t8SUhxljS6pc3LiE3iRUX$?0R8MN?46)QwAqhiLAaQ=&3a;|ML00 zcEzw~AMW|fJ?+2xeNcSptWQt8;Y@cvzApX3+?=`3&99TX@%u-D>koM6+ci`7elp?B zl-Uh4PJiZC?_BvNCssXl_*~_dc^_|l>HCeNUg@9ob)~%YjKeXlT1~r_eD7-~wzWM~ z^kkU;Hy@_t-I76 z{QVEXPenSKEJ{4^K-#`_4;?9=)co^isgGB4wEt$!lnt+Dy!icn(L*Z5Ecv)Y@}9Bt z?#pcRL&fn0{UQd`uRA27Nwf7?Wg7Iof8&XJ<8I_X)pqNOp-O=^!eJ6Tf&z=3q zPY>E=y;*nvxUw@pP^zvSw4w0XKigJYGQMf;N~8Z8+%@~-g?VG+IEitKnTOd4+&m6qc4O407?&8-&kqA8x!HI$a{n?WLfFKL&4CXZCJ=~F zmI1fSgju9WIu!pE+y`+ee?0cnsR82#bx9ETMgo6__&-lz^2PK9 z#5n5NF*j7&+U6qWRZM*pe!5ASFQ^xY|MfwgB92R48W^r4bS{^>G&Edq=EsV_5pO!c z&sSk?TZrTRF4{Td;6}W`V57k%NaAsHY@r43f));CHu8!C`?fKckOEhuau0>}KBaV$(Tj%|n;N10|E=D1!sP7cjr{`QzsO@%+~}SrtiT*sh1U7FFUcH>&r5rxkm<36#m*&j)mww`@3qz7G{YCPvDfrU1)W0TdC^>oZqAwN2i#{cJVT%xSWMw9= z+C}hk7Q>5vCwYYlUaZgL6;=c<`lOX!XYj@@UpQTyEdq8hLQ8}@0-|(adr=2`jJ{1= zT?<@23tW8*97h>uei0V9h8DO+7PvbsaFG_c#um6HCLH~W`IUCABkatchj!-6-mJ=> zwy?4@dC?}47w@xA=MqA}t6mYjXs@Dp(QcAg1Hp^+ntC-Tf){N%LzyXlvlQ(o>pE?# zVccgKM;p&BA{}k*rq`}yy`jx#iTW4`{a)hoBcWd;^n2Oxn}u4yI>_?SILv~kcPn%7 zlW{DUS>Rz#cLtt`JvGW_1|O{f9DnrM@0CI9>96)idi3&FS>HrQH_HaR&($b|Llobu zv<700dzj1apaOOHbo9J;WVuS z%`lr=2b#F*f?rM1MENOKKq;R;ylmsTP$f3i<;rP39@~k=8#Kn)h_40l>B0B>LrG*v z@iz~yC_x@=v$BI;iw^=#N-1|3W#}g=8l5@VICvxCFBT)tXw-$r za?~JQ1sdR*#mkn5Ee4t6i32>9HH0reQTU-gaqFIi&5ZnwSqc8Th>^0dt zvd3f3<^)i7IL>S}*%GqFV=KniinWX_4OGMN z&=$}R&>qkMz`EB7Kwe#Njs|oEbOUq;z>~3_8;@21cLI6?`T+U@`T_a_1^}3TAkKpT zg8@STv4A+hU4Ws0VSwR)5rC0^c)%#YXaLhE;5-(P2p9)Q0we=mfE2)ZKq?>&FaafohGdJ3`_*k0e zmJeGctl{KjHwbNI1)NjCWHzqX0p`FHff6w7^o9F*1A>NH40r+8Hb&yCzH^|k2d=Sh zJmIZ})7!n*b=Sv^o2yp+mgmIsS00DNe^I*fO8rkJQ@6|=dVc)DUfcKOcIvyc$#lB5 z4**Jtsz4b$Y9DN|b*jB8FpOEZqmry0lQ)QqcQ!g2D#W1ncC4~S;jhLHOwCrm8V{h|RU4R0XqH~jp?po>0X z#O_CPz`-K@!i=X}AHXZ3LpUHpr4f1s4G7cFZ>-Yzf-+ZFlpK7~#pDW|Whe+CT9F*+ zWo8bP2p9)5vh*ysn$Ffpbf2S4x|Cb}aT3POmMB|mzo6+hnBbMxa~nPH+MBL^=3 zA11mq86rRSx8z6fw&I6VIXFBx zu;y5C2=w3(C^)bqCWk-|4)h*x4i!LSjc0wcqGz46!n594;aT^r@T`AUc-BEHJnNwq zo?c{yXMME7vrby!={;6>)=eus>!%ri27{CJaOd;3x)|1r;4$h2+oR$$24dBp_N0HMqnt%qdu?g_kre)PcgUA?vT(J@4 z{V`A=Y(0%?@sFla4@^Bl};uM{PBgYW5GOQZRyHs>D*sFXNsX z(M9ru-C>r@vqA1K7P)#%rT7xvOQ2`Bz^NEFHeG7urbqMcHPvD{uuFDNwE~na>>WL( zS^o2W*oa0GmagG8OJWbjAQd}#&fSb-cWuV812*GoTHx5In(1nra2$^CI3VWM z+OY2+UKJyMhv3bmq0_x8=HA+{?=?mHy{^*GKa<4VoGI9{Bq>hdWC(lkaZ^bP`5+Xo zhkOyLqlf$us;h_m5vqsK-FEp@BN^9MyO1ZJYPiIFUxw_MFE>!rvDO+xz8)bzkB~p+ z%n_;t)*VVvqRA6mqLfX_1q5Ztjv-e=J>=sN^7RP$d4wpT5z;XatcjH15E8g2=KY zR1p%`l|Q8XpmJdco+|F!P=Z59Xs*Xmf;&VB?hqxk03{``1*3!-LIO4hBd(>&B~VCc zrH5#x)_RB%+;NoP4pBlIP*MVG79}`^1lFPX$~!6-){iuCkBNDpFB?O?9w9%E5KFq9 zDxtJ0AzVnn_Gx8}azd3*8WKi`yH}J@8WKi``&cr>`p{mdWPNalD1k#7=7DWB^H5hv z;P~VT#Se`Ex$xQc2&J>i1z$}=sEZz=1a}-IxI>f>4N6L2%TEdQg#>KvR_;^2M3@pd zJ{ckIvdIu7bkpM~p}QWU1b2uMdLWJx*pE;`gph#OIVek&Q);?0LPAeHL-g@l#L8)`b$%8;)|oS#R?ANMh1z=aaZsS=`u1l~MYiate_bUBfSfqIB}7^H`o zhrxP?d2olAharfg1WwkNhh{8O82oGGD& zkbswmAa10}v!alo<-4MgpjoJ*kl>CpTBxEZW!^!i1WrRKp{0;e2@>X_AD3EJ5)ww~ zA?AU1oSBD8Lc$n5L<#N?^N@fzN~nx8CA1O}DvLafMVMSF3kivOh!V!>AzCR(4^e_U zL<4PxKr*@C2({` z32lUgs*u1}r^`H4g@j>x-m5~wFx^U3A;B2OK3cO9za^Q1-a+PpV?9b}DizO z)r5pJJwyo;^bjSu<0!!$qJ)W{q?I^wq=a@t0#_-x#4`Zeg^%opiKhWFLhXi8xB&IFu6F3kfxZgvn~U8Xi`v;bEm39#-PlHQiRKA*?h-mB3LgC3FxH zxFRB5c~_Od6%iTY=>_vp6A~uzMGJ}y`QjDz@9C6&h|AJL{>VW#Ld-)goGGEBkWfoV zIIL3E5)yLs5GCa5Azy^tag^W=Q9>RlDS;zyO6Vjca3w~%^0vx_D={+gTwQ8iTjXJy z9-;(y93{9zlrSBXXVA+1C$ zsEaf6&{gDtyA+>OLToY*bs=F2`fDxZgZi{g5BYk8{7}1=>v8_57xy7V2`qi)K}z7N zl*!5pm6FR6reIVfCDcPXWGMxDh!Wf(N?4`GQNsNQoxv#S4Lc>c>w$4iMwD?)M(=;H zCIe~wAm=vMWU#B|J)nyC`S@rz|2W{02PbH-G8#VXn|`hT(M>-NR^&nH_0ZznIP%|o z!*77%bn>D3AjOG+W+DpMg(B~Z|2e=6!gVIj128xz#Q;p|nq%74SiRz#?s(XIef&RD zwmG{O=Hm;?fy#!`Egi|QZiq76&KnZL?X*T$G0_tV{saGPDi5AnrsZ+L2die*J^IAl z6|Rge^-9p?@`FM*JIwLMaI7()UTbnVy_biEVMzKA&z^@C*3Me244bi9tocmtnglKG zR?}+qCFk3-!0p&~Y$+@v84$x1f3tqo#pJ|pxr?8P zXcShb<0oNThFuNZGUm0UkQ1$5?mO_rV>g#S`NEBz`+E$zyUWqG7c%qmDkaZ(cHi1R zqlbTUIVv(Px6h3~{C^vj(eH)*eRuDE;o-+Je9v#M{N{n^kgGqAdu!^<`+iCJ;DcSS z9ND;|)@$`+3f8Q8^;*cWfpbdFnX~1%Yv>(6Jom)JUXR5+{=uCG-fFi0_<@&Bc8e#mySEeNFkjcW*v@F!QGwg+pRjzT2*sqs2$_ zo=X17=f-ERE=m4radKYvnTPH_kTRlk*spij+f>l0f5Ol&;}gCtzkc=NZX+)ZTAcLC zsiEgKR(iht!_TyjukpfHb8}z1r`20uwST_eGxsV(Rt0bQp>wkdaM$WUM(opbS1< zAdauT@wqWSi}z+qjuH!$SfIoLB^D^LK#2uPEKp*B5(|`Apu_?t7AUbmi3Lh5@Lytq zj>@>(c_{i{qV@lp8hkxiAQsWcC;oP@dZU1=dRf?Z`s}v<%s_Nb<#jRJD z%DThc#L*(aP0y`YRV%vVx%DcgoIA{|S5*yLvG{GqORe1T+z*={;tmILxrE_$Wh^PK z50Nje;F36by+t6ko$PeMQp$H+38ZK^uKOru*zL__Up(GWR^vZkI73lyc>UzwV{&{` zc}u0FRo?XaNlMBY=ds0R9G3jcB~!HCIAyIK@5goifSV(s#AoVhaj1mGm#6ySXTN?Z98 zcKHzJGk}i(9|JxCdUnx zkAN$HtAL*X{{s9B_yzDQ;2PjM;5Wbxz)isKfIk3#0{#MswQaCHT0GfH_@eFce%DdR zKkOyI+3>C-wrdXq~50$0NVSJMJl%K}&1gmaG+ zHX%mafNLBnxHsS)5sja=0rwqjCX~OU@ObjEgG0Q>=pbHs1UMOIN8DyTP6t-J&%k8^DE4C@4MH5bbzDPAjH0Cmmksn(CH$T=i@^c7&++ZvD zadYix(G`#%-)uKlbP5NskrCha!bU6pq)x1vrreH)WpmlEs#bG?9Xa+bWqaPkq>uk*0~D;l@aBS!~%z6D4T4wb7e~Egfl^ z2^wxr^rm6UN1En>hFc81b!JOQnihhFn*_aeX3I#LmV$=c{3y$_yx3Bbrj?-KMm=vD zww$DCEoivaj{11=VM|JyHiCwm<=z5KBI-APvP{{slBTVo;dZyfUNmfJNz+cyaKjpD zJZ05TY1#`KZaMR&VM|Ot9Rv+Gjd|0sWhPBWLBnld-ukemCQT>G~9aC9u-vE zdKHJA2|e^5w`1Mf@88*a#kSC?>e*T7>9ovmm`c+{(1dyAg?z$QnrJ~24w|<;?9VwL z+w%yKFYhM{byjfz$QDR+!d!CqOH_d4L;X zB5rXT4eedBVa7%?7!ED0owX<#HeOh^A!2%zwh_ zB|J(jP-1}+3zS%(!~!K2D6v3^1!#eyHq4}m4KtMkzg@et-pxCo{$}l}kCF#3`nGIZ za_@WYopG#tkKO0X_t?MSaIHrs=B(NDNbIlGr%XJV+;sDrb1Q;=e(>X}QwRU??vKN- z`y|Hqte<$One*Zke!q=+I&63Hg-5SsZ+xop`m4?7efwy;pjY-?zR`VCi~Us_=Qha9 ziWwcSXGM1M_HC1Y^Z9z`!G-6#3@$wN#F`0j9p5nci4Qt|*COHfjRluJO8&IqXvN(> z=Z;+0{@3rGZ{}ZpO8U5ArGDL7@0GYo<&W+^5Oj0uvNBWdcxcgE+pe_9@)-~99Q-O8jLIp*iPZQ$Xa zM^3j(d#LY@<85vZtb3}{oiDB&*6Xbr{YI_au=sN3`-L;V?X>cbo;y}Ies{yGaqYJM zzP!om5C5#R`_FZ|m)2U4y*w=PyfSlf_wU5|??Ay5{Z{Skw|?Q0N51;C`H(LE zT5|Hr8#|x;tJ3^>Q*%13@~MzAw%;B1G`{h}m2trZV-jkF=8lLPv3c^irmyUu^uvP4 ziVqEcC1GFd@A5AGH2wI&=U+V8I&Adpmp9z~eCCcZm#(~ZG^FpYUXdL(ADBKdTs;QX z&TpB~rNq5UEKp*B5(|`Apu_?t7AUbmi3Lh5P-1}+3zS%(!~!K2D6znQl?6&R%=}*z z$NzU5X1Idj0mEloxfD9Z@NFV)Xn9usc9CM|qBuo-6GVPtRolQ4V%V5M9G{b$aa^5a z#`##_xLDIn#|4*W92ZcUaa<5-#&Ln88OH^SW*iqFhA4f-BYtf;HWwV4>A1i!M5*aP zN4uEmxH!;^<6=M!mv4Jip{=<1&y3?@KQoSt`^-2l<}>5Cc+ZUEVm&jCi}OO1U>1vV zNY#al@j}$)=NgWS??RM4BEOo>Tu7(!Q`GN7ap9a9$Axlc92dr!aa;&z#BsSOk5fu% z$UPtyj@ht>q3B;3vEY)=WpB@TC=oLLw3Zeaas5C+c^iU8&2lY@eLi7WvOBsX?A;cwfES^;W zxg6S#Tx=D4C`ie=x=!r2kRcz0Skf}&i_mF=xa66i<6fuY{c*)|J^)%fR>!Tw9+`F6 z3v-Y7-H&gXP%dlcVu1Wg5jQ?<6ZqKINB;xRiT~*sDUBTv2#h>|&uzF6Uk%^2w##Tg0vwiTBg-{3w62uNrQb`G50OgZHJPMw%j752t!1)h zWIpBBj<{5Oo!A@1d~&&Xf!NJM-drv&eT7TK3&gG>iPwB605YWy(NnkuauGO759KFC z3&gG@F5?cs3QKqXHQ!>3%>2vmB5}$2IWh8w=ND?SHl~1 zaj3e;I>5fmt&77_7xo0Si~NET*MqJVd!VQbm#?oCyP~KIm#<6T;?niCdff_yE*jqG zbAixhEq<#FKUuffwlV+V(UiiLX|33AB}0_?31TUebxrbS4Opw3*YTQ6dW`gQNl%%Q zj{{d9fnF}B4>V}8TCH#F-I#azWZv0(GVk(ROkAG7R_rmOOn&WYt=N%9nf%(5lo{lacW$N7@XR}9N_s8t+@Rpj zJGUBmmH}n4$3CS5sl5xA_ZQu_ybo%oVUOJG<+yFT*nP*`@|#cF#lAcl@R%P;QQO_!65Mn;dL*^DCvpi%ztCZF8emdSCS6U4# z51Cu=^Uf#7gv_UGUAdxttKQP{8&d9;p5Ks?<;L$vxm#C$&|1T5<;j+wACg`K&eB^d zc(kq+;GJ$=w3eP@QFrUgjU-$3mY!dma<}ySgoTvJFHO01si^D1uS`kbqAnFxU1a%H z^w6cEr7rYc+C{dy+^|xhxAYtd73eK}CFml3i{GRw(EXf!x`sFUTqWpIfZuw7qsw&W1`pUY@%0lLOq@-U|)@4>k{-vKwJY}-JR2F&HTKdY!ySE-3 z?=kPP)#dJn0==c@_pA!^mY(0Ul6?6sD|g=cEh`OAJv2Y8Qe@saZ(!NWZ{l&&PJ!Oi z^9xr6dP~nQTuI*ix>bR49;ukes=7>m*-FZkcrEW$J@Q`FEAO-q=PK`uJ;t0zaMRD< zxAdILxLbN|0&=(X{O**yrRR62+$}x7JLPWa`Q0gZOV964xm)@gu$#N3uYr8HTlyNv zhr6Y(fjqcd`WhZBeGQM6zJ^CjU&EuN=S+1NGxm)_0 z$dS9HuZbMVT3S=DjU4ONL~gdCguGh-&i33bJ-0#a5c|hjGW_~gme@VcQmqBK+k^(S zAk#gjuLYSJ-XB+5t6K{)IgfD5)LMGZCYe{+(sNstdmh2>VPz?HwRPq9uq5x=9x`j| zGHWBBZke?$Wu8%@6@PSTJ?t$prkIA$$;jU_ypbRWxhEK7tnk_vE#oYhxG?0yj0-p5 z@@?`iLLCE6n~~SGz}2(B)wjSku)swKoV-JFNR`{rg07LkMZ(4kcHD-D`J@xq^aDB1 za(a{rzrdBH&+VLgnK(Vl#Hp8w)1yqBmSw^|g0`a{REVaxg?Y&2H@UJDU)2xzO)lvN zVM1mnq@quT=`zD0bBFLf$twUGd;O7Gh8)n_f>T*oG$Z zS_g8U68WhEnNNu~I?x7nAXCHp+gUq*_ zU)6>DE&5!SU;Nsl&volUz8nG7h5Rl0T(>UdYk1=bs4nDNkAUdoEO*({^BZ995l}tI zbdP}e4KQiXdXVWJb=1@CTu-+%^IQ)y7lE^EMeB*)=Lo`_W7YF0cWng3y2bp<5kP&R z%lin^Z|VzOzCnm~uCMD--$R%Bx-RuSbg8fEqVY1$b?aN|!a7a6)ED)k0d(1>kANCL zmu>n8r~!15^`QZD*`|+x8bB8fZ)_JEK$mU!dCs$Fu?Wax{^ckj0y5nrpa_wFZLS*u znQ{~mA@YA7sc4r7$kg!05l{qVYIx>d8v#Wi@7^OIwo}Zz{C;jjk@wFLW;rwzdH+S)brjD<*-d30W~Z#?`#K|_ef#yMndKns?0`0=EthcM!L*KLgslLui3ki zE|WHCBxF+eM)1LHdfpo$@1A9FMyaL@#|@{q(F-j@-;^)TTEArccHJQ3Yn5{T!E2R} zhIiA%wq1YD^P>UU;k|9wF1PJAMpjVJ_|6)x0xm*b-g@LwM*MiLE(URB#D-jd@$u`I zZGkX|5}WFB<+S~q4Y`tA$^ZXJ3k=2AxV!!vn)B`=Kb6M=4r6(got3($&eo4?Wq(e3 znr9Pj$e!k5ufAuqW6HQ6nj43pH^5{78H+yo@JQNgg8V5{_&c# zN{+T_!oPTKl>f7k+Y2VvQi`$Xf?BOQ4V_aYz~poQ)8rCbLvPUxYfa$jk3%L;k( z9tjunm}(I9Mmk;>MNc{ZjmK}$UDGQ~g2QP-e z+dS*45h?hBH-C*l&>r61676RTocYb%cGhGayvgtmIzH}{%C}XurD7e`>wkLs>m3`a zTlicDMi8p4am^dv4zTpawH=OIh3xYKg%C=W^g)V~7(tIgEiNTJ-aCV9(%EdiakZ9p z5r1Y1Tl+T*J9d@$OO$;;Me*_<3Hn@*kybYj5G>gpmi6X#t{Wx{%NIaPEJSTQzK$~8 zl?wJ6wz^SKEnC}X2hX}QJ#$=QdYJ8v*vW}WwpG0n9qHMwpycjZuEerAiR02M)*h7Q zawfZy(i0W`KFOiV6LDF&!QFaJo9xKUc2%em=gOF@q$lRMdbqOE{PXN}S9QzH&dJOO zN}J)^qipl;nUiuHS()i`*LKg$$WRg|C3nls$;m7`sad2`u|?tEfY@G{SsB@pt({nR za_=C#c{AD>>zg}nX>hZI?&)bt(!_{{!KLoX_H||1YBy^Vo0=ItHMmsINy&372R~XW zxKyRu%|mK853Vf?_;>%Z?#fq5c-F3YS4tMGcJ@&o0geZss?#mbGk`aiQP-=)* zo4%?_o~z3I#-Oz(P3A!h{a>B=Bp0v2!C_Z=s^{tI`91XCfZ=Jy%6iHeZbB($- z<*!G4%G&aYDxW?qjc3-pDtLhqD>L4yIhg-B`q2*Kbrg^c|M8ZLjg}|DgLuh9B8}Dc3Au=*tvFNJc8d74yG(-r*8a!mZqilUrOhPFpD%QONzFIC0`EPw*U)_e z1mdVwSGl1Q$xeQ;q4CyHF7kdI!*@{|!i(RTFDHIImp4b8JWCYe;1(Usu$S8;g^ zMZo1GtQ%zYKF$r)sTviTcKWGvjNuKZ#ef%ZEeA`QV4gJi_*D1*WA94< z;;hcK&o>M(5SAgE7-RBm^PcxC-#P0c8XLqm^dNQkx9!v%gKL7;Ke-Zhs=?0z@2fg#A^jgE`#v7(|D)lK zD?z6k{!;M%^N8@@kM_^OvjZKr3j0*UUmZ34MWCMk!|>5kWokEFUY6_=hzvAgvUC)AsR&e5Blxh;-{A z!NPX?M0EQ*JGQ$gHlT@G`YWW=`+ulAS{cIHM$cLEXhX<$b;Z)t%4;CS*4H&`+gMlU z-bQup=EBNG!*R1z*XHGx<>#F1*4C*4M6%bBxydT5SUKwYZZ>730+9|1*CJ`LB!WllC8F{^Hcy z{|B3w_@w>o8mO$3wExbS?O%=4&iSZ}(@xs%tyG^z`~UZ6DF>&*Wh=~wr2px7eA50u zY5(kFZI4w$EfW8>aHReB>iHpDF5!HzdXI>fny85xA=#%*PAYQi6tQSkZ_`naY z{ZugLvQv}?kSj0YlX)ZhPasc)ZfJtMS=VU1?~mg^K9D3kup*KRuHVE0B8ZrACVVZwp7#Ye3*!p7r?T>=0MT zV$YY`<&6<-T71cf`R-#XmW+ipA!CJjy7mWDQWkxbgp_^#(OwFtnkQU;xeMVJ>WE%~xvy%>d@YyrUpqwJsU*P0!yVt8r?dvEwpTIX z-FS1s87c$p>3=`<66u!{Hkc$m<@{fOpbMv~=tZAD9XWrWB>cL>tYoSAdP7{3sVLTb z{ayNR)&^_7p0ngk-A8wpoHthaqfO9S$&F!0&p&pbYW|rkt?Ho%J{W7_ZRh(4jedkb zCkx*h7Jeqm(22PkHF3|SEtqe^?1$-qxeMk14BNy#FyDc>7v`T} zI$^#GLw~*p`+k`3!~8(gy0ra6*xb+XBbbL_4#GSF(+%@~V15kq6PQO~ehTv#%psT{ z%wd?vVUEBsoF`yE3G)<84-6;qpN8SPXJG#V=2@8MV0vMmhj{_!moP8F{0inJ81CQi zgP}X_!27>2ufY5Z%x_?h!Sutt3iBGwzrwr@^IMoVV15TP07Lh`*YZ!Mvqu zZ^M2E<`4SsKf(S_m_Ne|!Tbg0zhK^lc@O5lVg3pu1+@WSij`OZ*a#6=33Ck=m8Z%r z6NVd*%g|~8dOjDRe=kWFU}HvsD8hz}Vo`#wdme=5Y`Fkk06ZIi<>BpeAg*99#2Ym! zS^!tvkg-Vqo&$~oY|NMnH*-LlDoqgYA_&1lkuYlWC zaF+|0#fbk(Q0BphRY=Juq@oVobyy&8Lh3BR-UzHhGU3lgu@z!}ljMk&{sqEF)9KHZ zS+ZFi8;#sTAtkDcLHrwFRti4HfLS5cURs=r(7nqfR&#!>{B~pT$h0o`g zptIolya>!f=kpTqpn~FM;6G~I2h4)z^Dn?GWIn$JmIDV^&jWKSHlG)Oxj~uF8^HWT zPl+l;JKbL@L;Ia#uM11E`q4O(e`=g-!==Ol7nb3K@Jp=1M@>I&-w_arXM(pCrm#ib z)YL8Ax|}Z9K^yL|VOb)9BqvGI{}%EmsuGEyyU~&Nld;9+8jX(vWNx>(QbuEuOXe7G z3V2NBUW>~;0iV0%YD_=5L56gG49*Qiz$sknmK`VjB~@#?FXl#V^Bc z({34Vr^XC7sIUyTS7U}ds4>Hpn_6_Z2wJ9v;mRQ(($28B0m@2aF6W=*__K3{5|IZkYf|&s{zxe%0j59GyA=>=YSh-yB#t&XNFMmPP1wZXb`r&h1*ZyY8 z=1Y&i@#RT{-yi$O;+Z#jyMO)29b2{^a2M<^y6Y>CfBxGW>Ep^NGnVGhJ*#x@V=w;p z&I?}{WTSs{Fy%-1gptE;^{y#u^v^%u$kqy{d9U49o`P_ zr(2q(_^<-2ciRE!y?CdAR3${nHn%RzXUF+!LSf`QxC4DU_vbCgzl9LV{HMBseAy{1 zg2-PWDJ4J!pylE3+2CFv|IGs}A3FFv`J0b!;Ir^yF;>#%gSr^}1=1aF#VL}0u~Xr$ zKXw}nWS3F^3UAC|N3<9n(K#@Th1%;UtF2Kwm1|{cFPmi#r%v2%NV$O2^I>)4Q>`p) ziKYNk`kT*jxx??Ma%^^Nb>utFb-2V1l-0@HS4j6h=ULbVY`#QDJ}YXbR*`3y|PWoXA|Nm0ht+85DI7vo=& zc$CLgh}u2Ha?XJ7TzZ|7Vl2S+jHh(As~&sp$EJ$+D)dB>Gc@6}An zD02+KJvOcR8J5LI%%|)OXr_M+?G=5+aL9I1Ligy|d^#Q5;gETyTrquXW2CQK(rdsU zp6*K}ee(!kAd#*7CVnGeo%C$%_B=j(jw5oVVeJ^AYYN<3DKdWR5tDQY`m3I-21gXJq){ z{G{&xh^-Qg|Nde3UvhNAJbPs+h zXT^V?BOm=I&X(}Q`3UzNS>g3wIC#cH0!C1l`y59z+~b@GKb((nADMqn2Ty`X!br<< z-{iMr{BR!AeK*3OUoJ-~6pL0~xGwjl*6va5gYURMntt?wHzZ$_{IS0$w%+^p z-Xq%uY4&#K+k0;edS?v!eKF|w$Dscp2E8i={f9B=KZ-$Da&ct34#wc`jzRx%RC-DV zzDYTt4G<&IN;Q>8}M(X5xd;lz-yI@)o;+PRj$O=`@em;eYDEQzc*Aq z?4OzEe0+POmyd7nlTpjfzgP9Q%u9Q}n38dwqa&GLImh|oZOroYq0H&l?MR1qvqL<8 zg7Wl(*D9}1$}>{Fgvv8q?nE!ol#GC*B83C3I6sPKMEO*lB}B)2+eAOgkmWNLU#(w@ ze@h+V?Tuks?FmAEMEOt;v)u{&>%dA^K9kYDd`;XF4)4tNI1e9Z_z4XO&Agc&&2z$G59zqRJWH z-jA02^x5QRc)f_#-fnjEVaW=o5cyGTG0UwCWy`Xe=opPz(6wS&+?{gCBbr`9KC9gP zd!HT7H@iId@9m92e_@zzm)m}u{t`}qF$VujG3b3U=)aCZ59M2U{6qRhI6b6~gwtP% z>c4OAqr>#@^7>5-dVf@UO2#dYjtqVt5a&lR#w^E7Oa-ufOve~;G5+25NjVPZXLx!2 zqssAiN6i?l2#YvBiZNz6_M@y>j?)}tu^_Ncy!J^se#FZ0P8lDZH0DP!#w^E9lr_uI z>llYcn5|-=^Aows{NVFZXph`;9sS_D0@P;7!|pd4-}w&Lc<4>w>y~_+){Mrt z)R7Cmd%!m&`8eA%l5b`J+N>~;0fI7>k9{wg zq9`unVSeE2JG?U8EKRvSg}20!d;$2~4r95Ew7c-G2d4i7JU-012HP!DodRj6v^;LBAh#>Y-Npd2lLPUFih(ZY%j*? zA0*vf+AsRyclaCuTh2lZ$ok87%`lPm#Er0PK#!~^d&JP1~qtJ6fH>1#-L3c-?4}vbD(EXslhp*`)^Pvs& zp(ylD&<8+|td}*Du-PCAe-QjHM&a)R{b&@r3;z5l3f%<#o+$Ko(C>^w&j)>P6nYux zO;PA>)Z3~k^Z@w%phxCU7wA_+q4$8kGKxQ}`=wF%`@x?dg?|WiZxp&0@yv`u_kr$; zLT9)`?~N?43h)m^q1S`n7llrLdPdM6bqt~1cWXLj3m?jtZus*f(8Kx{-LH0ypsRWA zjtGCcqv#G?k7iu#Plb)fZ8QV6zb!uB6y>fpYovRNC(`aSNAh-n=7nF~uuJ0#rG7OQ zF|yXXk$j}T(9w$b*7~s0y`V#ZM)%e;2uwcfVZI6Y?MFoH@;VbV#>Mi7d^Mnb8v2Qy zuL3l>xA>SI?rpI5=};|)pZ*)xu)8w+Q5X^b8qnz9 zG#ejSj{73~Zw3$DTYTi<-?Jjz<$`X{NAi8tANJ4V@sBrlSP#c2j5o(I93NU~;JAaB z;}MPnEjn#4^n7_#gZ3m-@4(4%yoga|wCC$MJ+cBm>9dided`hBY@^Y7?`EFdySV^6 zhZYJWoS27AM4Lwv7hqf(g>ybfCjS%nzp^~_9>-FRx!2IIu-t1{uQB%;wrR}0h8zT1 zdmK9ymU|pK6_$GqyEUErDSI_P_cab^%&-KtTfLvstue#O)tF&%AZ&%@Q&@&os<4wo z{tAs#uv+8SJTBmR8&5N^6Q@f#Aoc>J2QZSx!>ac|uyxv1YlNRFtT@pYL1$PLbnT#9 zZo4E8w{W1tu;HK$_tw}~ zBMbMZjCA-(e`+-UFpti|fZ{<@KTEW0oFXQP9?f402i!Qq^pb8SC`|rbjY;T{7)37#w-^fG2*~S)=9+K3prJ) zc${-^#4I;nz^%j`Hr#8&vJyq?Z>HN^Rxa(=gq*%A1D{vAM&@`_&XK9ll)ya z{vOTG37lRVf4}0F{twvrPsRVa2nL{4K6H){}mXxt(}WWAd}oS@Gc{NTi=+vC7nr=}#v3v*b4nDT0$E z%-fl;a-~12T>LiNY{P9Dv+wAXI4LAE1Iles(J6Ix99&M!Er~vxKSMU`Mi-3lF=T!4 zYD|6~G2+H%@7I`VuhDofaI?a$X~6OuP<-dWcI0J8(c&6Kw>}##)tLTsf!*S%x8Y`u zSL1bn*#5l)%8Oz3Dms?sG4Y`B<-lbejew^dR+qxEfmvn2e0H%Az;iCFe2td^H*0(l zxLf0V;Cf8vlYc9$PK}oXXR;6iNvstrpON0Hf&HWd(`{cQPXs@s?&d^&INinKF%_Lz zX!-AATgW9H`AnXCg_9NmmufnB0t$~Jz12n!5(jK`2Ib2*^e7%#)_sZxRIC0dU8P^~ z#53Q96i+B`TU_xnK5WD-uH;X{DpfdMwqN2v5_@5*U4$^)=7Qd(`HA~AW?gb)5CK1> z|6YZYe+*K-#@7Q6X?zQCU_5`4SXHfjlW}l!@L`Wbi%TA(o=LinvmBrxEXKKYB!4{f zs!h?USy^cbwL#sMJCvXCjDPP)e-gZ)4=A1_=9`<0(8HOxrou^#11I!BPc4L1W21K| zoIsv#V$@F)R#0JT8ewVgS9E)xOL@*k3b?h&3L8dRSPX+F;?d!{I7$!C+jzE9E>s}? zPU=);ibv^JiZ1JLo5D$Kavhq^bag45z&6{hG4p>wVHy7+Vtf1{x95Na#Ws>I`EyA} ze5kYKE1bY4TA}y_>utTpJAr#OE(P{+<^btk0IOAFh85J9GGUMy^=dV&dTEE zJUHPDnJ+OXnJvr-WMbwCCz%oFP~8Td*}=(Vi@(fc~}fK3LX!z$I7VbyEQu(;`;JSMC@jjshBvhg%eRXm@D)unL`u$!3* zw=7ei%-}FtVNi~hDY^j|R-gUaE%UHOVJXk+6;AMh9?*0La8T0=fqQIp_jC{-pBaZt z;s}{@E=XR*XBJ;0JRf<*-bJ@l7do6@{ff5KuUYV!Bmf zncfcKaM>8orrxRO@qj9Bfuw|CjPhl6_h^4u#RoNJe!3ZP@K6q9DxApp=PN8_c&WlN zZWS8KcA+uLu0vrN&n{wnJndM^^X^C<#DV!Rpy>AaC(HqTQ2C$W12(hq1DVWh^=oVb zw`xq*P8;sk_h_Bw3CM%f7pr z7<~#KJ>Hl7ML^N%)G8xFi%0emt;!#zlPLaBnYM6_3;7JX)kkzHo{&HGaBbM?JGzwr zvhV1YZdHHLW5fM6Jft!E4tEZI?6Oz)9bQRS{*>CV--eqtW*uuI)-u0K<7AM!HQo!{ zqcQ7k*=)tnw$QAwl=E#i+-}1iHr%N(%dSgf6BvgKFb-0-n;MhHuW>1G7jZzUY*raL zS!aec4`sMH7eDZaGO9x3PT+QpS(khi65zQ4RtThavz~M*?7S4X+eUY@)3BE#;>I{+k`C;GT29lZxNo zUZhUmp?IWD-lK3z1>E*&I>XInK|v>H9_A}73%*TZId*6#w)X|dE4uAa^ibUF<#;L> z>6J2kr2kUi?on}&`u3p0E@qi~A%66ju~cCxt1C2}ajQ`{fwH<@W0rN7!ZQ9rVtYKb zeC`=Zm;6K8pXG3dud^A41lH|RjoB7DHD-GmP&m;9b}z;c>IvQE62mQJaJSZ*8k+OSXK z(cr1jcr0+e#3Oa=R-4;S8xGoVpT?AvgTzu!juP&36z2SVrp9~40>i8EH1R3XrEw;% z#p_cTZ5eaC8czTove7eHP_n&`5~jwh#r48Vj54BZX;$=jFG{Rc($ zx#!^rZp&e{Da>j(+~2Xy4rm@a%Vgn$pY^jsP?WN*9}RQ^Nuy2X&fjz!`s;aVocML!-d zd>VvyH9yO%UGac1ly9tK9f}9~?aiWF@kGc~#7FT!uD&c>J~)DG z;W}E4#%YLiJ@EShtp{F%s~F2!$eQ;@5hMUUcvTy={$pyo4bvT>U18`;@uGtmb-;wxsc-_ICFf=QdlWqs2YWe=kjW0wJCa}aO?{*zPcFpa zSc8fuRDVz(#tKvT3c(ZZe~3rNvqJHN;sZa~2AfHTKa;RH-Jy6WO+--9F*o8C{R%@? zj~0WP&N9NO7j%ockKx1|@JsQse#yK3ajHKKqmU0`HBPtBJjk$Wo6GwJEH;Y6KV?wJ; z(MB91sN6zsj}|@3ZM=;K9Py$LbS1arM8D!0_Q%p`2Nd0~xt03uprk7qE(L>@=b21| z#|?a!cIV|&d8#2tpow_FNRe{ zY_Icn3?Aw;?U6iEh9f@}J*;l9Qg$odW39899V#QPTN#i>ZJjVnGdbR zCzS2TE6tw?)*i(l4`{VbsWbO09;q|C*5D=Pu~|G2XUajCl{>j^l*$G1^LFz3-70-Zl6y&{E;$8@yPxnpy+Zg zy+dKC+jnU?(->4(&ZYNgoCf-k!ZIzcbu!#g`_j6-dn8@*`$&gup9rf|@z~2Nf%#t( zNk_Tt1ieSmWj~Tn;Q>1Pk$}c?fV(wjc?}S2{Xh2-iKYHuPaK~AvN~AneRyltAK4z8 zm0PL*2b5cTT|z$sT@-Xn|8G}3^k!J*SlH@QI<%i|yy%qtdTrf?do^ZzAF$y;8y>P@ zaVZ$FCQE*o4ZCeP(}qnO_S$f+#-rg+zQ%0JWj3A~V$>^WW1?PThC8V7Sl}Ur6PQN# zdi;Q&d1Y!$93y9>$?fWA;JqBl+c?jiBO@GP6%( zillyxSwC|t@Pqctey2=f8UHro@Hj|W(XQx;cx%<46fba(a_go)g9^*}*xbuNXmO=6 zp7{z(x?f}VWi`YBDJF;gd<>*M&9eZwosA}ZJ~rhFka`uJSu*UFVdZ`bKajV4Q9*3? zKQ@;Ah+n&1VydW6Ob?ZS-D+Wghk^oHP+U{TiPSEUtvX*n$506i&$nF4LHDCZKs3)}X?& z+=mo4q_F#RsJ**@t#<7OhW~QAKqj%ZN5Y1E8q55*VZRO6*l@iKH`{Q)hFfj8&4$}; zxI<&Mmrji{frB=lK4P@f0IYtE8BhNP{D98(Sfj9PvjI(KUbWeH+HE{tHlCoS)1Mw2 zy`MO|P04mWpm`Vv;fFySSchH2;ry~)=aP>6Cx5BNY}aKPPXO-FcqwpDVOhR7%yxvI z)B#+iqpo^kcdo^ZT?jyFhFU$wN0#fNlNgsvZ;daV)?cF5l z_Wm)Y0VKbo%Pi4zo+-?eKGL!7BVSZWw-miryOZtLMLN>Lc42Bf3D~EwbnDl2rmKe7 z9%nn&?YCa>%l6x<{bBp+Qg{s8Z&1_eXJ$2iT3oXInhMKy-K?-|zX641`)$>j?YC27 z`ahug*?xyKW;Z8+D4^KIB?!=)OtEthG`wp?T52@s>bTnDRFW5&}} zqv&jdZiQuA_G&uIDBs58v+-2ecxp7A{?yy(t;FGNQ?}(c&EvxBPK~Dlca7wiZMjeJ z$hJJFG28Nx#;n7owfNC}G;VW~>1F&oiNoU{`{*u3PsH2dwl)X2U%8d-+RaLYx=nw| z6qd`_6*hW6V_K~mKL$LcG23tVHvB~N%M_`DitYj&jsx?dY&(7sE?+bg+uK@fEZcQJ zyJcH$x8ZJuWxMXvbf&AHIF_HfT@NUJ*{*T67vm}P^Hres&e%Y_E?3e2`rq!W&7?!(E^2>IesjzI8&9u|r(e_Q&w!1NX=moG6Tem+mTlZcI^x4P zm>RQgdq?uiHeRN9WE-#1cs2OzHD-Su)OaayzrwQIO?HOiagc4?OFHWC99R_!%XZzW z=}dc%!s(1#uZ=!LY;PCvhfNxX!$;C(-(9chBl_;LCdr>br&b?LuUi$J*)vRM9K
AM;~y6-MkSoYl=3d=U$sjzJ0T^h5E_i9Z4-Jg;E$Tn_jOmS1Du$=!1DlE&o zM`78qt6}71@G26|RJz{G6{J2fmCKPyhF0|MK9Q2RmQ*?ZZc(9DMrG7an@* zyFY%S8HLvmGfi~=<*|Pu&!N|X{k^~V@h^yp9(njDeJ{Us@L9S9Bc6ROeniOlzvJu% zqRmfoY4fw(`|-{rRyq!fI8n86o-jqRBOV9z9tSFQ{8hfcAGbK%4!$86Qt4)z$ags4 z@j4HSbU6&6+hBL@jLgl;z#aS@uR7W~8ibya_!@vnaFmW)vA|xIr0VWZ~1;b^nWSCJfyecFWCJiPX#toAJ zGa6{ic4|5L8xiII!%z;?~vlM0-j1Pu> zt$bui^Hm%v;KvmS<3{vwzw zVLk;z{;jY-4YL8J2Bs2bBg`h4Dwt}R%`jVFE{Caw*#=VwvmIt94E?Ex-3W6POoOJ8 ze!367^eyylWDUU6FR*GX%oUr>f=x}eS6A!%w71Psf8vha>ZUoXD|b|zOCmYsyGCzq zwt8P)Qw{zBW7S4siYi-7!|Lw=m z9eU@bho64RTv^-Lv_j^~OAjk{*^U+ecC>osZ=o$6>zb}XSF^<2yhEbmhPwLVy3g#S zPsn7`^u+L<{Sb4U-$OX-TlIe_m|4|qXZ@Ag5F*!Ir&z_*CQ%W zR+mD~8_272o1C03>d}8p5e?8ocpbqX@t%B+n0zMuV%la&J%o9Gs{HKfPlum9@9FTf zC$#wEPZED4BL2=(;J3#=?iBd#@lQAfek=aWUjzG}SZY>!)Zdrl??0gb<=57f1LugQ z%8lErPbjq53bW@FRd3%836_J}Hs{jH?YpXFKi(nz;fL!=lS1~P{~lsCBEEhH>xGH_ zb`)xvAqsp=$YI(4Yj>80sNChpMRVtXyJqcyGNq33mbQE~wo(MO8x;N5FWHzL@UzYIm)0x6hgHB)=)VjzV9n%oF}C)35z? zi=X}1LqF?%{KfyI?*GfT9(!G;N4wjM{HroT@>XeB;rUwNyIJ>7l)H*QPEZb88f_&1 zEt;SDSwBKzeEMMbBW^lAzv(_|k5Bh$#pm|ZjL)66_>}4R@N@;_vkaHZPiFjYhxy)6NIqROLvzTh>?7U;6W- z?}g~zVfxFjJbW}n_i4HldhC&RL;hDt`WX1ba(Vf{)4x#R)=PQ{^k`XL2cA888Bofn{iO?RJ%>p{;@w$be`JKk6NJkpS|zUuN1u(bc{OXuSg`$#IJhP zc(4@m-wDrMgC_e8u2D3`N``A^JwHYCK^`W8Sd zgjg;-;yxK;75;rlheO=;*bTBjPR5uDh=npM@CwpTV(LuYR)s@t`*iJ*E*b;HPH$aE}@G1`+uYnxx5I3_rm=S8jybSo@7`#B zrluNk-idC0$t7iFC2PGN)&u!c4p>lho@}!c1CC8pFY6lYY@v}td3AFWtDEL6zox!= ziKpBX5pl*lZ)ChzET_h*a&1X&wrQ4^maMjCI^9)`bcga}lGl~5RaMDTw6>(6yu>Uo zD8vYa=@=QoIU|!7k+~3E49^!eJXwXJ*I$pbxmeTGe#VZ z-gT;E^33JBNY-rJilS;X*UQ3C14WPQQ69zR7YD_e!ebVo2$-$rik+s{v(A&_xx|y5 zZ9)#%`yfgo0ZBnwlrGG$3^8p!QXY?VX~{$Cho#b=N2P4D^o1()w>>HJ|Dcpx*1V1i z4-%V?426M8lQ_%PlF;jfajKX&v((@7D} zyz!HtSR)?QFUfJTp5J3g>}#UObeeb!z56uGS#e%;IsE3sIZ?`fEB*F)(b#^mB$@A4 z`lz=@4^?qygHwgcbe3U#h3-8%cN|e&E0?T09`OUjF~lFeH0=DrVSZKX=$8IGj(&=M zaSW&C@lfmV_ooD^b+xY2B`Zsc%1u=1wQE+Hn|E&5j+zdcP>rsmsvhI*>V~Fkyq;C- zHWXJkZfdBlZ>p`^34!lfS5#WEs(`3!V;wEocs)5XmmZh3KSh|J7p+-&$*R>JSv!J~ zZi;MkeQC+s5-GmWl|*`*EZL$5b;!Zh1`PQCj#Vc8umOma#2As$r)q3szv3z)<8U6La z?nj!=jOeF^gYaa@^#f|-bmxZ6{0Y@WN=r&%`s2h5xf!N7LJt`3$yEMv9wWNE@(9kp zE4ga|PZLKWHL1~-T@=!m8BQW*wMU$A0z$&wX2ch(gb4%d~U(t@??O3Ih)YTBG1BCc7v5~_|QZrE76 z6N(4IrT;at{Ab^4J<&B76WZH~)iD&O4aEiJ1>vf*46i`MNRJL{Q|0#UCKe&9o2xhN zYO3}s^)_5FWV~mez@L)U#ZaLllq;QHFWg1XP~>NExNb*%z!$6jF%Wy5pJitG!v7u~ zLUG=PBYn;RuuZWw-y0_7*+X*N8q&?|nEc8IuUx!fedKAIv}<68>ZQ`dI4@TQI_En| zVefP1CL;N0VdM?@B-g?4rXRXr5=md+(y+885?U}!7Ja7 z((?qNc?F-O^Qu+OM}+1TDkPor4V;Gv%`31!c*og_Up+4Y#PoG*yI0%nuljK=CfsAa zy!-8^e@Z#Tb;c)U+hz{3twL!=8PT^;{>GAL%-4^@{6ly;45s0H4+08K6a%veEodax?+%f7*HYz{&lfHj9gRkFwT9 z`p2?Y{w0dylA@IbYfHk~r(I4fK8&9r4$F(yT(Y{H;JlOYp8HO$ z?qwHkkeaE|^Ct?(eX{`KPwL*9)zs4g%yq?wS*Gmhd7$EXmK9Hq=dFz6c%H-gD5Oiuy3)yGEw#R4Y}% z%9R^r{jlm)sIpkq%2ra*>q>b1pb6rMR#_tRINaS->5gvsgepzgWQUB4nx$7`+&Q+` zabz1U43#f>4p(_^vJ#Cfbrqw?ewr;s^&Qo$j!OSOOX-lvejRI1b2%|0>>aWqag=s!TI=+>`kvqbv1~0czTL68XhAYS7P)oQ&#N$yjPO4t<QXVONW#qWERQh}R<5r&Hs`7b^l`fq)4EsDI`*lh< z#XmiapL1rHV3K{ss#PV$D>&V*BycnzLiGnh=|Nm%Iz!<=ws6E2MKUXY3^6zC-AJEQ zxuIuQ56TTGGb8y}CM@46La`xgr<^7=g0R&Oohpp?Y-2sEt|&feElgL;c$_F*(R^jO zaBLHrf40Ve)_BzJ>VC*!YmGVJG`-lIs{cF2k zhG*65(73k(bdGz=U}K+X66FUamlZdTpgArK;7zn~FHfvj^zd;nPpnt;@Nq9suO~fn z+}khdvB$kb^8LthuREFkjU4xSC4J<$*9ZDLPM%r+jD8NG@|+7jtoYgzq7DlWp#zE^0@0%bKp@cOl$=Sc}?}Txt|Mo}=9; z>)GT8jTcba5j%>TQ2Mf@JDo(;iEX z`n+hRX62up8HM-iiC$0CqIGm%=ufyjjyAsOP9tBm_26m33Y&I}@J*(Np`1uVvSySx z-r-FMD&NEPl34z$mBdpEf&I}yYA8MS@eju@ltU`EAAB4XKsd3-LDqLWjQ7dH3XOvP z5$n?3DXKh9XZ%Br_iw*$hjI1#73HPFV;9dUthy;(JbYw?b_SQ$c$+t#sQL#zGt7Uh zCZFEONJNZ_YT!TXp(8qP;~MN8}IF!^aWamlJIq!FC*N91)Q8 zahT6}@J+Q_SFLNcOM2|_1#fTSzO=~wx|B!J#uxpPK5~391UhyfLu$X{^vYi!e$^8i zU;IzruS?zcAH7dEKCJw$^*NP+v>Wie@x$py}y?})8EtE-|NIJr(yYgf+5g|WXSM7*#2JU$8>+M z^L_5`#aA?u`8`~fVhoKw(EeU0_JKr{Z>R=GufI|D_p)9^`cu4iO_^S~#E`J0V#T`h zb#hBh*q-X}eJM(xoEWiR7tXnlO?wd<_eI~k%X%K!4@MiWxeW3}8?T|?=OcBKQyVXF zJk~A4rA);YzuPR`tN28Yw_=Zvtgp3BZ8R1dAu*Sj{^f|Tnm^@f-qiX{{5$bz zORXcm-~GF72#4kT(Hkdy@O_D_2VFRtM%CjF?w=h0z(4w10sB<;Ip%_o?!1y;?)!f8 z(O+_}(SzMDACSeaWY}@*Zeas_dihspfj?s9{bu5)Aog*Ho=}3d)6# z%YMqC^I2}EGAhT}!$bL_b|3H`H zKiK=66>^LdZM@fqH_^s>gTwUj@t#Z0+i`zo__~p)>5=P3`I7F&my?gYbm+B5UV8A& z@b5s&G|;ar-dGaf9#PM8fu2s)44zsou4$nEf zzqK=t`*Ptg{rAE?mGPngAKeYjRsG63@kH;z=lBgu@4yT9QCCAZRJF0bvZ1M#AFG-h zuQ6*X8*99^RoP}!6#B-97meop^H_=SDE$=sG-G`Gz`VO`_^U(KyRkU8ab(cSpA)T= z(?oXwTg>~16{IOO>V}}$u zw{qe%reh>%3!*VJXB9h^tcT1KKFk+vr9g^4{@+99&t^J4`1pM=$Epvfw~opiW!1Xz z$-akN`T@u9tVPdY=R528dBbCNmggtq_Teue`6VrPn}#h)u)p+uMAmIvXR7uWfUP78 z>sx5QXAS5axBFr5bGotHhw_lTp*3Lc_pHa8ew=#e5uMFUa_qutVQFo;VHRGhE6C=1+}>`AxT&M~~U#8dztuPARbXIg1_r z+e)j9N5(IN*^%85Pk*{8d=@&5lQMqq+N~G4I8jFw_#J=_FX%6S|=i@zc$zpMmkw+ zRL?|>_aII=$d;Q-<)UAhFHF^mzNdT%`D}`pkY8$Fsad-@d}C=7kBE&-IbAW`!+V4< zyCM(P;@6aw+ncHz)R|7^aOha=!*L@@b2@P@Q-1X6`c2N*`w>0j70IXM4A0-;`E$|E z-wA!^^@=0>j2-SDR^vtM4O`UC4fb!!?BA2+Ph)=dA-@dR%w2wuuVSqFmlKUCVtrRd z|32*Rs`{jSY@KSw_rv_IN|g`ghZp|SHiyHBwwul>Po{HtAF_$leB>bwX6=q0)m61P zO;*>U5xd?j_v(Ac(0Lu~Kdf^RevNW4(ev>4CHdPYe-#hE+pzj{)eq_KY;j}|>U>0q z?Ac7b8QC+Q=<6AV912b4iz`dnNH+SRr^L_{rEd(v-skK?FU@wuG77n5|DErSu5XkL z)5GKoC%O|i5M=FiULP^8dZ{jg@R2YDL3RKLK(kbtN|NHAHPC+##yf36aVW-$}q>jRR#eDJOTmjk@u&Jk%!REY3DQxUtNADh8 zPvJFL(dI=mhw0&ZN-pTsQ%be%*LJhE+qB)O?Vz^%v^}V8*BIrG2|Jpek}v5a^^`Ku zKaTSvLHRvBb;MKCQ`#hdY(1qO??1kJ%HMuoq-?w;*H1hz!qe@ob4Qe36MK$hn)nX~ z&ndKKz((p*vE7EZVUMupM>@wbp2PZzJ}*BSx0ZjB|L?7@{7;=9$-~0XhciEdS%V#Q zRkfS1F)5)>ZH7egosQm-_BWp&$%K6UIL(jLpg&RZ{oBlsxZpqgRrZrAoRjGt|GVZ# z1~3o7{NcO=^^QK+)H`}%?{n6mHnG2E-i6PP^vM2wK%Xk`H?>Cl2vm3qpf%3%6Oi--ht_Dr0egkcl>XiCpnp366#~ZHpPZ5-PmVq z!e>dKtE@U*U4?S|^!1hW82ZYGH&0TN%y@l#=1ID7?vsk|-)5eq0{*idfVp+Z(G>zEsrU!woyQbZ^|`vOq(% zT$vFG#Ve}Bi{%ZwQVUD`&GmJS)ka!IZn>!5QNJDQbH(oJhT5z5jV{{NX!5S2Yi}wp zt`$4X^2^FfHWZ7(dEUI-+#EA7FWW3=G}noP?wwmwlW$DNEuAi0(>Wny)w*>TC$Id5 z`?7ZTy3&#oQLc^)E*HE*XI**0T1RyW&_I_1Z|IP55J@b+pqKf^Q9Qj>9r`3iB7xqR2oO-+KEDz{WO6&s?4r!0A^ zHa^)DFcN(^W>p~J=gzL|)MQhLg5|ZXo-bbzU-k1*t)m+2wyjQiVozdiOTrQ}w$$bIwUjFcRaYEJ^&#U~P_>yLZmv z#KX8{ci9a|H=c7-W=V2SshF5$4&a003&-cJ9Dg`e$o+=N_ASyyNz#rhZ}6vT0MM zRtx;b@5!F_+bnsL+_9|VzscHj&7rJAS;n@TmTw-lKkHb0)~jNF)?Loqv#!~n6{tJD zKkK!x?$6qv)s|I_*M}$WuEy&r@n6as*lyNNztuc`(Wi1g?>qLYtGek`5#RaS2jc!! zJn_ACyEfvsBcX3@-4H0Msoc4x+S{>rVrp__Vn^KJc+W$B64r&v6A!&}!9$ga)8E~& zVrKx`TPwHMUi(_yp0(>Y)yk_we_wvqVdI9CD~=f*I~(dgbK9i2ox66NYosRcuPL~# zW{J7T^!)3V9|`L!Lw4oS?d2wkv6JTmaW1;SSuLzP4R?aUTCV^Sbzd6)(ikIdt^)iHt|a$KHff? zn*2m!UfUd85_{n5n|Iufn~n8Nv2I=!n~{r)Vuf`P?aHUj0%OmNmmWUHS!nc6tSXY* zM|QWZ@qMl*^>{r0{Uv_h)pPzD|JzaX-x|e#X34+B&wnf4)Ajti^q&dq_Sb;E{&hwA z{HNS)2%~V?pN)BQzV~0o7mWE|Haw1ps@o1!nch3RxX<-sSJ9)TxWV;T-%3rMwQR`( zbAH1F^A87%j-UU<$6H%dlb>I%%QEn(5Y-uV43?fxls@pbXF@$<4b#UJ<0 zjgNo*hGp@;E_opN-sENR|8K*QYv#t!jc@As;R|zroesQV)qx$P%#E*G`k5&|`&#-? zdcn^(#^+_fl|Ih7diR7~6BeeAOB%N<{?EU?JbhfkxCP7NUE|39?p528$IYLs|C$s3 z*F`hqB{%+!b*WZzM zW8$@e{)&e0%?kKdi5)oIt#DUUlc?L7_umhT4Mp2)H*ND~3y2eWMJ{9~?|xc$u~?}u z2orV9c`^&o8_Y7J%Ry0&3rr>ke}nwPW-_cEuAZ#b|p?e*e~^Jcy_KWS0Uj%xyK?e+O-i&tHfdf%c2 zt&7BWd7bDJnTyZ4b?4gRb)I7@&Pv@^Hs5uoZwET51|d7CIits zugG13KIrYyXW<~k@(I3#2hI#0ow#E2ml{Ol;}>8KGqwMM#m6r={2JBF_cmX1sPwhG z%cm_%P5Q##yz~dAeX;CSUuD|{$ec_FomcOiJrj3ve*MYrmGkcN{x)gOy5N^$x^?zl6zIIpcT6IjeG021>*SaK+EVe zwK_?XH(;vnrJEuJ5`wnBtnzJ@|{@gzG*7yhG zJ!g#nis*8cCmI`t9u&pD{lz6W2zj#k<7RgzPUFgIn>n-OGsVuy3Bl5=qu`vJu<}36 zjD-0P?*s9Bj6-7wlbly=e?DIBiVf)d9Cs(h{cGH;acc96uaGnJ=wRL?t|v0jLmfowT?5YAKhE|h@-q?Gj2^x^Bfy> zbkrO-&&E$M18c^Nm6sw8@*0J?nQ_ju$F4Op-cHA{D1VrN(<1%y&chdu)@^V4+~G-c z4yC;{J}xnRRFh#Qn3aijbL6=t%jy%Ko8J;Q!Ta?2SGiZ$1=U@I9saJp85d8)t!=NL zg*ynZ5(e%dy#A~srOVFpB(B|9nJI9nCGHvws>=q`ld4i4InVXuF}ZOw=3hQ;ins2} zo^d%_o3ro@EBKK;s2+&=N&JLuBsnizHHT|^HM7l-k$W_n&;N! zn7^4nY1?^;z0SAdbB@Q){aoGD&mE7y>e;-XntM_+Qn#KJxOl7Hla@TqJ2 z7JtcfS3xh%`t}lYOFQ(%Uh(Q=Z`R`nL{^TuvZ%7L`ZEvgPXEH-wF_TNPpWB3GSBNB z-U!8Yf=0Juu}9@qusQ$QL(n)C+Xs zS_Wa=s29*z>WNW!*;E~P6gTP#>q!VsqKP z6^X~+`j^ii|IFSq-z~cGE-@n^voJ0oUK3N!I=uTvULC%;`bM)QVfBUEzL=85Q*Zq8 z`nKxbM^en6Oir!-dVYLrLv!%6jlSH`c{@LAn*Z*`r(=V>lWl+Ajo*z=pFaLo-;M0T zdW@FVhf+4|zWdpf`}R#4HFJ%5QM%{d7t@yCZyp`nyMBe^Zs*e0$j$Nb>9vjZ+r<3+E6#3Nv7qYwsj2>RAsHP_;u|^UC8%T0YHv$YHY8+O;3CLX zh{*3P33}vL7e~&RZk*kJJ-)gKWc!jK*XvjB+F^E--cs^HV$O!1#QVHIOg%pF)rs?e zKhgY>Sv7h|ya7e7$eg=#fk>H~FgIYjA$tFsSCw!$?dcUq<1fv*HNAe!r0m>ztIl4Q z{wnTyIq%Gp@g8%oW2ytkUkK}pFjsM*S)I>oW`uP;Sjz>5x)-d_804*B$Kr3hwq(?l zNpV-rTcBlVF0bA7d-g(#`qX(9YnK&?Iz4VknNu#VJDkMR2nTuDSJ{~4xzDAT*Bie} z&|5Bqb&=P(-XjUwyPdn8S365q*YkcZk#;C?|Jdzs9!@sRxVZ`Db8}yETr=@Ze?pe8 zHElW=V)R!g zYUi4@S9T=U`r@YL1xnVJeHEkg0teJDBd)B$S9>*gsP+rf1--6A@Ghd1>g_)Bp$Dlu z2sLVL$T@DF<@l_}sJ!F3)FY|>9fmIx3c~0$MKhor1l5(?UCFl@#&^7?DV2lNcH`Q+ zG796U9;6*@HyZB9_!bp|iAUaTa~^f}-pp|TMzqiYjvmRxt=dh-?d2F7w?hFaNGLa& zuIY`R@|uHpT;1!~xvQuv`-p>`|1KkEqPg`RG3^4Mdu83u-)|{48k@wnCh^8ieur-z zW+rxSxjW_QfWF7d?|9b~Z(o^PFIpxPO!$?%W6U(udw9(HnljV$e%rhMqWu?DTy)nN zWAT~0#~E2?uR)jJ@EdbO;@n@>-~5xc*;A&BpYYcubuTZ&h4Wo*Q*>PZ#sp_1I(E;>QNZZ9N{GvvVB)oB^YB+>~+4+{XG%&bY#a2YYj!t7@OA@?Ma* z+ht}oxHfKlNpLjbH_WICwIj?eDtb?iMNc}ozUfwS2CTy zw&Xd-*dP;YR9l2~P`E0lzF zhf*$Y7{v@<>W0747%nf7|+ z-YX#6y@5*|THKxjLtI}RR5x0!o}HZZc{A}^U-p^}DWiPzgBO|o@-C{E zzmuH$%e#}FfzmVmE?(tx{PEkLxGQnr4R;;*N}BoF?W$s@~+t2c@+m6vU~f@ z&OqGjaY12@YV;?*p739$nXvV+5g+eJe`!)nhS74SzG*yie!yERtjoro+o9g(nDeve zbX;1weOL9}X{IrDVXdS%MY_0cD(SVYOfrfwXmg=!h z#T`a@hvCht3(9-WvNnuKntgov80Qn$=Q~q_XV;{93O70rwTSP=72b7h%Fm`4S9m8c z`bGSrMfZ3QCuC<;jlFOBp%q2dV_tVYE%q3}vo6`6|K{?wi*Ly9pOfW(>gc8$r+hV- zbZqkB$@#y{Jb!7=_J4oF)qnry*9!8s7f*Bk#|B}2AMNyd0*}rx*H+gzZ?D{RYj)kD z@4D)@SO_8Gf_y&cf{gzQj;eO<9EV8`J4Cn*RHSL*;bu3m#s# zKdkE-!npVLFMEuFjC6Ordt+9{N_1WCq&4C$L+ccw#31^vugs8L*MdjiW7l;iyRLi; zZQG5F|90`enVwt@YT0#NTV?p2oQy@+<>&B~U00>)_i*egyRLK5cX?iQy!ef`UA2w5 z9J%_PhtYfOJ@l*TP*b+%jJ>!y$80P!o*&n8@gwuH;yQK(jP*4bD4P!NbN}?0hefqk zsztR{stplDK~t#~XvUmwhuq|K=Jw&OPYrL~ub8FKj$Butzf?45`_Y@3-YM6nog-&& zxdP^g1!@eN*aXZ!`w+cA1Y6Bp3U+^ zsw-oK6&ZPZ+*?N_#yfIW?e z)gi0m(Ac7yz}54|WMHQF4+mcBshnjdk4;=&;s{QP3ufJD*RVvX({bH((8Sf5r|7OO zGcjZ~U-6uG%gn3C@0sMiW$cmKxT33^E9B7B^i^{De$)TG(1hx&KM}RQRC~P1aBvo6 z&73b~#wDgXmvK~DQyFMb_X|!+PZS44*%K4xj&lm71T>YKSU&>^gA+tLfJbtFFionQ^GJh(VGxT&E!u&m*WNg=hcLroN$L9yu7^4Y@Iq?$N?(Gr?;%WGAC=Xu^fF?+;U-EWe}8C#hERc4~$tlr|zs{GxrpC zh(E0Jcq=^SdHt#PUs>y~sQp60*Eg+DJxSn8$1j+5;O?WX>_L1^$KHgS&)Z)7WQO_2 zjE$3zeal-52{qsO@IR#=p7{9J?n-Mp-e^)H<=i#%cazgn(|i}AYNY!_N7|n%CvE-R z^v0kk_?^I%8Q=2D(c5fZvOEb66W35eqCYeVDbx|&ly3(_^eBx zKp#-|Q+pcL1<^^MkJvEt_$@C#pS#QDo9XdS%L>di7awnPj!QKYFD@DoZsU(PKIr=I zUWa+P>+spjT+6=tXYVrC@mD8(XWXj^6DB_`8k4e(F~-~tVvO;PQMX=a-jG|{II(_P z$D+EabyLwly!GP5`3b#ejW4=nbkSkwRlfJiF1pn>nEKqFi^sL3FA$%ryL9EoHTk1` ziN)V`PtSYg%TuYu^_aeV(*k5BvOOEM-N8`qz*uXC?B-gVEqF-s@9Q;(f- z>Lf2dJkn8{407Ea7E2SaF!SmFj!8>u~GvH`lb)Idea=$yxH=>SFh8={J~h z&y9I}j5}`knw!O#Taz;q-j4723f6%VeD8`2e}chEV|7psR_1*>`0e9+ME^Pajp~kv zR>ZsZ-4;yP^0W9-&#O~7Ncp1Ij646%-U7&Yh;8E znQ5AG7W2(tzV%qz>vtMoNozAWgDD3oZrdQG}#@gx~mClB3gHCzM z_?XI8r{mfxp8?q~)VSr{hY}$Cv({nU^3)^uzCFdoaZ6VsWdD()H(!;)SJB)GE}R;}-vq8f3@{G(_8!j<)mIb-8ZJ)fOrUNrUse|m|-H~I06PJ@%1 zLG@*fSmbp0Zn!Jn!?o zzwa%muDZ3IT27r)b!wXuBsrMEC~BhH60KHiOkr^AmCez@gF))iBqJC_k%i_!Okosj zYOUqP%i~+wzD2ci^r|Ip*TBlw%hTq!&Yn#(p5tk2by>w%vLs>@@(m?nHEvn1c|*cX z0U|YJrVtGYRU0vid23n~MsaLVt91w_KkPT_#)40@%KSapk77Tb6mpyx#V0x76O0Qn z!6%MRcglN*oEQ+lV|e<6!I^=758R%Rre6U1UL6f?!Ghkt(v~M%>2|I$VQmr4MJMTk z<>G-;n1PqTJ#6^#0=>k!C55Cq54;e$~7FF@?9R z-Tvy6H(%N|c3n~2o|i}vmGJ5NKfdPQ>KAN|O*fDID8}qr_)=b(!{5PL%`JnLMnweG zGTAe-LCx7 zk)6+kg_umk>hJV_DnJ)VtfR`Deq-#lGFZpSac$|Gb?lRO#m}5SeLC@tzsd3z!+}Qo zkdzGu@s|1}>*fw}Ns*(7Z(L){_Ba)eA?E*kV$j5(Sot@8bLM~VKgZ8&o3t|ETL?lA z7!DZHn^KydJ7CzVpByef=J!^;oE+2<^=EUbd8(8kY!ynFR}kgaB;}%A7r$xukhm-; z%c0z_+Zs2a4l}QT6Ph-9pE#Li_l_M=tlOr~XFuwXU3$`zC0-vDwr#KYz|gjgVKeMpKl$`cq6tgOn;6c$)XxCYspoVK#AEQMri4^5xF zF;gfkc0C|FV=qf<$(V4 zfv4o)6Nc*dY-6`^_Jmu_xkBS6?3XkZLrFrd-wmu43+O=R$kN-PBZ*00DtJUy^{)^a#C}K~6 zG4b+CcRI3(J!N-JL9oL_6Q3C|0b$R&v*%{#dmPK&bhmoBsBq8i#V%78~@ON4+f7SYeXJUR}x}Xx75G#0|5SQPN;8 zupRp5Ytx_mR@f*FtXspLi5exu(=^^NzH+6xf*ptwVu^bR`oT1D!IGPY2LIq-9`ol2gLg~zax8(vI%z%gZ{t~JO*yHzk}8G=bm>(~vUn6u#C z5=Ac2tSru&s$X4^E;V{w4Qr?9Hs!ZM^2Jo9b?Hf(LhM`U(61}nUl`Y_Te?x)7cq11 z7Io3>waDK@?VB5Y_;$ZNj)`%DljA&9duIlE@S>Ov90?3b<{ZgUp0(tUj_ia(STr2> z)nzloMoyVVtjIH(&tN?2k^k1*2Aaaq4CeLu&ts{LSW!uEbfwv^HQk}}AIs-0+LGFt zu?+l(vm>mbD@S10SJnvvv7^SpevjIs{3MyPBP_Tn^Om7|AQNth=IqGDFY53#xGd2Q z@FTFJ=H@l5mbg*vn%a!anS9;?b|g6FsPmQx&W}FM=j`Z#BKdmETR1yv=8~)CC+z#4 z)T^uroM;H{iZ-z==|@ruI=R^BWzJKTlLx5jYWZsyFzb?qo#@ClVD_ z1WsfJE5h`z9Ly+tNGCJOJLSWS#*b*}WJWV%ek5je{FQR>yl=udL} zGo~(vRb`GnLkz1e?qJT=`V7A{hV_whOOnE}MwA%j;{&!BwxD~_TxaghR}4C74vqe3 zaO;fbM8Pjfm4=D(zb;iLIo_BZ16u|TG`7V=u`!Wed3@0o0|VC%a-`oGNG!~|%<`FE zNXjw4J=>n!cFb>7#EWnG#n|L;r#x)DX|=q-a($FR+ATgBnIObVI9pUNL>J#I)SklKes}2Wqjv1xw)@V!7fz-{UV6o(dmnBx zEeTGlPk%A-#j6ZEBlJllL&8ILef0Gw0Vm>i?A^XM@pRmQy$70fTXnz5Y_iGnJ(lM% z^$ECTXnIkw-xFq+)D+efwyG(tIbrpv+NwFTq-@FNJshMPboUUQa4CCu(!>px3GLg& zsNt)sGu{?ATv_v(_q{!PGIwPj#%yeM+@KZnLs$G8)3M6g)0!>O@4HMgI};^)pC2{+ z=q0j#{kyYAeq&ocOXZeBV;zyg_S0!Hu7DycO~e}_6NLh@h3dvF#`he60^))yg#sGg z6%`D73KL?OvTcZ#MMb8Jqc?#cNEQ%6U1F=UP^udwnz11za=*+nKsE)bOy-*tWD9LZ zF;11872|3R4f?$h)|NMKi5`d6H2e9J*loxjio7WDrpXsa$%a|xdFvinCt}-Yol5U? zo`)rg=v|B~<;`4c?JoWn>x2a5jV{AQL05%O;;Uh}qfuE6iv|bR4UhRph;yb)%=;oX zZi3uozN|Ik&}2`*7Hm{l=$~L3+*%vyFit+OYJROp<)mw;9B9qci7bD-7KwiIJWpAd`%D7ILR;+Lo8;`X$?<7IiT zpL^7sesoUfEx+1)oy+41R#v5+``oa1^!uW1Z{R__{X6mMgzv<}e~ArZ(a@-nrGK0y zmd_HeDynD@zYb+wNT+P9Rrq@FYvyq}hiko#?n0~E{p1v>)|I?XXdYz~SXyK@=NSg~ z<~gogIomjiT^KSG-Y7U;r>kHJ%P6XGahCBY=CsAt?#1PmOUxxfkr$<{dhk)tBYv5+ zEuO4~KW&%SjLuAxcj8R>Dy z&#hWj8!wJqd?EzcyGCB>iTiluyuVe+MJAoTX!+7C;n7K-rpbjzqn9pzE6ccznW#3K zb7;{kW3!oy8=K#_wkPuTETXPCt8Qw2h>}&g6i+}zq>I>=rAzthORAz!^Y^!2VQ~gFp0;rP8=Ivc;DRnX8YUk9CR?~xa6%L z>1{gM)TsNu>AI0l(>25VJVBZE_b@lb1zI_Eo(HURF;6U-TcyijS^0dnxN@N7+Co=C z;lb^=Hp|2LbB%k~gQkP5u#y!JlRin4#*zLb{loot2Gtkqb|yBidVlgI`s9m74U9@3 zdE3gMhIK80p+WP)1b+#T$b;))QzqSDg2LX)-0TEFGR&v&l#yRCNQyjiUw^OC%uj($60cEI;r_6PWj z$8gOB7DkBif$z1x{2>hzZxUIk(8%X%;D8Rt9B|k^+^pAOd)*QX*iYa1S z!Aq5eCr6$ru<2~9w%O2OKkc_?QiFJr_*XV&L@}$sZP?!Nt!$cj@ZI2L=|@OHnR0k? z;q|u}6Br9l+vRVoSn4OfXKcN4Ma9g7U2)YdVedpo72D=|xU|k4ePYa!Z^opUECZve zheSFCHU^!Fii$Z^{fytl*>?)*rk@f`a*d$L~nqxlo54-S^ zY2vIu-=T{SC=ulChvo7%<@TmM3C+O=y`rvd_`_4`BeL|b-8bsq;CDXUabVnvsmF_4 zW}9oIi<#{uEaCm=mS;p+Vzk3B2V>vmHZJhpL_>TBDEh!sBgT*7S0F$#!`)2$a!HS} zMMM@7f6HP6$4xZl7%mGmOKV@pd+H1#Se?b-A3Bq50m%x&iaoYp62U5}lR&TnXyYZP zSdfuql(JI33uiT01mE-L#y+2#7{5yge;66LE|gC#IMHet393az%cEZTxG^}>ePb{Y zteb*sjrl7o8b%Vqnpe4apD&HbqRdl;e z+4e^Zw;pv0vTLw5%0Aa@ruIA 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 df6kl#4@ciB{|{D-?@; getStageCodeByCode(@RequestBody String code) { + return new ResponseEntity<>(paramService.findByCode(code), HttpStatus.CREATED); + } } diff --git a/nladmin-system/src/main/java/org/nl/modules/system/wql/sys.xls b/nladmin-system/src/main/java/org/nl/modules/system/wql/sys.xls index b3aa2d521d76150a40c8c0e73e68acf71234557a..47e23f40450d6ea15f9a208ea4b51590a66ac502 100644 GIT binary patch delta 46 zcmZqZ;ce*Q-H^k==3u;czx~q9MJziQ*%|%PEpoQUHyg6G8?rG1G1GQKHsCIEw+NZKH0x{F}scg*I_5gr9 B4_E*I diff --git a/nladmin-ui/package.json b/nladmin-ui/package.json index 652c22dfc..22e8b7780 100644 --- a/nladmin-ui/package.json +++ b/nladmin-ui/package.json @@ -33,6 +33,8 @@ "url": "https://github.com/elunez/eladmin/issues" }, "dependencies": { + "@logicflow/core": "^1.1.22", + "@logicflow/extension": "^1.1.22", "@riophae/vue-treeselect": "0.4.0", "af-table-column": "^1.0.3", "axios": "0.18.1", @@ -61,6 +63,7 @@ "screenfull": "4.2.0", "sortablejs": "1.8.4", "vue": "2.6.10", + "vue-color": "^2.8.1", "vue-count-to": "1.0.13", "vue-cropper": "0.4.9", "vue-easy-print": "0.0.8", diff --git a/nladmin-ui/src/api/logicflow/stage.js b/nladmin-ui/src/api/logicflow/stage.js new file mode 100644 index 000000000..7c6c95558 --- /dev/null +++ b/nladmin-ui/src/api/logicflow/stage.js @@ -0,0 +1,50 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/stage', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/stage/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/stage', + method: 'put', + data + }) +} + +export function selectStageList() { + return request({ + url: 'api/stage/selectList', + method: 'get' + }) +} + +export function addNewStage(data) { // 保存舞台数据 + return request({ + url: 'api/stage/addNewStage', + method: 'post', + data + }) +} + +export function getNewStageDataByCode(code) { + return request({ + url: 'api/stage/getNewStageDataByCode', + method: 'post', + data: code + }) +} + +export default { add, edit, del, selectStageList, addNewStage, getNewStageDataByCode } diff --git a/nladmin-ui/src/api/logicflow/stageImage.js b/nladmin-ui/src/api/logicflow/stageImage.js new file mode 100644 index 000000000..20b902def --- /dev/null +++ b/nladmin-ui/src/api/logicflow/stageImage.js @@ -0,0 +1,34 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/stageImage', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/stageImage/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/stageImage', + method: 'put', + data + }) +} + +export function selectStageIconList() { + return request({ + url: 'api/stageImage/selectList', + method: 'get' + }) +} + +export default { add, edit, del, selectStageIconList } diff --git a/nladmin-ui/src/api/system/param.js b/nladmin-ui/src/api/system/param.js index 0763489c7..07a8e5c94 100644 --- a/nladmin-ui/src/api/system/param.js +++ b/nladmin-ui/src/api/system/param.js @@ -24,4 +24,12 @@ export function edit(data) { }) } -export default { add, edit, del } +export function getStageCodeByCode(code) { + return request({ + url: 'api/param/getStageCodeByCode', + method: 'post', + data: code + }) +} + +export default { add, edit, del, getStageCodeByCode } diff --git a/nladmin-ui/src/main.js b/nladmin-ui/src/main.js index 1ffa5d8c6..d0fc1eda8 100644 --- a/nladmin-ui/src/main.js +++ b/nladmin-ui/src/main.js @@ -40,6 +40,12 @@ import 'echarts-gl' import 'jquery' +// 全局引入LogicFlow +import LogicFlow from '@logicflow/core' +import { Menu } from '@logicflow/extension' +import '@logicflow/extension/lib/style/index.css' +LogicFlow.use(Menu) + Vue.use(scroll) Vue.use(AFTableColumn) diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/Diagram.vue b/nladmin-ui/src/views/system/logicflow/editor/components/Diagram.vue new file mode 100644 index 000000000..fbd00de05 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/Diagram.vue @@ -0,0 +1,604 @@ + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/DiagramSidebar.vue b/nladmin-ui/src/views/system/logicflow/editor/components/DiagramSidebar.vue new file mode 100644 index 000000000..75eb62085 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/DiagramSidebar.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/DiagramToolbar.vue b/nladmin-ui/src/views/system/logicflow/editor/components/DiagramToolbar.vue new file mode 100644 index 000000000..42d0f9821 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/DiagramToolbar.vue @@ -0,0 +1,251 @@ + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/PropertyPanel.vue b/nladmin-ui/src/views/system/logicflow/editor/components/PropertyPanel.vue new file mode 100644 index 000000000..b59e078e4 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/PropertyPanel.vue @@ -0,0 +1,375 @@ + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Actor.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Actor.vue new file mode 100644 index 000000000..dc3818d88 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Actor.vue @@ -0,0 +1,38 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/AreaSelect.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/AreaSelect.vue new file mode 100644 index 000000000..edb8929ff --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/AreaSelect.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Blod.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Blod.vue new file mode 100644 index 000000000..3444a373b --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Blod.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Circle.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Circle.vue new file mode 100644 index 000000000..b8355a4a8 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Circle.vue @@ -0,0 +1,31 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorFill.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorFill.vue new file mode 100644 index 000000000..1c12d2a92 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorFill.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorText.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorText.vue new file mode 100644 index 000000000..8aa7da1b0 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ColorText.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cross.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cross.vue new file mode 100644 index 000000000..ba015272d --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cross.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cylinde.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cylinde.vue new file mode 100644 index 000000000..c32f508c3 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Cylinde.vue @@ -0,0 +1,27 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Diamond.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Diamond.vue new file mode 100644 index 000000000..ae6e48a3e --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Diamond.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Divide.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Divide.vue new file mode 100644 index 000000000..32bbd4fb5 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Divide.vue @@ -0,0 +1,37 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/DownArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/DownArrow.vue new file mode 100644 index 000000000..01de6a0e6 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/DownArrow.vue @@ -0,0 +1,18 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Ellipse.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Ellipse.vue new file mode 100644 index 000000000..e006feeec --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Ellipse.vue @@ -0,0 +1,21 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Font.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Font.vue new file mode 100644 index 000000000..e9a1bb211 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Font.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Heptagon.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Heptagon.vue new file mode 100644 index 000000000..1f10cb23d --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Heptagon.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Hexagon.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Hexagon.vue new file mode 100644 index 000000000..1a9c5136c --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Hexagon.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/HorizontalArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/HorizontalArrow.vue new file mode 100644 index 000000000..640f85cd0 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/HorizontalArrow.vue @@ -0,0 +1,18 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/LeftArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/LeftArrow.vue new file mode 100644 index 000000000..c62689e2a --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/LeftArrow.vue @@ -0,0 +1,18 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Line.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Line.vue new file mode 100644 index 000000000..d4b7141fa --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Line.vue @@ -0,0 +1,15 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Minus.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Minus.vue new file mode 100644 index 000000000..e8a5c19c7 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Minus.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Parallelogram.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Parallelogram.vue new file mode 100644 index 000000000..1929f7297 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Parallelogram.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Pentagon.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Pentagon.vue new file mode 100644 index 000000000..1f41d424d --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Pentagon.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Rect.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Rect.vue new file mode 100644 index 000000000..5a62bb46d --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Rect.vue @@ -0,0 +1,31 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/RectRadius.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/RectRadius.vue new file mode 100644 index 000000000..ee233aa66 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/RectRadius.vue @@ -0,0 +1,23 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/RightArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/RightArrow.vue new file mode 100644 index 000000000..509914129 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/RightArrow.vue @@ -0,0 +1,18 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Septagon.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Septagon.vue new file mode 100644 index 000000000..af7024203 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Septagon.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepBack.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepBack.vue new file mode 100644 index 000000000..254da46d0 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepBack.vue @@ -0,0 +1,16 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepFoward.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepFoward.vue new file mode 100644 index 000000000..cd96b6bfb --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/StepFoward.vue @@ -0,0 +1,16 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Table.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Table.vue new file mode 100644 index 000000000..50bdcedab --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Table.vue @@ -0,0 +1,158 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Text.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Text.vue new file mode 100644 index 000000000..c1af1cd52 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Text.vue @@ -0,0 +1,46 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Times.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Times.vue new file mode 100644 index 000000000..cbe890cc5 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Times.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Trapezoid.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Trapezoid.vue new file mode 100644 index 000000000..5d23b928e --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Trapezoid.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/Triangle.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Triangle.vue new file mode 100644 index 000000000..e40db5686 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/Triangle.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/UpArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/UpArrow.vue new file mode 100644 index 000000000..2ce28d72a --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/UpArrow.vue @@ -0,0 +1,19 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/VerticalArrow.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/VerticalArrow.vue new file mode 100644 index 000000000..360d21bc4 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/VerticalArrow.vue @@ -0,0 +1,18 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomIn.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomIn.vue new file mode 100644 index 000000000..a52571697 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomIn.vue @@ -0,0 +1,16 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomOut.vue b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomOut.vue new file mode 100644 index 000000000..c30a25f24 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/icon/ZoomOut.vue @@ -0,0 +1,16 @@ + + + diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/DownArrowNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/DownArrowNode.js new file mode 100644 index 000000000..e32d3c964 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/DownArrowNode.js @@ -0,0 +1,49 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 下箭头 + +class DownArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 50 + this.height = 80 + } +} +class DownArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowWidth = 1 / 3 * width + const upY = y - 1 / 2 * height + const downY = y + 1 / 2 * height + const downY2 = y + 1 / 5 * height + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + [x - 1 / 2 * ArrowWidth, downY2], + [x - 1 / 2 * width, downY2], + [x, downY], + [x + 1 / 2 * width, downY2], + [x + 1 / 2 * ArrowWidth, downY2], + [x + 1 / 2 * ArrowWidth, upY], + [x - 1 / 2 * ArrowWidth, upY] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'down-arrow', + view: DownArrowView, + model: DownArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/HorizontalArrowNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/HorizontalArrowNode.js new file mode 100644 index 000000000..0a8bf8098 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/HorizontalArrowNode.js @@ -0,0 +1,56 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 水平双箭头 + +class HorizontalArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 40 + } +} + +class HorizontalArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowHeight = 1 / 3 * height + const leftX = x - 1 / 2 * width + const leftX2 = x - 1 / 5 * width + const rightX = x + 1 / 2 * width + const rightX2 = x + 1 / 5 * width + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + // 右箭头 + [rightX2, y - 1 / 2 * ArrowHeight], + [rightX2, y - 1 / 2 * height], + [rightX, y], + [rightX2, y + 1 / 2 * height], + [rightX2, y + 1 / 2 * ArrowHeight], + // 左箭头 + [leftX2, y + 1 / 2 * ArrowHeight], + [leftX2, y + 1 / 2 * height], + [leftX, y], + [leftX2, y - 1 / 2 * height], + [leftX2, y - 1 / 2 * ArrowHeight] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'horizontal-arrow', + view: HorizontalArrowView, + model: HorizontalArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/LeftArrow.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/LeftArrow.js new file mode 100644 index 000000000..0405e10f7 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/LeftArrow.js @@ -0,0 +1,48 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 左箭头 +class LeftArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 50 + } +} +class LeftArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowHeight = 1 / 3 * height + const leftX = x - 1 / 2 * width + const leftX2 = x - 1 / 5 * width + const rightX = x + 1 / 2 * width + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + [leftX2, y - 1 / 2 * ArrowHeight], + [leftX2, y - 1 / 2 * height], + [leftX, y], + [leftX2, y + 1 / 2 * height], + [leftX2, y + 1 / 2 * ArrowHeight], + [rightX, y + 1 / 2 * ArrowHeight], + [rightX, y - 1 / 2 * ArrowHeight] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'left-arrow', + view: LeftArrowView, + model: LeftArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/RightArrow.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/RightArrow.js new file mode 100644 index 000000000..f963d0e3c --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/RightArrow.js @@ -0,0 +1,50 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 右箭头 + +class RightArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 50 + } +} + +class RightArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowHeight = 1 / 3 * height + const leftX = x - 1 / 2 * width + const rightX = x + 1 / 2 * width + const rightX2 = x + 1 / 5 * width + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + [rightX2, y - 1 / 2 * ArrowHeight], + [rightX2, y - 1 / 2 * height], + [rightX, y], + [rightX2, y + 1 / 2 * height], + [rightX2, y + 1 / 2 * ArrowHeight], + [leftX, y + 1 / 2 * ArrowHeight], + [leftX, y - 1 / 2 * ArrowHeight] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'right-arrow', + view: RightArrowView, + model: RightArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/UpArrowNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/UpArrowNode.js new file mode 100644 index 000000000..ae9b53864 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/UpArrowNode.js @@ -0,0 +1,49 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 上箭头 +class UpArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 50 + this.height = 80 + } +} + +class UpArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowWidth = 1 / 3 * width + const upY = y - 1 / 2 * height + const upY2 = y - 1 / 5 * height + const downY = y + 1 / 2 * height + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + [x - 1 / 2 * ArrowWidth, upY2], + [x - 1 / 2 * width, upY2], + [x, upY], + [x + 1 / 2 * width, upY2], + [x + 1 / 2 * ArrowWidth, upY2], + [x + 1 / 2 * ArrowWidth, downY], + [x - 1 / 2 * ArrowWidth, downY] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'up-arrow', + view: UpArrowView, + model: UpArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/VerticalArrowNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/VerticalArrowNode.js new file mode 100644 index 000000000..0a0fa261a --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/arrow/VerticalArrowNode.js @@ -0,0 +1,56 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 竖直箭头 + +class VerticalArrowModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 40 + this.height = 80 + } +} + +class VerticalArrowView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const ArrowWidth = 1 / 3 * width + const upY = y - 1 / 2 * height + const upY2 = y - 1 / 5 * height + const downY = y + 1 / 2 * height + const downY2 = y + 1 / 5 * height + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + // 上箭头 + [x - 1 / 2 * ArrowWidth, upY2], + [x - 1 / 2 * width, upY2], + [x, upY], + [x + 1 / 2 * width, upY2], + [x + 1 / 2 * ArrowWidth, upY2], + // 下箭头 + [x + 1 / 2 * ArrowWidth, downY2], + [x + 1 / 2 * width, downY2], + [x, downY], + [x - 1 / 2 * width, downY2], + [x - 1 / 2 * ArrowWidth, downY2] + ] + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'vertical-arrow', + view: VerticalArrowView, + model: VerticalArrowModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/BaseNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/BaseNode.js new file mode 100644 index 000000000..6c297ce81 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/BaseNode.js @@ -0,0 +1,16 @@ +import { BaseNode, BaseNodeModel } from '@logicflow/core' + +class BaseNewNode extends BaseNode { +} + +class BaseNewModel extends BaseNodeModel { + setAttributes() { + this.fill = 'red' + } +} + +export default { + type: 'BaseNode', + view: BaseNewNode, + model: BaseNewModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/CircleNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/CircleNode.js new file mode 100644 index 000000000..cc37250e3 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/CircleNode.js @@ -0,0 +1,33 @@ +import { EllipseResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 圆形 +class CircleNewModel extends EllipseResize.model { + initNodeData(data) { + super.initNodeData(data) + this.rx = 35 + this.ry = 35 + } + + setToBottom() { + this.zIndex = 0 + } + + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +export default { + type: 'pro-circle', + view: EllipseResize.view, + model: CircleNewModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/DiamondNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/DiamondNode.js new file mode 100644 index 000000000..38dc3152f --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/DiamondNode.js @@ -0,0 +1,35 @@ +import { DiamondResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 菱形 +/** + * model控制初始化的值 + */ +class DiamondModel extends DiamondResize.model { + initNodeData(data) { + super.initNodeData(data) + this.rx = 35 + this.ry = 35 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } + + setToBottom() { + this.zIndex = 0 + } +} + +export default { + type: 'pro-diamond', + view: DiamondResize.view, + model: DiamondModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/EllipseNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/EllipseNode.js new file mode 100644 index 000000000..c2976389c --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/EllipseNode.js @@ -0,0 +1,19 @@ +import CircleNode from './CircleNode' + +// 椭圆 +class EllipseNewModel extends CircleNode.model { + initNodeData(data) { + super.initNodeData(data) + this.rx = 60 + this.ry = 30 + } + getNodeStyle() { + const style = super.getNodeStyle() + return { ...style } + } +} +export default { + type: 'pro-ellipse', + view: CircleNode.view, + model: EllipseNewModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectNode.js new file mode 100644 index 000000000..ee242e26d --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectNode.js @@ -0,0 +1,27 @@ +import { RectResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 矩形 +class RectNewModel extends RectResize.model { + setToBottom() { + this.zIndex = 0 + } + + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +export default { + type: 'pro-rect', + view: RectResize.view, + model: RectNewModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectRadiusNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectRadiusNode.js new file mode 100644 index 000000000..9a336d63a --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/RectRadiusNode.js @@ -0,0 +1,14 @@ +import RectNode from './RectNode' + +// 带圆角的矩形 +class RectRadiusModel extends RectNode.model { + setAttributes() { + super.setAttributes() + this.radius = 20 + } +} +export default { + type: 'rect-radius', + view: RectNode.view, + model: RectRadiusModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/TextNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/TextNode.js new file mode 100644 index 000000000..b3a091170 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/basic/TextNode.js @@ -0,0 +1,37 @@ +import { TextNodeModel, TextNode } from '@logicflow/core' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 文本节点 +class TextNewNode extends TextNode { +} +class TextNewModel extends TextNodeModel { + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + if (properties.backgroundColor) { + style.backgroundStyle = { + fill: properties.backgroundColor + } + } + return getTextStyleFunction(style, properties) + } + + setAttributes() { + super.setAttributes() + if (!this.text.value) { + this.text.value = 'text' + } + } +} + +export default { + type: 'pro-text', + view: TextNewNode, + model: TextNewModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Bezier.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Bezier.js new file mode 100644 index 000000000..ecfc48eb9 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Bezier.js @@ -0,0 +1,26 @@ +import { BezierEdge, BezierEdgeModel } from '@logicflow/core' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 贝塞尔曲线 +class Model extends BezierEdgeModel { + constructor(data, graphModel) { + super(data, graphModel) + this.strokeWidth = 1 + } + getTextStyle() { + const style = super.getTextStyle() + return getTextStyleFunction(style, this.properties) + } + + getEdgeStyle() { + const attributes = super.getEdgeStyle() + const properties = this.properties + const style = getShapeStyleFuction(attributes, properties) + return { ...style, fill: 'none' } + } +} +export default { + type: 'pro-bezier', + view: BezierEdge, + model: Model +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Line.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Line.js new file mode 100644 index 000000000..c5ef06e0a --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Line.js @@ -0,0 +1,26 @@ +import { LineEdge, LineEdgeModel } from '@logicflow/core' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 直线 +class Model extends LineEdgeModel { + constructor(data, graphModel) { + super(data, graphModel) + this.strokeWidth = 1 + } + getTextStyle() { + const style = super.getTextStyle() + return getTextStyleFunction(style, this.properties) + } + + getEdgeStyle() { + const attributes = super.getEdgeStyle() + const properties = this.properties + const style = getShapeStyleFuction(attributes, properties) + return { ...style, fill: 'none' } + } +} +export default { + type: 'pro-line', + view: LineEdge, + model: Model +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Polyline.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Polyline.js new file mode 100644 index 000000000..86d53c295 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/edge/Polyline.js @@ -0,0 +1,26 @@ +import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 折线 +class Model extends PolylineEdgeModel { + constructor(data, graphModel) { + super(data, graphModel) + this.strokeWidth = 1 + } + getTextStyle() { + const style = super.getTextStyle() + return getTextStyleFunction(style, this.properties) + } + + getEdgeStyle() { + const attributes = super.getEdgeStyle() + const properties = this.properties + const style = getShapeStyleFuction(attributes, properties) + return { ...style, fill: 'none' } + } +} +export default { + type: 'pro-polyline', + view: PolylineEdge, + model: Model +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/getShapeStyleUtil.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/getShapeStyleUtil.js new file mode 100644 index 000000000..ccea7ddc5 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/getShapeStyleUtil.js @@ -0,0 +1,70 @@ +export const getShapeStyleFuction = (style, properties) => { + if (properties.backgroundColor) { + style.fill = properties.backgroundColor + } + if (properties.transform) { // 旋转 + style.transform = properties.transform + } + if (properties.imageWidth) { // 宽度 + style.imageWidth = properties.imageWidth + } + if (properties.imageHeight) { // 高度 + style.imageHeight = properties.imageHeight + } + if (properties.gradientColor && style.fill !== properties.gradientColor) { + style.fillGradient = properties.gradientColor + } + if (properties.borderColor) { + style.stroke = properties.borderColor + } + if (properties.borderWidth) { + style.strokeWidth = properties.borderWidth + } + if (properties.borderStyle) { + if (properties.borderStyle === 'solid') { + style.strokeDashArray = '0' + // nodeResize里的bug导致的,array小写了 + style.strokeDasharray = '0' + } + if (properties.borderStyle === 'dashed') { + style.strokeDashArray = '3 3' + style.strokeDasharray = '3 3' + } + if (properties.borderStyle === 'dotted') { + style.strokeDashArray = '1 1' + style.strokeDasharray = '1 1' + } + if (properties.borderStyle === 'hidden') { + style.stroke = style.fill + } + } + return style +} + +export const getTextStyleFunction = (style = {}, properties) => { + if (properties.fontColor) { + style.color = properties.fontColor + } + if (properties.fontSize) { + style.fontSize = properties.fontSize + } + if (properties.fontFamily) { + style.fontFamily = properties.fontFamily + } + if (properties.lineHeight) { + style.lineHeight = properties.lineHeight + } + if (properties.textAlign) { + style.textAlign = properties.textAlign + } + if (properties.fontWeight) { + style.fontWeight = properties.fontWeight + } + if (properties.textDecoration) { + style.textDecoration = properties.textDecoration + } + if (properties.fontStyle) { + style.fontStyle = properties.fontStyle + } + return style +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/html/htmlNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/html/htmlNode.js new file mode 100644 index 000000000..bbd4d84d9 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/html/htmlNode.js @@ -0,0 +1,89 @@ +import { HtmlResize } from '@logicflow/extension' +import defaultUrl from '../../../image/agv.svg' +import api from '@/store/modules/api' +import tray from '../../../image/托盘.svg' +import icon_alert from '../../../image/icon_alert.png' +class ButtonNodeModel extends HtmlResize.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 100 + this.height = 100 + this.text.draggable = true + this.text.editable = false + } +} + +class ButtonNode extends HtmlResize.view { + setHtml(rootEl) { + /** + * 自己设置的宽高在 imageHeight/imageWidth + * 用拖动设置的宽高在 properties.nodeSize.height/properties.nodeSize.width + */ + const oldNode = this.props.model + const properties = oldNode.getProperties() + // console.log(properties) + // console.log('oldNode', oldNode) + // 路径前缀 + const baseUrl = api.state.baseApi + // 颜色 + let statusColor = '#1a912a' + // 默认图片 + // let imageUrl = baseUrl + '/file/图片/专机-20220722094234555.png' + let imageUrl = defaultUrl + // 托盘图片 + const goods = tray + const trayHeight = Math.round(2 / 3 * oldNode._height) + const trayWidth = Math.round(2 / 3 * oldNode._width) + let trayDisplay = 'none' + // 故障图片 + const fault = icon_alert + let faultDisplay = 'none' + if (properties.imageUrl) { // 与图片尾部拼接 + imageUrl = baseUrl + '/file/图片/' + properties.imageUrl + } + if (!properties.transform) { // 如果没有值,设置默认为0度 + properties.transform = 0 + } + if (properties.isOnline) { + statusColor = '#54dc5f' + } + if (!properties.device) { + statusColor = 'rgba(255,255,255,0)' + } + if (properties.hasGoods) { + // 显示图片,并设置宽高 + trayDisplay = 'flex' + } + if (properties.isError) { + // 显示图片,并设置宽高 + faultDisplay = 'flex' + } + if (properties.isLock !== undefined) { + oldNode.draggable = !properties.isLock + } + const el = document.createElement('div') + el.className = 'uml-wrapper' + // el.id = 'uml-app' + const html = ` +
+
+ + + +
+ ` + el.innerHTML = html + rootEl.innerHTML = '' + rootEl.appendChild(el) + window.setData = () => { + const { graphModel, model } = this.props + graphModel.eventCenter.emit('custom:button-click', model) + } + } +} + +export default { + type: 'html-node', + view: ButtonNode, + model: ButtonNodeModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/index.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/index.js new file mode 100644 index 000000000..ec1544aed --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/index.js @@ -0,0 +1,74 @@ +// 导入组件并且注册 +// 基础图形 +import CircleNode from './basic/CircleNode' +import RectNode from './basic/RectNode' +import RectRadiusNode from './basic/RectRadiusNode' +import EllipseNode from './basic/EllipseNode' +import TextNode from './basic/TextNode' +import DiamondNode from './basic/DiamondNode' +// path绘制的个性化图形 +import CylindeNode from './path/CylindeNode' +import TriangleNode from './path/TriangleNode' +import ParallelogramNode from './path/ParallelogramNode' +import ActorNode from './path/ActorNode' +import StarNode from './path/Star' +import PentagonNode from './path/PentagonNode' +import HexagonNode from './path/HexagonNode' +import SeptagonNode from './path/SeptagonNode' +import HeptagonNode from './path/HeptagonNode' +import TrapezoidNode from './path/TrapezoidNode' +import CrossNode from './path/CrossNode' +import MinusNode from './path/MinusNode' +import TimesNode from './path/TimesNode' +import DivideNode from './path/DivideNode' +// 多边形绘制的箭头 +import LeftArrow from './arrow/LeftArrow' +import RightArrow from './arrow/RightArrow' +import HorizontalArrow from './arrow/HorizontalArrowNode' +import UpArrow from './arrow/UpArrowNode' +import DownArrow from './arrow/DownArrowNode' +import VerticalArrow from './arrow/VerticalArrowNode' +// 注册边 +import Ployline from './edge/Polyline' +import Line from './edge/Line' +import Bezier from './edge/Bezier' +// html图片 +import HtmlNode from './html/htmlNode' + +export const registerCustomElement = (lf) => { + // 注册基础图形 + lf.register(CircleNode) + lf.register(RectNode) + lf.register(RectRadiusNode) + lf.register(EllipseNode) + lf.register(DiamondNode) + lf.register(TextNode) + // 注册path绘制的个性化图形 + lf.register(CylindeNode) + lf.register(TriangleNode) + lf.register(ParallelogramNode) + lf.register(ActorNode) + lf.register(StarNode) + lf.register(PentagonNode) + lf.register(HexagonNode) + lf.register(SeptagonNode) + lf.register(HeptagonNode) + lf.register(TrapezoidNode) + lf.register(CrossNode) + lf.register(MinusNode) + lf.register(TimesNode) + lf.register(DivideNode) + // 注册多边形绘制的箭头 + lf.register(LeftArrow) + lf.register(RightArrow) + lf.register(HorizontalArrow) + lf.register(UpArrow) + lf.register(DownArrow) + lf.register(VerticalArrow) + // 注册边 + lf.register(Ployline) + lf.register(Line) + lf.register(Bezier) + // 注册html结点 + lf.register(HtmlNode) +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ActorNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ActorNode.js new file mode 100644 index 000000000..718e51172 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ActorNode.js @@ -0,0 +1,95 @@ +import { h } from '@logicflow/core' +import { RectResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' +// 人物 +class ActorModel extends RectResize.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 40 + this.height = 80 + } + + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class ActorView extends RectResize.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + // 人物头部圆形 + const ellipseAttrs = { + ...style, + cx: x, + cy: y - 3 / 8 * height, + rx: 1 / 4 * width, + ry: 1 / 8 * height, + width, + height + } + // 人物肩膀横线 + const pathAAttrs = { + ...style, + d: `M ${x - 1 / 2 * width} ${y - 1 / 8 * height} L ${x + 1 / 2 * width} ${y - 1 / 8 * height}` + } + // 人物身体躯干竖线 + const pathBAttrs = { + ...style, + d: `M ${x} ${y - 1 / 4 * height} L ${x} ${y + 1 / 5 * height}` + } + // 人物左腿斜线 + const pathCAttrs = { + ...style, + d: `M ${x} ${y + 1 / 5 * height} L ${x - 1 / 2 * width} ${y + 1 / 2 * height}` + } + // 人物右腿斜线 + const pathDAttrs = { + ...style, + d: `M ${x} ${y + 1 / 5 * height} L ${x + 1 / 2 * width} ${y + 1 / 2 * height}` + } + // 人物透明背景板 + const bgAttrs = { + x: x - 1 / 5 * width, + y: y - 1 / 2 * height, + width: 2 / 5 * width, + height, + style: 'fill: transparent' + } + return h('g', {}, [ + h('ellipse', { + ...ellipseAttrs + }), + h('path', { + ...pathAAttrs + }), + h('path', { + ...pathBAttrs + }), + h('path', { + ...pathCAttrs + }), + h('path', { + ...pathDAttrs + }), + h('rect', { + ...bgAttrs + }) + ] + ) + } +} + +export default { + type: 'actor', + view: ActorView, + model: ActorModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CrossNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CrossNode.js new file mode 100644 index 000000000..a9b4bbc71 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CrossNode.js @@ -0,0 +1,65 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 加号 +class CrossModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class CrossView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 1 / 2 * width, y - 1 / 6 * height], + [x - 1 / 6 * width, y - 1 / 6 * height], + [x - 1 / 6 * width, y - 1 / 2 * height], + [x + 1 / 6 * width, y - 1 / 2 * height], + [x + 1 / 6 * width, y - 1 / 6 * height], + [x + 1 / 2 * width, y - 1 / 6 * height], + [x + 1 / 2 * width, y + 1 / 6 * height], + [x + 1 / 6 * width, y + 1 / 6 * height], + [x + 1 / 6 * width, y + 1 / 2 * height], + [x - 1 / 6 * width, y + 1 / 2 * height], + [x - 1 / 6 * width, y + 1 / 6 * height], + [x - 1 / 2 * width, y + 1 / 6 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'cross', + view: CrossView, + model: CrossModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CylindeNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CylindeNode.js new file mode 100644 index 000000000..a719c7e30 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/CylindeNode.js @@ -0,0 +1,92 @@ +import { h } from '@logicflow/core' +import { RectResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 圆柱体 +class CylindeModel extends RectResize.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 60 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class CylindeView extends RectResize.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + // 圆柱体顶部椭圆 + const ellipseAAttrs = { + ...style, + cx: x, + cy: y - 1 / 3 * height, + rx: 1 / 2 * width, + ry: 1 / 6 * height, + width, + height + } + // 圆柱体左直线 + const pathAAttrs = { + ...style, + d: `M ${x - 1 / 2 * width} ${y - 1 / 3 * height} L ${x - 1 / 2 * width} ${y + 1 / 3 * height}` + } + // 圆柱体右直线 + const pathBAttrs = { + ...style, + d: `M ${x + 1 / 2 * width} ${y - 1 / 3 * height} L ${x + 1 / 2 * width} ${y + 1 / 3 * height}` + } + // 圆柱体下椭圆 + const ellipseBAttrs = { + ...style, + cx: x, + cy: y + 1 / 3 * height, + rx: 1 / 2 * width, + ry: 1 / 6 * height, + width, + height + } + // 圆柱体中间填充部分 + const rectAttrs = { + ...style, + x: x - 1 / 2 * width, + y: y - 1 / 3 * height, + width, + height: 2 / 3 * height, + stroke: 'transparent' + } + return h('g', {}, [ + h('ellipse', { + ...ellipseBAttrs + }), + h('rect', { + ...rectAttrs + }), + h('path', { + ...pathAAttrs + }), + h('path', { + ...pathBAttrs + }), + h('ellipse', { + ...ellipseAAttrs + }) + ]) + } +} + +export default { + type: 'cylinde', + model: CylindeModel, + view: CylindeView +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/DivideNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/DivideNode.js new file mode 100644 index 000000000..1fa2d9896 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/DivideNode.js @@ -0,0 +1,83 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 除号 +class DivideModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class DivideView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 1 / 2 * width, y - 1 / 8 * height], + [x + 1 / 2 * width, y - 1 / 8 * height], + [x + 1 / 2 * width, y + 1 / 8 * height], + [x - 1 / 2 * width, y + 1 / 8 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + + const attrs = { + ...style, + x, + y, + width, + height + } + + // 除号中间横线 + const lineAttrs = { + ...attrs, + points: points.join(' ') + } + + // 除号上圆点 + const upEllipseAttrs = { + ...attrs, + cy: y - 3 / 8 * height, + cx: x, + rx: 1 / 8 * width, + ry: 1 / 8 * height + } + + // 除号下圆点 + const downEllipseAttrs = { + ...attrs, + cy: y + 3 / 8 * height, + cx: x, + rx: 1 / 8 * width, + ry: 1 / 8 * height + } + + return h('g', {}, [ + h('polygon', { ...lineAttrs }), + h('ellipse', { ...upEllipseAttrs }), + h('ellipse', { ...downEllipseAttrs }) + ]) + } +} + +export default { + type: 'divide', + view: DivideView, + model: DivideModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HeptagonNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HeptagonNode.js new file mode 100644 index 000000000..b28d42b1f --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HeptagonNode.js @@ -0,0 +1,61 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 五边形 +class HeptagonModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class HeptagonView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 0.205 * width, y - 0.5 * height], + [x + 0.205 * width, y - 0.5 * height], + [x + 0.5 * width, y - 0.205 * height], + [x + 0.5 * width, y + 0.205 * height], + [x + 0.205 * width, y + 0.5 * height], + [x - 0.205 * width, y + 0.5 * height], + [x - 0.5 * width, y + 0.205 * height], + [x - 0.5 * width, y - 0.205 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'heptagon', + view: HeptagonView, + model: HeptagonModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HexagonNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HexagonNode.js new file mode 100644 index 000000000..a0e281fbb --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/HexagonNode.js @@ -0,0 +1,59 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 六边形 +class HexagonModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class HexagonView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 0.28 * width, y - 0.5 * height], + [x + 0.28 * width, y - 0.5 * height], + [x + 0.5 * width, y], + [x + 0.28 * width, y + 0.5 * height], + [x - 0.28 * width, y + 0.5 * height], + [x - 0.5 * width, y] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'hexagon', + view: HexagonView, + model: HexagonModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/MinusNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/MinusNode.js new file mode 100644 index 000000000..5f29f1e27 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/MinusNode.js @@ -0,0 +1,57 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 减号 +class MinusModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 20 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class MinusView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 1 / 2 * width, y - 1 / 2 * height], + [x + 1 / 2 * width, y - 1 / 2 * height], + [x + 1 / 2 * width, y + 1 / 2 * height], + [x - 1 / 2 * width, y + 1 / 2 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'minus', + view: MinusView, + model: MinusModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ParallelogramNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ParallelogramNode.js new file mode 100644 index 000000000..96b07f882 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/ParallelogramNode.js @@ -0,0 +1,57 @@ +import { h } from '@logicflow/core' +import { RectResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 平行四边形 +class ParallelogramModel extends RectResize.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 100 + this.height = 60 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class ParallelogramView extends RectResize.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - width / 2, y + height / 2], + [x - width / 5, y - height / 2], + [x + width / 2, y - height / 2], + [x + width / 5, y + height / 2] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'parallelogram', + view: ParallelogramView, + model: ParallelogramModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/PentagonNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/PentagonNode.js new file mode 100644 index 000000000..0bf20aad3 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/PentagonNode.js @@ -0,0 +1,58 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 八边形 +class PentagonModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class PentagonView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 0.5 * width, y], + [x, y - 0.5 * height], + [x + 0.5 * width, y], + [x + 0.3 * width, y + 0.5 * height], + [x - 0.3 * width, y + 0.5 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'pentagon', + view: PentagonView, + model: PentagonModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/SeptagonNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/SeptagonNode.js new file mode 100644 index 000000000..9ea030a49 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/SeptagonNode.js @@ -0,0 +1,60 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 七边形 +class SeptagonModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class SeptagonView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x, y - 0.5 * height], + [x + 0.395 * width, y - 0.3 * height], + [x + 0.5 * width, y + 0.145 * height], + [x + 0.225 * width, y + 0.5 * height], + [x - 0.225 * width, y + 0.5 * height], + [x - 0.5 * width, y + 0.145 * height], + [x - 0.395 * width, y - 0.3 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'septagon', + view: SeptagonView, + model: SeptagonModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/Star.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/Star.js new file mode 100644 index 000000000..28eaededc --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/Star.js @@ -0,0 +1,40 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' + +// 五角星 +class StarModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } +} + +class StarView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const svgAttr = { + x: x - 1 / 2 * width, + y: y - 1 / 2 * height, + width, + height + } + const pathAAttrs = { + ...style, + d: 'm0.36922,13.46587l12.98695,0l4.01307,-13.36885l4.01307,13.36885l12.98694,0l-10.50664,8.26231l4.01327,13.36885l-10.50665,-8.26253l-10.50664,8.26253l4.01327,-13.36885l-10.50665,-8.26231l0,0z' + } + + return h('svg', { ...svgAttr, viewBox: '0 0 37 37' }, [ + h('path', { + ...pathAAttrs + }) + ]) + } +} + +export default { + type: 'star', + view: StarView, + model: StarModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TimesNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TimesNode.js new file mode 100644 index 000000000..6d67a2fc1 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TimesNode.js @@ -0,0 +1,65 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 乘号 +class TimesModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class TimesView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 1 / 2 * width, y - 1 / 3 * height], + [x - 1 / 3 * width, y - 1 / 2 * height], + [x, y - 1 / 6 * height], + [x + 1 / 3 * width, y - 1 / 2 * height], + [x + 1 / 2 * width, y - 1 / 3 * height], + [x + 1 / 6 * width, y], + [x + 1 / 2 * width, y + 1 / 3 * height], + [x + 1 / 3 * width, y + 1 / 2 * height], + [x, y + 1 / 6 * height], + [x - 1 / 3 * width, y + 1 / 2 * height], + [x - 1 / 2 * width, y + 1 / 3 * height], + [x - 1 / 6 * width, y] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'times', + view: TimesView, + model: TimesModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TrapezoidNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TrapezoidNode.js new file mode 100644 index 000000000..3ffe197b4 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TrapezoidNode.js @@ -0,0 +1,57 @@ +import { h } from '@logicflow/core' +import RectNode from '../basic/RectNode' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 五边形 +class TrapezoidModel extends RectNode.model { + initNodeData(data) { + super.initNodeData(data) + this.width = 80 + this.height = 80 + } + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class TrapezoidView extends RectNode.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const pointList = [ + [x - 0.31 * width, y - 0.5 * height], + [x + 0.31 * width, y - 0.5 * height], + [x + 0.5 * width, y + 0.5 * height], + [x - 0.5 * width, y + 0.5 * height] + ] + const points = pointList.map(item => { + return `${item[0]},${item[1]}` + }) + const attrs = { + ...style, + x, + y, + width, + height, + points: points.join(' ') + } + + return h('g', {}, [ + h('polygon', { ...attrs }) + ]) + } +} + +export default { + type: 'trapezoid', + view: TrapezoidView, + model: TrapezoidModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TriangleNode.js b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TriangleNode.js new file mode 100644 index 000000000..67ff9e369 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/components/node/path/TriangleNode.js @@ -0,0 +1,47 @@ +import { h } from '@logicflow/core' +import { RectResize } from '@logicflow/extension' +import { getShapeStyleFuction, getTextStyleFunction } from '../getShapeStyleUtil' + +// 三角形 +class TriangleModel extends RectResize.model { + getNodeStyle() { + const style = super.getNodeStyle() + const properties = this.getProperties() + return getShapeStyleFuction(style, properties) + } + + getTextStyle() { + const style = super.getTextStyle() + const properties = this.getProperties() + return getTextStyleFunction(style, properties) + } +} + +class TriangleView extends RectResize.view { + getResizeShape() { + const { x, y, width, height } = this.props.model + const style = this.props.model.getNodeStyle() + const attrs = { + ...style, + x, + y, + width, + height, + points: [ + [x - width / 2, y + height / 2], + [x - width / 2, y - height / 2], + [x + width / 2, y] + ] + } + return h('g', {}, [ + h('polygon', { ...attrs }) + ] + ) + } +} + +export default { + type: 'triangle', + view: TriangleView, + model: TriangleModel +} diff --git a/nladmin-ui/src/views/system/logicflow/editor/constant/index.js b/nladmin-ui/src/views/system/logicflow/editor/constant/index.js new file mode 100644 index 000000000..710a725bf --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/constant/index.js @@ -0,0 +1,69 @@ +export const shortStyles = [ + { + backgroundColor: 'rgb(255, 255, 255)', + borderWidth: '1px', + borderColor: 'rgb(42, 42, 42)' + }, + { + backgroundColor: 'rgb(245, 245, 245)', + borderWidth: '1px', + borderColor: 'rgb(102, 102, 102)' + }, + { + backgroundColor: 'rgb(218, 232, 252)', + borderWidth: '1px', + borderColor: 'rgb(108, 142, 191)' + }, + { + backgroundColor: 'rgb(213, 232, 212)', + borderWidth: '1px', + borderColor: 'rgb(130, 179, 102)' + }, + { + backgroundColor: 'rgb(255, 230, 204)', + borderWidth: '1px', + borderColor: 'rgb(215, 155, 0)' + }, + { + backgroundColor: 'rgb(255, 242, 204)', + borderWidth: '1px', + borderColor: 'rgb(214, 182, 86)' + }, + { + backgroundColor: 'rgb(248, 206, 204)', + borderWidth: '1px', + borderColor: 'rgb(184, 84, 80)' + }, + { + backgroundColor: 'rgb(220, 210, 230)', + borderWidth: '1px', + borderColor: 'rgb(150, 115, 166)' + } +] + +export const borderStyles = [ + { + value: 'solid' + }, + { + value: 'dashed' + }, + { + value: 'dotted' + } +] + +export const fontFamilies = [ + { + value: 'Arial' + }, + { + value: 'Verdana' + }, + { + value: 'Georgia' + }, + { + value: 'Times New Roman' + } +] diff --git a/nladmin-ui/src/views/system/logicflow/editor/image/agv.svg b/nladmin-ui/src/views/system/logicflow/editor/image/agv.svg new file mode 100644 index 000000000..d7a91d45e --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/image/agv.svg @@ -0,0 +1,60 @@ + + + + agv@1x + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nladmin-ui/src/views/system/logicflow/editor/image/icon_alert.png b/nladmin-ui/src/views/system/logicflow/editor/image/icon_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..c224792e5be02bea43d6c1eb85ea6649241f7282 GIT binary patch literal 1649 zcmV-%29EiOP)G%)5j~=y{_Yz>d z3Hgnk$X&JQUiWmTKd6>w;Oi?Q&~XDmYX{WAz%uNBa$YY3=@)!8Qz!D6E4?#%>m|hI zJ!rVzr7wwpS7mVri=GGn{yk8*XaO{u&hiSO?EY{L z_J1%RFdhW+AS*DF6*3BkvzN2oW$fIt$53KMhQ;P&Ym3Apy;r-$9@Tjb5r=0pW#B;d zcp$0O*FZ#rk>3#g`!LwJgL`XAUh8W=P?k;ZH8YXlI)=P?FScxa9=UfbYW@cNv$FVd zs{efYGHbw#T5OtwU zgy1@eolH{bmmH*tXM;-P|GT9<$5wS#ZaW5Vl7rU{2{R;VItI<{I+>xpz z#@!U@Jg+(`_5wuR;NMqA#Ul=~)Wn!#nvc8Z$*Iao#TIp@T^TZJ1hoA`3Nbn_Ixtd% zcz{^55a>Kifk>IFur2-o zq3y>`6x0kwVE_dx=y2b($)I!XST{w^VYM=VZmihU)g^@y1vLW^q%5Ld9BlKKpi6Zg z63UXR%IR~gtOwTNNh%4X?1zg8jbfEDfytz3$_8_8E<|q|i0Xk%p)zfPytxbU>h6to?DW!ck$#!xjD+uZ`{x`X5bhXvw|#e% zrzQCvcauOAPmRSFiaoL^V{`thubcYX|F2~3s*)|D0LFYjVAONk;J>SC@}_@c^lwFo zsw%npR~MLK8Rb~M3vQTwj~_QVm)P z>4_*Ep+rHezBuRS9Ue)k%3QlsEtTxFN8W1t| za{?<|z7;GsD}nt&5p`bgL_sl%3f)+GS_qFWUg!!~hgzBKg>ppB*U?q4PqmpCcZ(3! zd1epyUV+ShLmbPt(RrPt^J*i5qIOWHbkYK}Hk=dz!hlH=NJeiTtr>fST(SUH?BLtH z0VGZP!{Kyrzi|Agrj85MC+ z5e;Jrz|OgdB82`dA_dsQS@EZJ~cN5y?zrvk@s%tk87e3(&4#1o}*xZC6ho zW^UD4M*RM4P}y2kao?oK%M50-87k`dguC|FZ?I=`!f0$39;57O>l7N00000NkvXXu0mjf%5&;E literal 0 HcmV?d00001 diff --git a/nladmin-ui/src/views/system/logicflow/editor/image/托盘.svg b/nladmin-ui/src/views/system/logicflow/editor/image/托盘.svg new file mode 100644 index 000000000..552024a41 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/image/托盘.svg @@ -0,0 +1,14 @@ + + + + 托盘@1x + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/nladmin-ui/src/views/system/logicflow/editor/index.vue b/nladmin-ui/src/views/system/logicflow/editor/index.vue new file mode 100644 index 000000000..4b0e21381 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/editor/index.vue @@ -0,0 +1,34 @@ + + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/image/index.vue b/nladmin-ui/src/views/system/logicflow/image/index.vue new file mode 100644 index 000000000..6c1eb6492 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/image/index.vue @@ -0,0 +1,310 @@ + + + + + diff --git a/nladmin-ui/src/views/system/logicflow/index.vue b/nladmin-ui/src/views/system/logicflow/index.vue new file mode 100644 index 000000000..cc41a4640 --- /dev/null +++ b/nladmin-ui/src/views/system/logicflow/index.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue b/nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue new file mode 100644 index 000000000..f6a8a1609 --- /dev/null +++ b/nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/nladmin-ui/src/views/system/monitor/device/index.vue b/nladmin-ui/src/views/system/monitor/device/index.vue new file mode 100644 index 000000000..7f6596baf --- /dev/null +++ b/nladmin-ui/src/views/system/monitor/device/index.vue @@ -0,0 +1,154 @@ + + + + + +