Compare commits

..

4 Commits

Author SHA1 Message Date
ythong
ca74624838 관리자 지방문화원 등록/수정 화면 지역 '전남광주' 통합 표기
지역 select에서 광주/전남 개별 옵션을 제거하고 서울 다음에 '전남광주'
통합 옵션(값=광주코드,전남코드)을 배치. 통합 옵션 선택 시 실제 저장할
단일 AREA_CODE는 선택한 구.군 코드 앞 2자리에서 유추(fnResolveAreaCode)해
hidden #areaCode에 반영. 수정화면 진입 시 기존 지역이 광주/전남이면 통합
옵션을 자동 선택하고, 저장 시 지역/구.군 조합 검증을 추가함.

- 운영(210.181.197.152 webapps/kccf) 개별 JSP 반영 완료
  (백업: lclttRegist.jsp.bak_20260709_165911, 동일 폴더)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 17:03:46 +09:00
ythong
a7bb871a74 지방문화원 찾기 구.군 '전남광주' 통합 조회 항목 추가
fnAreaSubCodeList에서 시.도 코드가 콤마로 조합된 경우(전남광주),
구.군 목록 최상단에 value="" '전남광주' 옵션을 추가해 구.군 필터
없이 광주+전남 문화원을 통합 조회하도록 함.

- 운영(210.181.197.152 webapps/kccf) 개별 JSP 반영 완료
  (백업: listLclttFind.jsp.bak_20260709_124900, 동일 폴더)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 12:50:27 +09:00
ythong
824fc3eb1b chore: .gitignore에 DB 덤프(*.dmp) 및 백업.txt 추가
- 20260616_full.dmp 등 Oracle expdp 풀덤프가 추적되던 문제 방지
- 백업.txt(덤프 명령 DBA 메모)도 저장소 제외

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 12:29:23 +09:00
ythong
5ea8d4fdb6 관리자 지방문화원 등록/수정에 구.군(AREA_SUB_CODE) 선택 기능 추가
- lclttRegist.jsp: 시.도 select 옆에 구.군 select 추가, /lcltt/selectAreaSubCodeListAjax.do 연동,
  필수값 검증, 주소검색 콜백에서 sggNm 일치 구.군 자동선택
- LclttServiceImpl.java: insert/updateLcltt에서 폼의 areaSubCode 명시값을 우선 사용하고
  비어있을 때만 주소 텍스트 추정을 setAreaSubCodeByAdres() 폴백으로 분리, null/배열 방어코드 추가
  (기존 주소파싱 추정의 ArrayIndexOutOfBounds/NPE로 저장 실패하던 "시스템 에러" 해소)
- LclttDAO.xml: selectLclttDetail에 A.AREA_SUB_CODE 추가(수정화면 진입 시 기존값 표시)

운영(webapps/kccf)에 개별 파일(class/jsp/xml)로 반영 + Tomcat 재시작 완료.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 18:04:28 +09:00
6 changed files with 187 additions and 34 deletions

6
.gitignore vendored
View File

@ -13,6 +13,12 @@ target/
*.mov *.mov
*.wmv *.wmv
# DB dumps (never commit)
*.dmp
# DBA 작업 메모 (덤프 명령 기록)
/백업.txt
# Sample large images (not real content) # Sample large images (not real content)
**/sample/sample-multimedia*.jpg **/sample/sample-multimedia*.jpg

View File

@ -31,3 +31,12 @@
| 날짜 | 변경 내용 | 대상 | 사유 | | 날짜 | 변경 내용 | 대상 | 사유 |
|------|----------|------|------| |------|----------|------|------|
| 2026-06-15 | 하네스 초기 구성 | 전체 | KCCF 개발 자동화 | | 2026-06-15 | 하네스 초기 구성 | 전체 | KCCF 개발 자동화 |
| 2026-07-08 | 지방문화원 시.도 검색에 '전남광주' 통합 버튼 추가 (광주/전남 버튼 제거, 서울-부산 사이 배치, 클릭 시 두 지역 통합 검색) | `kccf.lcltt` - listLcltt.jsp(관리자), listLclttFind.jsp(공개 찾기), LclttDAO.xml(selectLclttList, selectLclttFindList - AREA_CODE 다중값 매칭을 INSTR 방식으로 변경) | 사용자 요청(광주/전남 조직 통합 반영). 매퍼 XML 변경은 Tomcat 재시작 후 적용됨 |
| 2026-07-08 | 공개 찾기 화면에서 '전남광주' 선택 시 구.군 드롭다운이 비는 문제 수정 | `kccf.lcltt` - LclttDAO.xml(selectAreaSubCodeListAjax - ADIT_ATRB_INFO_VALUE1 매칭을 INSTR 방식으로 변경) | 병합 코드("GJ,JN")가 단일값 매칭에 걸리지 않던 문제. Tomcat 재시작 필요 |
| 2026-07-08 | 관리자 지방문화원 상세(lclttRegist.jsp) 저장 시 "시스템 에러"(egovError.jsp) 발생 수정 | `kccf.lcltt` - LclttServiceImpl.java(insertLcltt/updateLcltt - 주소1 텍스트로 구.군을 추정하는 로직에서 배열 인덱스/null 체크 없이 접근하던 부분을 setAreaSubCodeByAdres()로 분리, 방어 코드 추가) | 폼에 구.군(AREA_SUB_CODE) 선택 UI가 없어 서비스단이 주소 문자열 파싱으로 대신 추정하는데, 매칭 실패/이상 데이터 시 ArrayIndexOutOfBoundsException 또는 NullPointerException이 발생해 저장이 실패하던 문제. 매칭 실패 시 예외 대신 조용히 건너뛰도록 수정. WAS 재시작(재빌드) 필요 |
| 2026-07-08 | 관리자 지방문화원 등록/수정 화면에 구.군(AREA_SUB_CODE) 선택 드롭다운 추가 (근본 개선) | `kccf.lcltt` - lclttRegist.jsp(지역 select 옆에 구.군 select 추가, /lcltt/selectAreaSubCodeListAjax.do 연동, 필수값 검증 추가, 주소검색 팝업 콜백에서 sggNm 일치 시 자동 선택), LclttDAO.xml(selectLclttDetail - A.AREA_SUB_CODE 컬럼 추가로 수정화면 진입 시 기존 값 표시), LclttServiceImpl.java(insertLcltt/updateLcltt - 폼에서 areaSubCode가 명시적으로 전달되면 이를 우선 사용하고, 비어있을 때만 주소 텍스트 추정 로직을 폴백으로 사용) | 주소 텍스트 파싱으로 구.군을 추정하는 기존 방식이 근본적으로 취약(오탐/미스매치로 AREA_SUB_CODE가 계속 null 저장됨)하여, listLclttFind.jsp와 동일한 지역-구.군 연동 드롭다운 패턴으로 명시적 선택이 가능하도록 개선. WAS 재시작(재빌드) 필요 |
| 2026-07-08 | 지방문화원 구.군 선택 기능 - Tomcat 배포 디렉토리에 개별 파일 반영 (WAR 재배포 없이 빌드/배포) | `C:\apache-tomcat-9.0.79-windows-x64\apache-tomcat-9.0.79\webapps\ROOT` - WEB-INF/classes/kccf/lcltt/service/impl/LclttServiceImpl.class(WEB-INF/lib 클래스패스로 javac -source/-target 8 직접 컴파일해 교체, .java 소스도 갱신), WEB-INF/jsp/mng/lcltt/lclttRegist.jsp(교체), WEB-INF/classes/egovframework/mapper/kccf/lcltt/LclttDAO.xml(selectLclttDetail에 A.AREA_SUB_CODE 추가) | 사용자 요청: war로 통째로 푸는 것 금지, 변경된 파일만 개별 반영. Maven/네트워크 접근 없이 WEB-INF/lib 기존 jar를 클래스패스로 사용해 컴파일. Tomcat 재시작 필요 |
| 2026-07-09 | 공개 찾기 화면 구.군 드롭다운에 '전남광주'(통합 전체) 항목 추가 | `kccf.lcltt` - listLclttFind.jsp(fnAreaSubCodeList - 시.도 코드가 콤마로 조합된 경우, 구.군 목록 최상단에 value="" '전남광주' 옵션을 추가해 선택 시 구.군 필터 없이 광주+전남 통합 조회) | 사용자 요청: 시.도에서 '전남광주' 선택 시 구.군에도 광주/전남을 한번에 전체 조회하는 항목이 필요. 기존엔 '광주광역시'만 기본 선택되어 전남 문화원이 누락됐음. JSP만 변경되어 재컴파일 불요(Tomcat이 JSP 변경 자동 반영, 캐싱 설정에 따라 재배포 필요할 수 있음) |
| 2026-07-09 | 위 '전남광주' 구.군 항목 추가 - Tomcat 배포 디렉토리 JSP 개별 반영 | `C:\apache-tomcat-9.0.79-windows-x64\apache-tomcat-9.0.79\webapps\ROOT\WEB-INF\jsp\kccf\lcltt\listLclttFind.jsp` - fnAreaSubCodeList에 동일 로직 적용 | 사용자 요청: WAR 재배포 없이 변경 JSP만 반영. 단, 배포본의 `$(document).ready` 초기화 로직(pageNo 없이 진입 시 기본 '서울' 지역 선택하는 uniq/SU 처리)이 소스 리포지토리(src/main/webapp)에는 없어 배포본과 소스가 이미 어긋나 있었음 — 이번 반영은 배포본의 기존 코드는 그대로 두고 fnAreaSubCodeList 부분만 동일하게 수정함. 소스 동기화 필요 여부는 별도 확인 요망 |
| 2026-07-09 | 위 '전남광주' 구.군 항목 반영 확인을 위한 Tomcat 강제 재기동 및 동작 검증 | `C:\apache-tomcat-9.0.79-windows-x64\apache-tomcat-9.0.79` - shutdown.bat/startup.bat 정상 실행에도 JSP 컴파일 캐시(work 디렉토리)가 갱신되지 않고 두 번째 기동이 응답 없이 멈추는 문제 발생 → PowerShell(Stop-Process, commandline에 'catalina' 포함된 java.exe 대상)로 강제 종료 후 재기동하여 정상화. `http://localhost:8080/lcltt/lclttFindPage.do?searchAreaCode=GJ,JN`(구.군 값 비움)로 직접 요청해 광주+전남 통합 29건이 정상 조회됨을 확인(전남 소속인 목포문화원·여수문화원 포함) | 사용자가 재시작/새로고침 후에도 화면에 '전남광주' 항목이 안 보인다고 보고. 검증용으로 만든 임시 파일(force_kill_tomcat.bat, open_test_page.url, open_test_page2.url)은 bin 폴더에 정리 못 하고 남아있음 - 실행에는 무해하나 추후 수동 삭제 필요 |
| 2026-07-09 | 소스 저장소(`C:\Users\URP2026\Desktop\source_new\kccf`) git 커밋 시도 - 보류 | `.git/index.lock` | `listLclttFind.jsp`, `CLAUDE.md` 두 파일만 stage해서 커밋하려 했으나 `.git/index.lock`이 계속 존재해 `git add`가 반복 실패(재시도 5회 포함). 사용자가 lock 파일 강제 삭제는 거부함 - VS Code 등 다른 Git 클라이언트가 저장소를 물고 있는지 확인 필요. 참고로 저장소 전체는 CRLF/LF 줄바꿈 차이로 무관한 파일 2,361개가 수정된 것처럼 표시되는 상태(`git diff -w`로 보면 우리가 만진 2개 파일만 실제 변경분이 있음) |

View File

@ -30,18 +30,10 @@ public class LclttServiceImpl implements LclttService{
@Override @Override
public int insertLcltt(LclttVO vo) { public int insertLcltt(LclttVO vo) {
String[] adresArray = vo.getAdres1().split("\\s"); if(vo.getAreaSubCode() == null || vo.getAreaSubCode().trim().isEmpty()) {
setAreaSubCodeByAdres(vo);
CmmDetailCodeVO cmmDetailCodeVO = new CmmDetailCodeVO();
cmmDetailCodeVO.setAditAtrbInfoValue1(vo.getAreaCode());
List<CmmDetailCodeVO> codeList = lclttDAO.selectAreaSubCodeListAjax(cmmDetailCodeVO);
for(int i = 0; i < codeList.size(); i++) {
if(codeList.get(i).getDetailCodeNm().equals(adresArray[1])) {
vo.setAreaSubCode(codeList.get(i).getDetailCode());
}
} }
return lclttDAO.insertLcltt(vo); return lclttDAO.insertLcltt(vo);
} }
@ -52,20 +44,46 @@ public class LclttServiceImpl implements LclttService{
@Override @Override
public int updateLcltt(LclttVO vo) { public int updateLcltt(LclttVO vo) {
if(vo.getAreaSubCode() == null || vo.getAreaSubCode().trim().isEmpty()) {
String[] adresArray = vo.getAdres1().split("\\s"); setAreaSubCodeByAdres(vo);
}
return lclttDAO.updateLcltt(vo);
}
/**
* 등록/수정 화면에서 .(areaSubCode) 명시적으로 전달되지 않은 경우에 한해
* 주소1(adres1) 번째 단어(.군명 추정) AREA_SUB_CODE 목록과 매칭하여
* vo에 areaSubCode를 세팅하는 하위 호환용 폴백 로직이다.
* 예외 없이 매칭 실패 조용히 건너뛴다.
*/
private void setAreaSubCodeByAdres(LclttVO vo) {
if(vo.getAdres1() == null || vo.getAdres1().trim().isEmpty()) {
return;
}
String[] adresArray = vo.getAdres1().trim().split("\\s+");
if(adresArray.length < 2) {
return;
}
String adresGuGun = adresArray[1];
CmmDetailCodeVO cmmDetailCodeVO = new CmmDetailCodeVO(); CmmDetailCodeVO cmmDetailCodeVO = new CmmDetailCodeVO();
cmmDetailCodeVO.setAditAtrbInfoValue1(vo.getAreaCode()); cmmDetailCodeVO.setAditAtrbInfoValue1(vo.getAreaCode());
List<CmmDetailCodeVO> codeList = lclttDAO.selectAreaSubCodeListAjax(cmmDetailCodeVO); List<CmmDetailCodeVO> codeList = lclttDAO.selectAreaSubCodeListAjax(cmmDetailCodeVO);
if(codeList == null) {
return;
}
for(int i = 0; i < codeList.size(); i++) { for(int i = 0; i < codeList.size(); i++) {
if(codeList.get(i).getDetailCodeNm().equals(adresArray[1])) { if(adresGuGun.equals(codeList.get(i).getDetailCodeNm())) {
vo.setAreaSubCode(codeList.get(i).getDetailCode()); vo.setAreaSubCode(codeList.get(i).getDetailCode());
break;
} }
} }
return lclttDAO.updateLcltt(vo);
} }
@Override @Override

View File

@ -101,6 +101,7 @@
A.LCLTT_ID , A.LCLTT_ID ,
A.LCLTT_NM , A.LCLTT_NM ,
A.AREA_CODE , A.AREA_CODE ,
A.AREA_SUB_CODE ,
A.ADRES1 , A.ADRES1 ,
A.ADRES2 , A.ADRES2 ,
A.ADRES1 || ' ' || A.ADRES2 AS ADRES , A.ADRES1 || ' ' || A.ADRES2 AS ADRES ,

View File

@ -258,11 +258,15 @@ function fnAreaSubCodeList(areaCode){
success: function(data){ success: function(data){
$("#searchAreaSubCode option").remove(); $("#searchAreaSubCode option").remove();
if(areaCode != null && areaCode != ''){ if(areaCode != null && areaCode != ''){
<%-- 전남광주 통합 검색(시.도 코드가 콤마로 여러 개 조합된 경우)일 때, 광주/전남 전체를 한번에 조회하는 '전남광주' 항목을 최상단에 추가 --%>
if(areaCode.indexOf(',') > -1){
$('#searchAreaSubCode').append('<option value="">전남광주</option>');
}
for(var i=0; i<data.areaSubCodeList.length; i++){ for(var i=0; i<data.areaSubCodeList.length; i++){
$('#searchAreaSubCode').append('<option value="'+ data.areaSubCodeList[i].detailCode +'">'+ data.areaSubCodeList[i].detailCodeNm +'</option>'); $('#searchAreaSubCode').append('<option value="'+ data.areaSubCodeList[i].detailCode +'">'+ data.areaSubCodeList[i].detailCodeNm +'</option>');
} }
}else{ }else{
$('#searchAreaSubCode').append('<option value="">전체</option>'); $('#searchAreaSubCode').append('<option value="">전체</option>');
for(var i=0; i<data.areaSubCodeList.length; i++){ for(var i=0; i<data.areaSubCodeList.length; i++){

View File

@ -40,11 +40,35 @@
<td> <td>
<div class="row-df"> <div class="row-df">
<input type="hidden" id="hiddenAreaCode" name="hiddenAreaCode" value="${lclttVO.areaCode }" /> <input type="hidden" id="hiddenAreaCode" name="hiddenAreaCode" value="${lclttVO.areaCode }" />
<select class="form-control form-control-sm" id="areaCode" name="areaCode" /> <input type="hidden" id="areaCode" name="areaCode" value="${lclttVO.areaCode }" />
<%-- 광주, 전남 통합: 두 지역 코드 미리 조회 --%>
<c:set var="gwangjuCode" value="" />
<c:set var="jeonnamCode" value="" />
<c:forEach items="${areaCodeList}" var="areaCodeItem">
<c:if test="${areaCodeItem.aditAtrbInfoValue1 == '광주'}"><c:set var="gwangjuCode" value="${areaCodeItem.detailCode}" /></c:if>
<c:if test="${areaCodeItem.aditAtrbInfoValue1 == '전남'}"><c:set var="jeonnamCode" value="${areaCodeItem.detailCode}" /></c:if>
</c:forEach>
<select class="form-control form-control-sm" id="areaCodeSel">
<option value="">전체</option> <option value="">전체</option>
<%-- 광주, 전남 개별 옵션은 없애고, '전남광주' 통합 옵션을 서울-부산 사이에 배치 --%>
<c:forEach items="${areaCodeList}" var="areaCodeList"> <c:forEach items="${areaCodeList}" var="areaCodeList">
<option value="${areaCodeList.detailCode}">${areaCodeList.detailCodeNm}</option> <c:if test="${areaCodeList.aditAtrbInfoValue1 != '광주' && areaCodeList.aditAtrbInfoValue1 != '전남'}">
<option value="${areaCodeList.detailCode}">${areaCodeList.detailCodeNm}</option>
</c:if>
<c:if test="${areaCodeList.aditAtrbInfoValue1 == '서울'}">
<option value="${gwangjuCode},${jeonnamCode}">전남광주</option>
</c:if>
</c:forEach> </c:forEach>
</select>
</div>
</td>
<th>
<label class="requiredText">구.군</label>
</th>
<td>
<div class="row-df">
<input type="hidden" id="hiddenAreaSubCode" name="hiddenAreaSubCode" value="${lclttVO.areaSubCode }" />
<select class="form-control form-control-sm" id="areaSubCode" name="areaSubCode"></select>
</div> </div>
</td> </td>
</tr> </tr>
@ -199,21 +223,91 @@
</div> </div>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
if($('#hiddenUseYn').val() == $('#useYnY').val()){ if($('#hiddenUseYn').val() == $('#useYnY').val()){
$('#useYnY').prop("checked", true); $('#useYnY').prop("checked", true);
}else{ }else{
$('#useYnN').prop("checked", true); $('#useYnN').prop("checked", true);
} }
if($('#hiddenAreaCode').val() != null || $('#hiddenAreaCode').val() != ''){ if($('#hiddenAreaCode').val() != null && $('#hiddenAreaCode').val() != ''){
$('form#insertForm select[name=areaCode]').val($('#hiddenAreaCode').val()).prop('selected', true); var initAreaCode = $('#hiddenAreaCode').val();
// '전남광주' 통합 옵션(콤마로 조합된 값)에 속하는 코드인지 확인해 있으면 통합 옵션을 선택
var mergedOption = $('#areaCodeSel option').filter(function(){
var v = $(this).val();
return v.indexOf(',') > -1 && (','+v+',').indexOf(','+initAreaCode+',') > -1;
});
if(mergedOption.length > 0){
$('#areaCodeSel').val(mergedOption.val()).prop('selected', true);
}else{
$('#areaCodeSel').val(initAreaCode).prop('selected', true);
}
} }
fnAreaSubCodeList($('#areaCodeSel').val(), $('#hiddenAreaSubCode').val());
}); });
$('#areaCodeSel').on('change', function(){
fnAreaSubCodeList($(this).val(), '');
});
$('#areaSubCode').on('change', function(){
fnResolveAreaCode();
});
// '전남광주' 처럼 지역이 콤마로 통합된 상태일 때, 실제 저장할 단일 AREA_CODE를
// 선택된 구.군 코드(예: GJ001, JN008)의 앞 2자리에서 유추해 hidden #areaCode에 반영한다.
function fnResolveAreaCode(){
var selVal = $('#areaCodeSel').val();
if(selVal == null || selVal == ''){
$('#areaCode').val('');
return;
}
if(selVal.indexOf(',') > -1){
var subVal = $('#areaSubCode').val();
if(subVal != null && subVal.length >= 2){
$('#areaCode').val(subVal.substring(0, 2));
}else{
$('#areaCode').val('');
}
}else{
$('#areaCode').val(selVal);
}
}
function fnAreaSubCodeList(areaCode, selectedAreaSubCode){
$('#areaSubCode option').remove();
if(areaCode == null || areaCode == ''){
$('#areaCode').val('');
return;
}
$.ajax({
url: "/lcltt/selectAreaSubCodeListAjax.do",
type: "POST",
data: {"aditAtrbInfoValue1" : areaCode},
success: function(data){
$('#areaSubCode').append('<option value="">선택</option>');
for(var i=0; i<data.areaSubCodeList.length; i++){
$('#areaSubCode').append('<option value="'+ data.areaSubCodeList[i].detailCode +'">'+ data.areaSubCodeList[i].detailCodeNm +'</option>');
}
if(selectedAreaSubCode != null && selectedAreaSubCode != ''){
$('#areaSubCode').val(selectedAreaSubCode).prop('selected', true);
}
fnResolveAreaCode();
},
error: function(){
//전송에 실패하면 실행될 코드;
}
});
}
function fnLclttDelete(){ function fnLclttDelete(){
var conf = confirm("정말로 삭제 하시겠습니까?"); var conf = confirm("정말로 삭제 하시겠습니까?");
if(conf){ if(conf){
@ -231,12 +325,24 @@ function fnLclttSave(){
return false; return false;
} }
if($('#areaCode').val() == null || $('#areaCode').val() == ''){ if($('#areaCodeSel').val() == null || $('#areaCodeSel').val() == ''){
alert('지역을 선택해 주세요.'); alert('지역을 선택해 주세요.');
$('#areaCode').focus(); $('#areaCodeSel').focus();
return false; return false;
} }
if($('#areaSubCode').val() == null || $('#areaSubCode').val() == ''){
alert('구.군을 선택해 주세요.');
$('#areaSubCode').focus();
return false;
}
if($('#areaCode').val() == null || $('#areaCode').val() == ''){
alert('지역/구.군 조합이 올바르지 않습니다. 구.군을 다시 선택해 주세요.');
$('#areaSubCode').focus();
return false;
}
if($('#adres1').val() == null || $('#adres1').val() == ''){ if($('#adres1').val() == null || $('#adres1').val() == ''){
alert('주소를 입력해 주세요.'); alert('주소를 입력해 주세요.');
$('#adres1').focus(); $('#adres1').focus();
@ -279,10 +385,19 @@ function jusoCallBack(roadFullAddr,roadAddrPart1,addrDetail,roadAddrPart2,engAdd
$('#zip').val(zipNo); $('#zip').val(zipNo);
$('#adres1').val(roadAddrPart1); $('#adres1').val(roadAddrPart1);
$('#adres2').val(addrDetail+roadAddrPart2); $('#adres2').val(addrDetail+roadAddrPart2);
// 주소 검색 결과의 시군구명(sggNm)과 일치하는 구.군을 자동 선택한다.
if(sggNm != null && sggNm != ''){
$('#areaSubCode option').each(function(){
if($(this).text() == sggNm){
$(this).prop('selected', true);
}
});
fnResolveAreaCode();
}
} }
function fnList(){ function fnList(){
$('form#gotoListForm').submit(); $('form#gotoListForm').submit();
} }
</script> </script>