
(function () {
    'use strict';

    function decode(s) { try { return decodeURIComponent(s || ''); } catch (e) { return s || ''; } }

    function build(el) {
        var text = decode(el.getAttribute('data-tw-text') || '');
        if (!text) return;

        var motionRaw = (el.getAttribute('data-tw-motion') || 'none').toLowerCase();
        var spotlight = el.getAttribute('data-tw-spotlight') === '1';
        var parallax = el.getAttribute('data-tw-parallax') === '1';

        
        
        if (motionRaw === 'wave' || motionRaw === 'perspective') { motionRaw = 'none'; }
        var motion = (['scroll', 'drift'].indexOf(motionRaw) !== -1) ? motionRaw : 'none';
        var speed = parseFloat(el.getAttribute('data-tw-speed') || '1');
        if (!isFinite(speed) || speed <= 0) speed = 1;
        var space = parseInt(el.getAttribute('data-tw-space') || '24', 10);
        if (!isFinite(space) || space < 0) space = 24;

        var W = el.clientWidth, H = el.clientHeight;
        if (W < 2 || H < 2) return;

        if (el._twAnims) { el._twAnims.forEach(function (a) { try { a.cancel(); } catch (e) {} }); }
        el._twAnims = [];
        if (el._twParallaxOff) { try { el._twParallaxOff(); } catch (e) {} el._twParallaxOff = null; }
        if (el._twSpotOff) { try { el._twSpotOff(); } catch (e) {} el._twSpotOff = null; }
        el.textContent = '';
        el.style.webkitMaskImage = '';
        el.style.maskImage = '';
        el.style.webkitMaskComposite = '';
        el.style.maskComposite = '';
        el.style.webkitMaskComposite = '';
        el.style.maskComposite = '';

        if (!el._twBaseColor) el._twBaseColor = el.style.color || getComputedStyle(el).color || 'rgba(255,255,255,0.14)';
        el.style.color = el._twBaseColor;

        var probe = document.createElement('span');
        probe.style.cssText = 'position:absolute;visibility:hidden;white-space:nowrap;left:-9999px;top:-9999px';
        probe.textContent = text;
        el.appendChild(probe);
        var unitW = (probe.offsetWidth || 120) + space;
        var rowH = probe.offsetHeight || (parseInt(getComputedStyle(el).fontSize, 10) || 48);
        el.removeChild(probe);

        var gap = parseInt(getComputedStyle(el).rowGap, 10) || 0;
        var stepY = rowH + gap;
        var baseRows = Math.ceil(H / stepY);
        var nRows = baseRows + 2;
        var perRow = Math.max(1, Math.ceil(W / unitW) + 2);

        function fillStrip(strip, copies) {
            for (var k = 0; k < copies; k++) {
                var u = document.createElement('span');
                u.textContent = text;
                u.style.marginRight = space + 'px';
                strip.appendChild(u);
            }
        }

        var pLayer = document.createElement('div');
        pLayer.className = 'impulse-textwall-parallax';
        pLayer.style.cssText = 'position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;will-change:transform;';

        var wrap = document.createElement('div');
        wrap.className = 'impulse-textwall-rows';
        wrap.style.cssText = 'display:flex;flex-direction:column;align-items:stretch;width:100%;'
                           + 'row-gap:' + gap + 'px;will-change:transform;';

        var rowEls = [];
        for (var r = 0; r < nRows; r++) {
            var row = document.createElement('div');
            row.className = 'impulse-textwall-row';
            row.style.cssText = 'flex:0 0 auto;overflow:hidden;white-space:nowrap;will-change:opacity,transform;';
            var strip = document.createElement('div');
            strip.className = 'impulse-textwall-strip';
            strip.style.cssText = 'display:inline-block;white-space:nowrap;will-change:transform;';
            fillStrip(strip, (motion === 'scroll') ? perRow * 2 : perRow);
            row.appendChild(strip);
            wrap.appendChild(row);
            rowEls.push({ row: row, strip: strip });
        }
        pLayer.appendChild(wrap);
        el.appendChild(pLayer);

        if (motion === 'scroll') {
            rowEls.forEach(function (o, i) {
                var setW = o.strip.scrollWidth / 2;
                if (setW <= 0) return;
                var dur = Math.max(6000, (setW / (55 * speed)) * 1000);
                var kf = (i % 2 === 0)
                    ? [{ transform: 'translateX(0)' }, { transform: 'translateX(' + (-setW) + 'px)' }]
                    : [{ transform: 'translateX(' + (-setW) + 'px)' }, { transform: 'translateX(0)' }];
                try { el._twAnims.push(o.strip.animate(kf, { duration: dur, iterations: Infinity, easing: 'linear' })); } catch (e) {}
            });
        } else if (motion === 'drift') {
            var durY = Math.max(4000, (stepY / (14 * speed)) * 1000);
            try {
                el._twAnims.push(wrap.animate(
                    [{ transform: 'translateY(0)' }, { transform: 'translateY(' + (-stepY) + 'px)' }],
                    { duration: durY, iterations: Infinity, easing: 'linear' }
                ));
            } catch (e) {}
        }

        

        
        if (spotlight) {
            var _far = 0.12;
            var _c = el._twBaseColor || '';
            var _am = _c.match(/rgba?\([^)]*?,\s*([\d.]+)\s*\)/);
            if (_am) _far = Math.max(0.04, Math.min(0.6, parseFloat(_am[1])));
            var _rgbm = _c.match(/(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
            if (_rgbm) el.style.color = 'rgb(' + _rgbm[1] + ',' + _rgbm[2] + ',' + _rgbm[3] + ')';
            var _diam = parseInt(el.getAttribute('data-tw-spot-size'), 10);
            if (!isFinite(_diam) || _diam < 50) _diam = 600;
            var _mask = 'radial-gradient(circle ' + Math.round(_diam / 2) + 'px at var(--tw-sx,50%) var(--tw-sy,50%), #000 0%, rgba(0,0,0,' + _far + ') 72%)';
            el.style.webkitMaskImage = _mask; el.style.maskImage = _mask;
            var _sraf = null, _sx = 0, _sy = 0;
            function _sApply() { el.style.setProperty('--tw-sx', _sx + 'px'); el.style.setProperty('--tw-sy', _sy + 'px'); _sraf = null; }
            function _sMove(e) {
                var r = el.getBoundingClientRect();
                _sx = e.clientX - r.left; _sy = e.clientY - r.top;
                if (!_sraf) _sraf = requestAnimationFrame(_sApply);
            }
            window.addEventListener('mousemove', _sMove, { passive: true });
            el._twSpotOff = function () { window.removeEventListener('mousemove', _sMove); if (_sraf) cancelAnimationFrame(_sraf); };
        }

        if (parallax) {
            var tx = 0, ty = 0, cx = 0, cy = 0, raf = null;
            var amp = 24;
            function tick() {
                cx += (tx - cx) * 0.08; cy += (ty - cy) * 0.08;
                pLayer.style.transform = 'translate(' + cx.toFixed(1) + 'px,' + cy.toFixed(1) + 'px)';
                if (Math.abs(tx - cx) > 0.15 || Math.abs(ty - cy) > 0.15) { raf = requestAnimationFrame(tick); }
                else { raf = null; }
            }
            function onMove(e) {
                var r = el.getBoundingClientRect();
                if (!r.width || !r.height) return;
                var mx = (e.clientX - (r.left + r.width / 2)) / (r.width / 2);   
                var my = (e.clientY - (r.top + r.height / 2)) / (r.height / 2);
                tx = -Math.max(-1, Math.min(1, mx)) * amp;
                ty = -Math.max(-1, Math.min(1, my)) * amp * 0.55;
                if (!raf) raf = requestAnimationFrame(tick);
            }
            window.addEventListener('mousemove', onMove, { passive: true });
            el._twParallaxOff = function () { window.removeEventListener('mousemove', onMove); if (raf) cancelAnimationFrame(raf); };
        }
    }

    function initAll(root) {
        var scope = root && root.querySelectorAll ? root : document;
        scope.querySelectorAll('.impulse-textwall').forEach(function (el) {
            if (el._twInit) return;
            el._twInit = true;
            build(el);
            if (window.ResizeObserver) {
                var ro = new ResizeObserver(function () {
                    clearTimeout(el._twT);
                    el._twT = setTimeout(function () { build(el); }, 160);
                });
                try { ro.observe(el); } catch (e) {}
                el._twRO = ro;
            }
        });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function () { initAll(document); });
    } else {
        initAll(document);
    }

    window.ImpulseTextWall = { init: initAll, build: build };

    

    
    
    if (window._impulseEditorPreview && window.MutationObserver) {
        var _twMo = new MutationObserver(function (muts) {
            for (var i = 0; i < muts.length; i++) {
                if (muts[i].addedNodes && muts[i].addedNodes.length) {
                    clearTimeout(window._twReinitT);
                    window._twReinitT = setTimeout(function () { initAll(document); }, 80);
                    return;
                }
            }
        });
        try { _twMo.observe(document.body, { childList: true, subtree: true }); } catch (e) {}
    }
})();
