OLDBOY/skin/board/outline_target/list/list.script.php
<?php if($is_checkbox) { ?>
<noscript>
<p>자바스크립트를 사용하지 않는 경우<br>별도의 확인 절차 없이 바로 선택삭제 처리하므로 주의하시기 바랍니다.</p>
</noscript>
<?php } ?>

<?php if ($is_checkbox) { ?>
<script>
function all_checked(sw) {
    var f = document.fboardlist;

    for (var i=0; i<f.length; i++) {
        if (f.elements[i].name == "chk_wr_id[]")
            f.elements[i].checked = sw;
    }
}

function fboardlist_submit(f) {
    var chk_count = 0;

    for (var i=0; i<f.length; i++) {
        if (f.elements[i].name == "chk_wr_id[]" && f.elements[i].checked)
            chk_count++;
    }

    if (!chk_count) {
        alert(document.pressed + "할 게시물을 하나 이상 선택하세요.");
        return false;
    }

    if(document.pressed == "선택복사") {
        select_copy("copy");
        return;
    }

    if(document.pressed == "선택이동") {
        select_copy("move");
        return;
    }

    if(document.pressed == "선택삭제") {
        if (!confirm("선택한 게시물을 정말 삭제하시겠습니까?\n\n한번 삭제한 자료는 복구할 수 없습니다\n\n답변글이 있는 게시글을 선택하신 경우\n답변글도 선택하셔야 게시글이 삭제됩니다."))
            return false;

        f.removeAttribute("target");
        f.action = g5_bbs_url+"/board_list_update.php";
    }

    return true;
}

// 선택한 게시물 복사 및 이동
function select_copy(sw) {
    var f = document.fboardlist;

    if (sw == "copy")
        str = "복사";
    else
        str = "이동";

    var sub_win = window.open("", "move", "left=50, top=50, width=500, height=550, scrollbars=1");

    f.sw.value = sw;
    f.target = "move";
    f.action = g5_bbs_url+"/move.php";
    f.submit();
}

// 게시판 리스트 관리자 옵션
jQuery(function($){
    $(".btn_more_opt.is_list_btn").on("click", function(e) {
        e.stopPropagation();
        $(".more_opt.is_list_btn").toggle();
    });
    $(document).on("click", function (e) {
        if(!$(e.target).closest('.is_list_btn').length) {
            $(".more_opt.is_list_btn").hide();
        }
    });
});
</script>
<?php } ?>

<script>
jQuery(function($){
    var realtimeAssetUrl = <?php echo json_encode('/GNU/_PAGE/asset/upbit/data_assets.php?ajax=1'); ?>;

    var memoOpenKey = 'daemon_kind_bybit_memo_open';
    var memoViewKey = 'daemon_kind_bybit_memo_view';
    var $listRoot = $('#LIST');
    var $memoLayer = $('#MemoLayer');
    var $memoButton = $('#btnOpenMemo');
    var $memoViewButtons = $('.memo-view-btn');

    function getMemoView() {
        var value = localStorage.getItem(memoViewKey);
        return (value === '1x1' || value === '1x2') ? value : '1x2';
    }

    function setMemoView(view) {
        $memoLayer.removeClass('view-1x1 view-1x2').addClass('view-' + view);
        $memoViewButtons.removeClass('is-active');
        $memoViewButtons.filter('[data-view="' + view + '"]').addClass('is-active');
        localStorage.setItem(memoViewKey, view);
    }

    function openMemoLayer() {
        $memoLayer.addClass('is-open');
        $memoButton.addClass('is-active');
        $listRoot.addClass('memo-open');
        localStorage.setItem(memoOpenKey, '1');
    }

    function closeMemoLayer() {
        $memoLayer.removeClass('is-open');
        $memoButton.removeClass('is-active');
        $listRoot.removeClass('memo-open');
        localStorage.setItem(memoOpenKey, '0');
    }

    setMemoView(getMemoView());
    if (localStorage.getItem(memoOpenKey) === '1') {
        openMemoLayer();
    } else {
        closeMemoLayer();
    }

    $memoViewButtons.on('click', function(){
        var view = $(this).data('view');
        if (view === '1x1' || view === '1x2') {
            setMemoView(view);
        }
    });

    $('#btnOpenMemo').on('click', function(){
        if ($memoLayer.hasClass('is-open')) {
            closeMemoLayer();
        } else {
            openMemoLayer();
        }
    });

    $('#btnCloseMemoTop, #btnCloseMemoBottom').on('click', function(){
        closeMemoLayer();
    });

    $('#btnOpenNotice').on('click', function(){
        $('#NoticeLayer').fadeIn(120);
    });

    $('#btnCloseNoticeTop, #btnCloseNoticeBottom').on('click', function(){
        $('#NoticeLayer').fadeOut(120);
    });

    $('#btnOpenSearch').on('click', function(){
        $('#SCH').css('display', 'flex').hide().fadeIn(120);
    });

    $('#btnCloseSearch').on('click', function(){
        $('#SCH').fadeOut(120);
    });

    $('#SCH').on('click', function(e){
        if (e.target === this) {
            $('#SCH').fadeOut(120);
        }
    });

    var $rows = $('.list-row');
    var $noResult = $('#RealtimeNoResult');

    function normalizeText(value) {
        return (value || '').toString().toLowerCase().replace(/\s+/g, ' ').trim();
    }

    $('#realtimeSearch').on('input', function(){
        var keyword = normalizeText($(this).val());
        var visibleCount = 0;

        $rows.each(function(){
            var symbol = normalizeText($(this).data('symbol'));
            var matched = (keyword === '') || (symbol.indexOf(keyword) > -1);

            $(this).toggle(matched);
            if (matched) visibleCount++;
        });

        if (keyword !== '' && visibleCount === 0) {
            $noResult.show();
        } else {
            $noResult.hide();
        }
    });

    function parseNumber(value) {
        var cleaned = String(value || '').replace(/[^0-9.-]/g, '');
        var parsed = parseFloat(cleaned);
        return Number.isFinite(parsed) ? parsed : 0;
    }

    function formatAmount(value) {
        if (!Number.isFinite(value)) return '0';
        return Math.round(value).toLocaleString('ko-KR');
    }

    function formatRate(value) {
        if (!Number.isFinite(value)) return '0.00%';
        return value.toFixed(2) + '%';
    }

    function applyCellClass($cell, plusClass, minusClass, isPlus) {
        $cell.removeClass(plusClass + ' ' + minusClass);
        $cell.addClass(isPlus ? plusClass : minusClass);
    }

    function updateArrow($arrow, isUp, upClass, downClass) {
        $arrow.removeClass(upClass + ' ' + downClass);
        $arrow.addClass(isUp ? upClass : downClass);
        $arrow.text(isUp ? '▲' : '▼');
    }

    function updateRealtimeRows(currentAsset) {
        $('.list-row').each(function(){
            var $row = $(this);
            var base = parseFloat($row.data('base-num')) || 0;
            var target = parseFloat($row.data('target-num')) || 0;

            var liveCurrent = String($row.data('live-current')) === '1';
            var liveProfit = String($row.data('live-profit')) === '1';
            var liveProfitRate = String($row.data('live-profit-rate')) === '1';
            var liveReachRate = String($row.data('live-reach-rate')) === '1';

            var $currentCell = $row.find('.js-current-cell');
            var $currentValue = $row.find('.js-current-value');
            var $currentArrow = $row.find('.js-current-arrow');
            var $profitCell = $row.find('.js-profit-cell');
            var $profitValue = $row.find('.js-profit-value');
            var $profitRateCell = $row.find('.js-profit-rate-cell');
            var $profitRateValue = $row.find('.js-profit-rate-value');
            var $profitRateArrow = $row.find('.js-profit-rate-arrow');
            var $reachCell = $row.find('.js-reach-rate-cell');
            var $reachValue = $row.find('.js-reach-rate-value');

            var current = liveCurrent ? currentAsset : parseNumber($currentValue.text());
            if (liveCurrent) {
                $currentValue.text(formatAmount(current));
            }

            var currentUp = current >= base;
            applyCellClass($currentCell, 'val-up-bright', 'val-down-bright', currentUp);
            updateArrow($currentArrow, currentUp, 'arrow-up-bright', 'arrow-down-bright');

            var profit = current - base;
            if (liveProfit) {
                $profitValue.text(formatAmount(profit));
            } else {
                profit = parseNumber($profitValue.text());
            }

            var profitUp = profit >= 0;
            applyCellClass($profitCell, 'val-up-deep', 'val-down-deep', profitUp);

            var profitRate = (base !== 0) ? ((profit / base) * 100) : 0;
            if (liveProfitRate) {
                $profitRateValue.text(formatRate(profitRate));
            } else {
                profitRate = parseNumber($profitRateValue.text());
            }

            var profitRateUp = profitRate >= 0;
            applyCellClass($profitRateCell, 'val-up-deep', 'val-down-deep', profitRateUp);
            updateArrow($profitRateArrow, profitRateUp, 'arrow-up-deep', 'arrow-down-deep');

            var reachRate = 0;
            var denominator = target - base;
            if (denominator !== 0) {
                reachRate = ((current - base) / denominator) * 100;
            }

            if (liveReachRate) {
                $reachValue.text(formatRate(reachRate));
            } else {
                reachRate = parseNumber($reachValue.text());
            }

            var reachUp = reachRate >= 0;
            applyCellClass($reachCell, 'val-up-blue', 'val-down-bright', reachUp);
        });
    }

    function fetchRealtimeAsset() {
        $.ajax({
            url: realtimeAssetUrl,
            method: 'GET',
            dataType: 'json',
            cache: false
        }).done(function(res){
            if (!res) return;

            var currentAsset = null;
            if (res.success && res.summary && typeof res.summary.total_asset !== 'undefined') {
                currentAsset = parseFloat(res.summary.total_asset);
            } else if (res.ok && typeof res.current_asset !== 'undefined') {
                currentAsset = parseFloat(res.current_asset);
            }

            if (!Number.isFinite(currentAsset)) return;
            updateRealtimeRows(currentAsset);
        });
    }

    fetchRealtimeAsset();
    setInterval(fetchRealtimeAsset, 8000);
});
</script>