direito

Repositório direito
git clone git://git.sivaldodavi.com/direito.git
Log | Files | Refs

single.html (10200B)


      1 {{ define "title" }}{{ .Title }} · {{ .Site.Title }}{{ end }}
      2 
      3 {{ define "header" }}
      4   {{ $discSlug := .RelPermalink | strings.TrimSuffix "/" | path.Dir | path.Base }}
      5   <a class="site-name" href="{{ "/" | relURL }}">direito</a>
      6   {{ range $.Site.Sections }}
      7     {{ if and (eq .Section "txts") (eq (.RelPermalink | strings.TrimSuffix "/" | path.Base) $discSlug) }}
      8       <span class="header-sep">/</span>
      9       <a class="breadcrumb-link" href="{{ .RelPermalink }}">{{ .Title }}</a>
     10     {{ end }}
     11   {{ end }}
     12   <span class="header-sep">/</span>
     13   <span class="breadcrumb">{{ .Title }}</span>
     14 {{ end }}
     15 
     16 {{ define "main" }}
     17 {{ $slug     := .File.BaseFileName }}
     18 {{ $discSlug := .RelPermalink | strings.TrimSuffix "/" | path.Dir | path.Base }}
     19 
     20 {{/* Encontra quiz do assunto (exercício, não simulado) */}}
     21 {{ $quizPage := false }}
     22 {{ range $.Site.RegularPages }}
     23   {{ if eq .Section "quizzes" }}
     24     {{ $parent := .File.Dir | strings.TrimSuffix "/" | path.Base }}
     25     {{ if and (eq $parent $discSlug) (eq .File.BaseFileName $slug) }}
     26       {{ if not (or (.Params.simulado) (in (.File.BaseFileName | lower) "simulado")) }}
     27         {{ $quizPage = . }}
     28       {{ end }}
     29     {{ end }}
     30   {{ end }}
     31 {{ end }}
     32 
     33 <div class="page-text fade">
     34   <div class="text-meta">
     35     {{ range $.Site.Sections }}
     36       {{ if and (eq .Section "txts") (eq (.RelPermalink | strings.TrimSuffix "/" | path.Base) $discSlug) }}
     37         <span>{{ .Title }}</span><span class="dot"></span>
     38       {{ end }}
     39     {{ end }}
     40     <span>assunto</span>
     41   </div>
     42   <h1 class="text-title">{{ .Title }}</h1>
     43 
     44   {{/* Colapsáveis: guia de estudo e materiais do assunto */}}
     45   {{ $hasExtras := or .Params.guide (or .Params.files (or .Params.videos .Params.audios)) }}
     46   {{ if $hasExtras }}
     47   <div class="disc-extras-wrap">
     48     {{ partial "disc-extras.html" . }}
     49   </div>
     50   {{ end }}
     51 
     52   <nav class="toc" id="toc-nav" style="display:none;" aria-label="Sumário">
     53     <div class="toc-label">sumário</div>
     54     <ol id="toc-list"></ol>
     55   </nav>
     56 
     57   <article class="prose" id="prose">{{ .Content }}</article>
     58 
     59   {{/* Notas de rodapé — renderizadas pelo Hugo automaticamente no .Content;
     60        o floater (footnotes.js) intercepta os links #fn: e mostra tooltip */}}
     61 
     62   {{/* Questões do assunto — quiz inline embutido */}}
     63   {{ if $quizPage }}
     64   <div class="inline-quiz-wrap" id="inline-quiz-section">
     65     <div class="inline-quiz-head">
     66       <span class="sq-label">exercícios deste assunto</span>
     67       <a class="inline-quiz-link" href="{{ $quizPage.RelPermalink }}">modo completo →</a>
     68     </div>
     69     <div id="inline-quiz-body">
     70       <button class="btn btn-start-quiz" id="btn-start-inline" onclick="startInlineQuiz()">
     71         Iniciar exercícios
     72       </button>
     73     </div>
     74     <div id="inline-quiz-player" style="display:none;">
     75       <div class="progress-wrap" style="margin-bottom:.75rem;"><div class="progress-fill" id="iprog"></div></div>
     76       <div class="q-meta" id="iq-counter"></div>
     77       <div id="iq-body"></div>
     78       <div class="next-row">
     79         <button class="btn" id="ibtn-next" onclick="inlineNextQuestion()" style="display:none">próxima →</button>
     80       </div>
     81     </div>
     82     <div id="inline-quiz-result" style="display:none;">
     83       <div class="res-score" id="ires-pct">0%</div>
     84       <div class="res-subtitle"><span id="ires-a">0</span> de <span id="ires-t">0</span> acertos</div>
     85       <div class="res-msg" style="margin-top:1rem;">
     86         <div class="res-msg-label">diagnóstico</div>
     87         <div id="ires-msg"></div>
     88       </div>
     89       <div class="res-btns" style="margin-top:1.2rem;">
     90         <button class="btn" onclick="restartInlineQuiz()">refazer</button>
     91         <a class="btn" href="{{ $quizPage.RelPermalink }}">modo completo</a>
     92       </div>
     93     </div>
     94   </div>
     95   <script>
     96   (function() {
     97     const RAW = {{ $quizPage.RawContent | jsonify | safeJS }};
     98     // Remove frontmatter YAML e notas de rodapé
     99     const body = RAW.replace(/^---[\s\S]*?---\n/, '').replace(/\n\[\^\d+\]:[^\n]*/g, '');
    100     window._IQ = { raw: body, questions: [], idx: 0, acertos: 0, erros: 0, answered: false, flipped: false };
    101   })();
    102 
    103   function startInlineQuiz() {
    104     document.getElementById('btn-start-inline').style.display = 'none';
    105     const qs = prepareQuizQuestions(parseQuizBody(window._IQ.raw));
    106     window._IQ.questions = qs;
    107     window._IQ.idx = 0; window._IQ.acertos = 0; window._IQ.erros = 0;
    108     document.getElementById('inline-quiz-player').style.display = '';
    109     _iqRender();
    110   }
    111 
    112   function _iqRender() {
    113     const q = window._IQ.questions[window._IQ.idx];
    114     if (!q) return;
    115     window._IQ.answered = false; window._IQ.flipped = false;
    116     const total = window._IQ.questions.length;
    117     document.getElementById('iq-counter').textContent = (window._IQ.idx + 1) + ' de ' + total;
    118     document.getElementById('iprog').style.width = ((window._IQ.idx + 1) / total * 100) + '%';
    119     document.getElementById('ibtn-next').style.display = 'none';
    120     const body = document.getElementById('iq-body');
    121     if (q.type === 'mc') {
    122       body.innerHTML = '<div class="mc-area fade"><p class="q-text">' + md(q.text) + '</p><div class="options">'
    123         + q.options.map((o, i) => '<button class="opt" data-opt="' + esc(o) + '" data-answer="' + esc(q.answer) + '" onclick="iqSelectOpt(this)" aria-label="Opção ' + LETRAS[i] + ': ' + o + '"><span class="opt-letter">' + LETRAS[i] + '</span><span>' + md(o) + '</span></button>').join('')
    124         + '</div><div class="feedback-line" id="iq-feedback" aria-live="polite"><span class="feedback-dot"></span><span id="iq-feedback-msg"></span></div>'
    125         + (q.comment ? '<div class="comment-block" id="iq-comment"><div class="comment-label">comentário</div><div>' + md(q.comment) + '</div></div>' : '')
    126         + '</div>';
    127     } else {
    128       body.innerHTML = '<div class="flashcard-area fade"><p class="q-text">' + md(q.text) + '</p>'
    129         + '<div class="flashcard-simple" id="iq-flashcard"><button class="btn btn-reveal" onclick="iqFlip()">Revelar Resposta</button></div>'
    130         + '<div class="feedback-line" id="iq-feedback" aria-live="polite"><span class="feedback-dot"></span><span id="iq-feedback-msg"></span></div>'
    131         + (q.comment ? '<div class="comment-block" id="iq-comment"><div class="comment-label">comentário</div><div>' + md(q.comment) + '</div></div>' : '')
    132         + '<div class="flashcard-btns" id="iq-fc-btns"><button class="btn btn-ok" onclick="iqMarkOk()">✓ Acertei</button><button class="btn btn-bad" onclick="iqMarkBad()">✗ Errei</button></div>'
    133         + '</div>';
    134     }
    135   }
    136 
    137   function iqSelectOpt(btn) {
    138     if (window._IQ.answered) return;
    139     window._IQ.answered = true;
    140     const chosen = btn.dataset.opt, correct = btn.dataset.answer;
    141     btn.closest('.options').querySelectorAll('.opt').forEach(b => {
    142       b.disabled = true;
    143       if (b.dataset.opt === correct) b.classList.add('correct');
    144       else if (b === btn) b.classList.add('wrong');
    145       else b.classList.add('revealed');
    146     });
    147     const ok = chosen === correct;
    148     ok ? window._IQ.acertos++ : window._IQ.erros++;
    149     _iqFeedback(ok, ok ? 'Correto' : 'Incorreto — a correta está destacada');
    150     document.getElementById('iq-comment')?.classList.add('show');
    151     document.getElementById('ibtn-next').style.display = '';
    152   }
    153 
    154   function iqFlip() {
    155     const q = window._IQ.questions[window._IQ.idx];
    156     const card = document.getElementById('iq-flashcard');
    157     if (card) card.innerHTML = '<div class="ref-label">resposta de referência</div><div class="ref-content">' + md(q.reference) + '</div>';
    158     document.getElementById('iq-fc-btns')?.style && (document.getElementById('iq-fc-btns').style.display = '');
    159   }
    160 
    161   function iqMarkOk() { _iqMark(true); }
    162   function iqMarkBad() { _iqMark(false); }
    163   function _iqMark(ok) {
    164     if (window._IQ.answered) return;
    165     window._IQ.answered = true;
    166     ok ? window._IQ.acertos++ : window._IQ.erros++;
    167     _iqFeedback(ok, ok ? 'Marcado como acertado' : 'Marcado como errado');
    168     document.getElementById('iq-comment')?.classList.add('show');
    169     const btns = document.getElementById('iq-fc-btns');
    170     if (btns) btns.innerHTML = '';
    171     document.getElementById('ibtn-next').style.display = '';
    172   }
    173 
    174   function _iqFeedback(ok, msg) {
    175     const fb = document.getElementById('iq-feedback');
    176     if (fb) { fb.className = 'feedback-line show ' + (ok ? 'ok' : 'bad'); }
    177     const fm = document.getElementById('iq-feedback-msg');
    178     if (fm) fm.textContent = msg;
    179   }
    180 
    181   function inlineNextQuestion() {
    182     window._IQ.idx++;
    183     if (window._IQ.idx >= window._IQ.questions.length) {
    184       _iqShowResult();
    185     } else {
    186       _iqRender();
    187     }
    188   }
    189 
    190   function _iqShowResult() {
    191     document.getElementById('inline-quiz-player').style.display = 'none';
    192     document.getElementById('inline-quiz-result').style.display = '';
    193     const { acertos, erros, questions } = window._IQ;
    194     const total = questions.length;
    195     const pct = total ? Math.round(acertos / total * 100) : 0;
    196     document.getElementById('ires-pct').textContent = pct + '%';
    197     document.getElementById('ires-a').textContent = acertos;
    198     document.getElementById('ires-t').textContent = total;
    199     let nivel = pct >= 90 ? 'Excelente' : pct >= 70 ? 'Bom' : pct >= 50 ? 'Regular' : 'Insuficiente';
    200     let det = pct >= 90 ? 'Domínio sólido deste assunto.' : pct >= 70 ? 'Boa base, revise os erros.' : pct >= 50 ? 'Lacunas importantes, releia o texto.' : 'Retome o conteúdo antes de prosseguir.';
    201     document.getElementById('ires-msg').innerHTML = '<strong>' + nivel + '</strong> — ' + acertos + ' de ' + total + ' (' + pct + '%). ' + det;
    202   }
    203 
    204   function restartInlineQuiz() {
    205     document.getElementById('inline-quiz-result').style.display = 'none';
    206     window._IQ.idx = 0; window._IQ.acertos = 0; window._IQ.erros = 0;
    207     window._IQ.questions = prepareQuizQuestions(parseQuizBody(window._IQ.raw));
    208     document.getElementById('inline-quiz-player').style.display = '';
    209     _iqRender();
    210   }
    211   </script>
    212   {{ end }}
    213 
    214   {{ if .Params.references }}
    215   <div class="references">
    216     <div class="ref-head">referências</div>
    217     <div class="ref-list">
    218       {{ range .Params.references }}<p>{{ . }}</p>{{ end }}
    219     </div>
    220   </div>
    221   {{ end }}
    222 </div>
    223 
    224 {{ end }}