// media.js β€” rich media widgets extracted from helpers.js. // smiles (chemistry), tradingview (charts), music/MIDI (midiRouter + widgets). // Referenced via inline onclick strings generated by renderMarkdown (markdown.js). function renderTVChart(btn, containerId, symbol, interval) { btn.disabled = true; btn.textContent = 'λ‘œλ”© 쀑...'; var isDark = document.documentElement.getAttribute('data-theme') !== 'light'; function doInit() { try { new TradingView.widget({ container_id: containerId, autosize: true, symbol: symbol, interval: interval || 'D', timezone: 'Asia/Seoul', theme: isDark ? 'dark' : 'light', style: '1', locale: 'kr', enable_publishing: false, allow_symbol_change: true, save_image: false, withdateranges: true, hide_side_toolbar: false, studies: ['RSI@tv-basicstudies', 'MACD@tv-basicstudies'], }); btn.style.display = 'none'; } catch(e) { btn.disabled = false; btn.textContent = 'πŸ“ˆ 차트 뢈러였기'; } } if (window.TradingView && window.TradingView.widget) { doInit(); } else { var s = document.createElement('script'); s.src = 'https://s3.tradingview.com/tv.js'; s.onload = doInit; s.onerror = function() { btn.disabled = false; btn.textContent = 'πŸ“ˆ 차트 뢈러였기'; }; document.head.appendChild(s); } } // Fixed 180x130 was tuned for benzene-sized rings and left bigger molecules (e.g. // cholesterol's 4 fused rings + side chain) cramped/illegible. Scale the canvas with a // rough heavy-atom count from the raw SMILES so the figure stays roomy either way. function smilesSizeFor(smiles) { var atomCount = (smiles.match(/Cl|Br|\[[^\]]+\]|[BCNOFPSIbcnops]/g) || []).length; var extra = Math.max(0, atomCount - 6); var width = Math.min(420, 180 + extra * 8); var height = Math.min(320, 130 + extra * 6); return { width: width, height: height }; } // SMILES β†’ 2D ν™”ν•™ ꡬ쑰식 (κ²°ν•©μ„  포함). SmilesDrawerλŠ” 둜컬 μΊ”λ²„μŠ€ λ Œλ”λ§μ΄λΌ // λ„€νŠΈμ›Œν¬ μ§€μ—° 없이 μ¦‰μ‹œ κ·Έλ €μ§€μ§€λ§Œ, innerHTML둜 μ‚½μž…λœ λŠ” 아직 DOM에 // λΆ™κΈ° 전이라 μœ„μ ― μ½”λ“œ λΈ”λ‘μ—μ„œ λ°”λ‘œ 그릴 수 μ—†μŒ β€” λ²„νŠΌ 클릭으둜 트리거. // Auto-renders every not-yet-rendered .smiles-inline in `container` β€” mirrors // renderKatexIn(): innerHTML doesn't execute embedded