|  |  | 
 |  |  | package com.zy.core.model.protocol; | 
 |  |  |  | 
 |  |  | import com.zy.asrs.entity.BasCrnErrorLog; | 
 |  |  | import com.zy.asrs.entity.BasCrnp; | 
 |  |  | import com.zy.core.enums.CrnForkPosType; | 
 |  |  | import com.zy.core.enums.CrnLiftPosType; | 
 |  |  | import com.zy.core.enums.CrnModeType; | 
 |  |  | import com.zy.core.enums.CrnStatusType; | 
 |  |  | import lombok.Data; | 
 |  |  |  | 
 |  |  | 
 |  |  | @Data | 
 |  |  | public class CrnProtocol { | 
 |  |  |  | 
 |  |  |     private Integer crnNo; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 1 = 手动模式 | 
 |  |  |      * 2 = 自动模式 | 
 |  |  |      * 3 = 电脑模式 | 
 |  |  |      * 4 = 手动模式启动中 | 
 |  |  |      * 5 = 自动模式启动中 | 
 |  |  |      * 6 = 电脑模式启动中 | 
 |  |  |      */ | 
 |  |  |     public short mode; | 
 |  |  |     public Short mode; | 
 |  |  |  | 
 |  |  |     public CrnModeType modeType; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 1 = 急停 | 
 |  |  |      */ | 
 |  |  |     public short eStop; | 
 |  |  |     public Short eStop; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 异常码 | 
 |  |  |      */ | 
 |  |  |     public short alarm; | 
 |  |  |     public Short alarm; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 任务号 | 
 |  |  |      */ | 
 |  |  |     public short taskNo; | 
 |  |  |     public Short taskNo = 0; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机当前状态 | 
 |  |  |      * 0 = 未知 | 
 |  |  |      * 1 = 空闲 | 
 |  |  |      * 2 = 检查任务数据 | 
 |  |  |      * 3 = 定位到取货位 | 
 |  |  |      * 7 = 取货完成 | 
 |  |  |      * 8 = 等待调度柜允许 | 
 |  |  |      * 9 = 移动到放货位置 | 
 |  |  |      * 10 = 放货中 | 
 |  |  |      * 13 = 搬运完成 | 
 |  |  |      * 14 = 空载避让 | 
 |  |  |      * 15 = 检查任务数据 | 
 |  |  |      * 20 = 检查源位置 | 
 |  |  |      * 21 = 检查目标位置 | 
 |  |  |      * 50 = 移动任务 | 
 |  |  |      * 98 = 任务完成,wcs未确认 | 
 |  |  |      * 99 = 报警 | 
 |  |  |      * 0:空闲,无任务 | 
 |  |  |      * 1:取货定位中 | 
 |  |  |      * 2:取货中 | 
 |  |  |      * 3:取货完成,放货定位中 | 
 |  |  |      * 4:放货中 | 
 |  |  |      * 5:回原点中 | 
 |  |  |      * 6:反原点 | 
 |  |  |      * 7:库位移位 | 
 |  |  |      * 90:任务完成等待WCS确认 | 
 |  |  |      * 99:报警 | 
 |  |  |      */ | 
 |  |  |     public short status; | 
 |  |  |     public Short status; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 状态枚举 | 
 |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机当前列号 | 
 |  |  |      */ | 
 |  |  |     public short bay; | 
 |  |  |     public Short bay; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机当前层号 | 
 |  |  |      */ | 
 |  |  |     public short level; | 
 |  |  |     public Short level; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 当前货叉位置 | 
 |  |  | 
 |  |  |      * 1 = 货叉在左侧 | 
 |  |  |      * 2 = 货叉在右侧 | 
 |  |  |      */ | 
 |  |  |     public short forkPos; | 
 |  |  |     public Short forkPos; | 
 |  |  |  | 
 |  |  |     public CrnForkPosType forkPosType; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 当前载货台位置 | 
 |  |  |      * 0 = 下定位 | 
 |  |  |      * 1 = 上定位 | 
 |  |  |      */ | 
 |  |  |     public short liftPos; | 
 |  |  |     public Short liftPos; | 
 |  |  |  | 
 |  |  |     public CrnLiftPosType liftPosType; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 走行在定位 | 
 |  |  |      * 0 = 在定位 | 
 |  |  |      * 1 = 不在定位 | 
 |  |  |      */ | 
 |  |  |     public short walkPos; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机任务完成 | 
 |  |  |      */ | 
 |  |  |     public short taskFinish; | 
 |  |  |     public Short walkPos; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 载货台有物 | 
 |  |  |      */ | 
 |  |  |     public short loaded; | 
 |  |  |     public Short loaded; | 
 |  |  |  | 
 |  |  |     private Short temp1; | 
 |  |  |  | 
 |  |  |     private CrnTemp1 crnTemp1; | 
 |  |  |  | 
 |  |  |     private Short temp2; | 
 |  |  |  | 
 |  |  |     private Short temp3; | 
 |  |  |  | 
 |  |  |     private Short temp4; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计走行距离 | 
 |  |  |      * 异常1 | 
 |  |  |      */ | 
 |  |  |     public int xDistance; | 
 |  |  |     private boolean[] error1; | 
 |  |  |  | 
 |  |  |     private CrnError1 crnError1; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计升降距离 | 
 |  |  |      * 异常2 | 
 |  |  |      */ | 
 |  |  |     public int yDistance; | 
 |  |  |     private boolean[] error2; | 
 |  |  |  | 
 |  |  |     private CrnError2 crnError2; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计运行时长 | 
 |  |  |      * 异常3 | 
 |  |  |      */ | 
 |  |  |     public int duration; | 
 |  |  |     private boolean[] error3; | 
 |  |  |  | 
 |  |  |     private CrnError3 crnError3; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 异常4 | 
 |  |  |      */ | 
 |  |  |     private boolean[] error4; | 
 |  |  |  | 
 |  |  |     private CrnError4 crnError4; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 异常5 | 
 |  |  |      */ | 
 |  |  |     private boolean[] error5; | 
 |  |  |  | 
 |  |  |     private CrnError5 crnError5; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 异常6 | 
 |  |  |      */ | 
 |  |  |     private boolean[] error6; | 
 |  |  |  | 
 |  |  |     private CrnError6 crnError6; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * X行走线速度m/min | 
 |  |  |      */ | 
 |  |  |     private Float xSpeed; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * Y行走线速度m/min | 
 |  |  |      */ | 
 |  |  |     private Float ySpeed; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * Z行走线速度m/min | 
 |  |  |      */ | 
 |  |  |     private Float zSpeed; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计走行距离km | 
 |  |  |      */ | 
 |  |  |     public Float xDistance; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计升降距离km | 
 |  |  |      */ | 
 |  |  |     public Float yDistance; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计走行时长h | 
 |  |  |      */ | 
 |  |  |     public Float xDuration; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 堆垛机累计升降时长h | 
 |  |  |      */ | 
 |  |  |     public Float yDuration; | 
 |  |  |  | 
 |  |  |     //堆垛机配置信号-------------------------------------------------------------- | 
 |  |  |     // 故障读取锁定标记 | 
 |  |  |     private boolean errorMk = false; | 
 |  |  |     //写入标记 | 
 |  |  |     private boolean writeMk = true; | 
 |  |  |     private Boolean ibDriveFault = false;       // 行走变频器故障 | 
 |  |  |     private Boolean ibSupplyFault = false;      // 提供变频器故障 | 
 |  |  |     private Boolean ibForkDriveFault = false;   // 货叉变频器故障 | 
 |  |  |     private Boolean ibDriveCircuitFault = false; // 行走断路器故障 | 
 |  |  |     private Boolean ibLiftCircuitFault = false; // 提升断路器故障 | 
 |  |  |     private Boolean ibForkCircuitFault = false; // 货叉断路器故障 | 
 |  |  |     private Boolean ibForwardLimit = false;     // 前进限位 | 
 |  |  |     private Boolean ibReverseLimit = false;     // 后退限位 | 
 |  |  |     private Boolean ibDriveStart = false;       // 行走原点 | 
 |  |  |     private Boolean ibForwardBrakeSpeed = false; // 前进强制低速 | 
 |  |  |     private Boolean ibReverseBrakeSpeed = false; // 后退强制低速 | 
 |  |  |     private Boolean ibUpLimit = false;          // 上升限位 | 
 |  |  |     private Boolean ibDownLimit = false;        // 下限限位 | 
 |  |  |     private Boolean ibUpOrigin = false;         // 提升原点 | 
 |  |  |     private Boolean ibUpBrakeSpeed = false;     // 上升强制低速 | 
 |  |  |     private Boolean ibDownBrakeSpeed = false;   // 下降强制低速 | 
 |  |  |     private Boolean ibPlatformSignal = false;   // 载货台探货 | 
 |  |  |     private Boolean ibForkMidSignal = false;    // 货叉中位信号 | 
 |  |  |     private Boolean ibForkLeftLimit = false;    // 货叉左极限 | 
 |  |  |     private Boolean ibForkRightLimit = false;   // 货叉右极限 | 
 |  |  |     private Boolean ibFrontOverLimit = false;   // 前超限 | 
 |  |  |     private Boolean ibRearOverLimit = false;    // 后超限 | 
 |  |  |     private Boolean ibLeftOverLimit = false;    // 左超限 | 
 |  |  |     private Boolean ibRightOverLimit = false;   // 右超限 | 
 |  |  |     private Boolean ibHighOverLimit1 = false;   // 高超限1 | 
 |  |  |     private Boolean ibHighOverLimit2 = false;   // 高超限2 | 
 |  |  |     private Boolean ibHighOverLimit3 = false;   // 高超限3 | 
 |  |  |     private Boolean ibOneExtendLeftLoad1 = false; // 一伸左侧探货1 | 
 |  |  |     private Boolean ibOneExtendLeftLoad2 = false; // 一伸左侧探货2 | 
 |  |  |     private Boolean ibOneExtendRightLoad1 = false; // 一伸右侧探货1 | 
 |  |  |     private Boolean ibOneExtendRightLoad2 = false; // 一伸右侧探货2 | 
 |  |  |     private Boolean ibTwoExtendLeftLoad1 = false; // 二伸左侧探货1 | 
 |  |  |     private Boolean ibTwoExtendLeftLoad2 = false; // 二伸左侧探货2 | 
 |  |  |     private Boolean ibTwoExtendRightLoad1 = false; // 二伸右侧探货1 | 
 |  |  |     private Boolean ibTwoExtendRightLoad2 = false; // 二伸右侧探货2 | 
 |  |  |     private Boolean ibSpeedSignal1 = false;      // 超速信号1 | 
 |  |  |     private Boolean ibSpeedSignal2 = false;      // 超速信号2 | 
 |  |  |     private Boolean ibOverweightSignal1 = false; // 超重信号1 | 
 |  |  |     private Boolean ibOverweightSignal2 = false; // 超重信号2 | 
 |  |  |     private Boolean ibRopeReleaseSignal1 = false; // 松绳信号1 | 
 |  |  |     private Boolean ibRopeReleaseSignal2 = false; // 松绳信号2 | 
 |  |  |     private Boolean ibSafetyClamp = false;       // 安全钳 | 
 |  |  |     private Boolean ibTightener = false;         // 张紧器 | 
 |  |  |     private Boolean ibSpeedLimiter = false;      // 限速器 | 
 |  |  |     private Boolean ibSafetyDoorOpen = false;    // 安全门打开 | 
 |  |  |     //------------------------------------------------------------------- | 
 |  |  |  | 
 |  |  |     public BasCrnErrorLog toSqlModelError() { | 
 |  |  |         BasCrnErrorLog basCrnErrorLog = new BasCrnErrorLog(); | 
 |  |  |  | 
 |  |  |         // 错误字段转换 | 
 |  |  |         basCrnErrorLog.setCrnNo(crnNo); | 
 |  |  |         basCrnErrorLog.setIbDriveFault(ibDriveFault ? "Y" : "N");       // 行走变频器故障 | 
 |  |  |         basCrnErrorLog.setIbSupplyFault(ibSupplyFault ? "Y" : "N");      // 提供变频器故障 | 
 |  |  |         basCrnErrorLog.setIbForkDriveFault(ibForkDriveFault ? "Y" : "N");   // 货叉变频器故障 | 
 |  |  |         basCrnErrorLog.setIbDriveCircuitFault(ibDriveCircuitFault ? "Y" : "N"); // 行走断路器故障 | 
 |  |  |         basCrnErrorLog.setIbLiftCircuitFault(ibLiftCircuitFault ? "Y" : "N"); // 提升断路器故障 | 
 |  |  |         basCrnErrorLog.setIbForkCircuitFault(ibForkCircuitFault ? "Y" : "N"); // 货叉断路器故障 | 
 |  |  |         basCrnErrorLog.setIbForwardLimit(ibForwardLimit ? "Y" : "N");     // 前进限位 | 
 |  |  |         basCrnErrorLog.setIbReverseLimit(ibReverseLimit ? "Y" : "N");     // 后退限位 | 
 |  |  |         basCrnErrorLog.setIbDriveStart(ibDriveStart ? "Y" : "N");       // 行走原点 | 
 |  |  |         basCrnErrorLog.setIbForwardBrakeSpeed(ibForwardBrakeSpeed ? "Y" : "N"); // 前进强制低速 | 
 |  |  |         basCrnErrorLog.setIbReverseBrakeSpeed(ibReverseBrakeSpeed ? "Y" : "N"); // 后退强制低速 | 
 |  |  |         basCrnErrorLog.setIbUpLimit(ibUpLimit ? "Y" : "N");          // 上升限位 | 
 |  |  |         basCrnErrorLog.setIbDownLimit(ibDownLimit ? "Y" : "N");        // 下限限位 | 
 |  |  |         basCrnErrorLog.setIbUpOrigin(ibUpOrigin ? "Y" : "N");         // 提升原点 | 
 |  |  |         basCrnErrorLog.setIbUpBrakeSpeed(ibUpBrakeSpeed ? "Y" : "N");     // 上升强制低速 | 
 |  |  |         basCrnErrorLog.setIbDownBrakeSpeed(ibDownBrakeSpeed ? "Y" : "N");   // 下降强制低速 | 
 |  |  |         basCrnErrorLog.setIbPlatformSignal(ibPlatformSignal ? "Y" : "N");   // 载货台探货 | 
 |  |  |         basCrnErrorLog.setIbForkMidSignal(ibForkMidSignal ? "Y" : "N");    // 货叉中位信号 | 
 |  |  |         basCrnErrorLog.setIbForkLeftLimit(ibForkLeftLimit ? "Y" : "N");    // 货叉左极限 | 
 |  |  |         basCrnErrorLog.setIbForkRightLimit(ibForkRightLimit ? "Y" : "N");   // 货叉右极限 | 
 |  |  |         basCrnErrorLog.setIbFrontOverLimit(ibFrontOverLimit ? "Y" : "N");   // 前超限 | 
 |  |  |         basCrnErrorLog.setIbRearOverLimit(ibRearOverLimit ? "Y" : "N");    // 后超限 | 
 |  |  |         basCrnErrorLog.setIbLeftOverLimit(ibLeftOverLimit ? "Y" : "N");    // 左超限 | 
 |  |  |         basCrnErrorLog.setIbRightOverLimit(ibRightOverLimit ? "Y" : "N");   // 右超限 | 
 |  |  |         basCrnErrorLog.setIbHighOverLimit1(ibHighOverLimit1 ? "Y" : "N");   // 高超限1 | 
 |  |  |         basCrnErrorLog.setIbHighOverLimit2(ibHighOverLimit2 ? "Y" : "N");   // 高超限2 | 
 |  |  |         basCrnErrorLog.setIbHighOverLimit3(ibHighOverLimit3 ? "Y" : "N");   // 高超限3 | 
 |  |  |         basCrnErrorLog.setIbOneExtendLeftLoad1(ibOneExtendLeftLoad1 ? "Y" : "N"); // 一伸左侧探货1 | 
 |  |  |         basCrnErrorLog.setIbOneExtendLeftLoad2(ibOneExtendLeftLoad2 ? "Y" : "N"); // 一伸左侧探货2 | 
 |  |  |         basCrnErrorLog.setIbOneExtendRightLoad1(ibOneExtendRightLoad1 ? "Y" : "N"); // 一伸右侧探货1 | 
 |  |  |         basCrnErrorLog.setIbOneExtendRightLoad2(ibOneExtendRightLoad2 ? "Y" : "N"); // 一伸右侧探货2 | 
 |  |  |         basCrnErrorLog.setIbTwoExtendLeftLoad1(ibTwoExtendLeftLoad1 ? "Y" : "N"); // 二伸左侧探货1 | 
 |  |  |         basCrnErrorLog.setIbTwoExtendLeftLoad2(ibTwoExtendLeftLoad2 ? "Y" : "N"); // 二伸左侧探货2 | 
 |  |  |         basCrnErrorLog.setIbTwoExtendRightLoad1(ibTwoExtendRightLoad1 ? "Y" : "N"); // 二伸右侧探货1 | 
 |  |  |         basCrnErrorLog.setIbTwoExtendRightLoad2(ibTwoExtendRightLoad2 ? "Y" : "N"); // 二伸右侧探货2 | 
 |  |  |         basCrnErrorLog.setIbSpeedSignal1(ibSpeedSignal1 ? "Y" : "N");      // 超速信号1 | 
 |  |  |         basCrnErrorLog.setIbSpeedSignal2(ibSpeedSignal2 ? "Y" : "N");      // 超速信号2 | 
 |  |  |         basCrnErrorLog.setIbOverweightSignal1(ibOverweightSignal1 ? "Y" : "N"); // 超重信号1 | 
 |  |  |         basCrnErrorLog.setIbOverweightSignal2(ibOverweightSignal2 ? "Y" : "N"); // 超重信号2 | 
 |  |  |         basCrnErrorLog.setIbRopeReleaseSignal1(ibRopeReleaseSignal1 ? "Y" : "N"); // 松绳信号1 | 
 |  |  |         basCrnErrorLog.setIbRopeReleaseSignal2(ibRopeReleaseSignal2 ? "Y" : "N"); // 松绳信号2 | 
 |  |  |         basCrnErrorLog.setIbSafetyClamp(ibSafetyClamp ? "Y" : "N");       // 安全钳 | 
 |  |  |         basCrnErrorLog.setIbTightener(ibTightener ? "Y" : "N");         // 张紧器 | 
 |  |  |         basCrnErrorLog.setIbSpeedLimiter(ibSpeedLimiter ? "Y" : "N");      // 限速器 | 
 |  |  |         basCrnErrorLog.setIbSafetyDoorOpen(ibSafetyDoorOpen ? "Y" : "N");    // 安全门打开 | 
 |  |  |  | 
 |  |  |         return basCrnErrorLog; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public void setMode(Short mode) { | 
 |  |  |         this.mode = mode; | 
 |  |  |         this.modeType = CrnModeType.get(mode); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setMode(CrnModeType type) { | 
 |  |  |         this.modeType = type; | 
 |  |  |         this.mode = CrnModeType.get(type).id.shortValue(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setForkPos(Short forkPos) { | 
 |  |  |         this.forkPos = forkPos; | 
 |  |  |         this.forkPosType = CrnForkPosType.get(forkPos); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setForkPos(CrnForkPosType type) { | 
 |  |  |         this.forkPosType = type; | 
 |  |  |         this.forkPos = CrnForkPosType.get(type).id.shortValue(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setLiftPos(Short liftPos) { | 
 |  |  |         this.liftPos = liftPos; | 
 |  |  |         this.liftPosType = CrnLiftPosType.get(liftPos); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setLiftPos(CrnLiftPosType type) { | 
 |  |  |         this.liftPosType = type; | 
 |  |  |         this.liftPos = CrnLiftPosType.get(type).id.shortValue(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setStatus(Short status){ | 
 |  |  |         this.status = status; | 
 |  |  | 
 |  |  |         this.status = CrnStatusType.get(type).id.shortValue(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public Short getTemp1() { | 
 |  |  |         return temp1; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setTemp1(Short temp1) { | 
 |  |  |         this.temp1 = temp1; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 最近一次入出库类型 | 
 |  |  |      *       I:入库 | 
 |  |  |      *       O:出库 | 
 |  |  |      */ | 
 |  |  |     private String lastIo = "I"; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     public BasCrnp toSqlModel(BasCrnp basCrnp){ | 
 |  |  |         if (alarm!=null) { | 
 |  |  |             basCrnp.setCrnErr(alarm.longValue()); | 
 |  |  |         } | 
 |  |  |         basCrnp.setWrkNo(taskNo.intValue()); | 
 |  |  |         return basCrnp; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setxSpeed(float xSpeed) { | 
 |  |  |         this.xSpeed = xSpeed; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setySpeed(float ySpeed) { | 
 |  |  |         this.ySpeed = ySpeed; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setzSpeed(float zSpeed) { | 
 |  |  |         this.zSpeed = zSpeed; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setxDistance(float xDistance) { | 
 |  |  |         this.xDistance = xDistance; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setyDistance(float yDistance) { | 
 |  |  |         this.yDistance = yDistance; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setxDuration(float xDuration) { | 
 |  |  |         this.xDuration = xDuration; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void setyDuration(float yDuration) { | 
 |  |  |         this.yDuration = yDuration; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } |