( function ( ) {
"use strict" ;
const channelPattern = /^CH(?:0[1-9]|[1-3][0-9]|4[0-8])$/ ;
function mount ( options ) {
// The API independently enforces log.clear.
if ( ! [ "port" , "system" , "link" ] . includes ( options . kind ) || options . role !== "administrator" ) { return null ; }
const system = options . kind === "system" ;
const link = options . kind === "link" ;
const doc = options . document ;
const select = options . channelField ;
if ( ! doc || ( ! system && ! link && ! select ) || ! options . parent ) { return null ; }
let busy = false ;
let disposed = false ;
function node ( tag , className , text ) {
const element = doc . createElement ( tag ) ;
element . className = className ;
element . textContent = text ;
return element ;
}
const area = node ( "section" , "port-log-clear" , "" ) ;
area . setAttribute ( "aria-label" , system ? "시스템 로그 관리" : link ? "포트 상태 이벤트 관리" : "포트 로그 관리" ) ;
const copy = node ( "div" , "port-log-clear-copy" , "" ) ;
const target = node ( "strong" , "port-log-clear-target" , "" ) ;
target . setAttribute ( "role" , "status" ) ;
const scope = node ( "p" , "port-log-clear-scope" , "기간·검색 조건·표시 개수와 관계없이 선택한 포트의 저장 로그 전체를 삭제합니다. 새 로그 수집은 계속됩니다." ) ;
if ( system ) { scope . textContent = "기간·검색 조건·표시 개수와 관계없이 시스템 이벤트와 감사 기록 전체를 삭제합니다. 포트 로그·포트 상태 이벤트는 보존됩니다." ; }
if ( link ) { scope . textContent = "기간·검색 조건·표시 개수와 관계없이 저장된 포트 상태 이벤트 전체를 삭제합니다. 현재 링크 상태와 새 이벤트 수집은 유지됩니다." ; }
scope . id = "port-log-clear-scope" ;
const note = node ( "p" , "port-log-clear-note" , "다른 포트와 시스템·감사·포트 상태 이벤트는 유지됩니다. 설정 백업에는 로그 원문이 포함되지 않습니다." ) ;
if ( system ) { note . textContent = "새 시스템 로그는 계속 저장되며, 설정 백업에는 로그 원문이 포함되지 않습니다." ; }
if ( link ) { note . textContent = "시스템·감사·포트 통신 로그는 유지됩니다. 설정 백업에는 로그 원문이 포함되지 않습니다." ; }
const button = node ( "button" , "btn danger" , "로그 클리어 (삭제)" ) ;
button . type = "button" ;
button . dataset [ system ? "systemLogClear" : link ? "linkLogClear" : "portLogClear" ] = "true" ;
button . setAttribute ( "aria-describedby" , scope . id ) ;
copy . append ( target , scope , note ) ;
area . append ( copy , button ) ;
options . parent . appendChild ( area ) ;
function update ( ) {
const channel = system ? "SYSTEM" : link ? "LINKS" : ( select . value || "ALL" ) ;
const valid = system || link || channel === "ALL" || channelPattern . test ( channel ) ;
button . disabled = busy || disposed || ! valid ;
button . textContent = busy ? "삭제 중..." : "로그 클리어 (삭제)" ;
target . textContent = busy ? "로그를 삭제하고 있습니다." : ( valid ? "삭제 대상: " + channel + " · 저장된 통신 로그 전체" : "위 검색 조건에서 포트 1개를 선택하세요." ) ;
if ( system && ! busy ) { target . textContent = "삭제 대상: 시스템 이벤트 및 감사 기록 전체" ; }
if ( link && ! busy ) { target . textContent = "삭제 대상: 포트 상태 이벤트 전체" ; }
if ( ! system && ! link ) {
if ( channel === "ALL" && ! busy ) { target . textContent = "삭제 대상: 전체 포트(CH01~CH48) 통신 로그" ; }
scope . textContent = "기간·검색 조건·표시 개수와 관계없이 " + ( channel === "ALL" ? "전체 포트의" : "선택한 포트의" ) + " 저장 로그 전체를 삭제합니다. 새 로그 수집은 계속됩니다." ;
note . textContent = ( channel === "ALL" ? "시스템·감사·포트 상태 이벤트는 유지됩니다." : "다른 포트와 시스템·감사·포트 상태 이벤트는 유지됩니다." ) + " 설정 백업에는 로그 원문이 포함되지 않습니다." ;
}
area . dataset . ready = String ( valid ) ;
area . setAttribute ( "aria-busy" , String ( busy ) ) ;
}
async function clear ( ) {
// Capture the exact target: changing filters cannot retarget deletion.
const channel = system ? "SYSTEM" : link ? "LINKS" : ( select . value || "ALL" ) ;
if ( busy || disposed || options . isDisposed ( ) || ( ! system && ! link && channel !== "ALL" && ! channelPattern . test ( channel ) ) ) { return ; }
const prompt = system
? "시스템 이벤트와 감사 기록 전체를 삭제합니다.\n기간·검색 조건·표시 개수와 관계없이 삭제되며 복구할 수 없습니다. 포트 로그·포트 상태 이벤트는 보존됩니다.\n내보내기는 현재 검색 조건과 표시 개수 범위만 포함합니다.\n계속하려면 SYSTEM을 정확히 입력하세요."
: link ? "저장된 포트 상태 이벤트 전체를 삭제합니다.\n검색 조건과 관계없이 삭제되며 복구할 수 없습니다. 현재 링크 상태와 시스템·감사·포트 통신 로그는 유지됩니다.\n계속하려면 LINKS를 정확히 입력하세요."
: ( channel === "ALL" ? "전체 포트(CH01~CH48)" : channel ) + "의 저장된 포트 로그 전체를 삭제합니다.\n기간·검색 조건·표시 개수와 관계없이 RX/TX·명령·세션 기록이 삭제되며 복구할 수 없습니다.\n필요한 기록은 먼저 내보내세요. 내보내기에는 현재 검색 조건과 표시 개수 제한이 적용됩니다. 설정 백업에는 로그 원문이 포함되지 않습니다.\n" + ( channel === "ALL" ? "시스템·감사·포트 상태 이벤트는 유지됩니다." : "다른 포트와 시스템·감사·포트 상태 이벤트는 유지됩니다." ) + " 새 로그 수집은 계속됩니다.\n계속하려면 " + channel + "을 정확히 입력하세요." ;
const confirmation = options . confirm ( prompt ) ;
if ( confirmation !== channel || disposed || options . isDisposed ( ) ) { return ; }
busy = true ;
update ( ) ;
options . onBusy ( ) ;
try {
const result = await options . send ( system || link ? { confirmation : confirmation } : { channel : channel , confirmation : confirmation } ) ;
if ( ! disposed && ! options . isDisposed ( ) ) { options . onSuccess ( channel , result ) ; }
} catch ( error ) {
if ( ! disposed && ! options . isDisposed ( ) ) { options . onError ( error ) ; }
} finally {
busy = false ;
update ( ) ;
// Release page-level refresh guards even after navigation.
await options . onSettled ( ) ;
}
}
select ? . addEventListener ( "change" , update ) ;
button . addEventListener ( "click" , clear ) ;
update ( ) ;
return {
update : update ,
dispose : function ( ) {
disposed = true ;
select ? . removeEventListener ( "change" , update ) ;
button . removeEventListener ( "click" , clear ) ;
update ( ) ;
}
} ;
}
const api = { mount : mount } ;
if ( typeof module !== "undefined" && module . exports ) { module . exports = api ; }
if ( typeof window !== "undefined" ) { window . teraPortLogClear = api ; }
} ( ) ) ;