File size: 14,458 Bytes
5ed3bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f3f71c
 
 
 
 
 
 
 
 
 
 
 
 
 
3b1cb20
 
5ed3bc5
8f3f71c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5ed3bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258dba8
5ed3bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Liger - Green-Drive Optimizer</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link
        href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700&family=Noto+Sans+KR:wght@300;400;500;700&display=swap"
        rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <meta name="description" content="Liger: 친환경 주행 경로 최적화 및 충전소 추천 솔루션">
</head>

<body>
    <div class="background-glob"></div>

    <nav class="navbar">
        <div class="logo">LIGER</div>
        <div class="nav-links">
            <a href="#demo">Demo</a>
            <a href="#presentation">Presentation</a>
            <a href="#workflow">Workflow</a>
        </div>
    </nav>

    <header class="hero">
        <div class="hero-content">
            <span class="badge">Green-Drive Optimizer</span>
            <h1>스마트한 전기차 라이프의 시작,<br> <span class="gradient-text">LIGER</span></h1>
            <p>최적의 경로와 충전소를 찾아주는 당신만의 AI 드라이빙 파트너</p>
            <div class="cta-group">
                <a href="#demo" class="btn primary">데모 영상 보기</a>
                <a href="#workflow" class="btn secondary">워크플로우 확인하기</a>
            </div>
        </div>
        <div class="hero-image">
            <img src="hero_image.png" alt="Liger Dashboard Preview" class="glass-card">
        </div>
    </header>

    <main>
        <section id="demo" class="section">
            <div class="section-header">
                <h2>Demo Video</h2>
                <p>Liger가 어떻게 작동하는지 확인해보세요</p>
            </div>
            <div class="video-container glass-card">
                <video controls poster="hero_image.png">
                    <source src="liger_demo.mp4" type="video/mp4">
                    브라우저가 비디오 태그를 지원하지 않습니다.
                </video>
            </div>
        </section>

        <section id="presentation" class="section">
            <div class="section-header">
                <h2>Presentation</h2>
                <p>프로젝트 상세 소개 및 기술 스택</p>
            </div>
            <div class="ppt-container glass-card">
                <div class="ppt-wrapper glass-card" style="padding: 0; overflow: hidden; height: auto;">
                    <div class="pdf-canvas-container">
                        <canvas id="pdf-render"></canvas>
                    </div>
                    <div class="slide-controls">
                        <button id="prev-page" class="btn secondary small">Prev</button>
                        <span id="page-count-container">
                            Page <span id="page-num" style="color: white; font-weight: bold;">--</span> of <span
                                id="page-count">--</span>
                        </span>
                        <button id="next-page" class="btn secondary small">Next</button>
                        <a href="liger_presentation.pdf" download class="btn small"
                            style="margin-left: 1rem; padding: 0.4rem 0.8rem; font-size: 0.8rem; background: rgba(255,255,255,0.05);">
                            📥 PDF
                        </a>
                    </div>
                </div>

                <!-- PDF.js Library -->
                <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
                <script>
                    const url = 'liger_presentation.pdf';
                    let pdfDoc = null,
                        pageNum = 1,
                        pageRendering = false,
                        pageNumPending = null,
                        scale = 1.5,
                        canvas = document.getElementById('pdf-render'),
                        ctx = canvas.getContext('2d');

                    // Set worker source
                    pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';

                    /**
                     * Get page info from document, resize canvas accordingly, and render page.
                     * @param num Page number.
                     */
                    function renderPage(num) {
                        pageRendering = true;
                        // Fetch page
                        pdfDoc.getPage(num).then(function (page) {

                            // Adjust scale to fit the container width if needed
                            const containerWidth = document.querySelector('.pdf-canvas-container').clientWidth;
                            const viewport = page.getViewport({ scale: 1 });

                            // Calculate scale to fit width (minus some padding)
                            let desiredScale = (containerWidth - 40) / viewport.width;
                            // Limit max scale to keep quality reasonable
                            if (desiredScale > 1.5) desiredScale = 1.5;

                            const scaledViewport = page.getViewport({ scale: desiredScale });

                            canvas.height = scaledViewport.height;
                            canvas.width = scaledViewport.width;

                            // Render PDF page into canvas context
                            const renderContext = {
                                canvasContext: ctx,
                                viewport: scaledViewport
                            };
                            const renderTask = page.render(renderContext);

                            // Wait for render to finish
                            renderTask.promise.then(function () {
                                pageRendering = false;
                                if (pageNumPending !== null) {
                                    renderPage(pageNumPending);
                                    pageNumPending = null;
                                }
                            });
                        });

                        // Update page counters
                        document.getElementById('page-num').textContent = num;

                        // Update buttons state
                        document.getElementById('prev-page').disabled = num <= 1;
                        document.getElementById('next-page').disabled = num >= pdfDoc.numPages;
                    }

                    /**
                     * If another page rendering in progress, waits until the rendering is
                     * finised. Otherwise, executes rendering immediately.
                     */
                    function queueRenderPage(num) {
                        if (pageRendering) {
                            pageNumPending = num;
                        } else {
                            renderPage(num);
                        }
                    }

                    /**
                     * Displays previous page.
                     */
                    function onPrevPage() {
                        if (pageNum <= 1) {
                            return;
                        }
                        pageNum--;
                        queueRenderPage(pageNum);
                    }
                    document.getElementById('prev-page').addEventListener('click', onPrevPage);

                    /**
                     * Displays next page.
                     */
                    function onNextPage() {
                        if (pageNum >= pdfDoc.numPages) {
                            return;
                        }
                        pageNum++;
                        queueRenderPage(pageNum);
                    }
                    document.getElementById('next-page').addEventListener('click', onNextPage);

                    /**
                     * Asynchronously downloads PDF.
                     */
                    pdfjsLib.getDocument(url).promise.then(function (pdfDoc_) {
                        pdfDoc = pdfDoc_;
                        document.getElementById('page-count').textContent = pdfDoc.numPages;

                        // Initial/first page rendering
                        renderPage(pageNum);
                    }).catch(function (error) {
                        console.error('Error loading PDF:', error);
                        // Fallback UI or message could go here
                        ctx.font = '20px Arial';
                        ctx.fillStyle = 'white';
                        ctx.fillText('Error loading PDF.', 50, 50);
                    });

                    // Handle window resize
                    window.addEventListener('resize', () => {
                        // Re-render current page to adjust scale
                        if (pdfDoc) {
                            queueRenderPage(pageNum);
                        }
                    });
                </script>
            </div>
        </section>

        <section id="workflow" class="section">
            <div class="section-header">
                <h2>Core Logic & Workflow</h2>
                <p>Google Calendar 연동부터 AI 최적화 제안까지, One-Stop 자동화 프로세스</p>
            </div>
            <div class="workflow-container glass-card">
                <div class="workflow-img-wrapper">
                    <img src="workflow_diagram.png" alt="n8n Workflow Diagram" class="full-width-img">
                </div>
                <div class="workflow-details">
                    <div class="logic-step">
                        <h3>1. Trigger & analysis</h3>
                        <p>구글 캘린더에 새로운 일정이 등록되면 자동으로 감지하여 출발지와 목적지, 그리고 이동 시간을 계산합니다.</p>
                    </div>
                    <div class="logic-step">
                        <h3>2. Dual-Optimization Engine</h3>
                        <p>이동 경로를 바탕으로 두 가지 시나리오를 병렬로 생성합니다.</p>
                        <ul>
                            <li><strong>탄소 배출 최적화:</strong> 친환경 경로 및 운전 습관 제안</li>
                            <li><strong>경제적 충전 시나리오:</strong> 최저가 충전소 및 배터리 효율 분석</li>
                        </ul>
                    </div>
                    <div class="logic-step">
                        <h3>3. AI Evaluation (Upstage Solar)</h3>
                        <p>Upstage Solar LLM이 환경성과 경제성을 종합적으로 평가하여, 사용자에게 가장 밸런스 잡힌 최적의 스케줄을 확정합니다.</p>
                    </div>
                    <div class="logic-step">
                        <h3>4. Action & Report</h3>
                        <p>최종 확정된 일정은 캘린더에 다시 등록되며, 상세 분석 리포트가 이메일로 즉시 전송됩니다.</p>
                    </div>
                </div>
            </div>
        </section>

        <section id="team" class="section">
            <div class="section-header">
                <h2>Our Team</h2>
                <p>Liger 프로젝트를 만들어가는 사람들</p>
            </div>
            <div class="team-container glass-card">
                <!-- Image removed as requested -->
                <div class="team-grid">
                    <div class="team-member">
                        <h4>강윤재</h4>
                        <span class="role">Data Research & Scenario</span>
                        <p>전기차 전비/배터리 자료 조사<br>경제적 충전 시나리오 로직 설계</p>
                    </div>
                    <div class="team-member">
                        <h4>엄서훈</h4>
                        <span class="role">Workflow Architect</span>
                        <p>n8n 메인 워크플로우 개발<br>최종 리포트 템플릿 구현</p>
                    </div>
                    <div class="team-member">
                        <h4>이승현</h4>
                        <span class="role">Project Lead</span>
                        <p>프로젝트 총괄 및 일정 조율<br>서비스 기획 및 소개서 작성</p>
                    </div>
                    <div class="team-member">
                        <h4>이하윤</h4>
                        <span class="role">Presentation & Data</span>
                        <p>발표 자료 제작 및 최종 발표<br>탄소 배출 데이터 리서치</p>
                    </div>
                    <div class="team-member">
                        <h4>차성경</h4>
                        <span class="role">Media & Validation</span>
                        <p>아이디어 산출 및 검증<br>홍보 영상 제작 및 자료 조사</p>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <footer>
        <p>&copy; 2024 Liger Team. All rights reserved.</p>
        <div class="socials">
            <a href="https://huggingface.co/dltmdgus" target="_blank">Hugging Face</a>
        </div>
    </footer>

    <script>
        // Smooth scroll for anchor links
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });

        // Simple intersection observer for fade-in animations
        const observerOptions = {
            threshold: 0.1
        };

        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.classList.add('visible');
                }
            });
        }, observerOptions);

        document.querySelectorAll('.section, .hero').forEach(el => {
            el.classList.add('fade-in-section');
            observer.observe(el);
        });
    </script>
</body>

</html>