Quizlet Nitro

Aggressive unblur, direct JSON-to-CSV export, and turbo speed optimization for Quizlet.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Quizlet Nitro
// @namespace    https://greasyfork.org/users/quizlet-ultra
// @version      1.0.0
// @description  Aggressive unblur, direct JSON-to-CSV export, and turbo speed optimization for Quizlet.
// @author       Ultra
// @match        https://quizlet.com/*
// @icon         https://assets.quizlet.com/a/j/dist/i/favicon.6e263725c926227.ico
// @license      MIT
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    /** 
     * Speed Engine: Blocks heavy tracking (from markers found as of 2/2026, likely persistent for while)
     */
    const killTelemetry = () => {
        window.Snowplow = () => {};
        window.rollbar = { error: () => {}, info: () => {}, warning: () => {} };
        window.ga = () => {};
        window.comscore = {};
    };
    killTelemetry();

    /** 
     * Hard CSS Unfilter: Removes blur/ads/paywalls instantly
     */
    const style = document.createElement('style');
    style.innerHTML = `
        * { filter: none !important; -webkit-filter: none !important; user-select: text !important; }
        .LoginWall, .wugyavo, .LoginBottomBar, .SetPageTermsStickyBanner, 
        .SetPageWall--normal, [data-testid="PayWallOverlay"], .pfdaoy0, .o3dpi86, 
        .pxrylku, footer, a[data-testid="assembly-button-upgrade"],
        .SetPageEmbeddedAd-wrapper, .SiteAd { display: none !important; visibility: hidden !important; }
        * { transition: none !important; animation: none !important; }
        html, body { overflow: auto !important; position: static !important; }
    `;
    document.documentElement.appendChild(style);

    /** 
     * Direct Extraction: Pulls data from internal JSON (no scrolling needed)
     */
    const getCards = () => {
        try {
            const nextData = document.getElementById('__NEXT_DATA__');
            if (!nextData) return [];
            
            const root = JSON.parse(nextData.innerHTML);
            const stateKey = root.props.pageProps.dehydratedReduxStateKey;
            const items = JSON.parse(stateKey).setPage.studiableItems;

            return items.map(i => ({
                t: i.cardSides[0].media[0].plainText,
                d: i.cardSides[1].media[0].plainText
            }));
        } catch (e) {
            // Fallback for non-standard pages
            return Array.from(document.querySelectorAll('.SetPageTermsList-term')).map(row => {
                const text = row.querySelectorAll('.TermText');
                return text.length >= 2 ? { t: text[0].innerText, d: text[1].innerText } : null;
            }).filter(i => i);
        }
    };

    const runExport = () => {
        const cards = getCards();
        if (!cards.length) return alert("Scroll down or refresh to initialize data.");

        let csv = "\uFEFFTerm,Definition\n" + cards.map(c => `"${c.t.replace(/"/g, '""')}","${c.d.replace(/"/g, '""')}"`).join('\n');
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = `${document.title.split('|')[0].trim()}.csv`;
        a.click();
    };

    /** 
     * UI Injection: Minimal floating action button
     */
    const injectUI = () => {
        if (document.getElementById('ultimate-ui')) return;
        const container = document.createElement('div');
        container.id = 'ultimate-ui';
        container.style.cssText = 'position:fixed; bottom:20px; right:20px; z-index:999999; background:#2e3856; padding:12px; border-radius:12px; border:1px solid #4255ff; box-shadow:0 4px 20px rgba(0,0,0,0.4);';
        
        const btn = document.createElement('button');
        btn.innerText = '📥 Export CSV';
        btn.style.cssText = 'background:#3ccabe; color:#fff; border:none; padding:8px 16px; border-radius:6px; font-weight:bold; cursor:pointer; font-family:sans-serif;';
        btn.onclick = runExport;

        container.appendChild(btn);
        document.body.appendChild(container);
    };

    /** 
     * App Monitor: Handles dynamic page changes and unblurs
     */
    const observer = new MutationObserver(() => {
        killTelemetry();
        if (window.location.pathname.match(/\/\d+\//)) injectUI();
        document.querySelectorAll('[style*="blur"]').forEach(el => el.style.setProperty('filter', 'none', 'important'));
    });

    window.addEventListener('load', () => {
        observer.observe(document.body, { childList: true, subtree: true });
        if (window.location.pathname.match(/\/\d+\//)) injectUI();
    });
})();

/**
 * FUTURE TASK: UNLIMITED TEST BYPASS
 * id = window.location.href.match(/quizlet\.com\/.*\/(\d+)\//)[1];
 * url = `https://quizlet.com/${id}/test/embed?questionCount=100`;
 */