|
|
|
@ -4,6 +4,7 @@ import cn.estsh.i3plus.core.api.iservice.busi.ISysDictionaryService;
|
|
|
|
|
import cn.estsh.i3plus.core.api.iservice.busi.ISysFileService;
|
|
|
|
|
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
|
|
|
|
|
import cn.estsh.i3plus.platform.common.tool.StringTool;
|
|
|
|
|
import cn.estsh.i3plus.platform.common.util.FileContentTypeTool;
|
|
|
|
|
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
|
|
|
|
|
import cn.estsh.i3plus.pojo.base.bean.BaseConstWords;
|
|
|
|
|
import cn.estsh.i3plus.pojo.base.bean.ListPager;
|
|
|
|
@ -50,8 +51,8 @@ import java.util.List;
|
|
|
|
|
**/
|
|
|
|
|
@RestController
|
|
|
|
|
@Api(description = "文件资源服务")
|
|
|
|
|
@RequestMapping(PlatformConstWords.BASE_URL +"/sys-file")
|
|
|
|
|
public class SysFileController extends CoreBaseController{
|
|
|
|
|
@RequestMapping(PlatformConstWords.BASE_URL + "/sys-file")
|
|
|
|
|
public class SysFileController extends CoreBaseController {
|
|
|
|
|
public static final Logger LOGGER = LoggerFactory.getLogger(SysFileController.class);
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
@ -65,34 +66,36 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 修改文件资源
|
|
|
|
|
*
|
|
|
|
|
* @param sysFile 文件资源
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@PutMapping(value = "/update")
|
|
|
|
|
@ApiOperation(value = "修改文件资源", notes = "修改文件资源")
|
|
|
|
|
public ResultBean<SysFile> updateSysFile(SysFile sysFile){
|
|
|
|
|
public ResultBean<SysFile> updateSysFile(SysFile sysFile) {
|
|
|
|
|
try {
|
|
|
|
|
// 条件验证
|
|
|
|
|
ValidatorBean.beginValid(sysFile)
|
|
|
|
|
.notNull("fileSoftType", sysFile.getFileSoftType());
|
|
|
|
|
|
|
|
|
|
sysFileService.updateSysFile(sysFile);
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据id删除文件资源
|
|
|
|
|
*
|
|
|
|
|
* @param idStr 文件资源
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@DeleteMapping(value = "/delete/{id}")
|
|
|
|
|
@ApiOperation(value = "根据id删除文件资源", notes = "根据id删除文件资源")
|
|
|
|
|
public ResultBean deleteSysFileById(@PathVariable("id") String idStr){
|
|
|
|
|
public ResultBean deleteSysFileById(@PathVariable("id") String idStr) {
|
|
|
|
|
try {
|
|
|
|
|
startMultiService();
|
|
|
|
|
|
|
|
|
@ -106,40 +109,42 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
sysFileService.deleteSysFileById(Long.parseLong(idStr));
|
|
|
|
|
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询全部文件资源
|
|
|
|
|
*
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@GetMapping(value = "/list")
|
|
|
|
|
@ApiOperation(value = "查询全部文件资源", notes = "查询全部文件资源")
|
|
|
|
|
public ResultBean<SysFile> findSysFileAll(){
|
|
|
|
|
public ResultBean<SysFile> findSysFileAll() {
|
|
|
|
|
try {
|
|
|
|
|
List<SysFile> sysFileList = sysFileService.listSysFile();
|
|
|
|
|
return ResultBean.success("操作成功")
|
|
|
|
|
.setResultList(sysFileList)
|
|
|
|
|
.setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据id查询文件资源
|
|
|
|
|
*
|
|
|
|
|
* @param id 文件id
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@GetMapping(value = "/get/{id}")
|
|
|
|
|
@ApiOperation(value = "根据id查询文件资源", notes = "根据id查询文件资源")
|
|
|
|
|
public ResultBean<SysFile> getSysFileById(@PathVariable("id") String id){
|
|
|
|
|
public ResultBean<SysFile> getSysFileById(@PathVariable("id") String id) {
|
|
|
|
|
try {
|
|
|
|
|
ValidatorBean.checkIsNumber(id, "id必须为数字[" + id + "]");
|
|
|
|
|
|
|
|
|
@ -149,41 +154,43 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
return ResultBean.success("操作成功")
|
|
|
|
|
.setResultObject(sysFile)
|
|
|
|
|
.setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件资源复杂查询,分页,排序
|
|
|
|
|
*
|
|
|
|
|
* @param sysFile 查询条件
|
|
|
|
|
* @param pager 分页信息
|
|
|
|
|
* @param pager 分页信息
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@GetMapping(value = "/query")
|
|
|
|
|
@ApiOperation(value = "文件资源复杂查询,分页,排序", notes = "文件资源复杂查询,分页,排序")
|
|
|
|
|
public ResultBean<SysFile> querySysFileByPager(SysFile sysFile, Pager pager){
|
|
|
|
|
public ResultBean<SysFile> querySysFileByPager(SysFile sysFile, Pager pager) {
|
|
|
|
|
try {
|
|
|
|
|
ListPager sysFileListPager = sysFileService.querySysFileByPager(sysFile, pager);
|
|
|
|
|
return ResultBean.success("操作成功").setListPager(sysFileListPager).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 批量删除文件资源
|
|
|
|
|
*
|
|
|
|
|
* @param ids 文件id数组
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@DeleteMapping(value = "/batch-delete")
|
|
|
|
|
@ApiOperation(value = "批量删除文件资源", notes = "批量删除文件资源")
|
|
|
|
|
public ResultBean deleteSysFileByIds(String[] ids){
|
|
|
|
|
try{
|
|
|
|
|
public ResultBean deleteSysFileByIds(String[] ids) {
|
|
|
|
|
try {
|
|
|
|
|
if (ids.length == 0) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
@ -194,15 +201,16 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
|
|
|
|
|
sysFileService.deleteSysFileByIds(StringTool.getArrayLong(ids));
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件上传
|
|
|
|
|
*
|
|
|
|
|
* @param file 文件
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
@ -212,7 +220,7 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
try {
|
|
|
|
|
startMultiService();
|
|
|
|
|
|
|
|
|
|
if(file.isEmpty()){
|
|
|
|
|
if (file.isEmpty()) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
|
|
|
|
@ -221,26 +229,27 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean checkFileN = dictionaryService.checkFileName(file.getOriginalFilename());
|
|
|
|
|
if(!checkFileN){
|
|
|
|
|
if (!checkFileN) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_FORMAT.getCode())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s",file.getOriginalFilename())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s", file.getOriginalFilename())
|
|
|
|
|
.setErrorSolution("请到字典管理中添加文件类型")
|
|
|
|
|
.build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysFile fileDb = sysFileService.uploadFile(file);
|
|
|
|
|
return ResultBean.success("上传成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(fileDb);
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件上传至fastdfs并保存数据
|
|
|
|
|
*
|
|
|
|
|
* @param file 文件
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
@ -250,7 +259,7 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
try {
|
|
|
|
|
startMultiService();
|
|
|
|
|
|
|
|
|
|
if(file.isEmpty()){
|
|
|
|
|
if (file.isEmpty()) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
|
|
|
|
@ -259,40 +268,41 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean checkFileN = dictionaryService.checkFileName(file.getOriginalFilename());
|
|
|
|
|
if(!checkFileN){
|
|
|
|
|
if (!checkFileN) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_FORMAT.getCode())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s",file.getOriginalFilename())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s", file.getOriginalFilename())
|
|
|
|
|
.setErrorSolution("请到字典管理中添加文件类型")
|
|
|
|
|
.build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysFile fileDb = sysFileService.uploadFile(file,sysFile, AuthUtil.getSessionUser().getUserName());
|
|
|
|
|
SysFile fileDb = sysFileService.uploadFile(file, sysFile, AuthUtil.getSessionUser().getUserName());
|
|
|
|
|
return ResultBean.success("上传成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(fileDb);
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件下载
|
|
|
|
|
* @param id 文件id
|
|
|
|
|
*
|
|
|
|
|
* @param id 文件id
|
|
|
|
|
* @param response response
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@GetMapping("/download/{id}")
|
|
|
|
|
@ApiOperation(value = "文件下载", notes = "文件下载")
|
|
|
|
|
public ResultBean singleDownload(@PathVariable("id")String id, HttpServletResponse response) {
|
|
|
|
|
public void singleDownload(@PathVariable("id") String id, HttpServletResponse response) {
|
|
|
|
|
try {
|
|
|
|
|
startMultiService();
|
|
|
|
|
|
|
|
|
|
ValidatorBean.checkIsNumber(id, "文件ID不能为空");
|
|
|
|
|
|
|
|
|
|
SysFile sysFile = sysFileService.getSysFileById(Long.parseLong(id));
|
|
|
|
|
if(sysFile == null){
|
|
|
|
|
if (sysFile == null) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
|
|
|
|
@ -302,7 +312,7 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
|
|
|
|
|
InputStream fis = dfsClient.downFile(sysFile.getDfsGroupName(), sysFile.getDfsFileName());
|
|
|
|
|
|
|
|
|
|
if(fis == null){
|
|
|
|
|
if (fis == null) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
|
|
|
|
@ -312,7 +322,7 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
|
|
|
|
|
response.setContentType("application/force-download"); // 设置强制下载不打开
|
|
|
|
|
response.addHeader("Content-Disposition", "attachment;fileName=" + sysFile.getFileOriginalName()); // 设置文件名
|
|
|
|
|
response.addHeader("Content-type", "application/octet-stream"); // 设置文件名
|
|
|
|
|
response.addHeader("Content-type", FileContentTypeTool.getContentType(StringTool.getStringFileSuffix(sysFile.getFileOriginalName(), true))); // 设置文件名
|
|
|
|
|
|
|
|
|
|
BufferedInputStream bis = null;
|
|
|
|
|
try {
|
|
|
|
@ -339,22 +349,22 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
// 增加文件下载次数
|
|
|
|
|
sysFile.setDownloadNum(sysFile.getDownloadNum() + 1);
|
|
|
|
|
sysFileService.updateSysFile(sysFile);
|
|
|
|
|
return ResultBean.success("下载").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
ResultBean.fail(busExcep);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载文件资源
|
|
|
|
|
*
|
|
|
|
|
* @param sysFile 文件资源
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
|
@PostMapping(value = "/insert")
|
|
|
|
|
@ApiOperation(value = "新增文件资源", notes = "新增文件资源")
|
|
|
|
|
public ResultBean insertSysFile(@RequestBody SysFile sysFile){
|
|
|
|
|
public ResultBean insertSysFile(@RequestBody SysFile sysFile) {
|
|
|
|
|
try {
|
|
|
|
|
startMultiService();
|
|
|
|
|
|
|
|
|
@ -368,11 +378,11 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
// 文件类型验证
|
|
|
|
|
SysDictionary dictionary = dictionaryService.getSysDictionaryByParentCodeAndCode(BaseConstWords.DICTIONARY_FILE_TYPE,
|
|
|
|
|
StringTool.getStringFileSuffix(sysFile.getFileOriginalName(), false));
|
|
|
|
|
if(dictionary == null){
|
|
|
|
|
if (dictionary == null) {
|
|
|
|
|
throw ImppExceptionBuilder.newInstance()
|
|
|
|
|
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
|
|
|
|
|
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_FORMAT.getCode())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s",sysFile.getFileOriginalName())
|
|
|
|
|
.setErrorDetail("文件格式不支持 %s", sysFile.getFileOriginalName())
|
|
|
|
|
.setErrorSolution("请到字典管理中添加文件类型")
|
|
|
|
|
.build();
|
|
|
|
|
}
|
|
|
|
@ -382,16 +392,17 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
sysFile.setFileTypeName(dictionary.getName());
|
|
|
|
|
|
|
|
|
|
sysFile = sysFileService.insertSysFile(sysFile);
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysFile);
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysFile);
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据文件代码查询文件信息
|
|
|
|
|
*
|
|
|
|
|
* @param fileCode 文件代码
|
|
|
|
|
* @return 处理结果
|
|
|
|
|
*/
|
|
|
|
@ -404,10 +415,10 @@ public class SysFileController extends CoreBaseController{
|
|
|
|
|
SysFile sysFile = sysFileService.getSysFileByFileCode(fileCode);
|
|
|
|
|
ValidatorBean.checkNotNull(sysFile, "文件信息不存在");
|
|
|
|
|
|
|
|
|
|
return ResultBean.success().setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysFile);
|
|
|
|
|
}catch(ImppBusiException busExcep){
|
|
|
|
|
return ResultBean.success().setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(sysFile);
|
|
|
|
|
} catch (ImppBusiException busExcep) {
|
|
|
|
|
return ResultBean.fail(busExcep);
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|