| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| lang:joual [2026/02/26 00:13] – wikarai | lang:joual [2026/03/24 22:28] (current) – external edit A User Not Logged in |
|---|
| |
| <html> | <html> |
| <style> | <link rel="stylesheet" href="/den/testing/wiki/joual.css"> |
| /* ========== JOUAL TRANSLATOR – MAIN STYLES ========== */ | |
| #joual-app { | |
| font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; | |
| max-width: 1100px; | |
| margin: 1.5em auto; | |
| color: #e8e6e3; | |
| position: relative; | |
| } | |
| #joual-app *, #joual-app *::before, #joual-app *::after { | |
| box-sizing: border-box; | |
| } | |
| | |
| /* --- Header --- */ | |
| .joual-header { | |
| text-align: center; | |
| padding: 1em 0 0.5em; | |
| } | |
| .joual-header h2 { | |
| margin: 0 0 0.15em; | |
| font-size: 1.6em; | |
| color: #c5a3ff; | |
| letter-spacing: 0.02em; | |
| } | |
| .joual-header .joual-subtitle { | |
| font-size: 0.95em; | |
| color: #9e9e9e; | |
| font-style: italic; | |
| } | |
| | |
| /* --- Controls row --- */ | |
| .joual-controls { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 1em; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 0.75em 0; | |
| margin-bottom: 0.5em; | |
| } | |
| .joual-controls label { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.4em; | |
| cursor: pointer; | |
| font-size: 0.92em; | |
| color: #ccc; | |
| user-select: none; | |
| padding: 0.35em 0.8em; | |
| border-radius: 6px; | |
| background: #2a2a3a; | |
| border: 1px solid #3d3d50; | |
| transition: background 0.2s, border-color 0.2s; | |
| } | |
| .joual-controls label:hover { | |
| background: #353548; | |
| border-color: #6e5aad; | |
| } | |
| .joual-controls input[type="checkbox"] { | |
| accent-color: #9b7ad8; | |
| width: 16px; | |
| height: 16px; | |
| } | |
| | |
| /* --- Main panels --- */ | |
| .joual-panels { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1em; | |
| } | |
| @media (max-width: 700px) { | |
| .joual-panels { grid-template-columns: 1fr; } | |
| } | |
| .joual-panel { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .joual-panel-label { | |
| font-size: 0.85em; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| color: #9e9e9e; | |
| margin-bottom: 0.35em; | |
| padding-left: 0.2em; | |
| } | |
| #joual-input { | |
| width: 100%; | |
| min-height: 260px; | |
| padding: 0.9em; | |
| font-size: 1em; | |
| line-height: 1.55; | |
| border: 1px solid #3d3d50; | |
| border-radius: 8px; | |
| background: #1e1e2e; | |
| color: #e8e6e3; | |
| resize: vertical; | |
| font-family: inherit; | |
| transition: border-color 0.2s; | |
| } | |
| #joual-input:focus { | |
| outline: none; | |
| border-color: #7c5cbf; | |
| } | |
| #joual-input::placeholder { | |
| color: #666; | |
| } | |
| #joual-output { | |
| width: 100%; | |
| min-height: 260px; | |
| padding: 0.9em; | |
| font-size: 1em; | |
| line-height: 1.55; | |
| border: 1px solid #3d3d50; | |
| border-radius: 8px; | |
| background: #1a1a28; | |
| color: #e8e6e3; | |
| overflow-y: auto; | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| } | |
| #joual-output.placeholder { | |
| color: #666; | |
| font-style: italic; | |
| } | |
| | |
| /* --- Substitution highlights --- */ | |
| .joual-sub { | |
| background: rgba(155, 122, 216, 0.18); | |
| color: #d4b8ff; | |
| border-radius: 3px; | |
| padding: 0 2px; | |
| cursor: pointer; | |
| position: relative; | |
| transition: background 0.15s; | |
| border-bottom: 1px dotted rgba(155, 122, 216, 0.5); | |
| } | |
| .joual-sub:hover { | |
| background: rgba(155, 122, 216, 0.35); | |
| } | |
| .joual-sub.cute-sub { | |
| background: rgba(46, 204, 113, 0.18); | |
| color: #2ecc71; | |
| border-bottom-color: rgba(46, 204, 113, 0.45); | |
| } | |
| .joual-sub.cute-sub:hover { | |
| background: rgba(46, 204, 113, 0.35); | |
| } | |
| .joual-sub.grackle-sub { | |
| background: rgba(100, 220, 180, 0.18); | |
| color: #7eedc4; | |
| border-bottom-color: rgba(100, 220, 180, 0.5); | |
| } | |
| .joual-sub.grackle-sub:hover { | |
| background: rgba(100, 220, 180, 0.35); | |
| } | |
| .joual-sub.has-alts { | |
| border-bottom-style: dashed; | |
| border-bottom-width: 2px; | |
| } | |
| | |
| /* --- EN→FR Translate area --- */ | |
| .joual-translate-area { | |
| margin: 1em 0; | |
| padding: 0.8em; | |
| border: 1px solid #3d3d50; | |
| border-radius: 8px; | |
| background: #1e1e2e; | |
| } | |
| .joual-translate-area textarea { | |
| width: 100%; | |
| min-height: 80px; | |
| padding: 0.7em; | |
| font-size: 0.95em; | |
| border: 1px solid #3d3d50; | |
| border-radius: 6px; | |
| background: #1a1a28; | |
| color: #e8e6e3; | |
| resize: vertical; | |
| font-family: inherit; | |
| margin-bottom: 0.5em; | |
| } | |
| .joual-translate-area button { | |
| padding: 0.45em 1.2em; | |
| border: 1px solid #6e5aad; | |
| border-radius: 6px; | |
| background: #3a3a52; | |
| color: #cfcfcf; | |
| cursor: pointer; | |
| font-size: 0.9em; | |
| transition: background 0.15s; | |
| } | |
| .joual-translate-area button:hover:not(:disabled) { | |
| background: #6e5aad; | |
| color: #fff; | |
| } | |
| .joual-translate-area button:disabled { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| } | |
| .joual-translate-links { | |
| margin-top: 0.4em; | |
| font-size: 0.82em; | |
| color: #777; | |
| } | |
| .joual-translate-links a { | |
| color: #9b7ad8; | |
| margin: 0 0.3em; | |
| } | |
| | |
| /* --- Tooltip --- */ | |
| .joual-tooltip { | |
| position: absolute; | |
| z-index: 9999; | |
| background: #2a2a3e; | |
| border: 1px solid #5a4a8a; | |
| border-radius: 8px; | |
| padding: 0.7em 0.9em; | |
| min-width: 220px; | |
| max-width: 380px; | |
| box-shadow: 0 4px 20px rgba(0,0,0,0.45); | |
| font-size: 0.88em; | |
| color: #ddd; | |
| pointer-events: auto; | |
| line-height: 1.5; | |
| } | |
| .joual-tooltip .tt-header { | |
| font-weight: 600; | |
| color: #c5a3ff; | |
| margin-bottom: 0.3em; | |
| font-size: 0.95em; | |
| } | |
| .joual-tooltip .tt-english { | |
| color: #aaa; | |
| font-style: italic; | |
| margin-bottom: 0.5em; | |
| font-size: 0.9em; | |
| } | |
| .joual-tooltip .tt-alts-label { | |
| font-size: 0.8em; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| color: #888; | |
| margin-bottom: 0.25em; | |
| } | |
| .joual-tooltip .tt-alt { | |
| display: inline-block; | |
| padding: 0.2em 0.55em; | |
| margin: 0.15em 0.2em 0.15em 0; | |
| background: #3a3a52; | |
| border: 1px solid #555; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| color: #cfcfcf; | |
| transition: background 0.15s, color 0.15s, border-color 0.15s; | |
| font-size: 0.92em; | |
| } | |
| .joual-tooltip .tt-alt:hover { | |
| background: #6e5aad; | |
| color: #fff; | |
| border-color: #8a72cc; | |
| } | |
| .joual-tooltip .tt-alt.tt-alt-active { | |
| background: #7c5cbf; | |
| color: #fff; | |
| border-color: #9b7ad8; | |
| } | |
| | |
| /* --- Stats bar --- */ | |
| .joual-stats { | |
| text-align: center; | |
| padding: 0.5em 0 0.25em; | |
| font-size: 0.82em; | |
| color: #777; | |
| } | |
| | |
| /* --- Footer --- */ | |
| .joual-footer { | |
| text-align: center; | |
| padding: 0.75em 0; | |
| font-size: 0.78em; | |
| color: #555; | |
| border-top: 1px solid #2a2a3a; | |
| margin-top: 0.75em; | |
| } | |
| </style> | |
| |
| <div id="joual-app"> | <div id="joual-app"> |
| <label title="Strip accents from the input text"> | <label title="Strip accents from the input text"> |
| <input type="checkbox" id="chk-simplify"> <span data-en="Strip accents" data-fr="Supprimer les accents">Strip accents</span> | <input type="checkbox" id="chk-simplify"> <span data-en="Strip accents" data-fr="Supprimer les accents">Strip accents</span> |
| | </label> |
| | <label title="Replace entire phrases with native Québécois idioms. May behave unexpectedly with complex tenses." style="position:relative;"> |
| | <input type="checkbox" id="chk-expr"> <span data-en="Native Expressions ✨ Beta" data-fr="Expressions natives ✨ Bêta" style="color:#e6c84d;">Native Expressions ✨ Beta</span> |
| </label> | </label> |
| </div> | </div> |
| <div class="joual-panels"> | <div class="joual-panels"> |
| <div class="joual-panel"> | <div class="joual-panel"> |
| <div class="joual-panel-label"><span data-en="Formal French (input)" data-fr="Français formel (entrée)">Formal French (input)</span></div> | <div class="joual-panel-label"><span data-en="Formal French (input)" data-fr="Français formel (entrée)">Formal French (input)</span><span style="display:flex;gap:0.4em;margin-left:auto;"><button id="btn-example" type="button" title="Load a random example" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">🎯 Example</button><button id="btn-clear-input" type="button" title="Clear input" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">✕ Clear</button></span></div> |
| <textarea id="joual-input" placeholder="Tapez ou collez du français formel ici... Exemple : Il n'y a personne dans la maison."></textarea> | <textarea id="joual-input" placeholder="Tapez ou collez du français formel ici... Exemple : Il n'y a personne dans la maison."></textarea> |
| </div> | </div> |
| <div class="joual-panel"> | <div class="joual-panel"> |
| <div class="joual-panel-label" style="display:flex;align-items:center;justify-content:space-between;"><span id="joual-output-label" data-en="Joual (output)" data-fr="Joual (sortie)">Joual (output)</span><span style="display:flex;gap:0.4em;"><button id="copy-output-btn" type="button" title="Copy to clipboard" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">📋 Copy</button><button id="btn-share" type="button" title="Share link" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">🔗 Share</button></span></div> | <div class="joual-panel-label" style="display:flex;align-items:center;justify-content:space-between;"><span style="display:flex;align-items:center;gap:0.6em;"><span id="joual-output-label" data-en="Joual (output)" data-fr="Joual (sortie)">Joual (output)</span><span id="joual-legend" style="display:inline-flex;gap:0.5em;align-items:center;font-size:0.85em;color:#aaa;letter-spacing:0;"><span style="display:inline-block;width:10px;height:10px;border-radius:2px;border:1.5px dotted #7c5cbf;background:transparent;"></span>joual <span style="display:inline-block;width:10px;height:10px;border-radius:2px;border:1.5px dotted #6dbf7b;background:transparent;"></span>cute <span style="display:inline-block;width:10px;height:10px;border-radius:2px;border:1.5px dotted #e6c84d;background:transparent;"></span>expr <span style="display:inline-block;width:10px;height:10px;border-radius:2px;border:1.5px dotted #e07843;background:transparent;"></span>critter</span></span><span style="display:flex;gap:0.4em;"><button id="btn-randomize" type="button" title="Shuffle alternatives" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">🎲 Shuffle</button><button id="copy-output-btn" type="button" title="Copy to clipboard" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">📋 Copy</button><button id="btn-share" type="button" title="Share link" style="background:none;border:1px solid #555;border-radius:4px;color:#9e9e9e;font-size:0.75em;padding:1px 7px;cursor:pointer;line-height:1.4;letter-spacing:0;text-transform:none;transition:color 0.2s,border-color 0.2s;" onmouseenter="this.style.color='#e8e6e3';this.style.borderColor='#7c5cbf'" onmouseleave="this.style.color='#9e9e9e';this.style.borderColor='#555'">🔗 Share</button></span></div> |
| <div id="joual-output" class="placeholder" style="white-space: pre-wrap; word-wrap: break-word;">See Joual output appear here automatically | <div id="joual-output" class="placeholder" style="white-space: pre-wrap; word-wrap: break-word;">See Joual output appear here automatically |
| |
| |
| <html> | <html> |
| | <script src="/den/testing/wiki/joual.js"></script> |
| <script> | <script> |
| (function() { | (function() { |
| "use strict"; | "use strict"; |
| |
| // ============================================================ | // Engine reference |
| // THE BIG DICTIONARY | var E = window.JoualEngine; |
| // Each entry: { standard, english, joual:[], cute:[], grackle:[] } | |
| // - joual: default replacements (first is primary) | |
| // - cute: extra-cute mode replacements | |
| // - grackle: grackle-mode replacements (optional) | |
| // ============================================================ | |
| |
| var DICT = [ | // Convenience aliases for frequently-used engine members |
| | var entries = E.entries; |
| // ===================== CRITTER / FURRY SPECIFICS ===================== | var DICT = E.DICT; |
| { standard: "petit oiseau", english: "little bird", joual: ["p'tit oiseau", "p'tit piaf"], cute: ["p'tit-z-oiseau", "p'tit piou-piou"], grackle: ["p'tit quiscale"] }, | var CUTE_CONTRACTIONS = E.CUTE_CONTRACTIONS; |
| { standard: "petite oiseau", english: "little bird (f)", joual: ["p'tite oiseau"], cute: ["p'tite piou-piou"] }, | |
| { standard: "nuage", english: "cloud / cloud-realm", joual: ["nuageiller", "nuage"], cute: ["nuageiller", "nunu-nuage"] }, | |
| { standard: "mousse", english: "soft lint / nesting material", joual: ["moussi", "mousse"], cute: ["moussi-doux"] }, | |
| { standard: "charpie", english: "lint / nesting fluff", joual: ["moussi", "charpie"], cute: ["moussi-doux", "p'tite charpie"] }, | |
| { standard: "sorti de sa cage", english: "freed / out of the cage", joual: ["sorti d'sa cage", "libre comme l'air"], cute: ["sorti d'sa p'tite cage"] }, | |
| { standard: "sortie de sa cage", english: "freed / out of the cage (f)", joual: ["sortie d'sa cage"], cute: ["sortie d'sa p'tite cage"] }, | |
| { standard: "mon amour", english: "my love", joual: ["p'tit coeur", "mon amour"], cute: ["p'tit coeur d'amour", "mon p'tit trésor"] }, | |
| { standard: "mon ami", english: "my friend", joual: ["mon chum", "mon ami"], cute: ["mon p'tit chum"] }, | |
| { standard: "mon amie", english: "my friend (f)", joual: ["ma chum", "mon amie"], cute: ["ma p'tite chum"] }, | |
| { standard: "travailler dur", english: "to work hard", joual: ["bûcher fort", "travailler dur"], cute: ["bûcher comme un p'tit castor"] }, | |
| { standard: "faire son nid", english: "to make one's nest", joual: ["faire son nid", "nicher"], cute: ["faire son p'tit nid douillet"] }, | |
| { standard: "voler dans le ciel", english: "to fly in the sky", joual: ["planer dans l'ciel", "voler dans l'ciel"], cute: ["planer dans l'beau ciel"], grackle: ["planer comme un quiscale dans l'ciel"] }, | |
| { standard: "chanter une chanson", english: "to sing a song", joual: ["piailler une toune", "chanter une chanson"], cute: ["piailler une p'tite toune"] }, | |
| { standard: "manger des graines", english: "to eat seeds", joual: ["grignoter des graines", "manger des graines"], cute: ["grignoter des p'tites graines"] }, | |
| { standard: "plume", english: "feather", joual: ["plume", "penne"], cute: ["p'tite plume"], grackle: ["plume de quiscale"] }, | |
| { standard: "nid", english: "nest", joual: ["nid", "nique"], cute: ["p'tit nid"] }, | |
| { standard: "bec", english: "beak", joual: ["bec"], cute: ["p'tit bec"] }, | |
| { standard: "aile", english: "wing", joual: ["aile", "aileron"], cute: ["p'tite aile"] }, | |
| { standard: "griffe", english: "claw", joual: ["griffe", "serre"], cute: ["p'tite griffe"] }, | |
| { standard: "queue", english: "tail", joual: ["queue"], cute: ["p'tite queue"] }, | |
| { standard: "fourrure", english: "fur", joual: ["fourrure", "pelage"], cute: ["p'tite fourrure douce"] }, | |
| { standard: "museau", english: "snout / muzzle", joual: ["museau", "p'tit nez"], cute: ["p'tit museau"] }, | |
| { standard: "moustache", english: "whiskers", joual: ["moustache", "vibrisses"], cute: ["p'tites moustaches"] }, | |
| { standard: "patte", english: "paw", joual: ["patte"], cute: ["p'tite patte"] }, | |
| { standard: "oeuf", english: "egg", joual: ["oeuf", "coco"], cute: ["p'tit coco"] }, | |
| { standard: "corneille", english: "crow", joual: ["corneille", "cornaille"], cute: ["p'tite corneille"] }, | |
| { standard: "corbeau", english: "raven", joual: ["corbeau"], cute: ["gros corbeau noir"] }, | |
| { standard: "canard", english: "duck", joual: ["canard"], cute: ["p'tit canard", "ti-canard"] }, | |
| { standard: "rat", english: "rat", joual: ["rat"], cute: ["p'tit rat", "ti-rat"] }, | |
| { standard: "souris", english: "mouse", joual: ["souris"], cute: ["p'tite souris"] }, | |
| { standard: "chat", english: "cat", joual: ["minou", "chat"], cute: ["p'tit minou"] }, | |
| { standard: "chien", english: "dog", joual: ["pitou", "chien"], cute: ["p'tit pitou"] }, | |
| | |
| // ===================== GRACKLE-IZE / CRITTER-IZE ===================== | |
| { standard: "gagner", english: "to win", joual: ["gagner", "l'emporter"], cute: ["gagner"], grackle: ["pogner le fromage", "attraper le fromage"] }, | |
| { standard: "brillant", english: "brilliant / shiny", joual: ["brillant", "luisant"], cute: ["tout brillant"], grackle: ["comme un rayon de soleil", "brillant comme un scarabée"] }, | |
| { standard: "magnifique", english: "magnificent", joual: ["magnifique", "écoeurant"], cute: ["trop beau"], grackle: ["iridescent comme un quiscale", "majestueux comme un orignal"] }, | |
| { standard: "superbe", english: "superb", joual: ["superbe", "malade"], cute: ["trop beau"], grackle: ["iridescent en tabarnouche"] }, | |
| { standard: "victoire", english: "victory", joual: ["victoire"], cute: ["victoire"], grackle: ["victoire de quiscale", "le fromage est pogné", "le ver est attrapé"] }, | |
| { standard: "triomphe", english: "triumph", joual: ["triomphe"], cute: ["triomphe"], grackle: ["triomphe iridescent", "triomphe du terrier"] }, | |
| { standard: "briller", english: "to shine", joual: ["briller", "reluire"], cute: ["briller fort"], grackle: ["briller comme un quiscale au soleil", "reluire comme une plume mouillée"] }, | |
| { standard: "fierté", english: "pride", joual: ["fierté"], cute: ["fierté"], grackle: ["fierté de quiscale", "fierté du nid"] }, | |
| { standard: "réussir", english: "to succeed", joual: ["réussir", "l'avoir"], cute: ["réussir"], grackle: ["pogner le fromage", "grackle-izer ça"] }, | |
| { standard: "célébrer", english: "to celebrate", joual: ["fêter", "célébrer"], cute: ["fêter en titi"], grackle: ["croasser de joie", "faire la danse du quiscale"] }, | |
| { standard: "courage", english: "courage", joual: ["courage", "guts"], cute: ["courage"], grackle: ["courage de quiscale", "coeur de critter"] }, | |
| { standard: "force", english: "strength", joual: ["force", "force"], cute: ["p'tite force"], grackle: ["force de grizzli", "force du castor"] }, | |
| { standard: "rapide", english: "fast / quick", joual: ["vite", "rapide"], cute: ["vite-vite"], grackle: ["vite comme un écureuil", "rapide comme un faucon"] }, | |
| { standard: "courageux", english: "brave", joual: ["courageux", "brave"], cute: ["ben courageux"], grackle: ["brave comme un blaireau"] }, | |
| { standard: "courageuse", english: "brave (f)", joual: ["courageuse", "brave"], cute: ["ben courageuse"], grackle: ["brave comme une corneille"] }, | |
| { standard: "trésor", english: "treasure", joual: ["trésor"], cute: ["p'tit trésor"], grackle: ["trésor du nid", "butin d'écureuil"] }, | |
| { standard: "aventure", english: "adventure", joual: ["aventure", "trip"], cute: ["p'tite aventure"], grackle: ["expédition de critter", "vol de quiscale"] }, | |
| { standard: "malin", english: "clever / cunning", joual: ["malin", "smatte"], cute: ["smatte en titi"], grackle: ["malin comme un renard", "futé comme une corneille"] }, | |
| { standard: "maligne", english: "clever (f)", joual: ["maligne", "smatte"], cute: ["smatte en titi"], grackle: ["maligne comme une renarde"] }, | |
| { standard: "excellent", english: "excellent", joual: ["excellent", "écoeurant"], cute: ["trop bon"], grackle: ["excellent comme un vol de quiscale"] }, | |
| { standard: "succès", english: "success", joual: ["succès"], cute: ["succès"], grackle: ["succès du nid", "succès de quiscale"] }, | |
| { standard: "câlin", english: "cuddle / hug", joual: ["câlin", "bec"], cute: ["p'tit câlin", "huggle"], grackle: ["câlin de critter", "pelotage de fourrure"] }, | |
| { standard: "câline", english: "cuddle (f) / hug", joual: ["câline", "bec"], cute: ["p'tite câline", "huggle"], grackle: ["câline de critter"] }, | |
| { standard: "embrasser", english: "to hug / to kiss", joual: ["embrasser", "donner un bec"], cute: ["huggler", "donner un p'tit bec"], grackle: ["faire un câlin de critter"] }, | |
| { standard: "caresser", english: "to pet / to caress", joual: ["caresser", "flatter"], cute: ["flatter doucement", "huggler"], grackle: ["gratter derrière les oreilles"] }, | |
| { standard: "accomplissement", english: "accomplishment", joual: ["accomplissement"], cute: ["accomplissement"], grackle: ["le ver est attrapé", "le fromage est pogné"] }, | |
| { standard: "exploit", english: "feat / exploit", joual: ["exploit"], cute: ["exploit"], grackle: ["exploit de quiscale", "vol de maître"] }, | |
| { standard: "champion", english: "champion", joual: ["champion"], cute: ["p'tit champion"], grackle: ["roi du perchoir", "champion du nid"] }, | |
| { standard: "championne", english: "champion (f)", joual: ["championne"], cute: ["p'tite championne"], grackle: ["reine du perchoir", "championne du nid"] }, | |
| { standard: "héros", english: "hero", joual: ["héros"], cute: ["p'tit héros"], grackle: ["héros du terrier", "quiscale intrépide"] }, | |
| { standard: "incroyable", english: "incredible", joual: ["incroyable", "écoeurant"], cute: ["écoeurant en titi"], grackle: ["iridescent en masse"] }, | |
| { standard: "formidable", english: "great / wonderful", joual: ["formidable", "écoeurant"], cute: ["écoeurant"], grackle: ["iridescent comme un quiscale"] }, | |
| { standard: "impressionnant", english: "impressive", joual: ["impressionnant", "malade"], cute: ["malade en titi"], grackle: ["majestueux comme un orignal"] }, | |
| { standard: "merveilleux", english: "wonderful", joual: ["merveilleux", "écoeurant"], cute: ["trop beau"], grackle: ["beau comme un vol de bernaches"] }, | |
| { standard: "merveilleuse", english: "wonderful (f)", joual: ["merveilleuse", "écoeurant"], cute: ["trop belle"], grackle: ["belle comme une aurore boréale"] }, | |
| { standard: "fantastique", english: "fantastic", joual: ["fantastique", "malade"], cute: ["malade en titi"], grackle: ["fantastique comme un quiscale au soleil"] }, | |
| { standard: "extraordinaire", english: "extraordinary", joual: ["extraordinaire", "débile"], cute: ["débile en titi"], grackle: ["extraordinaire comme un vol d'outardes"] }, | |
| { standard: "sensationnel", english: "sensational", joual: ["sensationnel", "écoeurant"], cute: ["écoeurant en titi"], grackle: ["iridescent à l'os"] }, | |
| { standard: "prodigieux", english: "prodigious", joual: ["prodigieux", "débile"], cute: ["débile"], grackle: ["prodigieux comme un castor"] }, | |
| { standard: "glorieux", english: "glorious", joual: ["glorieux"], cute: ["glorieux en titi"], grackle: ["glorieux comme un quiscale au matin"] }, | |
| { standard: "écureuil", english: "squirrel", joual: ["écureuil"], cute: ["p'tit écureuil"], grackle: ["p'tit bandit du chêne"] }, | |
| { standard: "renard", english: "fox", joual: ["renard"], cute: ["p'tit renard"], grackle: ["renard du boisé"] }, | |
| { standard: "orignal", english: "moose", joual: ["orignal"], cute: ["gros orignal"], grackle: ["roi du bois"] }, | |
| { standard: "castor", english: "beaver", joual: ["castor"], cute: ["p'tit castor"], grackle: ["ingénieur du ruisseau"] }, | |
| { standard: "loup", english: "wolf", joual: ["loup"], cute: ["p'tit loup"], grackle: ["loup du nord"] }, | |
| { standard: "ours", english: "bear", joual: ["ours"], cute: ["gros nounours"], grackle: ["gardien de la forêt"] }, | |
| { standard: "lapin", english: "rabbit", joual: ["lapin"], cute: ["p'tit lapin"], grackle: ["coureur du pré"] }, | |
| { standard: "cerf", english: "deer", joual: ["chevreuil", "cerf"], cute: ["p'tit chevreuil"], grackle: ["danseur du bois"] }, | |
| { standard: "hibou", english: "owl", joual: ["hibou"], cute: ["p'tit hibou"], grackle: ["sage du boisé"] }, | |
| { standard: "grenouille", english: "frog", joual: ["grenouille"], cute: ["p'tite grenouille"], grackle: ["chanteuse du marais"] }, | |
| { standard: "tortue", english: "turtle", joual: ["tortue"], cute: ["p'tite tortue"], grackle: ["sage du ruisseau"] }, | |
| { standard: "papillon", english: "butterfly", joual: ["papillon"], cute: ["p'tit papillon"], grackle: ["danseur du vent"] }, | |
| | |
| // ===================== LONG PHRASES & IDIOMS (match first!) ===================== | |
| { standard: "c'est bien fait", english: "well done", joual: ["c'est gratiné"], cute: ["c'est gratiné en titi"] }, | |
| { standard: "la voiture", english: "the car", joual: ["la voiture", "le char"], cute: ["la voiture", "le p'tit char"] }, | |
| { standard: "une voiture", english: "a car", joual: ["une voiture", "un char"], cute: ["une voiture", "un p'tit char"] }, | |
| { standard: "ma voiture", english: "my car", joual: ["mon char"], cute: ["mon p'tit char"] }, | |
| { standard: "ta voiture", english: "your car", joual: ["ton char"], cute: ["ton p'tit char"] }, | |
| { standard: "sa voiture", english: "his/her car", joual: ["son char"], cute: ["son p'tit char"] }, | |
| { standard: "la forêt", english: "the forest", joual: ["la forêt", "le bois"], cute: ["la forêt", "le p'tit bois"] }, | |
| { standard: "une forêt", english: "a forest", joual: ["une forêt", "un bois"], cute: ["une forêt", "un p'tit bois"] }, | |
| { standard: "ne lâche pas", english: "don't give up", joual: ["lâche pas la patate", "lâche pas"], cute: ["lâche surtout pas la patate"], grackle: ["lâche pas le fromage"] }, | |
| { standard: "n'abandonne pas", english: "don't give up", joual: ["lâche pas la patate", "abandonne pas"], cute: ["lâche pas pantoute"] }, | |
| { standard: "dormir paisiblement", english: "to sleep peacefully", joual: ["dormir sur ses deux oreilles", "dormir ben"], cute: ["dormir sur ses deux p'tites oreilles"] }, | |
| { standard: "dormir tranquille", english: "to sleep peacefully", joual: ["dormir sur ses deux oreilles"], cute: ["dormir su' ses deux p'tites oreilles"] }, | |
| { standard: "tout de suite", english: "right away", joual: ["tu suite", "drette-là"], cute: ["tu suite là-là"] }, | |
| { standard: "quelque chose", english: "something", joual: ["de quoi", "queuqu'chose"], cute: ["de quoi de l'fun"] }, | |
| { standard: "quelque part", english: "somewhere", joual: ["queuqu'part", "quelque part"], cute: ["queuqu'part par là"] }, | |
| { standard: "quelqu'un", english: "someone", joual: ["queuqu'un", "quelqu'un"], cute: ["queuqu'un là-bas"] }, | |
| { standard: "il y a", english: "there is / there are", joual: ["y'a", "y a"], cute: ["y'a"] }, | |
| { standard: "il n'y a", english: "there is not", joual: ["y'a", "y a"], cute: ["y'a"] }, | |
| { standard: "il n'y a rien", english: "there is nothing", joual: ["y'a rien", "y a rien pantoute"], cute: ["y'a rien pantoute"] }, | |
| { standard: "ce n'est", english: "it is not", joual: ["c'est", "c'"], cute: ["c'est"] }, | |
| { standard: "c'est fini", english: "it's done / it's over", joual: ["c'est fait", "j'l'ai eu"], cute: ["c'est faite là"] }, | |
| { standard: "c'est bon", english: "it's good / it's fine", joual: ["c'est correct", "c'est tiguidou"], cute: ["c'est tiguidou là"] }, | |
| { standard: "c'est mauvais", english: "it's bad", joual: ["c'est poche", "c'est pas bon"], cute: ["c'est ben poche"] }, | |
| { standard: "c'est beau", english: "it's beautiful", joual: ["c'est beau en titi", "c'est beau"], cute: ["c'est beau en p'tit péché"] }, | |
| { standard: "c'est difficile", english: "it's difficult", joual: ["c'est tough", "c'est rough"], cute: ["c'est pas mal tough"] }, | |
| { standard: "c'est facile", english: "it's easy", joual: ["c'est easy", "c'est un jeu d'enfant"], cute: ["c'est easy-peasy"] }, | |
| { standard: "c'est cher", english: "it's expensive", joual: ["c'est cher en tabarnouche", "c'est cher"], cute: ["c'est cher en titi"] }, | |
| { standard: "c'est gratuit", english: "it's free", joual: ["c'est gratis", "c'est gratuit"], cute: ["c'est gratis là"] }, | |
| { standard: "c'est génial", english: "it's awesome", joual: ["c'est malade", "c'est écoeurant"], cute: ["c'est trop malade"] }, | |
| { standard: "c'est terrible", english: "it's terrible", joual: ["c'est épouvantable", "c'est terrible"], cute: ["c'est épouvantable en titi"] }, | |
| { standard: "c'est drôle", english: "it's funny", joual: ["c'est drôle en tabarnouche", "c'est comique"], cute: ["c'est ben drôle"] }, | |
| { standard: "c'est incroyable", english: "it's incredible", joual: ["c'est écoeurant", "c'est débile"], cute: ["c'est tellement écoeurant"] }, | |
| { standard: "c'est vrai", english: "it's true", joual: ["c'est vrai", "pour vrai"], cute: ["pour vrai là"] }, | |
| { standard: "bien fait", english: "well done / perfect", joual: ["gratiné", "ben fait"], cute: ["gratiné en titi"] }, | |
| { standard: "bien sûr", english: "of course", joual: ["ben oui", "c'est sûr"], cute: ["ben oui donc"] }, | |
| { standard: "pas du tout", english: "not at all", joual: ["pantoute", "pas du tout"], cute: ["pantoute pantoute"] }, | |
| { standard: "pas de problème", english: "no problem", joual: ["pas d'trouble", "pas de problème"], cute: ["pas d'trouble pantoute"] }, | |
| { standard: "en tout cas", english: "in any case", joual: ["en tk", "en tout cas"], cute: ["en tk là"] }, | |
| { standard: "de toute façon", english: "anyway", joual: ["anyway", "de toute façon"], cute: ["anyway là"] }, | |
| { standard: "à côté de", english: "next to / beside", joual: ["su'l bord de", "à côté de"], cute: ["su'l bord de"] }, | |
| { standard: "en face de", english: "across from", joual: ["en face de", "drette en face"], cute: ["drette en face de"] }, | |
| { standard: "très bientôt", english: "very soon", joual: ["tantôt", "très bientôt"], cute: ["ben tantôt"] }, | |
| { standard: "à plus tard", english: "see you later", joual: ["à tantôt", "à plus"], cute: ["à tantôt là"] }, | |
| { standard: "au revoir", english: "goodbye", joual: ["bye", "à tantôt"], cute: ["bye-bye là"] }, | |
| { standard: "bonne nuit", english: "good night", joual: ["bonne nuit", "dors ben"], cute: ["dors ben là", "fais de beaux rêves"] }, | |
| { standard: "bonne journée", english: "have a good day", joual: ["bonne journée", "passe une belle journée"], cute: ["bonne journée là"] }, | |
| { standard: "bonne chance", english: "good luck", joual: ["bonne chance", "lâche pas"], cute: ["bonne chance là"] }, | |
| { standard: "comment ça va", english: "how are you", joual: ["comment ça va", "ça va-tu"], cute: ["pis, ça va-tu"] }, | |
| { standard: "ça ne fait rien", english: "it doesn't matter", joual: ["ça fait rien", "c'pas grave"], cute: ["c'pas grave pantoute"] }, | |
| { standard: "ça fait longtemps", english: "it's been a long time", joual: ["ça fait un boutte", "ça fait longtemps"], cute: ["ça fait un méchant boutte"] }, | |
| { standard: "je suis fatigué", english: "I am tired", joual: ["j'suis brûlé", "j'suis magané"], cute: ["j'sus brûlé en titi"] }, | |
| { standard: "je suis fatiguée", english: "I am tired (f)", joual: ["j'suis brûlée", "j'suis maganée"], cute: ["j'sus brûlée en titi"] }, | |
| { standard: "je suis content", english: "I am happy", joual: ["j'suis content en titi", "j'suis content"], cute: ["j'sus content en p'tit péché"] }, | |
| { standard: "je suis contente", english: "I am happy (f)", joual: ["j'suis contente en titi", "j'suis contente"], cute: ["j'sus contente en p'tit péché"] }, | |
| { standard: "j'ai faim", english: "I'm hungry", joual: ["j'ai les crocs", "j'ai une faim de loup"], cute: ["j'ai une faim de p'tit loup"] }, | |
| { standard: "j'ai soif", english: "I'm thirsty", joual: ["j'ai soif en tabarnouche", "j'ai soif"], cute: ["j'ai soif en titi"] }, | |
| { standard: "j'ai froid", english: "I'm cold", joual: ["j'ai frette", "j'ai froid"], cute: ["j'ai frette en titi"] }, | |
| { standard: "j'ai chaud", english: "I'm hot", joual: ["j'ai chaud en tabarnouche", "j'ai chaud"], cute: ["j'ai chaud en titi"] }, | |
| { standard: "j'ai peur", english: "I'm afraid", joual: ["j'ai la chienne", "j'ai peur"], cute: ["j'ai la p'tite chienne"] }, | |
| { standard: "j'en ai assez", english: "I've had enough", joual: ["j'en ai mon voyage", "j'en ai assez"], cute: ["j'en ai mon maudit voyage"] }, | |
| { standard: "je m'en vais", english: "I'm leaving", joual: ["m'en vas", "j'm'en vas"], cute: ["m'en vas là"] }, | |
| { standard: "je ne sais", english: "I don't know", joual: ["j'sais", "ché"], cute: ["ché"] }, | |
| { standard: "je ne comprends", english: "I don't understand", joual: ["j'comprends", "j'catch"], cute: ["j'catch"] }, | |
| { standard: "qu'est-ce que c'est", english: "what is it", joual: ["kossé ça", "c'est quoi ça"], cute: ["kossé ça là"] }, | |
| { standard: "qu'est-ce que tu fais", english: "what are you doing", joual: ["kossé tu fais", "tu fais quoi"], cute: ["kossé tu fais là"] }, | |
| { standard: "qu'est-ce que", english: "what (interrogative)", joual: ["kossé", "c'est quoi"], cute: ["kossé"] }, | |
| { standard: "n'est-ce pas", english: "isn't it / right?", joual: ["hein", "han"], cute: ["hein là"] }, | |
| { standard: "il fait froid", english: "it's cold (weather)", joual: ["y fait frette", "y fait froid"], cute: ["y fait frette en tabarnouche"] }, | |
| { standard: "il fait chaud", english: "it's hot (weather)", joual: ["y fait chaud en tabarnouche", "y fait chaud"], cute: ["y fait chaud en titi"] }, | |
| { standard: "il pleut", english: "it's raining", joual: ["y mouille", "y pleut"], cute: ["y mouille en masse"] }, | |
| { standard: "il neige", english: "it's snowing", joual: ["y neige", "y tombe de la neige"], cute: ["y neige en tabarnouche"] }, | |
| { standard: "ferme ta bouche", english: "shut your mouth", joual: ["farme ta yeule", "farme-la"], cute: ["farme donc ta yeule"] }, | |
| { standard: "tais-toi", english: "be quiet", joual: ["farme-la", "farme ta yeule"], cute: ["farme-la donc"] }, | |
| { standard: "dépêche-toi", english: "hurry up", joual: ["grouille-toi", "enweille"], cute: ["grouille-toé donc"] }, | |
| { standard: "viens ici", english: "come here", joual: ["viens icitte", "arrive icitte"], cute: ["viens icitte là"] }, | |
| { standard: "va-t'en", english: "go away / get out", joual: ["décrisse", "sacre ton camp"], cute: ["décrisse de là"] }, | |
| { standard: "je t'aime", english: "I love you", joual: ["j't'aime", "je t'aime"], cute: ["j't'aime gros"] }, | |
| { standard: "s'il te plaît", english: "please (informal)", joual: ["s'te plaît", "s'teu plaît"], cute: ["s'te plaît là"] }, | |
| { standard: "s'il vous plaît", english: "please (formal)", joual: ["s'vous plaît", "s'il vous plaît"], cute: ["s'vous plaît là"] }, | |
| { standard: "je vais bien", english: "I'm doing well", joual: ["ça va ben", "j'vas ben"], cute: ["ça va pas pire"] }, | |
| { standard: "excuse-moi", english: "excuse me", joual: ["'scuse", "excuse"], cute: ["'scuse-moé"] }, | |
| { standard: "je suis désolé", english: "I'm sorry", joual: ["j'suis désolé", "m'excuse"], cute: ["m'excuse là"] }, | |
| { standard: "je suis désolée", english: "I'm sorry (f)", joual: ["j'suis désolée", "m'excuse"], cute: ["m'excuse là"] }, | |
| { standard: "pas de souci", english: "no worries", joual: ["pas d'trouble", "c'est correct"], cute: ["pas d'trouble pantoute"] }, | |
| { standard: "attention", english: "watch out / careful", joual: ["attention", "watch out"], cute: ["attention là"] }, | |
| { standard: "j'en ai marre", english: "I'm fed up", joual: ["j'en ai mon voyage", "j'suis tanné"], cute: ["j'suis tanné en titi"] }, | |
| | |
| // ===================== COMMON VERBS ===================== | |
| { standard: "travailler", english: "to work", joual: ["travailler", "bûcher"], cute: ["m'ostiner avec la machine"], grackle: ["bûcher comme un quiscale"] }, | |
| { standard: "regarder", english: "to look / to watch", joual: ["checker", "guetter"], cute: ["checker"] }, | |
| { standard: "manger", english: "to eat", joual: ["manger"], cute: ["grignoter"] }, | |
| { standard: "dormir", english: "to sleep", joual: ["dormir", "roupiller"], cute: ["faire un p'tit dodo"] }, | |
| { standard: "parler", english: "to speak / to talk", joual: ["jaser", "placoter"], cute: ["placoter"] }, | |
| { standard: "comprendre", english: "to understand", joual: ["catcher", "comprendre"], cute: ["catcher"] }, | |
| { standard: "aimer", english: "to love / to like", joual: ["aimer", "tripper"], cute: ["tripper su'"] }, | |
| { standard: "acheter", english: "to buy", joual: ["acheter", "pogner"], cute: ["pogner"] }, | |
| { standard: "chercher", english: "to look for", joual: ["chercher", "scruter"], cute: ["scruter"] }, | |
| { standard: "conduire", english: "to drive", joual: ["chauffer", "driver"], cute: ["driver"] }, | |
| { standard: "tomber", english: "to fall", joual: ["tomber", "débouler"], cute: ["débouler"] }, | |
| { standard: "ennuyer", english: "to annoy / to bother", joual: ["achaler", "gosser"], cute: ["achaler"] }, | |
| { standard: "courir", english: "to run", joual: ["courir", "galoper"], cute: ["galoper"] }, | |
| { standard: "sauter", english: "to jump", joual: ["sauter", "bondir"], cute: ["bondir"] }, | |
| { standard: "nager", english: "to swim", joual: ["nager", "barboter"], cute: ["barboter"] }, | |
| { standard: "crier", english: "to shout / to yell", joual: ["crier", "criailler"], cute: ["criailler"] }, | |
| { standard: "chanter", english: "to sing", joual: ["chanter", "piailler"], cute: ["piailler"] }, | |
| { standard: "jouer", english: "to play", joual: ["jouer", "niaiser"], cute: ["niaiser"] }, | |
| { standard: "se cacher", english: "to hide", joual: ["se cacher", "se terrer"], cute: ["se terrer"] }, | |
| { standard: "se battre", english: "to fight", joual: ["se chamailler", "se pogner"], cute: ["se pogner"] }, | |
| { standard: "se dépêcher", english: "to hurry", joual: ["se grouiller", "grouiller"], cute: ["se grouiller vite-vite"] }, | |
| { standard: "commencer", english: "to start / to begin", joual: ["commencer", "starter"], cute: ["starter"] }, | |
| { standard: "finir", english: "to finish", joual: ["finir", "boucler"], cute: ["boucler ça"] }, | |
| { standard: "attendre", english: "to wait", joual: ["attendre", "espérer"], cute: ["espérer"] }, | |
| { standard: "essayer", english: "to try", joual: ["essayer", "tester"], cute: ["essayer don'"] }, | |
| { standard: "oublier", english: "to forget", joual: ["oublier", "forgetter"], cute: ["oublier"] }, | |
| { standard: "revenir", english: "to come back", joual: ["revenir", "r'venir"], cute: ["r'venir"] }, | |
| { standard: "partir", english: "to leave", joual: ["partir", "sacrer son camp"], cute: ["s'en aller"] }, | |
| { standard: "arriver", english: "to arrive", joual: ["arriver", "débarquer"], cute: ["débarquer"] }, | |
| { standard: "rester", english: "to stay / to live", joual: ["rester", "demeurer"], cute: ["rester"] }, | |
| { standard: "penser", english: "to think", joual: ["penser", "jongler"], cute: ["jongler"] }, | |
| { standard: "croire", english: "to believe", joual: ["croire", "crère"], cute: ["crère"] }, | |
| { standard: "donner", english: "to give", joual: ["donner", "passer"], cute: ["passer"] }, | |
| { standard: "prendre", english: "to take", joual: ["prendre", "pogner"], cute: ["pogner"] }, | |
| { standard: "laisser", english: "to leave / to let", joual: ["laisser", "lâcher"], cute: ["lâcher"] }, | |
| { standard: "perdre", english: "to lose", joual: ["perdre", "paumer"], cute: ["paumer"] }, | |
| { standard: "trouver", english: "to find", joual: ["trouver", "dénicher"], cute: ["dénicher"] }, | |
| { standard: "montrer", english: "to show", joual: ["montrer", "shower"], cute: ["shower"] }, | |
| { standard: "aider", english: "to help", joual: ["aider", "donner un coup de main"], cute: ["donner un p'tit coup de main"] }, | |
| { standard: "demander", english: "to ask", joual: ["demander", "checker"], cute: ["checker"] }, | |
| { standard: "répondre", english: "to answer", joual: ["répondre", "répondre"], cute: ["répondre"] }, | |
| { standard: "écouter", english: "to listen", joual: ["écouter", "entendre"], cute: ["écouter"] }, | |
| { standard: "voir", english: "to see", joual: ["voir", "watcher"], cute: ["watcher"] }, | |
| { standard: "sentir", english: "to feel / to smell", joual: ["sentir", "feeler"], cute: ["feeler"] }, | |
| { standard: "toucher", english: "to touch", joual: ["toucher", "tâter"], cute: ["tâter"] }, | |
| { standard: "casser", english: "to break", joual: ["casser", "péter"], cute: ["péter"] }, | |
| { standard: "réparer", english: "to fix / to repair", joual: ["réparer", "patcher"], cute: ["patcher"] }, | |
| { standard: "jeter", english: "to throw", joual: ["jeter", "garrocher"], cute: ["garrocher"] }, | |
| { standard: "lancer", english: "to throw / to launch", joual: ["lancer", "garrocher"], cute: ["garrocher"] }, | |
| { standard: "frapper", english: "to hit", joual: ["frapper", "fesser"], cute: ["fesser"] }, | |
| { standard: "glisser", english: "to slide / to slip", joual: ["glisser", "slider"], cute: ["slider"] }, | |
| { standard: "voler", english: "to fly / to steal", joual: ["voler", "s'envoler"], cute: ["s'envoler"] }, | |
| { standard: "nicher", english: "to nest", joual: ["nicher", "se nicher"], cute: ["se nicher"] }, | |
| | |
| // IMPERSONAL "IL EST" → "C'EST" (phrase entries — must precede standalone "il est") | |
| { standard: "il est temps", english: "it's time", joual: ["c'est l'temps"], cute: ["c'est l'temps"] }, | |
| { standard: "il est nécessaire", english: "it's necessary", joual: ["c'est nécessaire"], cute: ["c'est nécessaire"] }, | |
| { standard: "il est important", english: "it's important", joual: ["c'est important"], cute: ["c'est important"] }, | |
| { standard: "il est préférable", english: "it's preferable", joual: ["c'est mieux", "c'est préférable"], cute: ["c'est mieux"] }, | |
| { standard: "il est probable", english: "it's probable", joual: ["c'est probable"], cute: ["c'est probable"] }, | |
| { standard: "il est certain", english: "it's certain", joual: ["c'est certain", "c'est sûr"], cute: ["c'est sûr"] }, | |
| { standard: "il est essentiel", english: "it's essential", joual: ["c'est essentiel"], cute: ["c'est essentiel"] }, | |
| { standard: "il est conseillé", english: "it's recommended", joual: ["c'est conseillé"], cute: ["c'est conseillé"] }, | |
| { standard: "il est dangereux", english: "it's dangerous", joual: ["c'est dangereux"], cute: ["c'est dangereux"] }, | |
| { standard: "il est facile", english: "it's easy", joual: ["c'est facile"], cute: ["c'est facile"] }, | |
| { standard: "il est difficile", english: "it's difficult", joual: ["c'est dur", "c'est difficile"], cute: ["c'est dur"] }, | |
| { standard: "il est rare", english: "it's rare", joual: ["c'est rare"], cute: ["c'est rare"] }, | |
| { standard: "il est interdit", english: "it's forbidden", joual: ["c'est interdit"], cute: ["c'est interdit"] }, | |
| { standard: "il est dommage", english: "it's a shame", joual: ["c'est dommage", "c'est plate"], cute: ["c'est plate"] }, | |
| { standard: "il est utile", english: "it's useful", joual: ["c'est utile"], cute: ["c'est utile"] }, | |
| { standard: "il est injuste", english: "it's unfair", joual: ["c'est pas juste", "c'est injuste"], cute: ["c'est pas juste"] }, | |
| { standard: "il est frustrant", english: "it's frustrating", joual: ["c'est frustrant"], cute: ["c'est frustrant"] }, | |
| { standard: "il est étrange", english: "it's strange", joual: ["c'est bizarre", "c'est étrange"], cute: ["c'est bizarre"] }, | |
| { standard: "il est fascinant", english: "it's fascinating", joual: ["c'est fascinant"], cute: ["c'est fascinant"] }, | |
| { standard: "il est regrettable", english: "it's regrettable", joual: ["c'est plate"], cute: ["c'est plate"] }, | |
| { standard: "il est impératif de", english: "it's imperative to", joual: ["faut"], cute: ["faut"] }, | |
| { standard: "il est impératif", english: "it's imperative", joual: ["c'est impératif"], cute: ["faut"] }, | |
| { standard: "il est possible", english: "it's possible", joual: ["c'est possible"], cute: ["c'est possible"] }, | |
| { standard: "il est parfois", english: "it's sometimes", joual: ["c'est des fois", "c'est parfois"], cute: ["c'est des fois"] }, | |
| | |
| // ===================== PRONOUNS & VERB PHRASES ===================== | |
| { standard: "je suis", english: "I am", joual: ["j'suis", "m'as être"], cute: ["j'sus", "j'suis"] }, | |
| { standard: "tu es", english: "you are", joual: ["t'es", "tu es"], cute: ["t'es"] }, | |
| { standard: "il est", english: "he is", joual: ["y'est", "il est"], cute: ["y'est"] }, | |
| { standard: "elle est", english: "she is", joual: ["a'est", "elle est"], cute: ["a l'est"] }, | |
| { standard: "nous sommes", english: "we are", joual: ["on est", "nous sommes"], cute: ["on est"] }, | |
| { standard: "vous êtes", english: "you are (formal/plural)", joual: ["vous êtes", "vous-z-êtes"], cute: ["vous êtes"] }, | |
| { standard: "ils sont", english: "they are (m)", joual: ["y sont", "ils sont"], cute: ["y sont"] }, | |
| { standard: "elles sont", english: "they are (f)", joual: ["y sont", "elles sont"], cute: ["y sont"] }, | |
| { standard: "je vais", english: "I'm going to", joual: ["j'vas", "m'as"], cute: ["m'as"] }, | |
| { standard: "tu vas", english: "you're going to", joual: ["tu vas", "tu va"], cute: ["tu va"] }, | |
| { standard: "il va", english: "he's going to", joual: ["y va", "il va"], cute: ["y va"] }, | |
| { standard: "elle va", english: "she's going to", joual: ["a va", "elle va"], cute: ["a va"] }, | |
| { standard: "on va", english: "we're going to", joual: ["on va", "on s'en va"], cute: ["on va"] }, | |
| { standard: "nous allons", english: "we are going", joual: ["on s'en va", "nous allons"], cute: ["on s'en va"] }, | |
| { standard: "ils vont", english: "they are going (m)", joual: ["y vont", "ils vont"], cute: ["y vont"] }, | |
| { standard: "elles vont", english: "they are going (f)", joual: ["y vont", "elles vont"], cute: ["y vont"] }, | |
| { standard: "je peux", english: "I can", joual: ["j'peux", "j'suis capable"], cute: ["j'peux-tu"] }, | |
| { standard: "tu peux", english: "you can", joual: ["tu peux", "t'es capable"], cute: ["tu peux-tu"] }, | |
| { standard: "je veux", english: "I want", joual: ["j'veux", "je veux"], cute: ["j'veux"] }, | |
| { standard: "tu veux", english: "you want", joual: ["tu veux", "veux-tu"], cute: ["tu veux-tu"] }, | |
| { standard: "je fais", english: "I do / I make", joual: ["j'fais", "je fais"], cute: ["j'fais"] }, | |
| { standard: "tu fais", english: "you do / you make", joual: ["tu fais", "tu fais-tu"], cute: ["tu fais"] }, | |
| { standard: "il fait", english: "he does / it makes", joual: ["y fait", "il fait"], cute: ["y fait"] }, | |
| { standard: "je sais", english: "I know", joual: ["j'sais", "j'sé"], cute: ["j'sé"] }, | |
| { standard: "tu sais", english: "you know", joual: ["tsé", "tu sais"], cute: ["tsé"] }, | |
| { standard: "je pense", english: "I think", joual: ["j'pense", "j'cré ben"], cute: ["j'cré ben"] }, | |
| { standard: "je crois", english: "I believe", joual: ["j'cré", "j'pense"], cute: ["j'cré ben"] }, | |
| { standard: "je mange", english: "I eat", joual: ["j'mange", "je mange"], cute: ["j'mange"] }, | |
| { standard: "je parle", english: "I speak", joual: ["j'parle", "j'jase"], cute: ["j'jase"] }, | |
| { standard: "je regarde", english: "I look / I watch", joual: ["j'checke", "j'regarde"], cute: ["j'checke"] }, | |
| { standard: "je travaille", english: "I work", joual: ["j'travaille", "j'bûche"], cute: ["j'bûche"] }, | |
| { standard: "j'ai", english: "I have", joual: ["j'ai", "j'ai"], cute: ["j'ai"] }, | |
| { standard: "tu as", english: "you have", joual: ["t'as", "tu as"], cute: ["t'as"] }, | |
| { standard: "il a", english: "he has", joual: ["y'a", "il a"], cute: ["y'a"] }, | |
| { standard: "elle a", english: "she has", joual: ["a l'a", "elle a"], cute: ["a l'a"] }, | |
| { standard: "on a", english: "we have (informal)", joual: ["on a", "on a"], cute: ["on a"] }, | |
| | |
| // ===================== PREPOSITIONS & ARTICLES ===================== | |
| { standard: "sur le", english: "on the (m)", joual: ["su'l", "sur le"], cute: ["su'l"] }, | |
| { standard: "sur la", english: "on the (f)", joual: ["su'a", "sur la"], cute: ["su'a"] }, | |
| { standard: "dans le", english: "in the (m)", joual: ["dans'l", "dans le"], cute: ["dans'l"] }, | |
| { standard: "dans la", english: "in the (f)", joual: ["dans'a", "dans la"], cute: ["dans'a"] }, | |
| { standard: "avec", english: "with", joual: ["avec", "ak"], cute: ["ak"] }, | |
| { standard: "parce que", english: "because", joual: ["pasque", "parsque"], cute: ["pasque"] }, | |
| { standard: "puisque", english: "since / because", joual: ["pisque", "puisque"], cute: ["pisque"] }, | |
| { standard: "lorsque", english: "when", joual: ["lorsque", "quand"], cute: ["quand"] }, | |
| { standard: "pendant que", english: "while", joual: ["pendant que", "tandis que"], cute: ["pendant que"] }, | |
| { standard: "ce soir", english: "tonight / this evening", joual: ["à soir", "ce soir"], cute: ["à soir"] }, | |
| { standard: "ce matin", english: "this morning", joual: ["à matin", "ce matin"], cute: ["à matin"] }, | |
| { standard: "cet après-midi", english: "this afternoon", joual: ["à après-midi", "cet après-midi"], cute: ["à après-midi"] }, | |
| | |
| // ===================== ADVERBS & MODIFIERS ===================== | |
| { standard: "très", english: "very", joual: ["ben", "très"], cute: ["ben ben"] }, | |
| { standard: "beaucoup", english: "a lot / much", joual: ["en masse", "ben gros"], cute: ["en masse"] }, | |
| { standard: "tellement", english: "so much", joual: ["tellement", "en masse"], cute: ["tellement"] }, | |
| { standard: "vraiment", english: "really", joual: ["vraiment", "pour vrai"], cute: ["pour vrai"] }, | |
| { standard: "peut-être", english: "maybe / perhaps", joual: ["p't'être", "peut-être"], cute: ["p't'être ben"] }, | |
| { standard: "maintenant", english: "now", joual: ["astheure", "à c't'heure"], cute: ["astheure là"] }, | |
| { standard: "ici", english: "here", joual: ["icitte", "ici"], cute: ["icitte"] }, | |
| { standard: "là-bas", english: "over there", joual: ["là-bas", "par là"], cute: ["par là-là"] }, | |
| { standard: "dehors", english: "outside", joual: ["dehors", "en d'hors"], cute: ["en d'hors"] }, | |
| { standard: "dedans", english: "inside", joual: ["en d'dans", "dedans"], cute: ["en d'dans"] }, | |
| { standard: "aussi", english: "also / too", joual: ["aussi", "itou"], cute: ["itou"] }, | |
| { standard: "encore", english: "still / again", joual: ["encore", "en masse"], cute: ["encore"] }, | |
| { standard: "toujours", english: "always", joual: ["toujours", "tout le temps"], cute: ["tout le temps"] }, | |
| { standard: "souvent", english: "often", joual: ["souvent", "des fois"], cute: ["souvent"] }, | |
| { standard: "parfois", english: "sometimes", joual: ["des fois", "parfois"], cute: ["des fois"] }, | |
| { standard: "jamais", english: "never", joual: ["jamais", "à grandeur"], cute: ["jamais"] }, | |
| { standard: "absolument", english: "absolutely", joual: ["absolument", "mets-en"], cute: ["absolument", "mets-en"] }, | |
| { standard: "certainement", english: "certainly", joual: ["pour sûr", "certainement"], cute: ["pour sûr"] }, | |
| { standard: "finalement", english: "finally", joual: ["finalement", "en fin de compte"], cute: ["finalement"] }, | |
| { standard: "seulement", english: "only", joual: ["juste", "seulement"], cute: ["juste"] }, | |
| { standard: "rapidement", english: "quickly", joual: ["vite", "rapidement"], cute: ["vite-vite"] }, | |
| { standard: "lentement", english: "slowly", joual: ["lentement", "doucement"], cute: ["tranquillement"] }, | |
| { standard: "soudainement", english: "suddenly", joual: ["d'un coup", "soudainement"], cute: ["d'un coup sec"] }, | |
| { standard: "évidemment", english: "obviously", joual: ["c'est sûr", "évidemment"], cute: ["c'est sûr là"] }, | |
| { standard: "normalement", english: "normally", joual: ["normalement", "d'habitude"], cute: ["d'habitude"] }, | |
| { standard: "heureusement", english: "fortunately", joual: ["heureusement", "chance"], cute: ["heureusement"] }, | |
| | |
| // ===================== NOUNS & THINGS ===================== | |
| { standard: "homme", english: "man", joual: ["bonhomme", "gars"], cute: ["p'tit bonhomme"] }, | |
| { standard: "femme", english: "woman", joual: ["bonne femme", "fille"], cute: ["p'tite madame"] }, | |
| { standard: "enfant", english: "child", joual: ["p'tit", "kid"], cute: ["p'tit bout d'chou"] }, | |
| { standard: "enfants", english: "children", joual: ["enfants", "flos"], cute: ["p'tits bouts d'chou"] }, | |
| { standard: "garçon", english: "boy", joual: ["gars", "garçon"], cute: ["p'tit gars"] }, | |
| { standard: "fille", english: "girl", joual: ["fille", "fille"], cute: ["p'tite fille"] }, | |
| { standard: "maison", english: "house", joual: ["cabane", "maison"], cute: ["p'tite cabane"] }, | |
| { standard: "voiture", english: "car", joual: ["voiture", "char"], cute: ["p'tit char"] }, | |
| { standard: "argent", english: "money", joual: ["cash", "piasses"], cute: ["cash"] }, | |
| { standard: "dollar", english: "dollar", joual: ["piasse", "dollar"], cute: ["piasse"] }, | |
| { standard: "nourriture", english: "food", joual: ["bouffe", "grub"], cute: ["p'tite bouffe"] }, | |
| { standard: "crème glacée", english: "ice cream", joual: ["crème à glace"], cute: ["p'tite crème à glace"] }, | |
| { standard: "petit-déjeuner", english: "breakfast", joual: ["déjeuner"], cute: ["p'tit déjeuner"] }, | |
| { standard: "petit déjeuner", english: "breakfast", joual: ["déjeuner"], cute: ["p'tit déjeuner"] }, | |
| { standard: "bière", english: "beer", joual: ["bière", "frette"], cute: ["p'tite frette"] }, | |
| { standard: "eau", english: "water", joual: ["eau", "de l'eau"], cute: ["eau", "de l'eau"] }, | |
| { standard: "café", english: "coffee", joual: ["café", "café"], cute: ["p'tit café"] }, | |
| { standard: "neige", english: "snow", joual: ["neige", "poudrerie"], cute: ["belle neige"] }, | |
| { standard: "vent", english: "wind", joual: ["vent", "nordet"], cute: ["vent"] }, | |
| { standard: "soleil", english: "sun", joual: ["soleil", "soleil"], cute: ["beau soleil"] }, | |
| { standard: "lune", english: "moon", joual: ["lune", "lune"], cute: ["belle lune"] }, | |
| { standard: "étoile", english: "star", joual: ["étoile", "étoile"], cute: ["p'tite étoile"] }, | |
| { standard: "forêt", english: "forest", joual: ["forêt", "bois"], cute: ["p'tit bois"] }, | |
| { standard: "rivière", english: "river", joual: ["rivière", "cours d'eau"], cute: ["p'tite rivière"] }, | |
| { standard: "montagne", english: "mountain", joual: ["montagne", "montagne"], cute: ["grosse montagne"] }, | |
| { standard: "chemin", english: "road / path", joual: ["chemin", "route"], cute: ["p'tit chemin"] }, | |
| { standard: "le travail", english: "the work", joual: ["la job"], cute: ["la p'tite job"] }, | |
| { standard: "du travail", english: "of work", joual: ["de la job"], cute: ["de la p'tite job"] }, | |
| { standard: "au travail", english: "at work", joual: ["au travail", "à la job"], cute: ["à la p'tite job"] }, | |
| { standard: "travail", english: "work / job", joual: ["job", "ouvrage"], cute: ["p'tite job"] }, | |
| { standard: "problème", english: "problem", joual: ["trouble", "problème"], cute: ["trouble"] }, | |
| { standard: "chose", english: "thing", joual: ["affaire", "chose"], cute: ["affaire"] }, | |
| { standard: "temps", english: "time / weather", joual: ["temps", "temps"], cute: ["temps"] }, | |
| { standard: "journée", english: "day", joual: ["journée", "journée"], cute: ["journée"] }, | |
| { standard: "soirée", english: "evening", joual: ["soirée", "veillée"], cute: ["p'tite veillée"] }, | |
| { standard: "matin", english: "morning", joual: ["matin", "de bonne heure"], cute: ["matin"] }, | |
| { standard: "histoire", english: "story", joual: ["histoire", "conte"], cute: ["p'tite histoire"] }, | |
| { standard: "chanson", english: "song", joual: ["toune", "chanson"], cute: ["p'tite toune"] }, | |
| { standard: "musique", english: "music", joual: ["musique", "musique"], cute: ["musique"] }, | |
| { standard: "fête", english: "party / celebration", joual: ["party", "fête"], cute: ["p'tit party"] }, | |
| { standard: "cadeau", english: "gift", joual: ["cadeau", "cadeau"], cute: ["p'tit cadeau"] }, | |
| { standard: "ami", english: "friend", joual: ["chum", "ami"], cute: ["p'tit chum"] }, | |
| { standard: "amie", english: "friend (f)", joual: ["chum", "amie"], cute: ["p'tite chum"] }, | |
| { standard: "copain", english: "boyfriend / buddy", joual: ["chum", "copain"], cute: ["chum"] }, | |
| { standard: "copine", english: "girlfriend / buddy (f)", joual: ["blonde", "copine"], cute: ["blonde"] }, | |
| { standard: "voisin", english: "neighbor", joual: ["voisin", "voisin"], cute: ["p'tit voisin"] }, | |
| { standard: "voisine", english: "neighbor (f)", joual: ["voisine", "voisine"], cute: ["p'tite voisine"] }, | |
| { standard: "patron", english: "boss", joual: ["boss", "patron"], cute: ["boss"] }, | |
| { standard: "bébé", english: "baby", joual: ["bébé", "bébé"], cute: ["p'tit bébé"] }, | |
| { standard: "magasin", english: "store / shop", joual: ["magasin", "dépanneur"], cute: ["dép"] }, | |
| { standard: "école", english: "school", joual: ["école", "école"], cute: ["école"] }, | |
| { standard: "église", english: "church", joual: ["église", "église"], cute: ["église"] }, | |
| { standard: "cuisine", english: "kitchen", joual: ["cuisine", "cuisine"], cute: ["cuisine", "p'tite cuisine"] }, | |
| { standard: "chambre", english: "bedroom", joual: ["chambre", "chambre"], cute: ["p'tite chambre"] }, | |
| { standard: "téléphone", english: "phone", joual: ["téléphone", "cell"], cute: ["cell"] }, | |
| { standard: "ordinateur", english: "computer", joual: ["ordi", "ordinateur"], cute: ["ordi"] }, | |
| | |
| // ===================== ADJECTIVES ===================== | |
| { standard: "beau", english: "beautiful / handsome", joual: ["beau", "pas pire"], cute: ["beau en titi"] }, | |
| { standard: "belle", english: "beautiful (f)", joual: ["belle", "pas pire"], cute: ["belle en titi"] }, | |
| { standard: "laid", english: "ugly", joual: ["laitte", "laid"], cute: ["ben laitte"] }, | |
| { standard: "laide", english: "ugly (f)", joual: ["laitte", "laide"], cute: ["ben laitte"] }, | |
| { standard: "gros", english: "big / fat", joual: ["gros", "gros"], cute: ["gros"] }, | |
| { standard: "grosse", english: "big / fat (f)", joual: ["grosse", "grosse"], cute: ["grosse"] }, | |
| { standard: "petit", english: "small / little", joual: ["p'tit", "petit"], cute: ["p'tit"] }, | |
| { standard: "petite", english: "small / little (f)", joual: ["p'tite", "petite"], cute: ["p'tite"] }, | |
| { standard: "grand", english: "tall / big", joual: ["grand", "grand"], cute: ["grand"] }, | |
| { standard: "grande", english: "tall / big (f)", joual: ["grande", "grande"], cute: ["grande"] }, | |
| { standard: "vite", english: "fast / quick", joual: ["vite", "vite"], cute: ["vite-vite"] }, | |
| { standard: "lent", english: "slow", joual: ["lent", "slow"], cute: ["lent"] }, | |
| { standard: "chaud", english: "hot / warm", joual: ["chaud", "chaud"], cute: ["chaud"] }, | |
| { standard: "froid", english: "cold", joual: ["frette", "froid"], cute: ["frette"] }, | |
| { standard: "froide", english: "cold (f)", joual: ["frette", "froide"], cute: ["frette"] }, | |
| { standard: "bon", english: "good", joual: ["bon", "correct"], cute: ["bon"] }, | |
| { standard: "bonne", english: "good (f)", joual: ["bonne", "correcte"], cute: ["bonne"] }, | |
| { standard: "mauvais", english: "bad", joual: ["poche", "pas bon"], cute: ["poche"] }, | |
| { standard: "mauvaise", english: "bad (f)", joual: ["poche", "pas bonne"], cute: ["poche"] }, | |
| { standard: "nouveau", english: "new (m)", joual: ["nouveau", "neuf"], cute: ["nouveau"] }, | |
| { standard: "nouvelle", english: "new (f)", joual: ["nouvelle", "neuve"], cute: ["nouvelle"] }, | |
| { standard: "vieux", english: "old (m)", joual: ["vieux", "fripé"], cute: ["vieux"] }, | |
| { standard: "vieille", english: "old (f)", joual: ["vieille", "fripée"], cute: ["vieille"] }, | |
| { standard: "content", english: "happy / pleased", joual: ["content", "content"], cute: ["content en titi"] }, | |
| { standard: "contente", english: "happy / pleased (f)", joual: ["contente", "contente"], cute: ["contente en titi"] }, | |
| { standard: "triste", english: "sad", joual: ["triste", "down"], cute: ["triste"] }, | |
| { standard: "fâché", english: "angry (m)", joual: ["en beau maudit", "fâché"], cute: ["en beau maudit"] }, | |
| { standard: "fâchée", english: "angry (f)", joual: ["en beau maudit", "fâchée"], cute: ["en beau maudit"] }, | |
| { standard: "fatigué", english: "tired (m)", joual: ["brûlé", "magané"], cute: ["brûlé"] }, | |
| { standard: "fatiguée", english: "tired (f)", joual: ["brûlée", "maganée"], cute: ["brûlée"] }, | |
| { standard: "malade", english: "sick", joual: ["malade", "poqué"], cute: ["poqué"] }, | |
| { standard: "drôle", english: "funny", joual: ["drôle", "comique"], cute: ["drôle en titi"] }, | |
| { standard: "gentil", english: "kind / nice (m)", joual: ["gentil", "fin"], cute: ["fin en titi"] }, | |
| { standard: "gentille", english: "kind / nice (f)", joual: ["gentille", "fine"], cute: ["fine en titi"] }, | |
| { standard: "méchant", english: "mean / nasty (m)", joual: ["méchant", "bête"], cute: ["méchant"] }, | |
| { standard: "méchante", english: "mean / nasty (f)", joual: ["méchante", "bête"], cute: ["méchante"] }, | |
| { standard: "intelligent", english: "smart (m)", joual: ["intelligent", "smart"], cute: ["smart en titi"] }, | |
| { standard: "intelligente", english: "smart (f)", joual: ["intelligente", "smatte"], cute: ["smatte en titi"] }, | |
| { standard: "stupide", english: "stupid", joual: ["épais", "niaiseux"], cute: ["épais"] }, | |
| { standard: "bizarre", english: "weird / strange", joual: ["bizarre", "capotant"], cute: ["capotant"] }, | |
| { standard: "parfait", english: "perfect (m)", joual: ["parfait", "tiguidou"], cute: ["tiguidou"] }, | |
| { standard: "parfaite", english: "perfect (f)", joual: ["parfaite", "tiguidou"], cute: ["tiguidou"] }, | |
| { standard: "horrible", english: "horrible", joual: ["épouvantable", "horrible"], cute: ["épouvantable"] }, | |
| { standard: "possible", english: "possible", joual: ["possible", "faisable"], cute: ["possible"] }, | |
| { standard: "impossible", english: "impossible", joual: ["impossible", "pas faisable"], cute: ["pas faisable pantoute"] }, | |
| { standard: "regrettable", english: "regrettable / unfortunate", joual: ["plate", "regrettable"], cute: ["plate"] }, | |
| { standard: "prêt", english: "ready (m)", joual: ["prêt", "paré"], cute: ["paré"] }, | |
| { standard: "prête", english: "ready (f)", joual: ["prête", "parée"], cute: ["parée"] }, | |
| { standard: "occupé", english: "busy (m)", joual: ["occupé", "dans l'jus"], cute: ["dans l'jus"] }, | |
| { standard: "occupée", english: "busy (f)", joual: ["occupée", "dans l'jus"], cute: ["dans l'jus"] }, | |
| { standard: "tranquille", english: "quiet / calm", joual: ["tranquille", "chill"], cute: ["tranquille"] }, | |
| | |
| // ===================== GREETINGS & SOCIAL ===================== | |
| { standard: "bonjour", english: "hello / good day", joual: ["allo", "salut"], cute: ["allo là"] }, | |
| { standard: "salut", english: "hi / bye", joual: ["salut", "allo"], cute: ["salut là"] }, | |
| { standard: "merci", english: "thank you", joual: ["merci ben", "merci"], cute: ["merci ben gros"] }, | |
| { standard: "merci beaucoup", english: "thank you very much", joual: ["merci ben gros", "merci en masse"], cute: ["merci ben ben gros"] }, | |
| { standard: "oui", english: "yes", joual: ["ouais", "ouin"], cute: ["ouais"] }, | |
| { standard: "non", english: "no", joual: ["non", "pantoute"], cute: ["non"] }, | |
| { standard: "d'accord", english: "okay / agreed", joual: ["d'accord"], cute: ["ok là", "d'accord"] }, | |
| { standard: "félicitations", english: "congratulations", joual: ["bravo", "félicitations"], cute: ["bravo là"] }, | |
| | |
| // ===================== NUMBERS & QUANTITIES ===================== | |
| { standard: "un peu", english: "a little", joual: ["un peu", "un p'tit peu"], cute: ["un ti-peu"] }, | |
| { standard: "trop", english: "too much", joual: ["trop", "en masse"], cute: ["trop"] }, | |
| { standard: "assez", english: "enough", joual: ["assez", "en masse"], cute: ["en masse"] }, | |
| { standard: "plusieurs", english: "several / many", joual: ["plusieurs", "une gang de"], cute: ["une gang de"] }, | |
| { standard: "tout", english: "all / everything", joual: ["tout", "toute"], cute: ["toute"] }, | |
| { standard: "tous", english: "all (plural)", joual: ["tous", "toutes"], cute: ["toutes"] }, | |
| { standard: "rien", english: "nothing", joual: ["rien", "rien pantoute"], cute: ["rien pantoute"] }, | |
| { standard: "personne", english: "no one / person", joual: ["personne", "personne"], cute: ["personne pantoute"] }, | |
| | |
| // ===================== MILD SACRES (flavor) ===================== | |
| { standard: "zut", english: "darn", joual: ["tabarnouche", "câline"], cute: ["tabarnouche"] }, | |
| { standard: "mince", english: "darn / dang", joual: ["mautadit", "câline"], cute: ["câline de bine"] }, | |
| { standard: "flûte", english: "shoot / darn", joual: ["simonac", "batince"], cute: ["simonac"] }, | |
| { standard: "merde", english: "damn / shit", joual: ["câlice", "crisse"], cute: ["câline"] }, | |
| { standard: "mon dieu", english: "my god", joual: ["mon dieu", "seigneur"], cute: ["ayoye"] }, | |
| | |
| // ===================== EXTRA PHRASES & IDIOMS ===================== | |
| { standard: "avoir du plaisir", english: "to have fun", joual: ["avoir du fun", "avoir du plaisir"], cute: ["avoir ben du fun"] }, | |
| { standard: "avoir raison", english: "to be right", joual: ["avoir raison", "avoir raison"], cute: ["avoir raison en titi"] }, | |
| { standard: "avoir tort", english: "to be wrong", joual: ["avoir tort", "avoir tort"], cute: ["avoir tort"] }, | |
| { standard: "avoir besoin", english: "to need", joual: ["avoir besoin", "avoir de besoin"], cute: ["avoir de besoin"] }, | |
| { standard: "avoir envie", english: "to feel like", joual: ["avoir envie", "avoir le goût"], cute: ["avoir le goût"] }, | |
| { standard: "avoir hâte", english: "to look forward to", joual: ["avoir hâte", "avoir ben hâte"], cute: ["avoir hâte en titi"] }, | |
| { standard: "faire attention", english: "to be careful", joual: ["faire attention", "watcher"], cute: ["fais attention là"] }, | |
| { standard: "faire la fête", english: "to party", joual: ["fêter", "faire le party"], cute: ["faire un méchant party"] }, | |
| { standard: "prendre un verre", english: "to have a drink", joual: ["prendre un verre", "caler une bière"], cute: ["prendre une p'tite frette"] }, | |
| { standard: "prendre soin", english: "to take care", joual: ["prendre soin", "s'occuper"], cute: ["prendre ben soin"] }, | |
| { standard: "tomber amoureux", english: "to fall in love", joual: ["tomber en amour", "tomber amoureux"], cute: ["tomber en amour"] }, | |
| { standard: "tomber amoureuse", english: "to fall in love (f)", joual: ["tomber en amour", "tomber amoureuse"], cute: ["tomber en amour"] }, | |
| { standard: "être en retard", english: "to be late", joual: ["être en retard", "être en r'tard"], cute: ["être en r'tard"] }, | |
| { standard: "être pressé", english: "to be in a hurry", joual: ["être pressé", "être dans l'jus"], cute: ["être dans l'jus"] }, | |
| { standard: "être occupé", english: "to be busy", joual: ["être occupé", "être dans l'jus"], cute: ["être dans l'jus"] }, | |
| { standard: "se sentir bien", english: "to feel good", joual: ["se sentir ben", "feeler bon"], cute: ["feeler bon en titi"] }, | |
| { standard: "se sentir mal", english: "to feel bad", joual: ["se sentir mal", "feeler mal"], cute: ["feeler poche"] }, | |
| { standard: "en avoir assez", english: "to have enough", joual: ["en avoir mon voyage", "en avoir assez"], cute: ["en avoir mon maudit voyage"] }, | |
| { standard: "être d'accord", english: "to agree", joual: ["être d'accord"], cute: ["être ok ak ça", "être d'accord"] }, | |
| { standard: "laisser tomber", english: "to drop / to give up", joual: ["laisser tomber", "lâcher ça"], cute: ["lâcher ça là"] }, | |
| { standard: "mettre la table", english: "to set the table", joual: ["mettre la table", "mettre la table"], cute: ["mettre la p'tite table"] }, | |
| { standard: "se lever", english: "to get up", joual: ["se lever", "se lever"], cute: ["se lever de bonne heure"] }, | |
| { standard: "se coucher", english: "to go to bed", joual: ["se coucher", "se coucher"], cute: ["aller se coucher"] }, | |
| { standard: "s'en aller", english: "to leave / to go", joual: ["s'en aller", "décrisser"], cute: ["s'en aller"] }, | |
| { standard: "aller chercher", english: "to go get", joual: ["aller chercher", "aller qu'ri"], cute: ["aller qu'ri"] }, | |
| | |
| // ===================== SINGLE IMPORTANT WORDS (fallbacks) ===================== | |
| { standard: "je", english: "I", joual: ["j'", "je"], cute: ["j'"] }, | |
| { standard: "tu", english: "you", joual: ["tu", "t'"], cute: ["tu"] }, | |
| { standard: "il", english: "he / it", joual: ["y", "il"], cute: ["y"] }, | |
| { standard: "elle", english: "she / it", joual: ["a", "elle"], cute: ["a"] }, | |
| { standard: "ils", english: "they (m)", joual: ["y", "ils"], cute: ["y"] }, | |
| { standard: "elles", english: "they (f)", joual: ["y", "elles"], cute: ["y"] }, | |
| { standard: "cela", english: "that", joual: ["ça", "cela"], cute: ["ça"] }, | |
| { standard: "ceci", english: "this", joual: ["ça", "ceci"], cute: ["ça"] }, | |
| { standard: "mais", english: "but", joual: ["mais", "mais"], cute: ["mais"] }, | |
| { standard: "et", english: "and", joual: ["pis", "et"], cute: ["pis"] }, | |
| { standard: "donc", english: "so / therefore", joual: ["faque", "donc"], cute: ["faque"] }, | |
| { standard: "voyons donc", english: "come on", joual: ["voyons donc"], cute: ["voyons donc"] }, | |
| { standard: "alors", english: "so / then", joual: ["faque", "ben"], cute: ["faque là"] }, | |
| { standard: "ensuite", english: "then / next", joual: ["après ça", "ensuite"], cute: ["après ça"] }, | |
| { standard: "cependant", english: "however", joual: ["par exemple", "cependant"], cute: ["par exemple"] }, | |
| { standard: "pourtant", english: "yet / however", joual: ["pourtant", "pareil"], cute: ["pareil"] }, | |
| { standard: "pourquoi", english: "why", joual: ["pourquoi", "comment ça"], cute: ["pourquoi don'"] }, | |
| { standard: "comment", english: "how", joual: ["comment", "comment"], cute: ["comment don'"] }, | |
| { standard: "quand", english: "when", joual: ["quand", "quand c'est que"], cute: ["quand"] }, | |
| { standard: "combien", english: "how much / how many", joual: ["combien", "combien"], cute: ["combien don'"] }, | |
| { standard: "ou", english: "or", joual: ["ou"], cute: ["ou"] }, | |
| { standard: "où", english: "where", joual: ["où", "oùsque"], cute: ["oùsque"] }, | |
| { standard: "qui", english: "who", joual: ["qui", "qui c'est"], cute: ["qui c'est"] }, | |
| { standard: "quoi", english: "what", joual: ["quoi", "quossé"], cute: ["quossé"] } | |
| ]; | |
| | |
| // ============================================================ | |
| // CUTE-PASS CONTRACTIONS (applied after main replacement) | |
| // These are micro-contractions for the "Extra-Cute" mode. | |
| // ============================================================ | |
| | |
| var CUTE_CONTRACTIONS = [ | |
| { pattern: /\btu es\b/gi, replacement: "t'es" }, | |
| { pattern: /\bje suis\b/gi, replacement: "j'sus" }, | |
| { pattern: /\bje ne\b/gi, replacement: "j'" }, | |
| { pattern: /\btu ne\b/gi, replacement: "tu" }, | |
| { pattern: /\bil ne\b/gi, replacement: "y" }, | |
| { pattern: /\belle ne\b/gi, replacement: "a" }, | |
| { pattern: /\bsur le\b/gi, replacement: "su'l" }, | |
| { pattern: /\bsur la\b/gi, replacement: "su'a" }, | |
| { pattern: /\bdans le\b/gi, replacement: "dans'l" }, | |
| { pattern: /\bdans la\b/gi, replacement: "dans'a" }, | |
| { pattern: /\bpetit\b/gi, replacement: "p'tit" }, | |
| { pattern: /\bpetite\b/gi, replacement: "p'tite" }, | |
| { pattern: /\bpetits\b/gi, replacement: "p'tits" }, | |
| { pattern: /\bpetites\b/gi, replacement: "p'tites" }, | |
| { pattern: /\bquelque chose\b/gi, replacement: "de quoi" }, | |
| { pattern: /\bquelqu'un\b/gi, replacement: "queuqu'un" }, | |
| { pattern: /\btout de suite\b/gi, replacement: "tu suite" }, | |
| { pattern: /\bpeut-être\b/gi, replacement: "p't'être" }, | |
| { pattern: /\bmaintenant\b/gi, replacement: "astheure" }, | |
| { pattern: /\bparce que\b/gi, replacement: "pasque" }, | |
| { pattern: /\bavec\b/gi, replacement: "ak" }, | |
| { pattern: /\bici\b/gi, replacement: "icitte" }, | |
| { pattern: /\ble ne\b/gi, replacement: "l'" } | |
| ]; | |
| | |
| | |
| // ============================================================ | |
| // ENGINE – Longest-Match-First Tokenizer | |
| // ============================================================ | |
| | |
| // Sort dictionary by standard phrase length (descending) for longest-match | |
| var sortedDict = DICT.slice().sort(function(a, b) { | |
| return b.standard.length - a.standard.length; | |
| }); | |
| | |
| /** | |
| * Build an accent-insensitive regex pattern from a string. | |
| * Each letter that has accented variants gets a character class | |
| * so "très" matches "tres", "très", "trés", etc. | |
| */ | |
| var accentMap = { | |
| 'a': '[aàâäáã]', 'e': '[eèêëé]', 'i': '[iìîïí]', | |
| 'o': '[oòôöóõ]', 'u': '[uùûüú]', 'y': '[yÿý]', | |
| 'n': '[nñ]', 'c': '[cç]', | |
| 'A': '[AÀÂÄÁÃ]', 'E': '[EÈÊËÉ]', 'I': '[IÌÎÏÍ]', | |
| 'O': '[OÒÔÖÓÕ]', 'U': '[UÙÛÜÚ]', 'Y': '[YŸÝ]', | |
| 'N': '[NÑ]', 'C': '[CÇ]', | |
| 'à': '[aàâäáã]', 'â': '[aàâäáã]', 'ä': '[aàâäáã]', 'á': '[aàâäáã]', 'ã': '[aàâäáã]', | |
| 'è': '[eèêëé]', 'ê': '[eèêëé]', 'ë': '[eèêëé]', 'é': '[eèêëé]', | |
| 'ì': '[iìîïí]', 'î': '[iìîïí]', 'ï': '[iìîïí]', 'í': '[iìîïí]', | |
| 'ò': '[oòôöóõ]', 'ô': '[oòôöóõ]', 'ö': '[oòôöóõ]', 'ó': '[oòôöóõ]', 'õ': '[oòôöóõ]', | |
| 'ù': '[uùûüú]', 'û': '[uùûüú]', 'ü': '[uùûüú]', 'ú': '[uùûüú]', | |
| 'ÿ': '[yÿý]', 'ý': '[yÿý]', | |
| 'ñ': '[nñ]', 'ç': '[cç]', | |
| 'À': '[AÀÂÄÁÃ]', 'Â': '[AÀÂÄÁÃ]', 'Ä': '[AÀÂÄÁÃ]', 'Á': '[AÀÂÄÁÃ]', 'Ã': '[AÀÂÄÁÃ]', | |
| 'È': '[EÈÊËÉ]', 'Ê': '[EÈÊËÉ]', 'Ë': '[EÈÊËÉ]', 'É': '[EÈÊËÉ]', | |
| 'Ì': '[IÌÎÏÍ]', 'Î': '[IÌÎÏÍ]', 'Ï': '[IÌÎÏÍ]', 'Í': '[IÌÎÏÍ]', | |
| 'Ò': '[OÒÔÖÓÕ]', 'Ô': '[OÒÔÖÓÕ]', 'Ö': '[OÒÔÖÓÕ]', 'Ó': '[OÒÔÖÓÕ]', 'Õ': '[OÒÔÖÓÕ]', | |
| 'Ù': '[UÙÛÜÚ]', 'Û': '[UÙÛÜÚ]', 'Ü': '[UÙÛÜÚ]', 'Ú': '[UÙÛÜÚ]', | |
| 'Ÿ': '[YŸÝ]', 'Ý': '[YŸÝ]', | |
| 'Ñ': '[NÑ]', 'Ç': '[CÇ]' | |
| }; | |
| | |
| function accentInsensitivePattern(str) { | |
| var out = ''; | |
| for (var i = 0; i < str.length; i++) { | |
| var ch = str[i]; | |
| // First escape regex special chars | |
| if (/[.*+?^${}()|[\]\\]/.test(ch)) { | |
| out += '\\' + ch; | |
| } else if (accentMap[ch]) { | |
| out += accentMap[ch]; | |
| } else { | |
| out += ch; | |
| } | |
| } | |
| return out; | |
| } | |
| | |
| // Unicode-aware word boundaries (JS \b doesn't treat accented chars as word chars) | |
| var WB_START = '(?<![a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])'; | |
| var WB_END = '(?![a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])'; | |
| | |
| // Build a single processed entry list with compiled regexes | |
| var entries = sortedDict.map(function(entry, idx) { | |
| var pattern = accentInsensitivePattern(entry.standard); | |
| return { | |
| idx: idx, | |
| standard: entry.standard, | |
| english: entry.english || "", | |
| joual: entry.joual || [entry.standard], | |
| cute: entry.cute || entry.joual || [entry.standard], | |
| grackle: entry.grackle || null, | |
| regex: new RegExp(WB_START + pattern + WB_END, "gi") | |
| }; | |
| }); | |
| | |
| // State: track user overrides (which alt was chosen per token position) | |
| var userOverrides = {}; // key: "entryIdx-matchPos" => chosen alt string | |
| | |
| /** | |
| * Main translation function. | |
| * Returns HTML string with <span> wrappers for substituted phrases. | |
| */ | |
| function translate(inputText, opts) { | |
| opts = opts || {}; | |
| var simplify = !!opts.simplify; | |
| var cute = !!opts.cute; | |
| var grackle = !!opts.grackle; | |
| | |
| if (!inputText || !inputText.trim()) return ""; | |
| | |
| var text = inputText; | |
| | |
| // Phase 0a: Always normalize smart quotes / curly apostrophes (macOS, Word, etc.) | |
| text = normalizePunctuation(text); | |
| | |
| // Phase 0b: Simplify if requested (strip accents) | |
| if (simplify) { | |
| text = stripAccents(text); | |
| } | |
| | |
| // Phase 1: Longest-match tokenization | |
| var tokens = []; // { start, end, entryIdx, original, replacement, cssClass } | |
| var occupied = []; // bitmask-like array to track occupied positions | |
| | |
| for (var i = 0; i < text.length; i++) occupied[i] = false; | |
| | |
| for (var e = 0; e < entries.length; e++) { | |
| var entry = entries[e]; | |
| entry.regex.lastIndex = 0; | |
| var match; | |
| while ((match = entry.regex.exec(text)) !== null) { | |
| var start = match.index; | |
| var end = start + match[0].length; | |
| // Check if any position in this range is already occupied | |
| var conflict = false; | |
| for (var p = start; p < end; p++) { | |
| if (occupied[p]) { conflict = true; break; } | |
| } | |
| if (conflict) continue; | |
| // Mark occupied | |
| for (var p2 = start; p2 < end; p2++) occupied[p2] = true; | |
| | |
| // Determine replacement | |
| var overrideKey = entry.idx + "-" + start; | |
| var replacement; | |
| var cssClass = "joual-sub"; | |
| | |
| if (userOverrides[overrideKey]) { | |
| replacement = userOverrides[overrideKey]; | |
| } else if (grackle && entry.grackle && entry.grackle.length > 0) { | |
| replacement = entry.grackle[0]; | |
| cssClass = "joual-sub grackle-sub"; | |
| } else if (cute && entry.cute && entry.cute.length > 0) { | |
| // Only color green if cute text actually differs from joual | |
| var cuteText = entry.cute[0].toLowerCase(); | |
| var joualText = entry.joual[0].toLowerCase(); | |
| replacement = entry.cute[0]; | |
| cssClass = (cuteText !== joualText) ? "joual-sub cute-sub" : "joual-sub"; | |
| } else { | |
| replacement = entry.joual[0]; | |
| } | |
| | |
| // Grackle overrides cute coloring only if entry HAS grackle options | |
| if (grackle && entry.grackle) cssClass = "joual-sub grackle-sub"; | |
| | |
| // Count total unique alts to add has-alts class | |
| var totalAlts = getAllAlts(entries[findOrigEntryByIdx(entry.idx)], cute, grackle); | |
| if (totalAlts.length > 2) cssClass += " has-alts"; | |
| | |
| // Preserve capitalization of original | |
| replacement = matchCase(match[0], replacement); | |
| | |
| // Skip no-op: don't highlight if replacement is identical to original | |
| // Also skip if difference is only accents (prevents "occupe" matching "occupé" entry) | |
| if (replacement.toLowerCase() === match[0].toLowerCase() || | |
| stripAccents(replacement).toLowerCase() === stripAccents(match[0]).toLowerCase()) { | |
| // Still mark occupied to prevent sub-matches | |
| continue; | |
| } | |
| | |
| tokens.push({ | |
| start: start, | |
| end: end, | |
| entryIdx: entry.idx, | |
| original: match[0], | |
| replacement: replacement, | |
| cssClass: cssClass | |
| }); | |
| } | |
| } | |
| | |
| // Sort tokens by start position | |
| tokens.sort(function(a, b) { return a.start - b.start; }); | |
| | |
| // Phase 2: Build output HTML by interleaving unmatched text and token spans | |
| var result = ""; | |
| var cursor = 0; | |
| var tokenId = 0; | |
| | |
| for (var t = 0; t < tokens.length; t++) { | |
| var tk = tokens[t]; | |
| // Add any unmatched text before this token | |
| if (tk.start > cursor) { | |
| var plainText = text.substring(cursor, tk.start); | |
| plainText = dropNe(plainText); | |
| if (cute) plainText = applyCuteContractions(plainText); | |
| result += escapeHtml(plainText); | |
| } | |
| | |
| // Build span data attributes | |
| var allAlts = getAllAlts(entries[findOrigEntryByIdx(tk.entryIdx)], cute, grackle); | |
| var entryData = entries[findOrigEntryByIdx(tk.entryIdx)]; | |
| | |
| result += '<span class="' + tk.cssClass + '"' | |
| + ' tabindex="0"' | |
| + ' data-entry-idx="' + tk.entryIdx + '"' | |
| + ' data-match-start="' + tk.start + '"' | |
| + ' data-original="' + escapeAttr(tk.original) + '"' | |
| + ' data-english="' + escapeAttr(entryData.english) + '"' | |
| + ' data-standard="' + escapeAttr(entryData.standard) + '"' | |
| + ' data-alts="' + escapeAttr(JSON.stringify(allAlts)) + '"' | |
| + ' data-current="' + escapeAttr(tk.replacement) + '"' | |
| + '>' + escapeHtml(tk.replacement) + '</span>'; | |
| | |
| cursor = tk.end; | |
| // Eat space after apostrophe-ending replacement (j'cherche, not j' cherche) | |
| if (tk.replacement.endsWith("'") && cursor < text.length && text[cursor] === ' ') { | |
| cursor++; | |
| } | |
| tokenId++; | |
| } | |
| | |
| // Remaining text after last token | |
| if (cursor < text.length) { | |
| var remaining = text.substring(cursor); | |
| remaining = dropNe(remaining); | |
| if (cute) remaining = applyCuteContractions(remaining); | |
| result += escapeHtml(remaining); | |
| } | |
| | |
| // Post-pass contractions (handles both plain text and HTML-wrapped tokens) | |
| result = result.replace(/\bque (<span[^>]*>)on/gi, "qu'$1on"); | |
| result = result.replace(/\bque on\b/gi, "qu'on"); | |
| result = result.replace(/(<span[^>]*>y<\/span>) y\b/gi, "$1"); | |
| result = result.replace(/\by (<span[^>]*>y<\/span>)/gi, "$1"); | |
| result = result.replace(/\by y\b/gi, "y"); | |
| // Collapse doubled diminutives (from petit→p'tit + cute p'tit prefix) | |
| result = result.replace(/\bp'tite p'tite\b/gi, "p'tite"); | |
| result = result.replace(/\bp'tit p'tit\b/gi, "p'tit"); | |
| result = result.replace(/\bp'tits p'tits\b/gi, "p'tits"); | |
| result = result.replace(/\bp'tites p'tites\b/gi, "p'tites"); | |
| // Also handle across HTML span boundaries | |
| result = result.replace(/(<span[^>]*>p'tite<\/span>) p'tite\b/gi, "$1"); | |
| result = result.replace(/\bp'tite (<span[^>]*>p'tite)/gi, "$1"); | |
| result = result.replace(/(<span[^>]*>p'tit<\/span>) p'tit\b/gi, "$1"); | |
| result = result.replace(/\bp'tit (<span[^>]*>p'tit)/gi, "$1"); | |
| | |
| return result; | |
| } | |
| | |
| /** | |
| * Find the actual entry index in the `entries` array given the sorted idx. | |
| */ | |
| function findOrigEntryByIdx(idx) { | |
| for (var i = 0; i < entries.length; i++) { | |
| if (entries[i].idx === idx) return i; | |
| } | |
| return 0; | |
| } | |
| | |
| /** | |
| * Get all alternative translations for an entry. | |
| */ | |
| function getAllAlts(entry, cute, grackle) { | |
| var alts = []; | |
| var seen = {}; | |
| function addAlt(str, mode) { | |
| var key = str.toLowerCase(); | |
| if (!seen[key]) { | |
| seen[key] = true; | |
| alts.push({ text: str, mode: mode }); | |
| } | |
| } | |
| // Standard joual options | |
| if (entry.joual) { | |
| for (var i = 0; i < entry.joual.length; i++) addAlt(entry.joual[i], "joual"); | |
| } | |
| // Cute options | |
| if (entry.cute) { | |
| for (var j = 0; j < entry.cute.length; j++) addAlt(entry.cute[j], "cute"); | |
| } | |
| // Grackle options | |
| if (entry.grackle) { | |
| for (var k = 0; k < entry.grackle.length; k++) addAlt(entry.grackle[k], "grackle"); | |
| } | |
| // Original standard (as "revert" option) | |
| addAlt(entry.standard, "standard"); | |
| return alts; | |
| } | |
| | |
| | |
| // ============================================================ | |
| // UTILITY FUNCTIONS | |
| // ============================================================ | |
| | |
| /** | |
| * Strip French accents. | |
| */ | |
| function stripAccents(str) { | |
| var map = { | |
| 'à':'a','â':'a','ä':'a','á':'a','ã':'a', | |
| 'è':'e','ê':'e','ë':'e','é':'e', | |
| 'ì':'i','î':'i','ï':'i','í':'i', | |
| 'ò':'o','ô':'o','ö':'o','ó':'o','õ':'o', | |
| 'ù':'u','û':'u','ü':'u','ú':'u', | |
| 'ÿ':'y','ý':'y', | |
| 'ñ':'n','ç':'c', | |
| 'À':'A','Â':'A','Ä':'A','Á':'A','Ã':'A', | |
| 'È':'E','Ê':'E','Ë':'E','É':'E', | |
| 'Ì':'I','Î':'I','Ï':'I','Í':'I', | |
| 'Ò':'O','Ô':'O','Ö':'O','Ó':'O','Õ':'O', | |
| 'Ù':'U','Û':'U','Ü':'U','Ú':'U', | |
| 'Ÿ':'Y','Ý':'Y', | |
| 'Ñ':'N','Ç':'C' | |
| }; | |
| return str.replace(/[àâäáãèêëéìîïíòôöóõùûüúÿýñçÀÂÄÁÃÈÊËÉÌÎÏÍÒÔÖÓÕÙÛÜÚŸÝÑÇ]/g, function(c) { | |
| return map[c] || c; | |
| }); | |
| } | |
| | |
| /** | |
| * Normalize punctuation (guillemets -> quotes, etc.) | |
| */ | |
| function normalizePunctuation(str) { | |
| return str | |
| .replace(/[«»„""]/g, '"') | |
| .replace(/[''‚‛]/g, "'") | |
| .replace(/\u00A0/g, ' ') // non-breaking space | |
| .replace(/…/g, '...'); | |
| } | |
| | |
| /** | |
| * Lightweight English contraction helper for tooltip examples. | |
| */ | |
| function englishContract(str) { | |
| if (!str) return ''; | |
| var s = str; | |
| var map = [ | |
| [/\bI am\b/gi, "I'm"], | |
| [/\bYou are\b/gi, "You're"], | |
| [/\byou are\b/gi, "you're"], | |
| [/\bwe are\b/gi, "we're"], | |
| [/\bthey are\b/gi, "they're"], | |
| [/\bhe is\b/gi, "he's"], | |
| [/\bshe is\b/gi, "she's"], | |
| [/\bI have\b/gi, "I've"], | |
| [/\bdo not\b/gi, "don't"], | |
| [/\bdoes not\b/gi, "doesn't"], | |
| [/\bcan not\b/gi, "can't"], | |
| [/\bwill not\b/gi, "won't"], | |
| [/\bgoing to\b/gi, "gonna"] | |
| ]; | |
| for (var i = 0; i < map.length; i++) s = s.replace(map[i][0], map[i][1]); | |
| return s; | |
| } | |
| | |
| /** | |
| * Apply cute contractions to plain text (for non-tokenized segments). | |
| */ | |
| function applyCuteContractions(text) { | |
| for (var i = 0; i < CUTE_CONTRACTIONS.length; i++) { | |
| text = text.replace(CUTE_CONTRACTIONS[i].pattern, CUTE_CONTRACTIONS[i].replacement); | |
| } | |
| return text; | |
| } | |
| | |
| /** | |
| * Drop "ne" / "n'" negation particles from plain text. | |
| * In Joual, the "ne" in negation is ALWAYS dropped. | |
| * Applied to unmatched text segments during output building. | |
| */ | |
| function dropNe(text) { | |
| // Drop standalone "ne " (word boundary, followed by whitespace) | |
| text = text.replace(/\bne\s+/gi, ''); | |
| // Drop "n'" before a letter (elided negation before vowel) | |
| // Exclude "n'importe" which is an idiom, not negation | |
| text = text.replace(/\bn'(?!importe)(?=[a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])/gi, ''); | |
| return text; | |
| } | |
| | |
| /** | |
| * Match the capitalization pattern of the original text to the replacement. | |
| */ | |
| function matchCase(original, replacement) { | |
| if (!original || !replacement) return replacement; | |
| // All uppercase | |
| if (original === original.toUpperCase() && original.length > 1) { | |
| return replacement.toUpperCase(); | |
| } | |
| // First letter uppercase | |
| if (original[0] === original[0].toUpperCase() && original[0] !== original[0].toLowerCase()) { | |
| return replacement.charAt(0).toUpperCase() + replacement.slice(1); | |
| } | |
| return replacement; | |
| } | |
| | |
| /** | |
| * Escape HTML entities. | |
| */ | |
| function escapeHtml(str) { | |
| return str | |
| .replace(/&/g, '&') | |
| .replace(/</g, '<') | |
| .replace(/>/g, '>') | |
| .replace(/"/g, '"'); | |
| } | |
| | |
| /** | |
| * Escape for use in HTML attributes. | |
| */ | |
| function escapeAttr(str) { | |
| return str | |
| .replace(/&/g, '&') | |
| .replace(/"/g, '"') | |
| .replace(/'/g, ''') | |
| .replace(/</g, '<') | |
| .replace(/>/g, '>'); | |
| } | |
| |
| function parseShareParams() { | function parseShareParams() { |
| jo: params.get('jo') || null, | jo: params.get('jo') || null, |
| cu: params.has('cu'), | cu: params.has('cu'), |
| cr: params.has('cr') | cr: params.has('cr'), |
| | ex: params.has('ex') |
| }; | }; |
| } | } |
| if (chkCute) chkCute.checked = !!shareParams.cu; | if (chkCute) chkCute.checked = !!shareParams.cu; |
| if (chkGrackle) chkGrackle.checked = !!shareParams.cr; | if (chkGrackle) chkGrackle.checked = !!shareParams.cr; |
| | if (chkExpr) chkExpr.checked = !!shareParams.ex; |
| // New format: fr= has formal French, en= has original English (display only) | // New format: fr= has formal French, en= has original English (display only) |
| var frenchText = shareParams.fr || shareParams.jo || shareParams.tr; | var frenchText = shareParams.fr || shareParams.jo || shareParams.tr; |
| if (enInputEl && engText) enInputEl.value = engText; | if (enInputEl && engText) enInputEl.value = engText; |
| // Put formal French into the input and trigger joual conversion | // Put formal French into the input and trigger joual conversion |
| userOverrides = {}; | E.resetOverrides(); |
| inputEl.value = frenchText; | inputEl.value = frenchText; |
| doTranslate(); | doTranslate(); |
| // ============================================================ | // ============================================================ |
| |
| var inputEl, outputEl, chkSimplify, chkCute, chkGrackle, tooltipEl, statsEl, dictCountEl; | var inputEl, outputEl, chkSimplify, chkCute, chkGrackle, chkExpr, tooltipEl, statsEl, dictCountEl; |
| var btnClear, shareHintEl; | var btnClear, shareHintEl; |
| var currentLang = 'en'; | var currentLang = 'en'; |
| chkCute = document.getElementById("chk-cute"); | chkCute = document.getElementById("chk-cute"); |
| chkGrackle = document.getElementById("chk-grackle"); | chkGrackle = document.getElementById("chk-grackle"); |
| | chkExpr = document.getElementById("chk-expr"); |
| tooltipEl = document.getElementById("joual-tooltip"); | tooltipEl = document.getElementById("joual-tooltip"); |
| statsEl = document.getElementById("joual-stats"); | statsEl = document.getElementById("joual-stats"); |
| chkSimplify.addEventListener("change", doTranslate); | chkSimplify.addEventListener("change", doTranslate); |
| chkCute.addEventListener("change", function() { | chkCute.addEventListener("change", function() { |
| userOverrides = {}; | E.resetOverrides(); |
| updateOutputLabel(); | updateOutputLabel(); |
| doTranslate(); | doTranslate(); |
| }); | }); |
| chkGrackle.addEventListener("change", function() { | chkGrackle.addEventListener("change", function() { |
| userOverrides = {}; | E.resetOverrides(); |
| updateOutputLabel(); | updateOutputLabel(); |
| doTranslate(); | doTranslate(); |
| }); | }); |
| | chkExpr.addEventListener("change", doTranslate); |
| |
| // Tooltip: hover on substitution spans | // Tooltip: hover on substitution spans |
| var altText = altEl.getAttribute("data-alt-text"); | var altText = altEl.getAttribute("data-alt-text"); |
| var overrideKey = entryIdx + "-" + matchStart; | var overrideKey = entryIdx + "-" + matchStart; |
| userOverrides[overrideKey] = altText; | E.setOverride(overrideKey, altText); |
| hideTooltip(); | hideTooltip(); |
| doTranslate(); | doTranslate(); |
| if (enInputEl) enInputEl.value = ''; | if (enInputEl) enInputEl.value = ''; |
| inputEl.value = ''; | inputEl.value = ''; |
| userOverrides = {}; | E.resetOverrides(); |
| doTranslate(); | doTranslate(); |
| }); | }); |
| if (chkCute && chkCute.checked) parts.push('cu'); | if (chkCute && chkCute.checked) parts.push('cu'); |
| if (chkGrackle && chkGrackle.checked) parts.push('cr'); | if (chkGrackle && chkGrackle.checked) parts.push('cr'); |
| | if (chkExpr && chkExpr.checked) parts.push('ex'); |
| var qs = parts.join('&'); | var qs = parts.join('&'); |
| var url = qs ? base + '?' + qs : base; | var url = qs ? base + '?' + qs : base; |
| var shareHandled = applyShareParams(enInputEl); | var shareHandled = applyShareParams(enInputEl); |
| if (!shareHandled) doTranslate(); | if (!shareHandled) doTranslate(); |
| | |
| | // ===================== EXAMPLE PHRASES ===================== |
| | var EXAMPLES = [ |
| | "Il n'y a personne dans la maison. Je suis très fatigué ce soir.", |
| | "Je suis complètement épuisé après cette longue journée de travail. Mon patron m'a donné beaucoup trop de responsabilités et je suis débordé.", |
| | "La température est extrêmement glaciale à l'extérieur. N'oublie pas de bien t'habiller, il fait vraiment froid.", |
| | "Arrête de m'agacer avec ces détails. Tu commences vraiment à me taper sur les nerfs.", |
| | "S'il vous plaît, cessez de me déranger pendant que j'essaie de me concentrer. C'est vraiment difficile.", |
| | "Le film qu'on a regardé hier soir était fantastique. J'ai complètement perdu la tête tellement c'était bon.", |
| | "Nous passons notre temps à nous contredire au lieu de trouver des solutions. C'est dommage.", |
| | "Mon téléphone cellulaire s'est cassé en tombant. Il est maintenant complètement ruiné et ne fonctionne plus.", |
| | "Cette vieille voiture ne fonctionne pas bien. Elle fait des bruits bizarres tout le temps.", |
| | "Peux-tu me passer la télécommande du téléviseur s'il te plaît? Je veux changer de chaîne.", |
| | "C'est dommage, mais on va devoir annuler la party de ce soir. Il y a trop de neige.", |
| | "Je suis vraiment content de te voir! Ça fait longtemps qu'on ne s'est pas parlé. Viens-tu prendre une bière?", |
| | "Il fait un froid de canard dehors. On gèle complètement. Il faudrait peut-être rester à la maison ce soir.", |
| | "J'ai passé la journée à faire les boutiques et j'ai dépensé une fortune en vêtements et en chaussures.", |
| | "Nous pourrions aller au restaurant ce soir. Est-ce que tu connais un bon endroit pas trop cher?", |
| | "Elle est vraiment gentille cette fille. Elle m'a aidé avec mon travail sans rien demander en retour.", |
| | "Il y a tellement de monde au magasin aujourd'hui. Je n'arrive pas à trouver ce que je cherche.", |
| | "On va s'asseoir pour jaser un peu. Il faut que je te raconte quelque chose d'incroyable.", |
| | "La nourriture est délicieuse et le chef a vraiment du talent. C'est incroyable comme c'est bon.", |
| | "Faut que nous commencions ce projet bientôt si on veut le finir à temps. Il ne reste plus beaucoup de temps." |
| | ]; |
| | |
| | var btnExample = document.getElementById('btn-example'); |
| | var btnClearInput = document.getElementById('btn-clear-input'); |
| | |
| | if (btnExample) { |
| | btnExample.addEventListener('click', function() { |
| | var pick = EXAMPLES[Math.floor(Math.random() * EXAMPLES.length)]; |
| | inputEl.value = pick; |
| | if (enInputEl) enInputEl.value = ''; |
| | E.resetOverrides(); |
| | doTranslate(); |
| | btnExample.textContent = '🎯 ✓'; |
| | setTimeout(function(){ btnExample.textContent = '🎯 Example'; }, 1200); |
| | }); |
| | } |
| | |
| | if (btnClearInput) { |
| | btnClearInput.addEventListener('click', function() { |
| | inputEl.value = ''; |
| | if (enInputEl) enInputEl.value = ''; |
| | E.resetOverrides(); |
| | doTranslate(); |
| | }); |
| | } |
| |
| // Copy button handler | // Copy button handler |
| var copyBtn = document.getElementById('copy-output-btn'); | var copyBtn = document.getElementById('copy-output-btn'); |
| | |
| | // Shuffle button — randomize alternatives for all substitution spans |
| | var btnRandomize = document.getElementById('btn-randomize'); |
| | if (btnRandomize) { |
| | btnRandomize.addEventListener('click', function() { |
| | var spans = outputEl.querySelectorAll('.joual-sub'); |
| | if (!spans.length) return; |
| | var changed = 0; |
| | for (var i = 0; i < spans.length; i++) { |
| | var sp = spans[i]; |
| | var altsJson = sp.getAttribute('data-alts'); |
| | if (!altsJson) continue; |
| | try { var alts = JSON.parse(altsJson); } catch(e) { continue; } |
| | if (!alts || alts.length < 2) continue; |
| | // Pick a random alt (up to 5 choices considered) |
| | var pool = alts.slice(0, Math.min(alts.length, 5)); |
| | var pick = pool[Math.floor(Math.random() * pool.length)]; |
| | var newText = E.matchCase(sp.getAttribute('data-original') || '', pick.text); |
| | if (newText !== sp.textContent) { |
| | sp.textContent = newText; |
| | sp.setAttribute('data-current', newText); |
| | // Update override so subsequent translates remember this choice |
| | var entryIdx = sp.getAttribute('data-entry-idx'); |
| | var matchStart = sp.getAttribute('data-match-start'); |
| | if (entryIdx && matchStart) E.setOverride(entryIdx + '-' + matchStart, newText); |
| | changed++; |
| | } |
| | } |
| | if (changed > 0) { |
| | btnRandomize.textContent = '🎲 ' + changed + '!'; |
| | setTimeout(function(){ btnRandomize.textContent = '🎲 Shuffle'; }, 1200); |
| | } |
| | }); |
| | } |
| | |
| if (copyBtn) { | if (copyBtn) { |
| copyBtn.addEventListener('click', function() { | copyBtn.addEventListener('click', function() { |
| var text = inputEl.value; | var text = inputEl.value; |
| evaluateModeAvailability(text); | evaluateModeAvailability(text); |
| var html = translate(text, { | var html = E.translate(text, { |
| simplify: chkSimplify.checked, | simplify: chkSimplify.checked, |
| cute: chkCute.checked, | cute: chkCute.checked, |
| grackle: chkGrackle.checked | grackle: chkGrackle.checked, |
| | expr: chkExpr.checked |
| }); | }); |
| if (html && html.trim()) { | if (html && html.trim()) { |
| var subs = outputEl.querySelectorAll(".joual-sub").length; | var subs = outputEl.querySelectorAll(".joual-sub").length; |
| var mode = []; | var mode = []; |
| var names = (currentLang === 'fr') ? { simplify: 'simplifié', cute: 'extra-cute', grackle: 'critter-ize' } | var names = (currentLang === 'fr') ? { simplify: 'simplifié', cute: 'extra-cute', grackle: 'critter-ize', expr: 'expressions' } |
| : { simplify: 'simplified', cute: 'extra-cute', grackle: 'critter-ize' }; | : { simplify: 'simplified', cute: 'extra-cute', grackle: 'critter-ize', expr: 'expressions' }; |
| if (chkSimplify && chkSimplify.checked) mode.push(names.simplify); | if (chkSimplify && chkSimplify.checked) mode.push(names.simplify); |
| if (chkCute && chkCute.checked) mode.push(names.cute); | if (chkCute && chkCute.checked) mode.push(names.cute); |
| if (chkGrackle && chkGrackle.checked) mode.push(names.grackle); | if (chkGrackle && chkGrackle.checked) mode.push(names.grackle); |
| | if (chkExpr && chkExpr.checked) mode.push(names.expr); |
| var wordsLabel = (currentLang === 'fr') ? 'mots' : 'words'; | var wordsLabel = (currentLang === 'fr') ? 'mots' : 'words'; |
| var subsLabel = (currentLang === 'fr') ? 'substitution' : 'substitution'; | var subsLabel = (currentLang === 'fr') ? 'substitution' : 'substitution'; |
| var value = text || ""; | var value = text || ""; |
| if (chkSimplify && chkSimplify.checked) { | if (chkSimplify && chkSimplify.checked) { |
| value = stripAccents(value); | value = E.stripAccents(value); |
| value = normalizePunctuation(value); | value = E.normalizePunctuation(value); |
| } | } |
| return value; | return value; |
| try { alts = JSON.parse(altsJson); } catch(e) {} | try { alts = JSON.parse(altsJson); } catch(e) {} |
| |
| var html = '<div class="tt-header">' + escapeHtml(standard) + ' → ' + escapeHtml(current) + '</div>'; | var html = '<div class="tt-header">' + E.escapeHtml(standard) + ' → ' + E.escapeHtml(current) + '</div>'; |
| if (english) { | if (english) { |
| var contracted = englishContract(english || ''); | var contracted = E.englishContract(english || ''); |
| var engHtml = escapeHtml(english); | var engHtml = E.escapeHtml(english); |
| if (contracted && contracted.toLowerCase() !== (english||'').toLowerCase()) { | if (contracted && contracted.toLowerCase() !== (english||'').toLowerCase()) { |
| engHtml += ' → ' + escapeHtml(contracted); | engHtml += ' → ' + E.escapeHtml(contracted); |
| } | } |
| html += '<div class="tt-english">' + engHtml + '</div>'; | html += '<div class="tt-english">' + engHtml + '</div>'; |
| |
| html += '<span class="tt-alt' + isActive + '"' | html += '<span class="tt-alt' + isActive + '"' |
| + ' data-entry-idx="' + escapeAttr(entryIdx) + '"' | + ' data-entry-idx="' + E.escapeAttr(entryIdx) + '"' |
| + ' data-match-start="' + escapeAttr(matchStart) + '"' | + ' data-match-start="' + E.escapeAttr(matchStart) + '"' |
| + ' data-alt-text="' + escapeAttr(alts[i].text) + '"' | + ' data-alt-text="' + E.escapeAttr(alts[i].text) + '"' |
| + '>' + escapeHtml(alts[i].text) + modeTag + '</span>'; | + '>' + E.escapeHtml(alts[i].text) + modeTag + '</span>'; |
| } | } |
| html += '</div>'; | html += '</div>'; |
| setTimeout(init, 50); | setTimeout(init, 50); |
| } | } |
| | |
| |
| })(); | })(); |
| </script> | </script> |
| </html> | </html> |
| |
| ===== About this Translator ===== | ===== About this Translator ===== |
| |