메이플스토리 + 계산기 (mCal) 시스템 아키텍처

“메이플스토리 + 계산기” (mCal) 시스템은 기존의 클라이언트 측 단일 페이지 애플리케이션(SPA)에서 Jekyll 기반의 다중 페이지 정적 웹사이트로 성공적으로 전환되었습니다. 이 시스템은 사용자의 웹 브라우저 내에서 전적으로 작동하며, Jekyll의 빌드 과정을 통해 생성된 정적 파일을 제공하는 것 외에, 계산 또는 동적 콘텐츠 생성을 담당하는 서버 측 구성 요소는 없습니다.

주요 구성 요소 및 역할 (Jekyll 기반):

1. HTML 파일 구조 (프레젠테이션 및 구조)

Jekyll의 템플릿 시스템을 활용하여 HTML 파일 구조가 재구성되었습니다.

</div> <div id="footer"> <div class="container"> <ul class="quick-links"> <li>사이트 소개</li> <li>이용약관</li> <li>개인정보처리방침</li> <li>문의하기</li> <li>가이드</li> </ul> <ul class="copyright"> <li>© Untitled. All rights reserved.</li><li>Design: HTML5 UP</li> </ul> </div> </div> 를 통해 공통 헤더와 푸터를 포함합니다. * <section id="weeklyBoss" class="ten"> <div class="container"> <header> <h2 class="accordion-header" style="cursor: pointer;">주간보스 시급계산기 </h2> <div class="accordion-content" style="display: none;"> <p> ‘주보돌이’는 메이플스토리의 중요한 수익 활동 중 하나입니다. 이 계산기는 다양한 주간/월간 보스를 선택하고, 각 보스마다 파티 인원수와 실제 클리어 타임을 개별적으로 설정하여 1인당 총 수익과 시급을 계산합니다. 이를 통해 어떤 보스를 클리어하는 것이 가장 효율적인지 판단하고, 최적의 보스 레이드 순서를 계획하는 데 도움을 줍니다. </p> <p>아래 보스목록에서 난이도, 인원, 클리어타임을 입력하고, 합산에 포함할 행을 선택하여 보스를 추가하세요.</p> <hr style="margin: 2em 0;"> </div> </header>

    <!-- 캐릭터 관리 탭 -->
    <div class="character-management" id="character-tabs">
        <!-- 탭이 동적으로 생성됩니다 -->
        <button class="add-char-btn" onclick="addNewCharacter()">+ 캐릭터 추가</button>
    </div>

    <div class="char-nickname-section">
        <label for="char-nickname">캐릭터 닉네임:</label>
        <input type="text" id="char-nickname" placeholder="닉네임 입력" onchange="updateNickname(this.value)">
    </div>

    <!-- 결과 표시 영역 -->
    <div class="summary-container">
        <!-- 현재 캐릭터 요약 -->
        <div class="summary-card">
            <h3>현재 캐릭터 요약</h3>
            <div class="row gtr-uniform">
                <div class="col-6 col-12-mobile">
                    <strong>선택 보스:</strong>
                    <div id="selected-boss-count">0 / 12</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>수익:</strong>
                    <div id="weekly-profit">0 메소</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>시간:</strong>
                    <div id="total-clear-time-hours">0분 (0시간)</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>시급:</strong>
                    <div id="total-weekly-hourly-wage">0 원</div>
                </div>
            </div>
        </div>

        <!-- 계정 전체 요약 -->
        <div class="summary-card account">
            <h3>계정 전체 요약 (합산)</h3>
            <div class="row gtr-uniform">
                <div class="col-6 col-12-mobile">
                    <strong>총 캐릭터:</strong>
                    <div id="total-char-count">0명</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>총 수익:</strong>
                    <div id="account-total-profit">0 메소</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>총 시간:</strong>
                    <div id="account-total-time">0분 (0시간)</div>
                </div>
                <div class="col-6 col-12-mobile">
                    <strong>계정 시급:</strong>
                    <div id="account-hourly-wage">0 원</div>
                </div>
            </div>
        </div>
    </div>

    <!-- 테이블 헤더 -->
    <div id="boss-table-header">
         <div class="boss-row header">
            <span class="header-item boss-name">보스명</span>
            <span class="header-item boss-difficulty">난이도</span>
            <span class="header-item party-size-per-boss">인원</span>
            <span class="header-item crystal-price">획득 메소</span>
            <span class="header-item clear-time-per-boss">최저시급컷(분)</span>
            <span class="header-item actual-clear-time">클리어타임(분)</span>
            <span class="header-item hourly-rate-won">시급환산(원)</span>
        </div>
    </div>

    <!-- 보스 목록 컨테이너 -->
    <div id="boss-list-container">
        <!-- 이 곳에 JS로 보스 목록이 동적으로 생성됩니다. -->
    </div>

    <h4 class="accordion-header" style="cursor: pointer; margin-top: 2em; margin-bottom: 0.5em;">상세 정보 <span class="accordion-icon fa fa-chevron-down"></span></h4>
    <div class="accordion-content" style="display: none;">
        <div class="flip-scroll">
            <table class="simpleTable">
                <thead>
                    <tr>
                        <th>구분</th>
                        <th>설명</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>**보스명**</td>
                        <td>메이플스토리 보스 이름</td>
                    </tr>
                    <tr>
                        <td>**난이도**</td>
                        <td>이지, 노멀, 하드, 카오스, 익스트림 등의 난이도 분류. 난이도에 따라 결정 가격이 변경됩니다.</td>
                    </tr>
                    <tr>
                        <td>**인원**</td>
                        <td>파티를 함께 가는 인원. 인원에 따라 결정 가격이 변경됩니다.</td>
                    </tr>
                    <tr>
                        <td>**획득 메소**</td>
                        <td>난이도와 인원을 선택 후 최종적으로 해당 보스에서 받게되는 메소</td>
                    </tr>
                    <tr>
                        <td>**최저시급컷(분)**</td>
                        <td>표기된 시간 이내에 클리어해야 최저시급보다 이득입니다.</td>
                    </tr>
                    <tr>
                        <td>**클리어타임(분)**</td>
                        <td>실제 해당 보스를 클리어하는데 필요한 시간을 입력합니다. 선택된 보스에 대해 입력된 시간의 합이 상단에 합산으로 표시되며, 최종 보스 시급을 계산하는데 사용됩니다.</td>
                    </tr>
                    <tr>
                        <td>**시급환산(원)**</td>
                        <td>획득메소와 클리어타임에 대해 계산하여 시급으로 생각했을 때 어느정도의 가치인지를 보여줍니다.</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

</div>

</section> ` 위치에 각 페이지의 고유한 콘텐츠가 삽입됩니다. * ``을 활용하여 GitHub Pages 환경에 맞는 상대 경로를 자동으로 처리합니다.

2. assets/css/ (스타일링)

3. assets/js/ (클라이언트 측 로직 및 상호 작용)

JavaScript 파일 구조가 다중 페이지 환경에 맞춰 리팩토링되었습니다.

4. images/ (시각적 자산)

전반적인 애플리케이션 흐름 (Jekyll 다중 페이지):

  1. 페이지 요청: 사용자가 특정 계산기 페이지 URL(예: https://mesangi.com/pages/mesoMarket.html)을 요청합니다.
  2. Jekyll 빌드 (GitHub Pages): GitHub Pages 서버에서 Jekyll이 해당 요청에 맞는 pages/*.html 파일과 _layouts/default.html을 결합하여 최종 HTML을 빌드하고 제공합니다.
  3. 리소스 로딩: 브라우저는 제공된 HTML 구조를 로드하고, _layouts/default.html에 명시된 공통 CSS 파일, global.js를 로드합니다. 또한 해당 페이지의 프론트 매터에 명시된 페이지별 JavaScript 파일(assets/js/pages/xxx.js)도 로드합니다.
  4. UI/JS 초기화:
    • main.js가 반응형 UI 및 모바일 사이드바 토글 등을 초기화합니다.
    • global.js가 실행되어 $(document).ready() 내에서 firstValSetting() (기본값 설정), dataLoad() (localStorage에서 값 로드), 메뉴 검색 기능공통 아코디언 기능을 초기화하고, fn_collection()을 호출합니다.
  5. 데이터 및 계산 처리:
    • fn_collection()setNumber()를 호출하여 mainDiv의 입력 필드 값을 전역 변수에 할당합니다.
    • 이후 run_page_calculations() (해당 페이지의 JS 파일에 정의된) 함수를 호출하여 페이지별 계산을 수행하고 결과를 DOM에 표시합니다.
  6. 사용자 상호 작용: 사용자가 mainDiv 또는 페이지별 입력 필드를 변경하면, global.js 또는 페이지별 JS의 이벤트 리스너가 이를 감지하여 saveData() (localStorage 저장) 및 fn_collection() (재계산)을 호출, 실시간으로 결과를 업데이트합니다.

이러한 구조는 각 계산기 기능의 독립성을 높여 유지보수 및 확장을 용이하게 하며, 웹사이트의 전반적인 반응성과 사용자 경험을 개선합니다.