|
|
|
@ -438,6 +438,7 @@ public class WmsHqlPack {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
|
|
|
|
|
//查询参数封装
|
|
|
|
|
//DdlPreparedPack.getStringLikerPack(wmsLocatePart.getLocateType().toString(), "locateType", result);
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsLocatePart.getLocateNo(), "locateNo", result);
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsLocatePart.getPartNo(), "partNo", result);
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsLocatePart.getPartNameRdd(), "partNameRdd", result);
|
|
|
|
@ -858,7 +859,57 @@ public class WmsHqlPack {
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 业务:库存表报查询封装
|
|
|
|
|
*
|
|
|
|
|
* @param wmsStockQuan
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String packWmsStoreQuanForReport(WmsStockQuan wmsStockQuan) {
|
|
|
|
|
|
|
|
|
|
StringBuffer findWhere = new StringBuffer();
|
|
|
|
|
HqlPack.getStringEqualPack(wmsStockQuan.getWhNo(), "whNo", findWhere);
|
|
|
|
|
HqlPack.getStringEqualPack(wmsStockQuan.getProdCfgTypeCode(), "prodCfgTypeCode", findWhere);
|
|
|
|
|
HqlPack.getStringEqualPack(wmsStockQuan.getLocateNo(), "locateNo", findWhere);
|
|
|
|
|
if(wmsStockQuan.getZoneNo() != null){
|
|
|
|
|
HqlPack.getInPack(StringUtils.join(new ArrayList<String>(Arrays.asList(wmsStockQuan.getZoneNo().split(","))),","),"",findWhere);
|
|
|
|
|
//DdlPreparedPack.getInPackArray(wmsStockQuan.getZoneNo().split(","), "zoneNo", result);
|
|
|
|
|
}
|
|
|
|
|
if(wmsStockQuan.getPartNo() != null){
|
|
|
|
|
HqlPack.getInPack(StringUtils.join(new ArrayList<String>(Arrays.asList(wmsStockQuan.getPartNo().split(","))),","),"partNo",findWhere);
|
|
|
|
|
}
|
|
|
|
|
if(!wmsStockQuan.getIncludeZeroStock()){
|
|
|
|
|
//含0库存显示,默认为否
|
|
|
|
|
//自定义条件,各汇总数量相加。为否时添加>0的条件判断
|
|
|
|
|
findWhere.append(" and (qty + failQty + holdQty + qcQty + rinQty + freezeQty + consignQty + lockQty) > 0 ");
|
|
|
|
|
}
|
|
|
|
|
return findWhere.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static DdlPackBean packWmsStoreQuanForReport1(WmsStockQuan wmsStockQuan) {
|
|
|
|
|
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
//查询参数封装
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getWhNo(), "whNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getProdCfgTypeCode(), "prodCfgTypeCode", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getLocateNo(), "locateNo", result);
|
|
|
|
|
|
|
|
|
|
if(wmsStockQuan.getZoneNo() != null){
|
|
|
|
|
DdlPreparedPack.getInPackList(Arrays.asList(wmsStockQuan.getZoneNo().split(",")), "zoneNo", result);
|
|
|
|
|
}
|
|
|
|
|
if(wmsStockQuan.getPartNo() != null){
|
|
|
|
|
DdlPreparedPack.getInPackList(Arrays.asList(wmsStockQuan.getPartNo().split(",")), "partNo", result);
|
|
|
|
|
}
|
|
|
|
|
if(!wmsStockQuan.getIncludeZeroStock()){
|
|
|
|
|
//含0库存显示,默认为否
|
|
|
|
|
//自定义条件,各汇总数量相加。为否时添加>0的条件判断
|
|
|
|
|
result.setWhereAppend(result.getWhereAppend()+" and (qty + failQty + holdQty + qcQty + rinQty + freezeQty + consignQty + lockQty) > 0 ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getStringBuilderPack(wmsStockQuan, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 业务:物料包装查询封装
|
|
|
|
|
*
|
|
|
|
@ -1384,7 +1435,7 @@ public class WmsHqlPack {
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(dataAuth.getOrganizeCode(),"organizeCode",result);
|
|
|
|
|
// String data = String.join(",", roleIds);
|
|
|
|
|
DdlPreparedPack.getInPackList(roleIds, "roleCode", result);
|
|
|
|
|
getStringBuilderPack(new WmsDataAuth(), result);
|
|
|
|
|
getStringBuilderPack(dataAuth, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1409,31 +1460,31 @@ public class WmsHqlPack {
|
|
|
|
|
String data = String.join(",", vList);
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(data)) {
|
|
|
|
|
|
|
|
|
|
List<Map> mapList = JSONObject.parseArray(data, Map.class);
|
|
|
|
|
|
|
|
|
|
if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.WAREHOUSE.getValue() + "", key)) {
|
|
|
|
|
|
|
|
|
|
packMutilConditionHql(mapList, "WH_CODE", "destWhNo", result);
|
|
|
|
|
|
|
|
|
|
} else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.LOCATE.getValue() + "", key)) {
|
|
|
|
|
|
|
|
|
|
packMutilConditionHql(mapList, "LOCATE_NO", "destLocateNo", result);
|
|
|
|
|
|
|
|
|
|
} else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.ZONE.getValue() + "", key)) {
|
|
|
|
|
|
|
|
|
|
packMutilConditionHql(mapList, "ZONE_CODE", "destZoneNo", result);
|
|
|
|
|
|
|
|
|
|
} else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.MATERIAL.getValue() + "", key)) {
|
|
|
|
|
|
|
|
|
|
packMutilConditionHql(mapList, "PART_NO", "partNo", result);
|
|
|
|
|
}
|
|
|
|
|
DdlPreparedPack.getInPackList(cyclicTraversal(mapList,"WH_CODE"), "destWhNo", result);
|
|
|
|
|
//packMutilConditionHql(mapList, "WH_CODE", "destWhNo", result);
|
|
|
|
|
}/* else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.LOCATE.getValue() + "", key)) {
|
|
|
|
|
DdlPreparedPack.getInPackList(cyclicTraversal(mapList,"LOCATE_NO"), "destLocateNo", result);
|
|
|
|
|
//packMutilConditionHql(mapList, "LOCATE_NO", "destLocateNo", result);
|
|
|
|
|
}*/ else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.ZONE.getValue() + "", key)) {
|
|
|
|
|
DdlPreparedPack.getInPackList(cyclicTraversal(mapList,"ZONE_CODE"), "destZoneNo", result);
|
|
|
|
|
//packMutilConditionHql(mapList, "ZONE_CODE", "destZoneNo", result);
|
|
|
|
|
} /*else if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.MATERIAL.getValue() + "", key)) {
|
|
|
|
|
DdlPreparedPack.getInPackList(cyclicTraversal(mapList,"PART_NO"), "partNo", result);
|
|
|
|
|
//packMutilConditionHql(mapList, "PART_NO", "partNo", result);
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String hqlString = " and ( 1=1 " + result.getPackedHql() + ") ";
|
|
|
|
|
//转换封装后的hql
|
|
|
|
|
/*String packedHql = result.getPackedHql();
|
|
|
|
|
if(packedHql.startsWith(" or")){
|
|
|
|
|
packedHql = " and (" + packedHql.substring(3,packedHql.length()) + ") ";
|
|
|
|
|
System.out.println(packedHql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.setWhereAppend(hqlString);
|
|
|
|
|
result.setWhereAppend(packedHql);*/
|
|
|
|
|
// 通用数据拼接
|
|
|
|
|
WmsDataAuth wmsDataAuth = new WmsDataAuth();
|
|
|
|
|
wmsDataAuth.setOrganizeCode(organizeCode);
|
|
|
|
@ -1442,20 +1493,36 @@ public class WmsHqlPack {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 把 List<Map> 中的一组数据重新封装到List<String>中
|
|
|
|
|
* @param mapList
|
|
|
|
|
* @param keyName
|
|
|
|
|
*/
|
|
|
|
|
private static List<String> cyclicTraversal(List<Map> mapList,String keyName) {
|
|
|
|
|
List<String> list = new ArrayList<String>();
|
|
|
|
|
for(int i=0;i<mapList.size();i++){
|
|
|
|
|
Map<String,String> map = mapList.get(i);
|
|
|
|
|
list.add(map.get(keyName));
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 把 List<Map> 中的一组查询条件封装成 HQL
|
|
|
|
|
* @param mapList
|
|
|
|
|
* @param keyName
|
|
|
|
|
* @param columnName
|
|
|
|
|
* @param packBean
|
|
|
|
|
*/
|
|
|
|
|
private static void packMutilConditionHql(List<Map> mapList, String keyName,
|
|
|
|
|
String columnName, DdlPackBean packBean) {
|
|
|
|
|
Integer index = 1;
|
|
|
|
|
|
|
|
|
|
private static void packMutilConditionHql(List<Map> mapList, String keyName,String columnName, DdlPackBean packBean) {
|
|
|
|
|
int index = 1;
|
|
|
|
|
String columnParam = null;
|
|
|
|
|
for (Map item : mapList) {
|
|
|
|
|
packBean.addColumnQuery(columnName," or model." +
|
|
|
|
|
columnName + " = :m_" + columnName + (index++).toString(),
|
|
|
|
|
columnParam = columnName + String.valueOf(index);
|
|
|
|
|
packBean.addColumnQuery(columnParam,
|
|
|
|
|
" or model." + columnName + " = :m_" + columnParam,
|
|
|
|
|
item.get(keyName).toString());
|
|
|
|
|
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1466,8 +1533,33 @@ public class WmsHqlPack {
|
|
|
|
|
* @param orderList
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlAndIn(WmsTaskInfo bean, String columnName, List<String> orderList) {
|
|
|
|
|
public static DdlPackBean packHqlAndIn(WmsTaskInfo bean, String columnName, List<String> orderList,Map<String, List<WmsDataAuth>> groupDataAuth) {
|
|
|
|
|
DdlPackBean packBean = new DdlPackBean();
|
|
|
|
|
Set<Map.Entry<String, List<WmsDataAuth>>> entries = groupDataAuth.entrySet();
|
|
|
|
|
//拼sql
|
|
|
|
|
entries.stream().filter(o -> !Strings.isNullOrEmpty(o.getKey()));
|
|
|
|
|
for (Map.Entry<String, List<WmsDataAuth>> map : entries) {
|
|
|
|
|
String key = map.getKey();
|
|
|
|
|
List<WmsDataAuth> valueList = map.getValue();
|
|
|
|
|
List<String> vList = valueList.stream().map(x -> x.getDataObjValue()).collect(Collectors.toList());
|
|
|
|
|
String data = String.join(",", vList);
|
|
|
|
|
if (StringUtils.isNotBlank(data)) {
|
|
|
|
|
List<Map> mapList = JSONObject.parseArray(data, Map.class);
|
|
|
|
|
if (StringUtils.equalsIgnoreCase(WmsEnumUtil.DATA_OBJ_TYPE.TRANS_TYPE.getValue() + "", key)) {
|
|
|
|
|
DdlPreparedPack.getInPackList(cyclicTraversal(mapList,"TRANS_TYPE_CODE"), "transTypeCode", packBean);
|
|
|
|
|
//packMutilConditionHql(mapList, "TRANS_TYPE_CODE", "transTypeCode", packBean);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//转换封装后的hql
|
|
|
|
|
/*String packedHql = packBean.getPackedHql();
|
|
|
|
|
if(packedHql.startsWith(" or")){
|
|
|
|
|
packedHql = " and (" + packedHql.substring(3,packedHql.length()) + ") ";
|
|
|
|
|
System.out.println(packedHql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
packBean.setWhereAppend(packedHql);*/
|
|
|
|
|
DdlPreparedPack.getInPackList(orderList, columnName, packBean);
|
|
|
|
|
DdlPreparedPack.getStringRightLikerPack(bean.getOrderNo(), "orderNo", packBean);
|
|
|
|
|
DdlPreparedPack.getNumNOEqualPack(bean.getTaskStatus(), "taskStatus", packBean);
|
|
|
|
@ -1694,6 +1786,41 @@ public class WmsHqlPack {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 库存条码 查询条件封装
|
|
|
|
|
*
|
|
|
|
|
* @param wmsStockSn
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsStockSnReport(WmsStockSn wmsStockSn) {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockSn.getWhNo(), "whNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockSn.getZoneNo(), "zoneNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockSn.getPartNo(), "partNo", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsStockSn.getSnStatus(), "snStatus", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsStockSn.getQcStatus(), "qcStatus", result);
|
|
|
|
|
DdlPreparedPack.getStringNotNullPack("locateNo", result);
|
|
|
|
|
result.setWhereAppend(result.getWhereAppend()+" and locateNo != ''");
|
|
|
|
|
|
|
|
|
|
getStringBuilderPack(wmsStockSn, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static DdlPackBean packWmsStoreQuanForLocateReport(WmsStockQuan wmsStockQuan) {
|
|
|
|
|
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
//查询参数封装
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getWhNo(), "whNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getPartNo(), "partNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsStockQuan.getZoneNo(), "zoneNo", result);
|
|
|
|
|
result.setWhereAppend(result.getWhereAppend()+" and (qty + failQty + holdQty + qcQty + rinQty + freezeQty + consignQty + lockQty) > 0 ");
|
|
|
|
|
getStringBuilderPack(wmsStockQuan, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 线边库物料信息 分页查询
|
|
|
|
@ -1711,6 +1838,28 @@ public class WmsHqlPack {
|
|
|
|
|
getStringBuilderPack(wmsLineLocatePart, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 任务数据来源唯一校验
|
|
|
|
|
*
|
|
|
|
|
* @param wmsTaskSrc
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsTaskSrcIsUniq(WmsTaskSrc wmsTaskSrc) {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
|
|
|
|
|
//查询参数封装
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsTaskSrc.getOrganizeCode(), "organizeCode", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsTaskSrc.getOpTypeCode(), "opTypeCode", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsTaskSrc.getDataSrc(), "dataSrc", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsTaskSrc.getBusiType(), "busiType", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsTaskSrc.getPriority(), "priority", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsTaskSrc.getIsSn(), "isSn", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsTaskSrc.getIsOneStep(), "isOneStep", result);
|
|
|
|
|
getStringBuilderPack(wmsTaskSrc, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 任务数据来源 分页查询
|
|
|
|
|
*
|
|
|
|
@ -1725,6 +1874,7 @@ public class WmsHqlPack {
|
|
|
|
|
getStringBuilderPack(wmsTaskSrc, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 供应商零件 分页查询
|
|
|
|
|
*
|
|
|
|
@ -1739,4 +1889,72 @@ public class WmsHqlPack {
|
|
|
|
|
getStringBuilderPack(wmsVendorPart, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 主数据信息 分页查询
|
|
|
|
|
*
|
|
|
|
|
* @param wmsProdCfgType
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsProdCfgType(WmsProdCfgType wmsProdCfgType) {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
//查询参数封装
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsProdCfgType.getProdCfgTypeName(), "prodCfgTypeName", result);
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsProdCfgType.getProdCfgTypeCode(), "prodCfgTypeCode", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsProdCfgType.getIsValid(),"isValid",result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),"isDeleted",result);
|
|
|
|
|
// getStringBuilderPack(wmsProdCfgType, result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 盘点范围 条件封装
|
|
|
|
|
*
|
|
|
|
|
* @param wmsCSRange
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsCSRange(WmsCSRange wmsCSRange) {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsCSRange.getOrderNo(), "orderNo", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsCSRange.getPartNo(), "partNo", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsCSRange.getLocateNo(), "locateNo", result);
|
|
|
|
|
DdlPreparedPack.getStringLikerPack(wmsCSRange.getZoneNo(), "zoneNo", result);
|
|
|
|
|
|
|
|
|
|
getStringBuilderPack(wmsCSRange, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 物料 条件封装
|
|
|
|
|
*
|
|
|
|
|
* @param wmsPart
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsPartByList(WmsPart wmsPart,List<WmsStockSn> partNoList) {
|
|
|
|
|
|
|
|
|
|
DdlPackBean packBean = new DdlPackBean();
|
|
|
|
|
DdlPreparedPack.getInPackList(partNoList.stream().map(part -> part.getPartNo()).collect(Collectors.toList()),"partNo",packBean);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsPart.getOrganizeCode(),"organizeCode",packBean);
|
|
|
|
|
getStringBuilderPack(wmsPart, packBean);
|
|
|
|
|
|
|
|
|
|
return packBean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 单位定义
|
|
|
|
|
*
|
|
|
|
|
* @param wmsUnit
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static DdlPackBean packHqlWmsUnit(WmsUnit wmsUnit) {
|
|
|
|
|
DdlPackBean result = new DdlPackBean();
|
|
|
|
|
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsUnit.getUnitCode(), "unitCode", result);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(wmsUnit.getUnitName(), "unitName", result);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(wmsUnit.getUnitPrecision(), "unitPrecision", result);
|
|
|
|
|
getStringBuilderPack(wmsUnit, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|