PageSourceSearch

https://myschoolhero.com/word-problem-generator.html

html myschoolhero.com collected 2026-10-02 01:36:44 UTC 639,673 bytes, 8,560 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<title>Free Math Word Problem Generator — MySchoolHero.com</title>
7<meta name="description" content="Free math word problem generator for grades K-5. Put your students' names in the problems, pick a standard, and print three differentiated levels with an answer key. English and Spanish. No logins, no ads.">
8<link rel="preconnect" href="https://fonts.googleapis.com">
9<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet">
11<style>
12:root{
13  --ink:#0C1226;
14  --panel:#161F3D;
15  --panel-2:#1E294D;
16  --edge:#2E3B66;
17  --gold:#FFC53D;
18  --blue:#4C8DFF;
19  --red:#EF4444;
20  --green:#34C77B;
21  --paper:#FBF9F3;
22  --paper-line:#D8D2C4;
23  --text:#EAEEF9;
24  --dim:#94A0C4;
25}
26*{box-sizing:border-box}
27html,body{margin:0;padding:0}
28body{
29  background:var(--ink);
30  color:var(--text);
31  font-family:'Nunito',system-ui,-apple-system,Segoe UI,sans-serif;
32  min-height:100vh;
33}
34
35/* ---------- header ---------- */
36.top{
37  background:linear-gradient(180deg,#101838,#0C1226);
38  border-bottom:2px solid var(--gold);
39  padding:14px 18px;
40  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
41}
42.brand{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:700;font-size:1.15rem;letter-spacing:.3px}
43.brand a{color:var(--text);text-decoration:none}
44.brand .dot{color:var(--red)}
45.brand .hero{color:var(--blue)}
46.top .spacer{flex:1}
47.chip{
48  background:var(--panel-2);border:1px solid var(--edge);color:var(--text);
49  border-radius:999px;padding:8px 14px;font-weight:700;font-size:.85rem;
50  cursor:pointer;font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;
51}
52.chip:hover{border-color:var(--gold)}
53.tagline{color:var(--dim);font-size:.85rem;font-weight:600}
54
55.brandlink{display:flex;align-items:center;flex:0 0 auto}
56.brandbanner{height:38px;max-width:min(300px,52vw);object-fit:contain;display:block}
57@media (max-width:640px){.brandbanner{height:30px}.tagline{display:none}}
58
59.panelpills{display:flex;gap:8px;margin:0 0 18px}
60.panelpills .chip{flex:1;text-align:center;padding:9px 6px}
61
62/* ---------- layout ---------- */
63.wrap{display:grid;grid-template-columns:340px 1fr;gap:0;align-items:start}
64@media (max-width:900px){.wrap{grid-template-columns:1fr}}
65
66.panel{
67  background:var(--panel);
68  border-right:1px solid var(--edge);
69  padding:18px;
70  min-height:calc(100vh - 60px);
71}
72@media (max-width:900px){.panel{min-height:0;border-right:none;border-bottom:1px solid var(--edge)}}
73
74.field{margin-bottom:18px}
75.label{
76  display:block;font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;
77  font-size:.82rem;letter-spacing:.08em;text-transform:uppercase;
78  color:var(--gold);margin-bottom:6px;
79}
80.hint{color:var(--dim);font-size:.78rem;margin:4px 0 0;line-height:1.4}
81textarea,select,input[type=number]{
82  width:100%;background:var(--panel-2);border:1px solid var(--edge);
83  color:var(--text);border-radius:10px;padding:10px 12px;
84  font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:.95rem;font-weight:600;
85}
86textarea{min-height:110px;resize:vertical;line-height:1.5}
87textarea:focus,select:focus,input:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
88select{cursor:pointer;border-left:3px solid var(--gold)}
89.stdhint{color:#CBD5F0;font-weight:700}
90.stdhint .star{color:var(--gold)}
91.stdhint .pair{white-space:nowrap}
92.stdhint .sep{color:var(--dim)}
93
94.btn{
95  width:100%;border:none;border-radius:12px;padding:13px;
96  font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;font-size:1.02rem;
97  cursor:pointer;transition:transform .06s ease, filter .15s ease;
98}
99.btn:active{transform:translateY(1px)}
100.btn-go{background:linear-gradient(180deg,#FFD86B,#F5B21A);color:#2A1D00;box-shadow:0 3px 0 #B8850C}
101.btn-go:hover{filter:brightness(1.06)}
102.btn-sub{background:var(--panel-2);color:var(--text);border:1px solid var(--edge);margin-top:8px}
103.btn-sub:hover{border-color:var(--blue)}
104
105.namepick{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
106.namepick:empty{display:none}
107.namechip{
108  display:inline-flex;align-items:center;gap:5px;
109  background:var(--panel-2);border:1.5px solid var(--edge);border-radius:999px;
110  padding:3px 10px 3px 8px;font-size:.78rem;font-weight:700;color:var(--dim);
111  cursor:pointer;user-select:none;transition:border-color .12s,color .12s;
112}
113.namechip::before{content:"✓";font-size:.7rem;color:var(--gold)}
114.namechip.off{opacity:.45}
115.namechip.off::before{content:"✕";color:var(--dim)}
116.namechip:hover{border-color:var(--blue)}
117.pickrow{display:flex;align-items:center;gap:10px;margin-top:6px}
118.minilink{background:none;border:none;color:var(--blue);font-size:.75rem;
119  font-weight:800;cursor:pointer;padding:2px 4px;font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif}
120.minilink:hover{text-decoration:underline}
121.pickCount{font-size:.72rem;color:var(--dim);margin-left:auto}
122/* The generate button sits below the fold on short viewports; pin it so a
123   first-time user never has to hunt for it after pasting a roster. */
124#genBtn{position:sticky;bottom:10px;z-index:6;box-shadow:0 6px 18px rgba(0,0,0,.45)}
125@media print{#genBtn{position:static;box-shadow:none}}
126.rowbtns{display:flex;gap:8px}
127.rowbtns .btn{margin-top:10px}
128
129.privacy{
130  margin-top:16px;background:rgba(52,199,123,.09);
131  border:1px solid rgba(52,199,123,.35);border-radius:10px;padding:11px 12px;
132  font-size:.79rem;color:#BFEBD4;line-height:1.5;
133}
134.privacy b{color:var(--green)}
135
136.locked{
137  margin-top:18px;
138  background:linear-gradient(160deg, rgba(255,197,61,.20), rgba(255,140,20,.10));
139  border:2px solid var(--gold);border-radius:14px;padding:16px 16px 15px;
140  box-shadow:0 0 0 1px rgba(255,197,61,.18), 0 6px 20px rgba(255,170,20,.16);
141}
142.locked h4{
143  margin:0 0 10px;font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;
144  font-size:1.12rem;color:#FFD86B;letter-spacing:.2px;
145  text-shadow:0 1px 0 rgba(0,0,0,.45);
146}
147.locked ul{margin:0;padding-left:20px;color:#FFF3D4;font-size:.92rem;font-weight:700;line-height:1.75}
148.locked li::marker{color:var(--gold)}
149
150/* ---------- stage ---------- */
151.stage{padding:22px;display:flex;flex-direction:column;align-items:center;gap:18px}
152.empty{
153  color:var(--dim);text-align:center;max-width:420px;margin:60px auto;
154  font-size:.98rem;line-height:1.7;
155}
156.empty .big{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:1.5rem;color:var(--text);display:block;margin-bottom:10px}
157
158/* ---------- paper ---------- */
159.sheet{
160  background:var(--paper);color:#1A1A1A;width:100%;max-width:820px;
161  border-radius:4px;padding:44px 46px 52px;
162  box-shadow:0 18px 44px rgba(0,0,0,.5);
163  font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;
164}
165.sheet-head{border-bottom:3px solid #1A1A1A;padding-bottom:12px;margin-bottom:8px}
166.sheet-title{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:1.7rem;font-weight:700;margin:0 0 2px;line-height:1.15}
167.sheet-meta{display:flex;flex-wrap:wrap;gap:6px 18px;font-size:.8rem;color:#4A4A4A;font-weight:700}
168.sheet-meta .code{background:#1A1A1A;color:#FBF9F3;padding:2px 8px;border-radius:4px;letter-spacing:.04em}
169.namebar{display:flex;gap:26px;margin:14px 0 22px;font-size:.9rem;font-weight:700;color:#3A3A3A}
170.namebar span{flex:1;border-bottom:2px solid var(--paper-line);padding-bottom:3px}
171
172.prob{margin-bottom:22px;page-break-inside:avoid;break-inside:avoid}
173.prob-n{
174  display:inline-flex;align-items:center;justify-content:center;
175  width:26px;height:26px;border-radius:6px;background:#1A1A1A;color:var(--paper);
176  font-weight:800;font-size:.92rem;margin-right:9px;vertical-align:top;
177}
178.prob-q{display:inline;font-size:1.02rem;line-height:1.65;font-weight:600}
179.work{
180  margin:9px 0 0 35px;height:72px;border:1.5px dashed var(--paper-line);
181  border-radius:6px;position:relative;
182}
183.work::after{
184  content:attr(data-label);position:absolute;top:5px;left:9px;
185  font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
186  color:#A9A296;font-weight:800;
187}
188.ansline{margin:8px 0 0 35px;font-size:.9rem;font-weight:700;color:#3A3A3A}
189.ansline i{display:inline-block;min-width:150px;border-bottom:2px solid #1A1A1A;font-style:normal}
190
191.sheet-foot{
192  margin-top:30px;padding-top:12px;border-top:2px solid var(--paper-line);
193  display:flex;justify-content:space-between;align-items:center;
194  font-size:.78rem;font-weight:800;color:#5A5A5A;
195}
196.sheet-foot a{color:#1A4FD8;text-decoration:none}
197
198/* answer key */
199.key .keygrid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px 26px;margin-top:6px}
200.key .keyrow{display:flex;gap:9px;font-size:.95rem;font-weight:700;padding:5px 0;border-bottom:1px solid var(--paper-line)}
201.key .keyrow b{min-width:22px}
202
203.lvlpill{font-family:"Nunito",system-ui,sans-serif;background:#1A1A1A;color:#FBF9F3;padding:2px 10px;border-radius:4px;letter-spacing:.06em;font-weight:800}
204.key .lvlpill{background:#B4530A}
205.lvlsub{color:#6A6A6A;font-weight:600}
206.demoflag{
207  background:rgba(255,197,61,.13);border:1px solid rgba(255,197,61,.45);
208  color:#FFE39A;border-radius:10px;padding:11px 15px;max-width:820px;width:100%;
209  font-size:.85rem;font-weight:700;line-height:1.5;
210}
211
212.lvltabs{max-width:820px;width:100%;display:flex;flex-direction:column;gap:9px}
213.tablabel{
214  font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:.78rem;letter-spacing:.09em;
215  text-transform:uppercase;color:var(--gold);font-weight:600;
216}
217.tabrow{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
218@media (max-width:640px){.tabrow{grid-template-columns:1fr}}
219.tab{
220  background:var(--panel);border:2px solid var(--edge);border-radius:12px;
221  padding:11px 13px;
221cursor:pointer;text-align:left;color:var(--dim);
222  font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;transition:border-color .15s, background .15s, color .15s;
223}
224.setmark{
225  font-family:"Nunito",system-ui,sans-serif;
226  display:inline-flex;align-items:center;justify-content:center;
227  width:21px;height:21px;border-radius:5px;background:var(--edge);color:var(--text);
228  font-size:.8rem;font-weight:800;margin-right:8px;vertical-align:1px;
229}
230.tab.on .setmark{background:var(--gold);color:#2A1D00}
231.tab b{display:block;font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;font-size:1rem;color:var(--text)}
232.tab i{display:block;font-style:normal;font-size:.76rem;margin-top:2px;line-height:1.35}
233.tab:hover{border-color:var(--blue)}
234.tab.on{
235  background:linear-gradient(160deg, rgba(255,197,61,.20), rgba(255,140,20,.09));
236  border-color:var(--gold);color:#FFE9B8;
237}
238.tab.on b{color:#FFD86B}
239.reroll{
240  float:right;margin:-2px 0 4px 10px;
241  background:none;border:1.5px solid #D8D2C4;border-radius:6px;color:#8A8276;
242  width:26px;height:26px;font-size:.95rem;cursor:pointer;line-height:1;
243}
244.reroll:hover{border-color:#B4530A;color:#B4530A}
245.printall{max-width:260px;font-size:.95rem !important;padding:10px 18px !important}
246.printall-unused{
247  align-self:flex-start;background:var(--panel-2);border:1px solid var(--edge);
248  color:var(--text);border-radius:999px;padding:8px 16px;cursor:pointer;
249  font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:700;font-size:.85rem;
250}
251.printall:hover{border-color:var(--gold)}
252
253/* ---------- mode picker ---------- */
254.moderow{display:grid;grid-template-columns:1fr 1fr;gap:8px}
255.mode{
256  background:var(--panel-2);border:2px solid var(--edge);border-radius:11px;
257  padding:9px 10px;cursor:pointer;text-align:left;color:var(--dim);
258  font-family:'Nunito',system-ui,-apple-system,'Segoe UI',sans-serif;transition:border-color .15s,background .15s;
259}
260.mode b{display:block;font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;font-size:.9rem;color:var(--text)}
261.mode i{display:block;font-style:normal;font-size:.7rem;margin-top:2px;line-height:1.3}
262.mode:hover{border-color:var(--blue)}
263.mode.on{
264  background:linear-gradient(160deg, rgba(255,197,61,.20), rgba(255,140,20,.09));
265  border-color:var(--gold);color:#FFE9B8;
266}
267.mode.on b{color:#FFD86B}
268
269/* hide level tabs + problem count when making exit tickets */
270body.et-mode .lvltabs{display:none}
271
272.demoflag.soft{
273  background:rgba(76,141,255,.10);border-color:rgba(76,141,255,.38);color:#C8DBFF;
274}
275
276/* ---------- exit tickets ---------- */
277.ticketpage{padding:26px 26px 30px}
278.cutrow{
279  text-align:center;font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;
280  color:#A9A296;font-weight:800;margin-bottom:10px;
281}
282.tickets{display:grid;grid-template-columns:1fr 1fr;gap:0}
283.ticket{
284  border:1.5px dashed var(--paper-line);padding:13px 14px 10px;
285  display:flex;flex-direction:column;min-height:250px;
286  break-inside:avoid;page-break-inside:avoid;
287}
288.tk-head{
289  display:flex;justify-content:space-between;align-items:baseline;
290  border-bottom:2px solid #1A1A1A;padding-bottom:4px;margin-bottom:7px;
291}
292.tk-title{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:600;font-size:.95rem}
293.tk-code{background:#1A1A1A;color:var(--paper);font-size:.62rem;font-weight:800;
294         padding:2px 6px;border-radius:3px;letter-spacing:.04em}
295.tk-name{display:flex;gap:12px;font-size:.66rem;font-weight:800;color:#5A5A5A;margin-bottom:9px}
296.tk-name span{flex:1;border-bottom:1.5px solid var(--paper-line);padding-bottom:2px}
297.tk-prob{font-size:.76rem;line-height:1.45;font-weight:600;margin-bottom:3px}
298.tk-prob b{margin-right:3px}
299.tk-line{border-bottom:1.5px solid var(--paper-line);height:17px;margin-bottom:8px}
300.tk-foot{
301  margin-top:auto;padding-top:6px;font-size:.6rem;font-weight:800;color:#8A8A8A;
302  display:flex;justify-content:space-between;align-items:center;
303}
304.tk-stamp{
305  color:#C9B27A;border:1px solid #D8CDAE;border-radius:3px;padding:1px 5px;
306  letter-spacing:.1em;font-size:.55rem;
307}
308.keyblock{margin-bottom:14px}
309.keyblock > b{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:.9rem;display:block;margin-bottom:3px}
310.keyrow em{font-style:normal;color:#8A8A8A;font-size:.8rem}
311
312@media (max-width:640px){ .tickets{grid-template-columns:1fr} }
313
314/* ---------- site banner (bottom of every screen) ---------- */
315.sitebanner{
316  position:fixed;left:0;right:0;bottom:0;height:58px;
317  background:linear-gradient(180deg, rgba(10,10,20,.55), rgba(10,10,20,.95));
318  border-top:2px solid var(--gold);
319  display:flex;align-items:center;justify-content:center;
320  z-index:900;
321}
322.sitebanner img{height:44px;max-width:94vw;object-fit:contain;display:block}
323.wrap{padding-bottom:74px}
324.panel{padding-bottom:26px}
325
326/* ---------- overlays ---------- */
327.ov{
328  position:fixed;inset:0;background:rgba(6,9,20,.82);
329  display:none;align-items:center;justify-content:center;padding:20px;
330  z-index:1000;overflow-y:auto;
331}
332.ov.open{display:flex}
333.ov-card{
334  background:var(--paper);color:#1A1A1A;border-radius:14px;
335  padding:26px 28px;max-width:620px;width:100%;
336  max-height:86vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.6);
337}
338.ov-title{font-family:'Fredoka',system-ui,-apple-system,'Segoe UI',sans-serif;font-size:1.4rem;margin:0 0 14px}
339.ov-card p{margin:0 0 13px;font-size:.94rem;line-height:1.6;font-weight:600}
340.ov-card p b{color:#B4530A}
341.ov-card .lvl{font-weight:800;color:#1A1A1A}
342.ov-close{margin-top:8px}
343
344/* ---------- print ---------- */
345@media print{
346  body{background:#fff}
347  .top,.panel,.noprint,.ov,.sitebanner{display:none !important}
348  .wrap{display:block;padding-bottom:0}
349  .stage{padding:0;gap:0;display:block}
350  .sheet{box-shadow:none;max-width:none;width:100%;padding:0 6px;border-radius:0;page-break-after:always}
351  /* exit tickets: fill the page so students have room to write */
352  .ticketpage{padding:0}
353  .ticket{min-height:430px;padding:16px 16px 12px}
354  .tk-prob{font-size:.85rem;line-height:1.5}
355  .tk-line{height:52px}
356  .tk-title{font-size:1.05rem}
357  .tk-name{font-size:.72rem;margin-bottom:12px}
358  .sheet:last-child{page-break-after:auto}
359  @page{margin:14mm}
360}
361</style>
362</head>
363<body>
364
365<header class="top">
366  <a class="brandlink" href="https://myschoolhero.com" target="_blank" rel="noopener">
367    <img class="brandbanner" src="data:image/webp;base64,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" alt="MySchoolHero.com">
368  </a>
369  <div class="tagline" id="tagline">Name Swap Word Problems · Free edition</div>
370  <div class="spacer"></div>
371  <button class="chip" id="langBtn">🌎 Español</button>
372  <button class="chip" id="printBtn">🖨️ Print</button>
373</header>
374
375<div class="wrap">
376  <aside class="panel noprint">
377
378    <div class="panelpills">
379      <button class="chip" id="howBtn">📖 Directions</button>
380    </div>
381
382    <div class="field">
383      <label class="label" id="lblMode">What are you making</label>
384      <div class="moderow">
385        <button class="mode on" id="modeWs" data-mode="ws"><b>Worksheet</b><i>Full page · 3 levels</i></button>
386        <button class="mode" id="modeEt" data-mode="et"><b>Exit ticket 🔒</b><i>4 per page, quick check</i></button>
387      </div>
388    </div>
389
390    <div class="field">
391      <label class="label" for="roster" id="lblRoster">Your class list</label>
392      <textarea id="roster" placeholder="Maya&#10;Jordan&#10;Aisha&#10;Diego"></textarea>
393      <p class="hint" id="hintRoster">First names only, one per line. Nicknames are fine.</p>
394      <div class="privacy" id="privacyBox">
395        <b>Student names never leave this device.</b> Nothing is uploaded, and no account is needed. Your list is saved only in this browser.
396      </div>
397      <div class="namepick" id="namePick"></div>
398      <div class="pickrow noprint" id="pickRow" style="display:none">
399        <button class="minilink" id="pickAll">All</button>
400        <button class="minilink" id="pickNone">None</button>
401        <span class="pickCount" id="pickCount"></span>
402      </div>
403      <div class="rowbtns">
404        <button class="btn btn-sub" id="saveBtn">Save list</button>
405        <button class="btn btn-sub" id="clearBtn">Clear</button>
406      </div>
407    </div>
408
409    <div class="field">
410      <label class="label" for="std" id="lblStd">Standard</label>
411      <select id="std"></select>
412      <p class="hint stdhint" id="stdHint"></p>
413    </div>
414
415    <div class="field">
416      <label class="label" for="theme" id="lblTheme">Story theme</label>
417      <select id="theme"></select>
418    </div>
419
420    <div class="field">
421      <label class="label" for="count" id="lblCount">How many problems</label>
422      <input type="number" id="count" value="8" min="4" max="16" step="1">
423    </div>
424
425    <button class="btn btn-go" id="genBtn">Make my worksheet</button>
426
427
428    <div class="locked" id="lockedBox">
429      <h4>In the full version</h4>
430      <ul>
431        <li>Every standard, K through 5</li>
432        <li>Three levels of the same worksheet</li>
433        <li>Themes: soccer, aquarium, bakery, space</li>
434        <li>Write your own theme</li>
435        <li>Save your class list to a file</li>
436      </ul>
437    </div>
438
439  </aside>
440
441  <main class="stage" id="stage">
442    <div class="empty noprint" id="emptyState">
443      <span class="big">Put your students in the math.</span>
444      Paste your class list, pick a standard, and press <b>Make my worksheet</b>. Every problem stars a kid from your room.
445    </div>
446  </main>
447</div>
448
449<div class="ov" id="ovHow"><div class="ov-card">
450  <h3 class="ov-title" id="ovHowTitle">❓ How to Play</h3>
451  <div id="ovHowBody"></div>
452  <button class="btn btn-go ov-close">Close</button>
453</div></div>
454
455<footer class="sitebanner noprint">
456  <a href="https://myschoolhero.com" target="_blank" rel="noopener">
457    <img id="bannerImg" src="data:image/webp;base64,UklGRmzOAABXRUJQVlA4WAoAAAAQAAAArwQArAAAQUxQSH5fAAAB/yckSPD/eGtEpO4Tktw2EiTJsmMHVUjP/x9c2d01DdSeI/o/AfrvLfNsgVuS4kfrYu6QeTYb69aZhyPJHVB+nwwXPkoKPWbmvd+P+Awk7oNvajDAzCeBc+ZkdmW1rZFgUmatLgUOBaZLbSnQglJGUkCBUdGqvyccyQHwXjYL/O+Faeu2SewkXatVghPwtT26xUpiKwlOsE+3/ioHb2Z22cN50rLLxtRWm9C1VpvaSb1bttdq0ya2dZ6hiS/n+U3Y5oABZmYHmzmJ9jZg252ZsUtPaFvXrXuBHVEr2z4rtbJ7+vo90pjs+Nk4MJPI9rzocXgrjW1Xdv3CL+pNYtsbW3bV9thVEndwQ0w1cwbGliTD+MIbp1+qXMLFbmJPYtfbtdbyjz1JsNt6ktbbrkpLbtdStaS1LqvLkrrWW/ZMA1YuVyfebtqubmdIhqhtNSQKUdvV166GyHiIhqSrV+td9LdubXscQB86M/YFqFQAIQkJQEKSkAQq1wJISEJCEhJQgLf+2slc9Ln9K3n3vHYr276FPJk13JVoniuauUe2Zc8zxZZk3RlsaebHD5S0Ujt3wLIk0AODrnDHfyb88f//Sk6bfa/358zM9qbeK2pIAiGaqKJ3DLh3jFtMLse+cI+dOC7pjltix4lbjA02YANudBCmgygChJBEEepdWm0vM+f7+WPOOTO7MnuTx9737xcRE8D/3///X/JmptF5MrMRl2RGuTT6TqLcTBoxyQxg0jc+u7wRbLSdQePyz35jEoCZRkbujB3bENVcfcXO1b+9Dx9d54w5+/ITptz6g4G458ABRsgNR66c1VZXe6h9aSOdt88DjZ4TzPu/FzXTvbattX//K0//aX3PyEfUvftUkt3dtHgy8tFyLiYvXupBEonrfvSjPo1wZKFvPfPrESDhMY0xptFxMuJGSpFwB1xdt/70IUwjGoPpJ+dfHHSRbvTvojQ6rsSufszIOPDSY6seBRvBGE0fPr0ETqqrb9/u/RtnTx0dN3X2xv279zXWuVKA3tUfbsJGLGLxT3vwgCU5obR3wyv333jwgpNGw510wcEb739lw7gJOUMJ7kg9P12MRiZS7tLHPcSRkVoqRX1hzBHTj5yyLQxKo9tkHm+bcuT0I8YUrS7O5RIAD8EfvzQnjUCc0tgpBIl0d7NG8zhH6ambj5zrGs0mjlj4nb8qQEkiJrhSQIEpY0v4yAO6IlxkzuXi7p7+unFg/2PHM6pdvPOJo5pC4FB3bUNdbSCznKiLkac40BFLZHbv7G4cky/URLE99uC8eh/NRv2XHz3ZieKmqHgobmm0TEhxxwE0whCPXHfLZkI2gzE5PCYXbN+3mpvQ6DUx8Vu7lgJeU6fSQGwVBDbfct0jaGQB//yxm/rk2VADXuovFCDon6IpjGIXx3y3oRBy5Ab7aqOGILK7+m762D8z0tTB2ztEpZKTQ0Cwa4tT0eg145JvzCIAhTzuRsXquP2gRhhizf2EikAi0QdemTJpNFvEh6+f0F8HIIwqBu5fg0YWEd/ZGsWVOC6XwEuvrWqaMw4fvWZ84ZGb154yKydwlwtVEEdbv0M0sjD+amd7HMfuWYIRzFHQwfvv/FPPeI1ic43v/cpTz3cScBSMYBnc4zhu3/lX2MhCnPnZTSH2DM72qH9NaeKKGuL2nP1pQ74uxyj2XF3+Q5eea/uDM/D4ntwxtfE0z+Bx2PTZM9HIAnHWIe9/stM9Sf0/OKHxkZe3fndaoC9XM2hj+nw0m/eP+eyFLfX15tr+yRnzTulefbWS3Duf7PdDZyFGHJd19X39yq5Assd/O/njPc/WHZ0DEVs89lBJo9dUah+nfFzTIHnpub5lDd/b9XVPInRd+fW+rstGHsbFvTe1HbnW4yS05cCSHAauve0za0oH6+rC6LVQV7ffKW7cKwSB0gtjZ5Ic+9oj227qvRgbeZy67lxyH+lVSBAQhBuuPdfOu8R2T12BjVYzVkzdo9Idv3OAINxACUG9H8lx7rpTRx5i7OWNovH7eAIEJMpda7evrJ9kSxjFvsQm5Yq1F050Ue6Okeh8vxE1Xj4WjTSSxcwHolJS9pKi1nhsc9DoNIXmsXErNecuRVRaih6YiRipCjBmjg+qLIC1NtbOZLQaM2sbWxsDGJUqjJ+JAI1MEo1cbAQH3NNweeOY/BhGrY/Jj2l0uUh1BzxgcY5yZ2QrEVGGoFSqkQucxtbW0WutrY24wOUDJRBlRLgYAQsOPP5qbIAEg30NObwUAT2G
457j05zrAcCcU6UegZBAix+9Yl9uEY+uLPhZ9fvdQdw7+muVVdDC5TimFHrcVwi0NHT5P2N7gDue6+/9iVwRsj9jzdNDgagUhcemvPqG7BNo9c22UBfnRc7TTQJwMLkpsf7GUHntPgMvCzVdai0br18dJpr/brSockuMjpnLFZuJOXBl8x1eZZScdMtMaPW41s2DU7Jk+7yuUs8+EgK7Oa9727NEko7riPnGpUmYaWV3/SQgajzl4VSYAQtuZf+Zdulp7W4JRX9h1vBHY0+k0MUcw1xSlDHQ39oAsl9pGTutNZs/v3t/rU5wQB3bnz0hEuOaG7f1GejzSw0LF8ytv+Bnb+z4GUh99qXRW7iwCGkMAISOIVTV4wrhdU371oKBu4qXfmuL+za3Xrc7IeRmUaLyUzM+OD0gdoF4/7h9iB3yqO1nHWCxfsff3gQgY9IJAkHHIhOePOUPQeis96xe0sPEomPHVsqTu3cdMJJcyNAo8MERHM/Nf3VeXPqpu24Oi8TIMaunDnp1lWDYyduv+WpGBAgJI0UZCZSo3ztmKNOnrh5y5zlNZv1zoHgRrqP8WNn7zr+8V986rhaNBpM1B73qV88Pn/fpOb9LTmdQLK8/v/UtPusrmc2zZy9+9HnD/YXY5Jlptc/GUDthDkN9RNqognNU2qLuw8tPmsO4CqQ0T06tLpm8Xjc+7f8x9Fo9Jc4+j+29LsDL7x82rjgKUjjg89sgk2r1rVOyvfv7NwbD+ztnTOhFsD0+maCwpGXf/Yb//nfIe7Ld5kdGJi47MRxBNe9G986CaUBzQu7g1MqBfd1l0XS6C4pumydeyiVzOmyBqE0nN2/WXCOy9i/es2emrEhNBXrov/+z2989vIjCyB7/VJwpp1/VPtjtz+/ubOueez0ifXjW6dPhYCAuiJOVmFNLWaKzEvURwEf1QVRPSW3SJS7yOra9/uZ5ziOwY5th/b17tl2oLOvYfykeWMPPDkVD3p9koiOfPc5N39nNcdfccbC8WPGNFLuLgF+7kxQJsBJlImuzW6juaLS8i5kItERlbsAd4ny7oMH921b99ihsXNPOfc9R0ZIr0MKLL58yYs/9tPf856pJQAPEIgkEgMSlUoJ5b5mI67RWlKx4cPOULqjMnCPMTABpYPr7nz8wE9fXHL5YoJebxSYdOZRL1y797gPLwRCjBBykS5RaSCzW89WJ2DSaCshD17/iW7zbMGyVepyHEcGnQ8es+faF446cxJBrysiOmrprlXh/A9fBO5ExnBUJlzWMCVnHjCNppKBWzTn/b04mV0MR3ckLv7o+WHVrqVHRej1hNZjGla9dtq7TyRGkRjaEBycgb2eDXl01hevuWBuHWj0lKBuyoJFC9oG3Mns7GvBwUMYkvLgsU5892mvrWo4ppXX09q57RsaTz6x4JgYapchXI99cps8E1Bz9Hu+9M0fnGroz5ei3P/qyUR4Q0nYqT+Y3zkI7soU7OkfXZlg5hoiMLxw4smNG9rn1r6OjG/eevC4FTmCiSF31jwknIFrX1tWS6UhDoUWf/UT9ejPj5mZqK7MXm9sCGRKkQ2JTClmqpbMzDR0UkqolgTosJBFSjLTnxeZKclsWBngzhvOov4TrzqEmEhkDbbuoebigNztoWdAQ4UskFtx3MGtzeNfN1rb9nUtmGPBxNC7dn71d+1F15pfXLmsf0IlgHtgQk+f/DCTkkKZ5BCTOGFlQ88De+VpEh5CmYR7tSTwBOFeJQlPEEpTihLcQXIgVM0IZJVVSyKQWRVIgKMQyCyVeZqDhKNAFaUEL1Mgs5TgGYR7laTYnfSgYSThZcK9KhKBjAFVTwLMlGAOgcRJK2vsNfSGkauvZwIBiYon9C+78ufPy4vtv/vqTvmQAe52cEHXvrbW14nBQm3z1AZcDEPR8LOnrp5SCvzg0IfZXlfvVglYYOsz6PAQSgpkdgfmj/PcuceUciWK33g5TYqd1lMWCnBAwisTCmSWqiHFTnpQiqeEhHJ3gNlTYqk475ZvjEdZ5NB05FmnFg1cz16/0asVYPLCy46IBcHveGJdKYtE7JSH5iN18gktae5l2d0B6pbkytSxsYRU5k7mCfNilXbsBCFiT6hQXg0pdpbVXnRMbITSHU8aw1XgZJRXQQ5j50x585gg4vwjMwiVSCnuZA7AgnEhd+FRxVyAp99AEs9sJRgVm9fXbedDB39MKE25+qmfNaBhAHHUMLW5tjD4OhBx6GBP09h8EMPSzf79ksvqC9H+b55/lvfvndGAV4SrdPOayA8Lx5PqpyBC27Lbdwof/6HppZopOXfI4Y55gkTshemn3HzPV2sQ40/YdmibA4pMSpMBtZPHXjI+FiG/+pG+7V6ZFPu41iVnu4DeO3Ikyt56qgvc9v6hS67OfUGNZ58FuVNnlgS1vmZGFhl2zOXHrmgVyS/dsqQqEvWzznnvwiaSi+0/+K8s7rRMIF5+hscLj/euh+aipPwMw0461gV47qFfyce1zD+nEGaeEgEe3fSLkgKJM2pc6KTjg8CXLx2s2fSlvRElnNYJTrzo7JySgu7ecGg/1QyeX/GByUZycf9nl6Ph4TAjf96SWCHacN/WHlMlsjg385QPHFVXT/J7rpyLZ3NPYVJzEHOvuFQgznhbsWHleI8gD7HlecPYozU3l+RU7DTM2NvPmWd9Z39UqL/skn8382FBCPmxTT0HDxH9mZM6u+r7zRDDtHXz3mvaKA48etfHZwcrDs6vBiFa/zviw6G2rmVlq4PiZae5iFu73oLwy04kBxjuIBMBMGJn1pnL5vacVTdGGEt+xv47d/fd1ykyyqB+yqknndI8TZT37N57wySUTQQff95FbQfHkLjr3Scm+dkfIdG39SnU/Pa7/fkPnERGL327TqTHHPWet8wG9yTJv3ZZJFUiZ/wnzptSg3uSVFy9MEU+/5zCkkmuiS0A7t8TiRY++uZBowcBiEeet/Cu9x4YR6qKq7D4xBNBcdvlTUFoSgPJrkc7iKmZdOrEJZNi2QGyHmhf/+W1wSsRhRPfMQEISdLkZYYPnaBh5mVvb5hWB9C/665/2lpRzNhPvGtyI+4pLH7H8SZlUOOp873M6y6dFIv1Xd+NZBz9kzkkBkDGrjeOYn63PgpUY/5g0cLsj9322ECRtmv2bm5lmAqz/vquTunPmmjpmVAf4QxPeb6u66pzXZQ63/7BGsGrapSDezY3L84pDD8LR32urjcAyEh8BQgTz6MYgUAGzroCAQJtxy47vh+86AE8t+IrBQjFdd1ffetJ9bWFMoOmy69fOq8W3Ms8Aj/R8EzOlPPP7QFCkk0+ZyyOmDE/BCtjBsDYgz7rFEoGCHDrfCeWoW3JWcsJCCURfOz5Hipxz5953IwoIJHsjrXGSV5z1aIYBLEA/Jsku84jBx4Agu15CGdmLQHcgGDPFQiTPnFWSWAiMZS5FOyv1XDipBNndjvkECGLwcs/+veBCpxxn5sMQZgSnBK5OvlQyTn6U0fOj3Avk+Jn/11WwfhL3ntKjbtQkhMYWwp4imo+sSRWGSYA9+/kpMK/zylGboAJ3Hp/+8ZRYU7RzbO5g6tRr4JqP3p5Vwn5uVd11eVdwwKcqH5CTwv6c2Z8vrW3g2E8vsuvbpZg7KeWo5j4tbEBECEIpSDXzKmm4YZWtOEuABcQDEdcOhAKZH4SBQpzjzyztQRBiiQIzSvPj82FKHVv/OX/vBkkWq648aDjLkSi44KcMtnbLuyFIJTkMSAiP/IYi1TmjtN3m2jMe0TGP81GScJPWECQqLBxdiC7OGLFjMhdIqsHnnpegHz8UkIQEAGuno+gBDyO4ghZGXT3EebMcDeSXWtrLFzUW+cCT1EZEOwTtHxyjkMgMcrihOi19z2qLPLClDEQW0RWQddmhthpO3XRkbgLlTlo73tRBmFnvyPnLpFRFnjhKZFsHL+Y2BIcAcXwb2ZMXe+RkXWg540i2dSZcpHuhICAMPa1mFiceM1YkJqv9q7xDOOO3tbPY3++ZFz1o4a9YdjIo7oDY06DGGE5uZsNjN8tSrtjMzJ7oHsFNrwUN5zupbzIKAniaWcQlA0pnH/e1B7woIjUYxbNCAbuBHfffz4RdsSPOtxjJDI79LRnaRmzGA+KyCjI7/FcHJEqkAZ2EJ3Y65blNw0pDlYAo1KxqLVbWURp0Xh3o1JX97oOHBEiN5HqbJyT4g31ZAy2qiZXGtsASnILO3PGTBxRudP1USYUiFGUVGlsd/8FloFw/Im456nQLdy4FR8CwfJj5xHLyFrKPTcHSyOXyxGbqNQGN+xLiZhYdCNr8H2XEvG+XozM5m8QGSu6CU5ms3h3Ce0eP2DmrpwhYjhtzIG6yDVswt6GH12F6c+VcfGtK9oHNHxo6lVNQ1yKBQhkEHpCFF/z+TvXFHKzaoKUAOr6i2FHfR5R4dO75LMbEJm9C/Pz5kOQjHQdNV0uykMo+Q/rRO6dz8ReCk7Fzu7fduFlYuIZBYIZFd+2OiriKYm9A+TmE5RmxU9HSmIwyKmmM+lVz2AoEFNNt1f+AJgv34+T9bHJSRZOGcTSxEbyfnx/hhDtfRKpgIsqxtEjb+PskkdU2xn4rClNodSEm1Gx2zO3OtV3qDsu7zKyeyh9LkupRGyi8mB7bumxBBWWllwVbDwS2u7zQFbX0y3yN4j+okukutvA5tKaOz9/TRyFngAmEKC4FDfUqLeJ4aOB9hW3Xoz9mRJ7vXFnr/mwce3vWeTEESCSXW2Bl3//zas+XSeIFJKc3o8Nt4izlrpV8gzGpSFEWdx2/w6QFz0io3zCMkJEoozLTnBmnTXV3EQVzSefRKITWluRqNj8zXsewnJZnHvXyUVGV9dpGIAhk1NV8yVvQymOImRVkS86CgOdNi4o0x/2ystEWw2ZSwROxy3F6SrhC2dS7fYCbbiqplB7Yg1KcCcvXFTRwrGX2xAIM1xUHKL3TwsqcyIhqmph2nF4mby1JqoAiGJdNOiWjSc77I2ij/XiCe5GqW/X5k9f9c3fv0xoI6MDceSLevbLh41b785G34v+PBEGmnv6GNZ+dCOiQs8T391d2N13wbRX791UrJF7wsG3Dr/JjU6lFsJxswhk79pbJhOZNadAusKE99URJk/ARbVPn+UGqGgEqql40vG31ZxfFyxN7OljcUsW2LMUAaIUR1J18OikgisJL1FteeHcuhjcySx2xiI5xtNC/tUtBFykB93fEMVjC1Wy0l05SjmGUIydkCSzQSGq6zqv0VU14jyIKoZFbyOBOCCqrTOnuZVxagMVm3vNuYRskOMNYuOtBxPcjf2v7py/eE/f7kL33TH5LKmNRzvDuq+nuafEn2E5yDocH06DdfMRlecP3jPgmrOwaYo/9Ju1ICDohdloeKnxZEeVyGvfikcVWB44GERWEc4LIZfGu85FOWJRbTF3AuD22rO4qoJ85Yb2JRaT6jr4oHxqDmVZZQnU53GqLc5ZktYZM4RaWIuFccdnCnrlWZJD4WxcKa79vfiREZk3k/MSuUye5MGK27BGhuaEi7EyKz1xiKqbLzqG6pvjVNVtCYAURTjVn9dCuZhbF1TJoVqOLFChwr43isT
457sFxQAsf/x55uOPbKle4584J6DeSoX8+sGh5PjHVHBcP2ZMWxK3nv6Gc6uji7SHZTCQC/us+fkJp582bQnfrnW5YTw3UgMazHlNFGpDzLxCEcVDAzg/H6bBctAqXEegdRQ/5WZJSExhCUv47kDOFXWMQfWF8no7HvOkZP5EIBU+32GUDQ2Ue62+7dBQ8DEIzBmHo0ywKaX8DJ5y2mku/mamlzp6MEMgYO7cC3qIpsAuRkxLJpWiaMsUHhrgrT3mdirJp9xdPW6I6pfwkE71+OqmmhZhAOhfqGoUNyer7scLJPbtpsJbwyh6Lsh4PK1D7SevKzgXprtTu8A6Q5KADo65MMH6O/3aIoF/TmRqJ+j7pqYYS2KLTlPi82S5FEBtyOmuat1xWXTajZ3ENhzLja8jEvGBssWcut2cFonFTq/3W2Bzl4yq3RR0S3Dsiu8QIUhjkM2ASIuRFS/ZFMnoDR4uZe6c0KIUkK09XkExsX98uoRN1weOcjV14lXz8K80xEDTlYnypEaBjNg/Q9SCINRlMG27CTUrMQtzfE+QYj23B22ttKUzxYccJPS7O0JEfsiVQ98sEpujz+DV0+AwlObLVC9ePzZBphPOsu8AuJuJi8hZIOebt4oNs7dQ6Bjc81ZR9W5O9ER5hQiV5I8RGm5liIaVvRbt82pxfVnw2DOdw/sqXeG+9gIpYGSCMEIc5c1IRNtp8yp39OHvjVXGmY1x+UDlR4o5ZZQqeJdMSJSNqJLCGmuD4cnqFBRZGR3R75qH2EIouJ5i0MG+e/arTCRQMaOHoRYtD4whIK5OXD8vt3mDKU7ziWtrgyKf9slT2pryUIUDToTimS0PW147HlXilvX118wJz2WZTJRacc5ZcbFe3GGUGNyVXHveyFmSGXeuEkMpQiU6/zxVBxZ8aQDblRqbxhJc78l+vbUzxkfPHL3aNncgIVAskWQIlrGMtyjxt0H5kzC9edBRu0Hbrzm0Ix6htwBZaqhutG4qfjpc80EERFNU+J41cxPi2FtnHAuUUV1vYtn45YNzwM42UvHRGT0RW9e245nY8e//cXzeAbPRXjD01TqaY5DlBPpjgyM7H01SFb/bx4PBVACUOeamKGV4ZyQczJaab2TKC6f45birB+k2HIBIUpyuIFcaUGESNO9W4mBgIHiuhIZgx67tp+w4ryp9UmBR5okjFP3GkP7lmmuKqCb23Mhm6c5cXDw6G8GfUhACX5UQ1A21+Z9tpxQUZ43jvXpmavieEoTsckBn3u6M3VclCKRNVeTzQENFfUzDr046fRa0OEnwQn//bOVRywbz5A7goCUVnVB47lNocwxo7am/q737hh2ZzRR+ZrGDwQ3Koy8rNLiCtxS4tyHH/mjOVmdzTf88Oj/UYqHWBt3Es4rmVeQ7IGIiKinhiy2dx3hjG6UJn6DEO/ri0MlXonAab9z0HxoKAIlssa8tIv0Wpw02xBZqCmQVYPAUSWy+nPKBcpLKESXBbeUkNv37wCF1n/4cJwgSnVIUf0t7pV4JQ0FqvryyzgVOOCORMFizE+9MgpDZA7ycbOo1HmtfcEsKnXWdMjfMNrx3rvqa2oxBYQoNZ3bCGLI3TFwNDQOE5blnuk76SgCOrwkZ/YZtU/tWH5SPRqqOPJDcV0D7lKSe1VcXT2clMNACAjYHZt6v4GGlezfPFRipfvqj8HJ7jrUWZlr785lrhT0k5YVriwed7+fXHRhZ4sLR5KVHoDGd8mpOAgEYfDJLS9PvQqUxvon5BOanFQXBxFh3MXEls0xrwAw1u+kUkeubNPz8QmnZHIefVGe4IXJZLR4p0ExzqKDO4FiyKTIY08oz03Aydg/YDkL+z7ysyiluCsPKp3RGCpwcM8WVJX+/ikomwRBAooHHu6IiKd9kkq9P
457NtJR7rJ55/hlcA7YUJF+F09xhvEYvxn6+dcGDDMJDBOO4ndXXhV3FPcJXr6olbF0ZBAME5avuOp2jNm49LhIwWmnLvgpYcnXDyHWAxxsH2/3VDTuGDR7Dpi0xBAiLmYOE96CPzxwNpoWIkxD0elShw7r49K3Z47gHsFFcaFdTcumSmyBl89S6arBwLIYPtr224/wqLPl6h055eueBOw55Udv+/Jw4y5ZN7pYtDJqN4SKP/mfo/I6h6BKpLW3kGFjoHI6tSLmVNQBohEovncizKE6MDD5FgxF6UEHnlEcf0Z9a4Ut+0PkTkOebI+PBYPHr02YJSH6MCTmMcLPkYgqyMkZRNVlLZPjCrpufofPaL04oFHHm/Pg8I7Ys/mrvIsYvoUcC6sCarorZs6LSib4+INY0UfXzr2EsxItXjKxRQD1U3xENH32vqN3QMLLx8fhggPzLl4wsMvLTh3CkE6PKRA24pj+h7MX3FWE2KIXdr0P3svbVu/zqYdu7zRXSBVywbmzCdjcEPF+2rehIaRcUFP5JUoKpxHiCqAwYhyr8CVJv+fg28tBGXBH5ws+JkjfOe6+7d3NgDHLSBkCw3tvzvvX5u23//4U42AKIUMbqVfxlZ3dN4txbWmE8UnnkmwLG7ad9vTR/VX1H/DVoVMIQo7X7jnxCvc08QrgxTcSfdoYLUrAWpqMwAlxPIxTsYQy1uPNSeN3S9lEbPyZF6HIFdCngDPN+BE7yXksrh46V8+9eUX8SzV7emagsjq/f1farrhuAefXLW3KwYsnnUKFRh7Hvmb/+7KAr19iPxZokIXE19tNd64Fm/6vwNn552gFOCCOUWrlgTuUteap7eHxYva/zDhqjnyocFF01lX5B/sO2ZFG0E6HAJN55998LbuS66YRqyhUuDZa08+rwX6t6xdP3DcOY0EuOkO96p47RXBowQPMujZWwr5nzWg4aPoyx6oMNjmuQuoojwhqiBjyD27vmYsTlb5y8ehKQ95x8anDqxpBDD8JAJZ5S1vkWlGQ8dWwHDCnI4MKO4kTFwpsvZBqHszIUdGt9133FvPnicJ2fzp3yMy51771VPNvPJhhTQwaq+QK4M6H8VTpEyv1ePgKEX+QhBeInOsLHBMMYsIElHeSTV/BLkfvdhFRmfTL3/x3a9//aud8gzulYk9483JKB87meJ7zmra2g0YjvO22JUlsP/XX/rFP3zyd4Q057HnwU9f4lYBKu5eV0/lofRGkWj42WlFy01ogBB7gvm8d9Z4VdzvuAlCRPe9T9YuWjqzFjrufvRKgoYGKWbaFZd033bw7PObCMNPRCdcwH07Ln77XIKJoRbRf7717D4ruETnM/d2nneeFZ/58HcG8Wr0nbEIVwJR2HX/wy/ui1W7KM/wFeMfqyzWi29qRFWgvHt3lVzx9RRislsIdy/khBt+8nDIRSAg+MQjyS6/cGVsARAQg7iQOEpj3yHDDWXZUYsvn+xGRo/uvq4JcjvuQ5kUbtyskO3V7xnYvk1UWDOH7Du6SXY7c6xbinjIcmHc6Qoku3X/EdHWnEWs2qME4QiR0W3HVsLRM4qkOts3A4W34JYFf2RdwHTfg2SxanTHk0X286bHbHsRBA4ozDiVYBmErXt8K9HA07E8BfZ0yXVCc1AlxNMazFWB20tPEN4YgvyifL9H44889UwiEoV94MS+ajiD3/nwM0UbvPvulnOOacZdg6Huvt9EDBXIAnPffvGO+7jghAgNL8ERZ8erus99+wICYhjWjTn54nCwriHgRHQ+fmvTlnEvPHT7AFUUze8eRACu+IVb//BKN8NezNlQGZy2CLfKOurAbe/tLq9KtOUFApV67HceVdPWBMg8ANK5RbcsRsuxNe5I7qTWkjHO3fU8HDXZSfWo/y5U9yZCJh77FYhAiczu9bcHKvwBMnfdPGCeqaGAMji3bzNPIL88F8g4QGDsEjKXEGcsdKW4Suv6oyDAQaFwbHBL0559be9Y3uRp6I91IsxejCtNeERkwTm4iXTnib14BWJPa4Sy+JL5DkjuJMrfXHIjq4USFoLu25rJpDDmMhcVisIlExAVb9/MG86NR3zluRgHEDM/1owqg4HbH3ph3Jb/6rpiRTMxwnr6xthtY+oYhiKw4O3ndq+Kz54LGk6BY+Y89fz8tyyVuzH0Ymxj/KYYjwYpIHdj//VfmHH1ulVUaaJT7mr/yUOAJdjw+mh/7JU11yAqdBu4F3PknU5VxZMNuKEKPPbn/6qWXPDgJOZPII6yeP4tY1xOdmURU06vKX54fLAUiPvwCQvJKhbfSBQCsO6QPENuYNlO8wxCJSwE5F1FkVFcMM+zQHcg2b1I5sUTNbi0DmVYvx2nqYasqkECxW0TN+BtpxCUIiaccFodTmqIXl6NBY7uRmR0BwdHUQbxRIeopKN7Elnl466sd+GBVMXTzyZkUIAgd8e7+6i0bpKo3FoLonLLvYFkSYGvX/Zv7Tjl+XlVYtW6q2d84eT3jCNIziCFWERx41g0ZGDuWvqW+c8/NfMYwvARLVPZNv68Y3CPGIYKbUfsJwgokUNAMI574T1vKspVGeBKQD5jxqt73BOGs6j5sZeooouKNdBOYkRV3Q7+Dut7LeAVeOw9vzj1T4hEhQVtiIzyZVdIZFY8dR5KizjvtyVrxkh17SzAGZ0ogzOmxoqUv3qQdPFq7l04GX3qWKxEeURmMaPgpLv1bSVZtE1CaeKiq2Kva8jg/Gl3FBcm4UoR0Qe/Q3k8b+fVwoORLqZ80UEproF/NouZcC4hSpFPGo87Ze4ZwKhUvLQvhzLAhae6yCx/p4eIVNE6yQU4mGUS4qzJbpXhVDW8gZQqTT51BiLZqaZcxTe954Xj3kQwwCmRA5z9R7QFDR1E7hxz3viduWktaLgwZuG+nSvOrg1BAO42RLBQB+SGI1JDYN7E7Ve82fDKhADcQ8l98FcT0GEw42ysGtXNJXmVdB8iXPJOSVmS649f0kL6vCOyuT21nQrlU+oZSteDERPOwy3N7f6NCEB+9mxXkkd9dzQvzKZf5xVIHFSa22Av9WQN2nAPnrL85CypLjIGmc8+h+ynkHqLoK6eSp1UL/kvm5H56QVEuu5vkUhWpsrFK81yMrpdXy8qzB9LnMGjR6dRBhRDmhPaMVYQV0NVcNpL+BtMYsKvBt1Lwb1MqDLH3nzF9onzKJmR6oigA1rIkAcJIJAfv2Xb3oVjGJ6Ot+5vnzYFNwF4rGho5DO1XxKVimnj97QHBa9Coofgfc/9/KMtDH/XiROdYeqeVF2PDt1CVIqP+EwtlSlmwQkxAuT1l9SHLG6DN8nibDAQ5bI5KAsMGLObyehR529lcRk0iIylgUt63NLcXvkJ8qRja0OG516btTwTdPSTXlcgs4NLpIt+h9r6CtwT4lyPGxcuccvkItVL/svxSDSdT4hS3DpuwUj2YgaV+ity21RDVo/2no9ls9JRY4hIdR06nojkIyegFNv2e+J5cxHD0a3314PGG84tH/35c30eQgJV8KDQvmf8NBRRqbRfM11DFHskQApWP719f6vjw4E8fWE8joBQjJAYUnnzwp1ONUXTotrVW40qe+w9d390jjgM5X5enWuYaGh0R51ixMwF7hUhC1gRB5i6xJysenoXlc8Z8GyVW8ybim5pwe4xUkVGl+WX4sqgn5vFAIrtksiVBAODk/MozeW/6TZPKSlbpa7tvyZQ9ApkZZ7rvcmN8TVOlYP/uhVDzGhwkaYHB6QEefOUtKBnV1Uiz/fWuLJwV4OUTXY0wdJCdHM+UsqZ40IKDPagpYPDBA128Ia05nz03h6PPaFy19bVtYuaENX0nQubXUODOyUJ5EQTQh95hl4cCuOihhAMwEqDNWKIxSIdkFfiCOQsPWb3DzsIVcE3/OVUkB0GsPx4xLB0nngKr1qIDtyKBUTdeW2oIiCgeoE49Si3LK4X85UotvcRq3qe636I5iNwUkOu+3dYnOTFDHD3rL8iY8htfBwjtUTW/fkJXXgaYkcQ5Qr159YEVQ86dwHnTHbLlKr+7UAf1Ra/asHAWBmHKMWjzluJSDSOWYmSnI4DlUDDJgXSPRpcRURmkbscT/PowG8wUmMn44E+ai4jRMMDojekTDD9Lzc4VQ126MbdxyzFBTiqwHVAi5CGBnwwFADkoSEaFw6hobKD62aG7SbKvS6PAE9SVUTL0b1U6sExAGfSwv+6Vl4N9d5wPJg4HMWsuQzb13YPgbizxmKA4FEgVAHnmUO4U59HGTza8QAWZ4MgMaTt+zm9j6y6q1aBcpWaj8/03Nl9rjTnBfAElxXS3Ab/wAeILQODg6Q3Hc3Q9jpuR9c7VVWeuOVE3KrhEdaEAbJ6Aul+b0BpJZFq4dF+VSBOGGtkfqmIVXJ00Y10vVpEKVYrT5H/cZPyBYathzekQAbH39Cr6vz3Qwsn4QAhIFMmoPfoFqrsSQKwggtAtj3MXHfQhkisnTXhqW48IURydyQ5yN2RKoK26aESF4AAKeaqAaeK0qbxmHF4ui0w13DJ5Uj0KrjtvR3zMvBBVJXc8ze5fMKlUSDzfQUClU7LMbRuOjZ2y+CPI0/yaSvwDOEcSmlu3CDFCRafNYCSoNRHI1ldDzxCSCn1D4nz60PmlKhSqUiYfhJVlYr9YIAxdTnpbt23YCTLFjWkuIqrB+TZoNGVwdV/q0R24wRClOa61YxE88UXYCmErsAKQ8MlF71BBWaM3yRVwf2xCcQSIAG4KgjT26rg7khykLsjZEECnO6nJsxai4ZETOq98Lnd5pTL3Q2g1CPwugJAHCqSUaFr22P7o9OdcmnZTFNlwb0H4zCVt5wfOcM1eJKqwe21BFJz+14ErwjCT3ZF1E1AWdT/AlaJ/GRCbgji6PaaMccQlBJyr+4USWhaLUryaGf3NURk2NKJSB2Hp7g9bq35bHR2y1MmjMOHQGEPkS85HVXFV22Ux8WqiE23OQIQK5VFrxVJFbkLG4ISYOdBnMwKTeflPAM68AKWTbSscJHqtm8raTRNIDVo/UPklzJcnF2737ACo8c9VFYuUe4bHozHnzzVlQ1TRcEjgME+gTfkADkIAW67n7uwdxIamqvP6r2fROHB6N2xYcPW/fvLWiZOW3DUFCP2ClAFHvxvvhOHswpyykOgYnn9Aog4fE9YgIZNRHJ7X0Vue+7BMtBzXxdRZcGeuw3qC2R1dm6gihHZ3ZGyiFeZVCKja0NEul86LqSxoe48MoboYRQnhfxJGWB3fE4ByyA/4KSfvtSjDO6AZcHyiMnT
457s7knKETb+nKlUya6VcEXnNAtUr/uIZcCjxghyVi2FJEYeGKNKoCm+ebKwOOtqJLpU/C0ED3XhZLQac2uJDi4i7bjCTZcHlorf8OKCBbUuyoLJLoKH1ulwqe/HEnZRIUeInp3Pr9hx56OsnHjZixcWJdXQGXA/b1nXT0kov6W26e8yQ2IS0QcuP0fntrdNUhqvmniyQ90YV5BpUW/ezI544+eZFYZcXTjVf06fOw4hqur+4lYQOCBtfJK+Fk9mQ3aByoT82fAhfPcMj3chFdWg2eSqLRm8NwBlGbhTlNIUJg0g3Txx/fHIUpx67uXVHnrElLdBtaprkhGt0O/CUoS9Tkno0R21+ZnCOREZlkCUddu0PF1MdU18wRFrXLSvT2ItGPnepJb/wP9VB4j0uVP7xeVmkh3Kz0mkSjqjyUkufFsA8v6EcNTDAbewFL/VTdGMVV3bsNyTLvLiwylG10P3Pzons4SqYWmSf9w+wEiSjFg/qYpt59b76pexJkPP3DBRBe4F+lbfd2t6wApyXG45bo1JTQU/tKZmGlaY2wJVQ3WeVtXdLhYPGM+bsNl32NeBt09VBhs93lYJsSOewZwz4bXzoHxBSej+WosRvIsoeYyUFqwpx6NTzzZ09x6djCWjG6ldsxTLg2uJLfOV75KrBTs0ANpcFG/W9rTW5CyQKmT6rp23darxoN4Gi8+SxxdUh8yOC/fHcqCPXonwWOqfO6c2MrMjzwVpQTbcQcpov58c5J04CGvzI2MzqZ7EEjKctFMtxSsdw2WZKwoIVJefRo7EbdhAuL1UxrJyJRBpj8bUddtnRaqZ6WWaTLjzJd8KERpzXW3tINQkjusu/W61X0U3UE+8YIHJpyIVS/HNb8LFzjlOfatWt2J4TipQtD+2P37FarkHrHuTSZJ/3CVGELXLX/gsGG+MYyNZKkS+GOTlCYSD/TFoEzy3KU1crI67YMA7kgpomEuIjXkNv0LzPlL85SQ27AzasUtTc+CU65QdwEhjd/qHDI6W3tSFKaeTyD9ITWcRLA0Z19HisLEMzK49f3rdoXWXYQUUAS1c3Bl+eOnyOj1Y6vki9+Nl8GEaRmgczepxoIlpDoPbJVXII5fgLJ07MEBZEqbVXAy7s2TLDVegVuKnqhj2mxHw+bPo6JIw0CgobFc9DomKtWfC/5wi5wh1Af+QZLsTeuI3KsUtP/+x9oxHCdVyOhcvWofOcr9gnBgGRqKz3+/aZYEHnPwuV0oBCoOxmtru6hukAZfWYFA9rk4qp6DDuYXoMNC6OzgNnyq7trzG0SqSM1tfRg8C1AbeVzB2nac/Iox94OkMiiWyLzOLRTcyRgPHLEAV4YtRrLCYnOR6NZ
457/M43Z/rjHPMkvGnRLcu3fRPMcUJq492WFJMYuygDdrxLFZ84PluQqPVCUl0pkdOtehTxBKCxb6VYNEb1jvlvCYCBrd4ynfXmmW4KLJ7tExfMneQboKgIsXgaYBHLVksH1UI3iJC5oINWj/mdyzG7EGbbm1TBP8qGQHJAlDLlkAsZNYLhaJMnscDAfGslUNeqmZZpah2R2+IkF+YMCr15U/JwJxIpXBqVQHbrWvoYFKg5B7HruILGDNKtpe4EhjHj39XMKACGqiTGq7KJYFUc9T9yxCQGi7YvrBzxUCfeS1X8IO0ymTCBo2PgQ3PW4yDgun+AqPT0Ano1S49xMcKiA/IjP1MdvGwuYyo6YmMEV3ykVLiQoQ1EthshoVkqQ599FbGkvd55YcksTXYhyxdNOJ2S4O6JEjsy9QSQ6kTJZYQBvyruSUPfDRMyYijKwa7VQgiOaGqmyLzwWAa6FjZnu3K4kY8G6HMnBNtyNVxbcSVe4fa/c9Ncvfe306bibxMKzURr0SJSLlutwS7End5M/reQ2TFz960I1skoqk5QkKSmzqeXyt0/AJJBUJqlMkkiO9I597VdiSFKCJCVIEnDs+09PikgWSFKCJIGkJClJUraskpQgSSnlEiApRSozjngm/LBOyfn/jp+eAyAdbsaH6q3kTpWDBjf9og0BYtMdT/QIr8yhiJwqG3FtFAAKc1q34dUzFtwwqQcnhIPjGUpheVSJR6y54ba9GMnfeucdUlV8sBMTP5uFDgtjSQGR7hUFrwCvktueGzosRRxz6/tMlBvuldjgwtNRBg3eKzmLBzmn59a/O74AQjp/SrAUKB2Amslkvo36opHZSYqPWoxIdEo3czwhAxipumDAjUS3vfeiMWQvbiddp051ZdhteDSerJ5HnLokZAA3lyeUl8gchzS5nV8bQF57YX1Qmu8eFOVS0/djV5L8+hdVBZHRVdoRS0x/wOMD931gfl1wMXZyNuEJxkV7SbeBW6QxMwhZvBKvZPcDqCJx1iebgkLtPV8rAJJyQCQwAyJAPuUrC4oKD/ysWfmIS9yfaAMMwFAOMEkAOVp/sOor9fCk+waUA8gBEYAZMoDIeMgHP04EsPjTN9x+05dnIQOIBBFAzoAIiASKwAwwpUiFL5wXBKHwQg7ADCIBkZXl/u3+b4wBFAEWlRkYCH3Oi34kecBsmbtf84GH/ms+6DATs36GjM5Br4q4/Voj2dh72w1riLwiyxtiKKccCgGnZ1L09FCA/cfkDQD6g7kPAc60MUEV0PH0PduQkyw9/9s920ruFbn333Rf9+NfmMJhahrTzRAGUwVPbsWr47c9KtLqf+prF2JliPmd5plckZHR1fcy5mMupGTu/up/vH8W4EZGV6egeRCluPlLyKmmwvyPEnIp9uw6lUxk9SSLzzwOVxLcXVA4o+RRWtCmuzJEC+tCmutBU2nmsSjF6eoAiMjg3H9ATqrrzDq3NDOy+ptOdQMsInNOJEa8uz+IxGDrfsHQ50BcXSzF7j2//e4ZY8ED1TSOfDi4JQV7bC8cm0ekOxV7JuGiYtG8BQxjwfWoqQkgas6BDOqawSBX+vGHANyXQa7pAx565+bHAfkxIFBzPUBLWxNoTof7W8fk/yGU/hmDpiYAYY0tdSBobGuOEI/Ffi2RjK92efmmSaJ2THMNSNDUBNQ1gTBoaAQJGlpqSZQw5jrJodHGtNSDBA3NtWCIpi3un2+rF+Sb60AANXUArZzeFT88BgotjdD8tLefcLP7T8Y0c/hP+cLj3ffd1O9ekRPvKjxGpCRcbLvn6Q4qdZuGM4Qean8vgA2T971MGArePe3ZkoJ1/RpjaFuWN3sFB57fQSQn3Wn4zXXBqTzw6HX25ZP+RYeHaFxJiDKU4gq4fzueae1BS1I2t55bOtKMM3fHxesnIAEWn1wku7uUBagZtOKZhZAnlErugw9/ZJI3H5WJR/IWLim6pYBq+qlQOGDuf0OcJyX+tZA8k1Rmpca3EiISA/t/RS40EJQm4oEMYYCsPoC51ZL1gRcU55fhZPTVxShOUag73WJSnXtewVMstH2wniqWPCHHcS94TLL4xRbzIXOM2Y947KHkiz5y/U3vBGUTDkj2Dx5IVekGoriRzCHO5l7KBng1JvcEj4Bf8xe3v7Dhe7UT/2nVxvu/WCtO+uHq9b99J5LC7y+KVQzd94/JffLOdXtCaF/4o123L+D6nbcvpfnzd65/5rvNU37+8uZ1v38HM3fExd07vvoZH3yL9OFb177wu6tNXHX32pee/u95tPzbC1vW3/d/TI96+DGR8Xfu7r29RT+aTz25ZeNjf98Kb73thXW3fvEnT6377TsxLr12zdrrz4aFP31u45P/2SZhYGL8jinuIF1/4T2bX13zoyVw4Y3PbXz8P5djonFdXDyw9QZm/NuDG1f/6FRkXPD4mndT+7OXvn/BIf8B+c8/8tKzvz0+/4hvbP1VPNi57cFmdJjpX076sl33KIHK3X9Ze2WPk+6K2PH8gQq89lALQ2vc1GVBpWenPRYYSjHp1v95zgf90dnO0Mq//2LkmcKuXnkgo8KYpc9OLrgAByW5g3hMHb/jcNGSICfjf65SyOC8ctOhCnKklhzPwksvkyoV3k2I3nHCP+0hCh5xPBVGVKpSieefNUdAAHtpms9bidKgx3JhHE6qa/dreAUBC2bB7+uQk6zofb+mQrdPfDuKo4jQPuhOovm4t9cpeInsL7cqJMhbp2eSAVObUYaOosLYC1EGKY+TsThIRvcf/tBJD9HeSa5Kgv3zTyxgMeTJ+r7pLkCWELw6Zv25L3qcR+bu0xdOuDGOsgT7z6vdLfJwoMtJdXtit0qNp3mIUpxNX++Sp7n6//UFPFtV3Y1rfpyPu34CcE58Ce7uf+SKAS//HJETR/mHvqt3TOEmd3fkDSdMuvCy361gWcMdNwF1pxWc8hs+cEfObCKndJG/kn/xxOIn/nES0OQbmq92d+d73/q0IZFjel8x3vSRd3/sdz/kFAf40l2XfPzbJLv7+/mil8eXjtvi5f9ODhobACbWnfffDLzz2f69EDUf99YPHvNHyvuuCAZm5r5v0nov71lJDV903994jHv/ILzlwS9SftNF85l/8qDRNO20mdjhxu869BgC9xQHgbww+dmlY4LSILh6d4VMnnvxftfQwOxHfdCf+59bJ6GhQLz1gTv6Sn59Gz408PTNg3iaN9QjJ7NxVLHjdESFkoTtf+SkXTukw8L48DjSnZ5Hd5I18EDbEpTJk8SKI1EG+NMrCkkRp45x4e+++N/vLCL8zJoK9qEK8o3UkjXmO88RnIwKByKLGnFlePjJCozjOjdYHGYsNiNVYdp5m6MKFN3/awJxs+cjUsWlx7v5uDOzuEp3EMVJHH0WlhK0+w6kSyaELDlATsZgL90ji3B3OeLko11pUu6mHnmKUzqvGpuuHwSnEOEpCkve5gIpJlmmKqiXSVcfQACSwuD95ErZ1v0YlaiJCkaqnP8mCuMn4aT7rXV1rjTY9XhHBaoKwt/7Y+v71jkh7una/z1KnZuLJf+rtT64f1sx7p9DDhFW/Dh0/c0FXvSdrwi8z+Mo7q0Lxc8wWDh0aEKpf7CnNLMm94l3F9Haju9dAYNHhpJv3eKlTz4x00PHgTmD/o437Xhp7YEW/Z+2QYAC7/A4nPuV/e37N79j4a7enjGT/Pzj3k7pUNeMoK17iuGBucEHt+0b9Mf/zgcHNz5/4OsUOPf5587BgB3gWza37lJPzaww+4wmivEr0+vq/m1MANArj3z0q95feqF3wB+RcXRXyU/8WCl+7cBi9a9YGrN377i9pUG8XuR2vfbUS+LwlnbsOumR/YYkpaSK0zuKR5EJXNQ3eJpr8A8MtdN2vZf67njgrQyxrPZLazcN+rUtDLVx6zYLSebjl5io0HTqa7NnB8vipDrPdh91H3Y4SE0/jDzLE6sasrgNPByoMMPcyZ6tVyLZCu8izoGfW7z3B3cNFi76YlNQmlv/9RT7sijUffGTc7IEe/WtRXKFDG57/oQvOJ7MbmSXz3rbPWuWHHtaE+nythMkKjQnF3HaJ9fgpCq0vL0Q8HFLs0CQkR6LjNq/ETzgpHs3YIUszpbNXqLcQSwZF0cpru2r1U0aIfrIxKAKgI0d+HEfGIfIuLwOocCEkwsu+h8+GFwVeeG85gsgCULuiV1ULo5/z4V50uW6rSRnZb9HaWLL/LyTHrh3YyPZ+warAhwLrOxsjT73i4l/8tyeF/qDv1IK/torpZJfjgAvtOG/+K/Yt06+DNxNkRA2dnmove/z7UfU1BwxfsZg3mc0xOgrt9AA3X/t8cHZ0/fFXPJkm33rv+70+Mv8580P7oqIjhgoq+Hzwbubt7kH/zlfOK5ljnlY0Ou5n/10XZ73XePhic95HF7YXvJ93/N44Okf/1sesyfd12BEXgMU7NB3Lm+dEhV8/hbPP3/0e66Lp89zXOivqVkb+2/4rIeBhRhPevi3n3r45eTZRB3WVIrXhn89mEcOuusqDnvjvqO6n8VJ9SwWZs9+7VRRqWzJeLekkNvyFDZE0HKtD25a+6VaaWgQbT/ZsT/cNnnIxEurSfXcyqlxRbTN2nGaUV2neNMxr9Whw4Ej1gmlwKFTT0VpQQ/8vqJ8khfmORndtv06DknGaeNDBCgYvY+1t67Mu5F1oJe1d+JpGEdPJpO+/UXZ28YEpYA75CKUpRQqQOG97zQgZDCOPhq8AhBNP2j/03fI6NGxrR4CxYFsRilOcltQ7xnwHN56BOlu22/GePuMWGlQE+qX5OKZlzSx+huBojtp9uKm7X/I4ix/RwR4NjH5u3+4qIWMYuVRQcDEt//18ggorllzCi7AMwjedyFBItHVdzN4RXV/+/dnGlk4/l+wuH4+QSnO1teKZHQrrumOK7j9FYXqxKX8/pcLMEBDILi77/i5B3f3sHk+Dmj70/xqzs3ud/BWAMEgiAaDe+BR/gfAZQICCKJ/DL4GHnVv64Pgfe5f/LiXywwQBT7moXTCu27dVgzfOa+3DsAkwYCD/ZX7Y38fYnf34iNTfu3u3vW3RHrU/XGEBQcUFl4DUDJJBF6AfD2JX6B1p/sXONm9eBZ5Pudh9yb3yy9qpP65H/9t67T38u1PDwKCADrMRN1rx9xUzFKhnbZjVluoKJ66MudJsLoBDZGYfFvYv+MnbQy9mPmTAwNPzUdDhHrvi+VlUXzySioWywZqT3JlUhpuj79w3GnYYWB8pJN0V/h9fiyZHziUy+Tq2ooDCtMulCtNtP3dt49HZar5OXEZRjDAXWR0Hlyjgf1k96AMQa++73ExRWTdWQdTu0h367l1EM+G+cylBClDWHS84+CeDVh2abMrzcKsk4XDxJYsIveBhZGDn4g3XNLgynD7VoUlZ2Ep0HMAmGqewVj6gwlnGnU
457FuDsaaL5MSoNcobQfpRG4tCagKBvOsjcTlCFMXEj5mLeekHPKxZ1fMBeY0oAAOVI9enyvXKqEOYSgNIXGc8yCT1lMRufZR6JMevx3Y1pQmuP7i6KK7vrOTfW7DtWC/GDUFPX89vPf/uJyL/run3zqv9+DBZzo4Q/S2Pg/Iew96ipQqc+Z37MH7y616L1rD57eUfLwy/w7cQ8wacmOAYg/66We007uKuYPNBYAc//n57x053c/QcAB8izzor94+YT7PHz3Zo/X3nl1c6BcAJ9wX321l/yl737q5yfnvnfdjXuKvnmsOGXVPSswjHLxNkqHfnzRMQ6Qn/peGDgEFJ1/nr3kqdhXTf1XjwfnEzHnYAghHGy8FDzqf/iVkxdG557XBx47LXOanz3MjNOOe+Fxc9KVSX5S7cAyVAGw8uQ4KnOL/yQx5POfGjjwk5lo6DCav7bj4NsYcvmT+y1BNZe3ulV26qZJY0M2z+LxT0/7BjoMVPsjd2XYs7o/zhCirU8QV/DSAyTHZPc/xsuaMcA4qzPkSHUHiYxOz08OiXwFEumOvvF3/aGhgYzOKovitxCiNHW/AqoABciRtWFJiwSYKgqOkaow6QxHjl00NVgacOKpCHQUCoGsvnnQKIqsuRyoiazyto8BhBgVRfORZIn/OMiq/Zn8yKWouM+zQRwQ6Z6/eIzLsQKxK8G98atfrAmsflmexVykugZvURQ6Y7yCWEa6Qn1rEHBqh1uKa+DuQWUR9+y6YG4WIKKaImjDapjmjnPo8YsGi7tfPNR7ygM+MLh5Y9dzLeSwOH5HL77p4x6Cl0pxzY71GvjI34bBmv1PXFI85rpm1m5p1imKqd/dE+J/z/2gFKg/KnjsHnzgtisDQBx//dG4uGtd7LnYAjGR8VMvurv3+fd+5GH2xbVxzgkECwH/v6V47Zz9PjiwcVP3Lz7qB9fvK4b1TRjJhmIFp6PFm1ceLOUiiBdvtcHCMxuMvv0US/Ht/+gDHvuA3yZh3BQPDPhPmRjoOeFTA7EpzvUS6Nqn/ste3n4cOqzEN077aexZPFsYO2nTqVRs3np5jRKiva9hQ/e2gzu+1owxH
457I385dd9EB8qZ+/LJPrppzmVisKsXYupvkd3HLxuOhp2xpKX3Enj/o11ngFeXtO0BFcaDBYTxNKJKM3Rqve+42HKLf8LL0VplbvteUrw9D7zLJmDPfvBNRHHn4zSIMZowpUCuRwM9OOZMLLKOfOIADjrNptXYCZSHebMAhw14mQOLgiR47NmZ9FgEdcxjUEpzjO7VTriQiwD8oCBomCCyEh39T0FT2+SpxGmvLdWA7/rMM9mEekSVu+4Xt5KkEgNhb+5ppaXd5IJkdF+0oizbkdFRlbxpqkQFJ1ISEO9zw9kcW1/ikZzMntV+olojQoDPRK5Qfvy8Ve4u/dNP3Kzlz/YKLE/KgDux33Z3T0X/ezgDw7UYOTan31h5lsgx6PrPqY5wC07b/xaHlp6jAl81stLH+c4qOkruX/lUnd3eHKtGfVEUv0NnnzFUT31LUth35/yRkNHDnIfct/Fmw56+Q9OG/Tyj2CYZAldEfXGTUceY/OAG08BjMLuT/QRhWuVd18z5k9evna2jIhz3N2PoqeJ1k2bTpoK3PLbZqP1hoFaaK7BDicx/bqDd0RO9RfvmlVwVQB+2uleBi+34EPl9qHrLs9jDE+J5pahg94tOFgYf1WLq7IpUV9FyqT+m77xPuwweG9vIF3sDyKjSr8/NPtEsovU08fEGWDfa4N7B8qMM9pDjqoHer+1B3hyB1Vyej58k6ClmXRX50uAkfnVXeiVe1C27MIbDSCwbr1XUqFKrjJKVGii3OCYBW4pQeseItSeWyBd4bH2iLYxKAuKSBSlwKVTg1KgJKLOP5JVnD0hcLCXoYyE0OCPDhlZLa5523j6XgpUN0QbHkBBpV5UQYVhnHuweMEYMjqb9uaiDIENaxiGrvZvvb/z8XjQ279y3sAE1HFlzQ/ufOA/joLJH//Fffd+YSIq8fUvzw/44z9v5Ox//f3Dv7vyk3r2lH950AYeuhvekVs5d+D+Ol48Z0r9rvuvtX/44KVNz3+79V/bbhNnXv/ww786HX320tDI393/8Ju58Pu3PXjw4WsH/v6v6+7HEFz684cevOc7Z8OydxzZ2vPkL7f802fzq/d+5eI9u8b88snvRiz87I0P3PbxRk76lz/e9cOzEOni0f86btMOdn/gqBPG6MU/8C3U/XT+8f94SiHWz6646Z7vLaHxE/c9+NA/TkKA9NmH7ngbdudry7fXf2n6SS1d9/y896vv69729FlXzd71s+3icDbe942b+pVJFfVF46hY3nLV+GDg2tLMkLu3NCMxXCWGZd9uBOZnX+Si8skDhWkok3sWhdrl25fgw87tHOIoxa3rCeRpce7pneSprhdayep6sVMKZdRce3+TVC0L9Rfm3BUm/veyYNUIIXyvVZLGFrPYq7uIl9SgNNe/YsYX3KtHFAKJ4gde8moZv5+KUV5fX0lqDBJZ22OI82R1gMECVXXrvx/mUopS3B57AeKn2+VKCaHnfWjib6fEqlLJd51DBHBcK8pC5HNPpuO+95iq4jPfFxmIaz7tViWHSAhg0QDKoEc5tRelWHiwYLEqkFdWRZEso6pGqkiWGEoj0choVCyRLJEsKjSSRaJRRZFs3y7FawAMQJSLZFF1AYhycVg7S7a/iTjK4tnEtMLA5MqQX3S2G4jdfUNXLjGMpaFzlToBQvO726ogJnU1NVUgZUG+oq9tvGuYKdTXIdL1WjulXBo8W0uVLV44BcsAe/IkiolPvjdEVFuMmQMOuvQ0VzXi8J+tSIw7hRClACWYQxb4RyLj7J3uqlZcREnGsbtDXB2BT8IALF4yAatKAzTkMnU2wnxlMoJzmgerBnRvxfJkdL10UIHHnyODx37vRPjbN4WoOvL2v6gRKIx5q4sKWxbB859pCKrMQt05bahsxpXm1ZEoOYBiu8TdUjzqWMuCQVLdDr5K5GQf7KWqhlRmSIAiExaBRZIiKzMDhERkQpHADBQZKDIpEpEJRUJRQDguiASKwJAwISITigwTKoNIIIsgMiEzTAhDSAgsEopEZJJFZJchwCJJVuAf3F8BMxIjyQxFAjOSDRnIEBZJioQhEZkUcVjLx7f1nelGVlXS1NQ1CVWh7d3NAaCzJB86iT+zIqoHgh97tFO5aFSbyBy/0uGeRTPq4nkMNwvHe5Zgd+VtXsmV4FHvA8JVQVFlUJsno5vfjMUJXv+Pi4OqRhQBuHzKO+tdVfA7WhEiX09G8WKbXEGki68QifzPquSQN5xU2U+8VJXgCIwEGkV139Tml0QhxaP+exTFS2O3FLc9hwg6m2qRL86bhaVBQUD3IdI9LnnXqXDCVVTVYdtfRgCiboyo1J1o4xXLvDKHphoEID5wtFs13IkE4DCrmaA09u/AUUqw1QXFeVxpbi/uxqvx/xiNWb958u8Rr89iXlw3nqxO5744C6hNjVUAP/pYD0B9hIbuz3HDfICJb82jyiAM1lTg371JcQZonnRoPMPddQwhSvGo90XGriCQxCtFKnQV/1QjL5vc68qy+RAZm9uokgPCykAXnOpU6vCjhQjEmDiD28DDRIUzCVGSh9zOUzAiztrpVNEhdkS68ZGBklfBIxBGSkxUnakNxalkLR7CPJg8Kbi91AEuqugOQrTUoRS34g4XVrx7QC5wR+7dvz3TVPvO2W6VOTx5QoQScCqWgy94a95VgUMAUW5c9OlAFd0IAZVZOKWISPet40GkWvxcntnTyRrUEXgDe/yhSb2Z4tyNu7yCmsFAFUX+rRMB5jfwOiyfd6IT27mLXVTTB5vNlebsuef7r+ZCmrxhcl/bcFNcexEZQ7R+NyZSnVUWxfIyB3ciizdhAZy3E0c44E7IrzIrpREEXpmHiCCcRPnEiwrBKjCKtQgwzgweJTlI7s2z3QUByBntkzFE7keTgypxt767O8gsNfzUSxW50b6PjKKhRLqnuKM41BXSHO/JEdce63EUlylnWHBfZCiDQwByQiimfoBEJ5Df9wQ4/vRuBdwjg5d+/67WGomFp+OVuBvxFiQS+g54Bc7eJwiyS5e7ZXKPiIqIZOWXNwerxFHvXuEAoVRYQYgy6A6RMUQHVotJTQkOARXIx/H/s5HQ61hb32R3SwuFV++cvxdPk1vzoFcD+eJzLMZPnOd63bEw7popDl2nmFNVNdeT1bln13P/2o6n4BrvDfgw86O73cqCA+qsJaPTuQ4jF4jBhImevYNTSbSm4BABJnLxVox0EReJQsgWgjj4yCCZpx6rkFNa7HSUHAMQNThAcAzb1oVbHDnIgL5duTAJgVgwBw+ZQog4dGA9FRrHvUzJM3kgbLu9PYOoOc9DBMGBKMVkFMIlR7gBwTHPPVSr
4570HYkTlTm2wfYXmfhaJKCAxFEQPc+7V3VN0NvJ0QEJ5Kpe9sMnKB1D3kcRRrY+ejqJU2UG/OPwj2LB7HlKcdItoM3ySvQHx8EfPyRhDjNg7H5cbLKJ14OnskDvvfu13AAN29eSHJwXDt2QymSq4zwbKvwOOcBImSwa9An8Ia10+DjCUpxtf+IlvuzAPXNqgqu07rAp1wzLtjrjNH4mbe4u/2iXqrOQKnbM7j67+iMfvlT3FOgJdSaa5idRtEcyAsifmM4eFwW8vtewu3c/rgGSv35tauj5zbVtRDA4pUiB4Ml+XPPEq0er5ABiF7bSS7EAeGAe2S9a59cT1ZRu2A3lAzhlIh47bYYkVg71h2cvKAvvtMsPrvYb3G0+4Fet+c2++x8GaIEkYeQENxz7L7lXlQJEedtUYiDJwRCpNKDa/rxLPk2Yoe8gH4vc1u9Noq2dkwoxLjIi1B66eWceeiuK0UvPm4ebXsuDvVEXoyAIPICBot65OXIn9lOLaAJIYi8KB56cNczqsWBnmeU920PPrOhATAB8rEzt2JxkMCdYNa79tG9OBmfOqiQJbb9P+s1dxgIRB6rLOToee6xA3gGUKtjccAAd2KZnn6wE1EejCkd7g54DuDlDtnUYmyhTLlHiAKEPNBH35/2dTzZOSOPv0Elj2pDC+mOflobHby7T57Bu0sD1RHNv5S7v+UzjdjriRmT//GaQlD0m38IoprO7qgUy1OCnngIuv/lRtzTGtoa8kjDSKUxp5CnfMs6OaXxgIhIXP9fNQr5GZSe3N/xh3YViMk4/pGtym24N+C1EFOps/dPj79CLsLdKN/0za/eizLh3v/A0+8cA3EEES/csKEkEo0j53oE4tWNftvmeBxG8Vur8g4RBIhJNeJt7YrMARlsu+GnTzpeEWLB9zERx2CC3rvu3UFERuFxLgdsfpHoycfdAXkdcUzURgTwwhZ+vyWH4NDXX8iHPIGYxLj2bBAG+54djF67q+j1xIBjVmqIyMH6rWvv9zoy3vrjlt8eMiAykeh+4P7nBywXHCKg547/Wk1ExmAPftlCSHJK0aGrH1EARGnfdnIk9tz+w9UYFfr+W7stRwzIsPCn32/FnCQV3g0R5XufCehXeSacSKqe3S4HY88ae/LhXKnAG9oSNQ1tDWmObtxMxP1PKKS44lK0G68G8q/fEikUrvnHiZi9bgiOvaVUHPTuH89GVFXMralzUs1XvI/dOJHHKW61cVeO4MPJ2y7Jk/jscxF4iKk9axLlzm4AW/HBd0zMGYAZ4J4wabDTGKTcAPdsyGDJh2/aoNn5zT1R781XLgGMSg1OvOr0pml9W/x/3jsXjLSjb529rav313uffIkiiRYolyj3FAw78/r1u8rY+fRdj4IZ1TRq33XXxkPuEL/WccszfwIjW8PvfOMzf/PBY54t+CDphrF4a8+La//jSjuAkd1IdnzCfeP25fv/8Gp+4xMwCGCUewxX/GRf+6/3P7K5BBjuSYpCQMKddBm5i2/ZMgMY3Lr/D+cVwMhsTFjlHicYHLiCVMGyq38/P8YO/XH1Q2BUanD+LevHjgd4recfr2gDI2PTaRMF4NHGRyO8CPVnTvIEtx6Qjz+9beNj0QCAAe5vVHkg6oprzVNij3C2866T3JLA62oOVAln9o+7fbBYuuVY0OsF8z/9nLv7xk82Y1SraTCOUxTXvGu+mwNRLq8k1dYMui2bOoyyywVOdiNVMjNRoQAB7lRVgprx0dkTbu6xwQ4wE5XLAmPGvXnjQ8qBGaliwtuab93jh0AI3AFLCFQskRtz9N/mPLfvji0DyKiyQf3Yc7/2FXKv3FZqBxMV5N/54SltgEBp7ogp11wwZiwEFAxCmQHuKcgbLn1mb754CEAugXsCOMvm31fsBCHcyShEoFKJ/PRLpsTR+vv6OpGJCsWMf93iCZ29j51BlIIMapodBjuRicpl1LTNPzfv0Y4/9gImqiwXCmQNyEmUG+DOG9lTl5kGa2qVpHwuAtx8/rtqYqXE8eBeqm00f3Kju/tzn57P66KY/k+r+723a80/H2+IyiXKrcO68YQozLtUTgCIBvrlCYOFmtD6pfOx4WRKcockU0qIyywyicoF4AypRaRbZFTZ3EmMRBVN7jhDLSNj5FRfRkbDqa5FAjwtqyKCExhaGe7gZHbKTQFnWBrpZqJywdJ/nBmwA7fufxUjq0UkGk51jYyKRIWmFHfAAVMKIQCS3HHe4DbO/1JrXFMYTHD1D0QAAdel80KU4HRbRw8OSJUh7Ph/XtPV6/2r/2k6+vMH0z7//e99+3NvnlfARNVN+9v2FAU43nD2OJcDEj17kDtBe0rH0nLcDEaMQjjgDKEQTuWGgzNcJStznCGVZAY4TjVlEtU1SQy1ypzqCnCGsVTmOFWVyGhUqASn+kJlzv9aGjOOa7HlpT0KuIs9PUiAy8ed3eA4oOKetv1uAO5VQEZh3ps/9+3vff/z03h9NaraPEFlvDJ+43454Cw5ClGGQ097N5LbvOLE8yZRV+cjhTecTQnC+d9m1dUx+fyJxXnmEt3tPeCUIY5aggOu/RvHv+IAmtBcDTBeZ608MlFNceGPpyLE9rpQD2ChaUHeBWBHjAXF2/cDPmnF1vde8KLGuv536n+vxVi9eMHbtq2Y5MD+7bFg7BEGIM8vaAoGUB/qtuOIKf94CqoGssjKXy+G1Hjznk8RIU3YV2oJIqhpWkSios9/LgIVt8WOs2DOpAvVUM8oa1HfoAsmzV2A4/G2oiD63OcjkRhNa1JAoaW0b4JAvOPSuiqNIMVbb792BZGxdOdYHLe+2lpPMr/wiy2Tcat5+yI3mucvOpp8PRpdZdTnOXrRvGbMF729xpzJLV+80C3Ja2v7zHHG7lzqsnDqUU8bPrKBmpcf/tAYDxMuXjM/h7TzmiYshVmv+lPvL5RywYH82LZCdyli1HVU6i60jc0D7oX+2neuZNNeUo2ma3bKYVzvygnBx37wkZdrGPHuGlsae1WY9Okbm09GGvgmiGTReEvw733v2GiMARSgq7Nl9FVLZxcqAFhrx7KrwJ9vxJMQfKsfMa+08dOT/P3NpbG7Rj7dOr7j2EuubDz4Fzj26u2KQFKZ9Lc+2PChn/3jUpUBdS2to69aW+pI1pJ3TSEUC89IZZIg0v2b5T72g72NV158Qu/x6h75dPSFkw/833cffzEuyG/FZCLReHOXEy/52EIX4FBXjPHRVU5crAMH5IvOII7y3VuwQLlMxsQWJJ/5hePffc2Bk0Jfx8int75v1qKXZh4XQoTC+MktkWDuFFR29PPuUUDgUAp0HxrHqOtxh7qJS+BCHvKxXgsAYspcUNTylsnBUKg5buZLC2b01feOfPoGC50rG24o5SjX3AXUr/yX+y7DQDTf4I5FJgFmhKhu9FVdFDADhASuF+vwssvu+5eV9Sw4xctR6YaGlR2Fwb6Rz2B/6MhdoRtPz4NE3Yevvn273z8ZAcani+aUC5eTi8LoqxDlQI4o96i0BovBmXy/b7/96g+PkwmseKOuyB/y/sGRjhMfyvfQ8I6Bh+e15osD3YOr2913XopIOOXlFOg/2MfY1tFYrWPpO9hPskebdlPu4tKd7u2r2/d2D/rA1hsG3tFEd/5QjI9soLg3HCRufvuqvrbmUMrVtg+UJl5YkyTV30yKq7aGuhoffeU1ddTWylO4uV4CEDUXTiwNtB/sL+Wss73u7c1FDoQ9RUa6Ku4a2E880Ki9+6NcvrWpBjtlkYtE4+M95gkqKNDbp9FX6uslVkEJbj0fx0iULzrFqPGuQ8VSPG5C40Bg38CuokY6+F66MHOMcleYe4yRKuZtUkigFGB/+2is9v14KJEYtGkeSgI7Zm6QifLgJrrY54x0xT7r8Jw8KvbXmcBrjo5cKZC7GyV4vjFPYUxu9FVuTIFCY94TxN050uXR0TVu4KGvNu/Kxx22D410oDdX7FakkhULEYTcvCku0sXv95iXCaB+TD8aXSX6x9QDqMxtz+9RGvIp83LBIB7MB0V0l3K9jICL9BwSXsqbiziaM5HseuJXxA4gCfoP4KOrnAP9IAnAY371hMg+cc7COMIVio4O9VEc+Tj9pYGDYMhFsL1zqNAGfrQmF8rK5YFR18FFasit+dGAVcCc704IhssNDhWL/fhIB/p7ew+AAIJ6vpRD2bAXv90ZxSmlUDv6qjaUUuKo89svGtlF7i//ocENELT39/QzAu7trI9JlNdMLwQq9vyMyJVU7G0bfdXWW0ySRzPyTsWhML3GRWLc0NU7EvJCbUgQuekNonJRY3HKhKg+56OrPFcfTUiJrQZVhhqm51BCqC34yMc
457pHdzfjQNobptXA7yYq4sBMTOaUkCjqURhSjQTAXFdruhUU942VwBOz4EDJXykg+iLS5T7jKVUWbQsyceOfKoaJzLKemKjprrwOL+kBVUFWDrDKS+GPsQIOEQFwMLYY+pRdRDzl0cBQq5h4EQ0mkqcONCQCxCi5fMR1RX1x4wNBhQUGPkKa2lrAIiWNQSqHni/C2Bh93L5aCrX8u6FAPL3E6h6aFgWATSMaTE00sFrWqMaFPyE07Dqmb+1ywLGLLVMco2ekk9q0SyMYF1vdauecdoJHkSNtdU6I13RNj6egXz8lc1BQxBmb8YR9WP75ohR1JrTN7Ye4WyeHYZAofnK8S6mDoxvRSMenVOcNCugcFsXXj2nfT0OIX9Ex6pHIh8t5dEjqzqOyAdw1rfj1UP6aCzCrHGlczTSEdMubT9DjnU85Qxp6EeAzdg5eD9Bo6MUuH9w5wwDRH9gKMXygwZ29sFLp6GRzvT+OQuDwZbdDLEA5JMf2FI3iyCNfpICs+q2PDDZBSCGaMoaUDhyTv/0kY6pvnciyCnGQ+RxAvXt2w/VL2smII1mkgg0L6s/tL29noTYh2jialwwsbdeNqIRLJoxTQK29Q+JmLQEAXJaZ/X1n/S26YCNXjJg+ttO6u+b1YoLEEsmoSFpuRmQps1YBBrBGIWLZq2dJoJt+kGH+RDAysVOuQgNC1tePbT8iycWkEYnSRRO/OLyQ6+2LGwIiHJfvJIhNc7ZZAFNWzvrogI2UhEs/sq31i9tdTnrnsUZwpBbWedWlrj4vPzTn/7+104CG41kcNLXvv/pp/PnLSbdvG5lLgyFGLcOV2hduv5bX1kMGpFIdvm1X/z4+y6QgPGNaAiMs1Yi0kXDaW/93CWfvPbLR2Cjj8QRX772k5d87q2nNaA0xMqzsCEwZo0HpAve9/EvXnu5SSMQ9/xs3zBp8dg4AqfvbTkfkn/2yShLHDR9cs8rOmL3yxptJObPfXnnivedpBBnIp41bxVD6Lkrej1CxGcunrTBZ+fdRx420FF7YNIYYhPg+uKlriEJxSgDyAg2ofHxnSuedY0uEjWta3MXLiHGRGZHDKHCm5biAixmzKQDtR0DNuIQT6t+UEFGYtz6uQVuVRMnb5TILnDVvnJg8SI0mkha1JubP5sgicweal9aj1fN4gWXEecAZAoarNfTaKTBhs6ZawcRqR4f9wFjKN/XSC54FhAoenD2Wc6oIv7P8aEBJDJ7yEU7f8oQYO8vxXlSxeDamZ0bGGGarjvzhactJmvu/EXBqif2r+sm8tgzgJyueRdMc40eEtP+cGWPI7J6UGTdj92InGpbafEMYqUR29MvnHmdbGQhnlr6/WLkWSzMW84QSqy9/q5XB02ZANWdeRw2eiji8u42iQpzg1ueeaAXOUO4vDvkyOhR8ftLn0IjC1oX7f6JnKzyxiPMq1e+/bp/um5dsApCMDGKOOKKnlIgu/maO581UKD6bnOILQuun+xe1MqI0vjQ9x58ykImoCVCQyEjfvqXjxQ9Du6OgwcnevBZfPSQMfvOKMRxcHfcPcRe/MmDgBFTfXnUSIXBnnrwex/CRhCi7nt/uX7SGCptru0aEkBG4199rhU8ICQo3b4MMYpYLPv6BTlwxzHBoX9txMTQiqafeskzwcHdi75Xh0YSzT/6MK4K5Octf2CowIje/pG5jfU1ojjQtf+Z2+9h1PHYsy9aPq6pJo8P9Ha/+qObMIbaWLk9xJW4+FHzSALlP/UvueBCCHBwnCmTGIbCJ8yfOXZcbdzevv2lHf1otJGc2qnzp7W1Rf37D2x5aa/EMHhHCKUYgQDHcVnpU3kxkmD8R96zIAKCA0KC0p+ex4euYjH6WDjDXCy6p+iOOw7IgHjj9eMZUQC5hSeduHRWYz4PEBd7dq558P7Nw0SSlwl3H4UEkvAyuftwAJvzoWufn9KQjwCKxe7Na594bAMjTeHUtR4xb/rk8aZ9+7e/tOFAL6P566cvnD9t3HgP+3Zte/mVQ31IIw0kdyoUPmpPolLJGYkKgcoccGc0vwxQmYPj/P/9///lDlZQOCDIbgAAUCwBnQEqsAStAD49HItEIiGhE/qVBCADxKbvx8mYvAH8g9+Wa94n9t3JMe+Mfwv+K/X78svltrT9i/vP6N/vn7W/KHr57A8tvyj9J/1v+H/yP/h/yH//+rP+p/3v+O9yH6T/5HuA/qN/mP7d/f//N/kP/////wv/t/209zH9x/5H5X/AP+e/2v/r/4j9//lT/3f/R/2nuc/on+n/8P+Q/znyB/0f+5/8z89/mp/5PsW/37/mf/T3A/6J/if+37N3/L/93+0/3///+ij+m/7b/5/6r/ff//6Bf5j/bf/F+fv/W+gD/w+oB/0P///6Pgq/gH7y+4f0z/nn4nfuH80viv5n/VP7t+xX+A/7Hr7+G/Jf1f+2fsN/dP/p/pvi+/1fFH6Z/T+Jb7Jfg/7X/jP+F/hv3V+Mf+D4J/Af/D+5z5Avxj+V/4j+7/ub/iP3p+lz2D/ldsdqn+i/8n+j9gX1Q+gf53++/6P/u/4X0av7v80vcj9J/u/+8/t340/YD/H/53/hv7/+5P+E////W+5/9x4H32X/Kf7r/Fflz9gP8i/oH+i/vn7gf4b///9j8Rf4j/k/4//Q/s57Tfyv+/f8j/Nf6z/z/6H///+/9A/49/Ov9B/c/8x/4f8X////T91vsS/Yn76vol/U3/S/ml+///5LzIbkt4XvKE8iFH4B232MeX5NZ0ZIemQ9Mh6ZD0yHpkPTIemQ9Mh6ZD0yHpkPTIemQ8G6o4BAe0b3h/9j8Z1bLV6wXjrYYbLfx9xKTYY/rPV7xowosgRAgFecmpPZw6CUyJTLfx9/j7/H3+Pv8ff4+/x9/j7/H3+Pv8ff4+/x5ErkQ206wpCAk0Yc0oeDl/tAf7HVv1ckPTFMIb4zE+ZsWZvMHRdzO1HMnB+N1CVeqypq/EFMh6ZD0yHpkPTIemQ9Mh6ZD0yHpkPTIemQ9Mh6QhMOdQ2Dc72Ze//+P7tsvjIUn2rRcLhIKYm2kg4hp1Wn26bXyz+uLl8OCX6c0iCkxuczzoGRQcuA8c2RgbZrn2L58fXxLH05Rh9FUSQhBPVKvYob+eSYiP+cUis6gNry8t426xJqMMMOYl3/jCE9rtbEaHMHLm4hi+2n1dBLwXImTafzBA6fppMeUd+j88VbsbjS2NPHwFF0fRieNleQCuF2HwtdMsq4GdRf/RoE81VenR9Mk/UFXyoS+Ry3zLVgvzModGikCEEr5RHcSNfl/48KAKltKK3vtV4fT4yWpGpJ7XrPnD8ff4+/x9/j7
457/DCvc+sL/ICWPl+RGGPI6N6DCSJgooCEPmWJzawVxD5zNJ/b2A+7AYgAs3KvMHZEGDYgvBcAIZK9XqEYP15ijDr1pExNBJJii2+/xBvZEWeMQu2eSnMj03CbQ65BRuX7kbnzwluS34Spu2WtNgGbUc9rkzOaas3qY0OFfNnt+iOG5EMFSgjSJFyFA1uPZ9yJeA1QDbPor9Hc4+eARaF3hEspXWhac992ouws5e4SmBm0moEc9iu8RU3JYwg/A06NftPNZLII4uNZ6CQcclExQmg4bNa1b0JIkmEPv+LoAge5fumOxr15Cuj32q/ISmN+hh7dBs1kwZwgNW5KZb+Pv8ff4+/bleQxlIQHLzvqQPyH0MZ4llhVUbmmF2ArtdoWTlzfjUlTsJM+OPZvngZDbjED80ITzRlEGicNNOTsv/PduieoK/soknKp09fe7MiXj6fltB9xKkBn7qOpKKSrbLMttTmvaHCVBE4FvansSFxp279NHDVU8N+bDPwKzxHy1Ntb2ewqVQ7zDvzgk5SQ26s25RIi9YWDAZLZHW5Z7K4afbk8aB8zZo7+opG6mlWWqY4XXjWDjRIpYgLdkS1Fn1On9M6Q2R35RjbmMhtH4w5SfA8b92Qp5SR4IZ0S1vPwYrMPvmiTs1VAxGz5OHe/leH4JfGW7SKHbz8kOY0a36DPMkEq6/rV8DTcVpY0ckTfRArOSOaSTMfsI4FbRFPe4fZ6uKv79YmEEMLPwB3FGdF0KJ+JPm9HmVqasHWYJcRk1YveP75HxJW5dHj3ze6O6dXxOK/W5E3Eu2TNZawAhv0SWFYcC4vlN6XYj6eERgis3KYjau3/y+/6Y7v0l10sgQ4hnw+I/rSWThqy5w/j4ENtKhOkzdcX96ZXt9AiW/y3ZeU+yB+2lTY4PBO1JZ45Iv2Av8a1MJncp+gqOj5RXC+b7stkO7oXCMNPuob6oDl5xdKDnht89E4Ze+3Xd9zg3jqtsGAYO+OoBzFoDnw6EXYPczYU492vLIlaHTo+EUncrWB+7M5krlU58wYXwgYKr+lsYdC6t4q+tX/Ai4fu1OmasCIuNGLsojOrHsiiAiUpeBGrSAKlecHmIcIgdY/uvL6Dv+2X9dG4z1HluCa/JbhcmZgt6qn/fPxaBrETP+0rHc8sQrGk3x81dtSxwwTJwKSPGYeG5dPiK+xVkEbDcw9X52LL2jlM89nTKfRS/ZNca3l3tVTZ4m+6TE5PUrE6O497sVSBxbTJfnv3EarP7yaco6AjJrggTvrLWjnA4IzbOCRLjwnUIlpPWFMh4oFaeh2CN01d/0NK5BJdsyLztPZK/WW3nhvZFpw50V6NHv8ixOkiIvYD8Ssh6K6+ObED/9vtfo+uVOCOPCOHFjepivIdC5OyIwhz4q8wHglf3c8P4aW+XUFtHwVPvZRRYwKvvvKW6S+hC+glIN7uUc/6iya3WStvNXdWJoW4xcQTzh0m3u8+doRHf8/IHRPMgiQ8LvPS6zHPgx0b6s1lrZ9hLBVGYQWwlc8v5/buaH9m0i9P5/wFgH4EH6Dh+dYfn/Y/M/o7vA7onaRl+5HMgeQhXgQPPOu88sPQWlyyh/xc2fJHS4dxHy6INsBI2leHwA7asJXAW34ylnRkMqxlG2wCnnsA/xtRF/SeZog8yhD5IOX4lX/j7/H3+Pv8ff4/isDfx9/j7/H3+Pv8ff4+/xGi/OX7SjZaO6elNZZR6AFr1MhP6ejvxBRwmS+m4/sQ7zbwX2kJhkwVS093iWpr7GMpfXk1FQ7ULfx9/j7/H3+Pv8ff4+/x9/j7/H3+Pv8ff4+/x90IdjRzwtZeuQOJHjQJYrDBulwuuGdsxRX432pEplsMYFYg4zTHFyE5VE4t2eMsLKf4Bvcyg/TIemQ9Mh6ZD0yHpkPTIemQ9Mh6ZD0yHpkPTIekN75vqs73/scbZ1AHlumJ6Sxeljq0/pIeAAA/vU7WmsDK/NcVdaY4rkArooIuRL2kgY7HRmxKamUoV81NIJcpRtle+GbLLljlj+ndyXI+MjJVRB2FabD20WY/XJnULviZ6jNY0Rqy/IlXFfTLSrpVHFfUPRkOYjW45rnKz07F0JsaCR0xOwRyEXTZEqnniYkLPCZ+ZmISIEfX0lG+I40VfxCAhgXrKCBn3VcRC/v53rj2jEJtogHtP4bHqZ/6LsXb+tua8vXIcMo4SdtBSp7WcbeYS4b3P/QiBBXmnEADZaW2Pk8y6Hgmbj5aXpUO5dAAAAAAAPTpy7FB96rFI87KBnb6HCywMkt3CpXk+w0quMQlMaiuiVvuXbsrduajgjy3VH+SAgIcV93sAHRYgVEcZ2wxhG6iFB8svGxTdMgjkBeaQgooFrA2QM+4y+eNGZoYOeejpI0pq41z0RlhnYp1yJWZU9bMJkGI0VihbFeiZRgqlPopb4Kynrt8zGxtFMdV3Ga78LN/eaxw0XGPtaMk4+YgG+Bn3QQhMaTeUvSCOGnI+FPGpThayWfimaW5YQFHVN9bBl4NsgNkllNYLE68rkgIvMJAQsh9Dv8HF5SgGEn5Fg4lFFSQRo41oQj/kw1OI4OCIljvALFCDRuWMUJHj79Qt+rp6n6tWckUhqj/DbCdWNrdvn3xF//D8/U6a82Z+7SiOC/ggtTRyNL7UzV96C2AJvoeKOuqYYd5UjvhwyYn1S/ag9rf1CyOwZZULN22qlWeelZLpH4rCY4trNFYGCsgbPCK7NWeXK0hYLj/ZXL4MuQW6tq3w/7NNs5Ur/UF2Kx3NZUoGEUgYj3mc1qekanx8yo4beCgwFmOGPqkw2X5lm09J4O5ArN4fwXiwpadhoQJfT84wiAo5137MfsJcqDRYqTWq9woclw1uQNdciIDVlP0Tk65IHr2mwH+Mf4aqR8+n4KYYKE7w2UfbMZd4sKgCSeitEyadLP3icW1pJiBeN/SE1dle3qFc64vSOBJE8Oggjr51lqtlB76ilcwB8QVYAAAAAAFUq9qW7l1LU5KDB9lYrq6wBYnqiXnQaQx/E4RnOUf+xOnlCgliE1EeeZjzK0gK2FS8/PpiQdFIpsJ9gzfPpIM36/N14FlUvirQ2VtDD8j78m971LZyYB1d+Hxyme1dtjM7iIsApDNxfWb0Z2HAVpbDVqedSL9pWL6TxaYGsmEXoHfEmfRMhoVLN83REQxN+G+XOoQdjdkjKfW7FbR6CuZfdDXS7zgsVuzaqJvnoO4UOukv5SpXPhANr7h3/d29w1KfqePMuoyP3UIppw3bvfQLzSfuoYostNVnLq+GaQN6PV5t5v1IdHGwBpKjXMX/h5mHVYqSXqxdB37rP+RqC8daS9yXGlKkxhD9NoVNXL/BJdPc2pMfjVCvyCRgky+fdWesNbXgRt7iN0CGMvG8tpGXNlqc+OcXM8fTJtqOjnjtoJ8nP4hALTkBifeoBBwA8oKyy6kTxQyuPmxDDtEHhDbbO+tpD5u0G40ZtfPMH9umvin5H53EyrXhlt+zeC1leoHR/WyBcdhmXztrSjsBxlKn+tle9PxYkqIwaz20dXU8glGK66KVWde91QHTmhvMXdu0FMOq+4zWEDk2qRfN1x4tfp+SyPm8VRPh7nPoM4on6TXV865YBAoSVnqrPisnmGZyBpOM7bSeC7khEdhOx51unXZ80+cLhszNSa1P/r7qKtsnKtXQqhuHINEAtxastIk5iZJQlhv1oawhqQTskDW0jdTW+Gmnb8knYB0mN9ftQYZuuVCyVkFJrYg4mAWSy+ZnKUbK7acUnBWUFuX7r2ksfmlBnQtqmjWzsL6m9mc7IJZVpb1HwwHtgNv0BfQQN/8xlXmpnwFRdSG6em73xA3LEds4MwjmT4yR2oQmTc6Em3ozQ2P7bSpahk8t8yELR3L/WZuV3tc0K1bkWO6cIhxnrqZXZNJZnkempgAAAAADQcQp5O/eWHsnTz5700EEbu7ozkl+5fLwNazvytFRL++klYHr2nmJQbdRYUctWuegiqXwLNspBMKfHEzwu0qMcDI3bSaMnrmRnEE5Ce/pexnpR56r350+UFkhXfV8hl0J6V1qzkmIknxgO4La6M62JX8FA4iPpm1TYmExIGKvZKHWi2InJJ/2yxvNdUaT18j64a4PdaTOe4TaiFw1Qy/pJlBKpDkrO6IZ7KKdzB6pCaOfYeBa7fJMA2czfUhWFJadMA638efa47XnZaPVvaHxQY7B0JefSZRGh+HujmNWHGwYLnLfuieNSQzJJVBld1Tl3MtN7aaqD7UdxJ/h+35cb4fC1VOmvp7KncV21mvdwdsFL2QpbnUpYaEnaM+AWQz0kkkPZ7kIDEfjjHoNFOFwr4m7EF6rh3kNjacZzFFeR6h6M0K7EJzRgfH94S1rF1/uYml0IQqG7ByGQrE5IxjFc+OYS9JtT0yADMilReKQ/T2Kj7NUMJnkW+H9wrbjgwJYwoYPpoEi+ShRM5bYfySPuvMrz3KrSEQp/5UMHcJVDY/3AH3fhWf4fUTiAvzCU4IntpSbCx+C3CvtNCoIKflFvshZmJqE0DiX8gSf3VTIuiT/vf/RGggUmrFQDhjQS5bkZMZqBOqlbO0WhX0v1DgRL1WDh1qf6Tv+G9ANY
457n+FDG+psODpyf/Pjs1cYPYev3KRmsEX81PysquapoZqYwQC9mfW5ixR2qQiKiJLxKYO1K3n2rW6UJXVtYfJEy2neO/njx1Od5FkV5EmorDrB8vW/uIHHNKX/yKGXBaYM5gFfjNg5+hQPyEA7s/c6IpucHAUMdEbjaKaXNOShYtqtzrA6H9tDnRDS3/pzXmmhzFZA5i0Bxsq3bqh/4SjO+pIzbJoNe7A65+L4ksv1o8b1tpw5hIjSBojjo7vbodP11j0VEe9OFJn5DNEqUm3RkcI+379x3iB19eD2ObPk0EpQOl4fFGvjnzjhvHjnHCI09X8kWVyVv6QOJ6b3HK5gP8eVkzj9H6Jpe4dMmqoJ2zFlNyr4hRZp759apRxxhxyPr6vo3R0nuWy9SChrWNT4jHy4Of0+2FTE3GznX91IMiZSQJC8mEyk8kBvh8E7h4HSNTWnzyKMUNeuIJ1+gSLoU+5kAYQU0IikRYaUXEyAbDlJfVfQayrnyx9T18gdYyoYD33bEdel08zqpdN4t2QvOJ1Q3wg63X5aoewtY0txn9Rof7geB3VhYG4+bSdQUqnFyT5MYc0E1j78nOXnc7tt6r1223IAdaboz6C/2IRyv1RsBrTqNIhvnxVX4JV7b4TiTzIMzK4IBdcJ32e/0/xrSwQkc0Wt4y45hk8Su4hrl2kh14WWWiOvXYvZTBxutxRMF9yPS/GkeFTg27sj7KnJzPRVLwQkdBw6aKA3tw/4GySYpszk6HD16mayhJBmmJyOcSnQTzp/Xm9OpHyayh8rcCTJV2oWPqELFBt/We+EpCZsZLYxuiAAnt/PcEoRbPhRmAVSJiXVQkGLXly3g3y6UR4dzVZjBPn8IysHe10aIPIOakXprze+hgpcN1bHyVhhaVA8U8H9Hacz/1/KCfdiSiq2u90G7KYliKXo9lFn4gaPm+TL6UW0yUOPam9JV1oiyN36YAgy8iXbhNDRjQ2d6MIXr8xmr8o5S+0SOYVlA2B3pJaxI191Ya//YT+yDc3etKDawH6JPrSxIU7/zxxydVwR5uxSa6x+8iEGzw+aIvs9jItiDpiMkq+VdSiOEQYzT7/GC65sIxhXS47Zb/7YYatkElTlE3sgwAVkkTYDj2eYEECozu6pjbDBf3HGwMPgy7RRv5tUvdYS555fixCKCbJdguHPLSXnLSSS2ps6XxZlpAcunDx/BG/G8VZkUFO8q5WemF9sLawm6hjsS4tK3kafu4PmYrGsvmH+7HEFEO37xkMzU9xJXfqsblSSM/5e+080RZ/0xJJaX3OLYi8/vClKvB48xyzYBIUw2abDnOD7QaE4QuIECRERti4V5lSvr2hKtcleY6aqEnQRagKnaBWqsdKxhc3iRyTCGviY7zYs4LWO3By1PWmxHdl/SKGuOl7Q949zryUKp8oJyyUAtkkn0bI4O2+v3nlQgj7FavITLwU3zYAbz+lGibnTaGGBHI4Bk5JhV2FUCXrkccNmOJEYy4VO45CVnlPFSaLrZ5DqNQhiRw19zHE5jfikyzeWI4m0mOTVvrF6pf7B2kJPR6PiBgGiQiTd1Tbn/x1V2MR35M7dI+HP46KX3WyuiiY2Q1/rKdziRHBQaQd1LwinnkZEH4yX196aytrGC5WYnu4Uob0XD2hHBKZD/ZrW8MY//DRyP/PnZw0E0PAFr/5ECRQQTZ2q2HFLdmnwnT+JKF3lQD8Eq+UYtv1nYRxHo/Uvn/7+NGjSZGX4bVtnNuGJzN7+lVcR1y/cS/47wnYMIkK5/OmYvZpFfJC/FgRf3F9j+PpTFirofom+8+NRx6Bc9hFDIRl2VICB4VOOE9iEnICKuGCzghF8HXe1Lmwhj0x4ICNJfaCpF4H0ZEyVOTc7Hu+oQabXz7yEoxcpd3GEHS6omeBmc2GoZcPT3JRi2aamjZsT4hvdCGv92Uu2v31T77brt7VvZsScXcDkby9tXoN/1awqIjdUfZ/86dJJgrNca0awhlQZ1sStx8d7TBW/nhfLnFBPYN9X3mpR9769elb6CLD+1fPdmqoVQLa8RAkC7M6pBn/cdheeC+l0e84tez0W2VFBqlo63FfajhYRi8MhG6L9WkhCI4raBoSfnMIrEwkQ/+2uWlnfDKfJy7kiV9R1gQhT/jmXxhexAQq98rfn/OnSSYQAQsud0S1sZ5Tix+fc+spDHUZMAdsfbTsvu4hygejlQ9G/3MixCmrP/eQd00H9J5025v7CSzF8h2J1mVJEK1hRuvzN9bm7Wu4t7ZuzKbY+Bfv/sWxh26K5A4iX0vyrE1INz+9qyCa357Q2MHR2lVwNixOr/+z1mtxC6mwgM7somIJzC7FXropYdoE/iE0ZZMUvjYXxdCPH9Y2qLuku9woAco8d3ftdWVicilBMd/MmbsDlBj0j4D9ImFHGfN70OtGN13/lRK0YmDtH/eCFbYVrLy6Y7fjuIeCzkJarQZuE242hL9UU3LbWqMYscfZ3rWNBxG+LHYAuI4MfRhHRIzIzl5QFJ/ZCIe/Na5kJ7jA+9zw0/wXsbckFkFy+L20/ywp7lYBcX8kE8dCm+bPRABs54zsJS4MKVji5NJzf5OGXdnES+UnUaWEMlNBJnTDd+papokvRi7eJTC3vT2YAfPLtageXKavjfh85/uXcFLaLIy7Bxo2T6sLK/jbWc/xWz2lTvPvJHjQIbPy5wMktS9tfHRrEq/iSutpyxh/EMlYTzXP22EOOlEkshKg0MIukbFR5B1RlW/fzhrrc4B+nqbI78yFK0P15t8xzYsjpxic9RMKrTRzAGLAQQ8epEyhyQF/HGfJHTY+V2SBGcjP7ruU8IV323RLrfp7nfoXa5PqDb3iiJkq0K0ZTut/1GVzfU1Ntqu7UobbX1nC/j4xakmRFWylIfVQjs24tmDe5JOuQwvALPGYBwfOXNgzjyoFhXSk32MTwhsoGC6FkPgN8Z1IS+wSBvDuSjs90VhFhefGXfFICF5cmPRDQYEGbiVzHjJQE7EeGzMRoF/YyG7LMNBn4XkV+IFF0+1UGDei6E6dpPttR/stj2Fl7vAJMFLxMEaOJV/4REkjeMWpyMS1FilBYGWHhtPQz4Pa3KxWtJaTATV77bBDY7RqjKo6Y6cj7xlZNEvOqbCNbrZjJWm4mRRvvON0+oWMJCxk3cK9TWsJJGXSlSg2dR6x64Go/qgFdQ1anlLUGOT4YMgDasO68D7Hn3HQXiO5o2cmf9hxie56r8w5Ca3jm9+FHmX05nQsspowLbUi+cuI+4JO3mtkkynjgmD5y+rPSEt3np1WMsA7fuA+XVU68FBaXx8NDsP7uN7dlmwLLxIgNBOn+dMxjj9GoxpKsqc4hLfnNF1tkMzfDYcikMgUllOmOQq0vpbkGrzqiwkMcoUpMu/eEoFw7DBJTIDWGX+ZA2vjyzbVdypOLKxqXFktT179aOv8fwcHI9stIBTl/Bq+tTg5Qnwr7psKBLuJFw2hcVn8OwGBTMt+bWlMckdmnvvMz6af8M+3uxS9nzExf+zaBM+KTqtwu58jn56/53t89FmHLp/WY97ixXR/WVN8+LYUQZmpvj2wlbY4N4snee7h6CtkABlA0eMrpmvGvblaeH/5iFwnRmseqlX2Yiw0C8wTixs6zgHtg/XR5my69s6xR0Q+GsK17u8RkDSKFHUvja8eJ2JCKHM0DP0/SRX8qC4TPxF5iSQ6PiHF5RtSC65InB2Gj2umPTi2apLp8A1GtKXhTm4Coy8UWgdmGFuxllD4LmhfjZrPrBmnv9uabN9l0UHEIgfsi3eYTAypWKMXgFFQE3YhEqJhmlIpp6e1AeBKQNw3gZUygM34ueQU07Hnal69WE/nBj5wNG/ZmLWtqFc4b4FGYKe4LO+XwuXvULiEGJ7PIiOTv0uVSo86v9hv4UhnasH7rXu1whOYJXqF0ntUzYeuDiMFQ9sT+U0PKBSQFJiQZJHaPrd+OfC3G4SmglmwBVhcyRZacltZXmQEz3LGslirpxoJybxh+AZ/F0fbPwK7yr7P3hIu0DM4yldHmrmymG8igx26PY/gjWLIPVZeUm68L+ilRUzBrT42oAkq+6pd1VHLFI+Azs3oTV0WZCVvLR/t9QfqMHHWGxI4aHVU5V/S+J0+YD2baRhFiHf7BXoRb95fOe6Lb8KOAUCiOXQBmYYW6UCvnA4fcnqICQh3xcfszJ8bnIBdanNczchr2dpgyqMJDVwW99YZZgpOJc+5jjkUUzabTrL8A3ub7lr+mpY/Pk4wA8LPOgofReDRF8dOWghVtbDa9GFXKSYhxb83ny51OVJfNwYqeTx4R1GdwOexaO0gNBRlLR5y7cC+y+8KiRX7QZRFi2PUe9RWBFIC7qqzzsvrrOdIwcNGQubo4bUgQo7RcVRqqJ6Sm3+vjUCLAXphCnXflotOdvZgQN222suNqg5Pgp1gfyxN5XaIUoFBLJQ06TkUV1hVnmh/zopuVLeagwWMFz+OD6rRIXiD9rMaGJrq7juyqyteWAbUkMJezwO7+PgbzMnNWdvbPn9fvO84LGnm6sIYmxrgd/dzDTRdMV5mw0AUSpk3QEBDs1uVRK95OXY7oIF3DxOQ6/0D3gCaehg6bGdhxBBF1eiv6182ZVPHLhY65KKpg9klRQngHhoggF2z6AoV42Hylq4CC36F5ZCCL6dAu0+WiTQOVfKF/Yls9PYa4gqCmgNpx7FrEzy63W3LWEqQKFDLwl4F2xe7S+L/Xsrk2MtFsSGUHkdCQJcpydQSjGzUSY5gQM4DTfvReH1jzBFG615zk/nrq4Cne40FLEVo9gDHC24CF7gRkkeMCMWOxogtR7M0ULvr1odtpZPXfrku3RhjYBPwz9fSB4QN4Sfx+eULmY11eR3+a5ptLSXzT8tdVG4g1S20BCBlM1vvyPIiOmT5IrXFciMeEuGrMueyUjCU3cLEGDWjJs3tjDnSLbMLcF7cNxiBg1G+Uxx3MUVwqhYlTVDqKPfZXt/WsDToPpvaDhyAYF6T
457sH+qq8IAd61XkoJ5lojmcCR0+uf4EnwmgyzVoUDMJ7kTEh3F6BlO3sGlDbF6+VwuYV2YGFE7BopYQlIP4ngF3LLSzOmMGUPNEwz+IOfZ6DZjYp9Ci/I808+WGqwGhNwFEZ3dGc59IvvaXEQ9Ekdm09koR/LrPXn2C85CDVMAxDMYZg7tvJVE0ERBq46tgb2IBU06MEh60QlZro7sRHMpPkhXlOG5pjPGBfBYwZTLZ3kUgguab0ec3kteviTwUfhl537WoEXtqE8BkXSMqaQsh7STZMmz45EeG7KU3eh8Va9TidRnHc9vnBqxcws+rsLa5MEp2H5iDO258cR/2TpYN/ON1ETqZeqc439qkhy42R3j2rEJHuhSm4whthqqWxX+Moq9vh5xzh2n5IKYj3QHSq+jH7R76ElQVdbIZvzSJzEADDLteJA4oftMJYwXjIsyKwDh5HX57oyEuAXf10wr72ByIvv9HfA7bn38TnTQ/+b4HCGyAMBXT/K40oj4n2nTkHAFKXeRfQSydxDBOogTLznNQSL5XpFRWrQPPvZQ8KBiGwQH2OYFMVLlX+NTaZYJvJhKUSG/S1u1bIMraTVY6EcfQj9oDPkJJDUTv0SywgCba8tyY2dHe6a6mJjd5gw8VOiHhLbCCGHSeH101mKMRI7QgO3uWxNxQyBbsym23H3/BllIIHVNFoE5UUI9SUedDnFA31AKtKLjjaFtv1CPoI3ZNcoEOQiL3Ihq609AvxxJHBh4fwI+HO4vLfEMBxOsBLz1mA9/lstqu61XzorbxxXaN5sFCAQCJav6CNxbO8WW75lB/rjmAiM1ECQ6apPKB2USZJWmz7asuSUewQxNI2eQRf6gX5LUenIPq4aAouj2PeQ/jOceGXZEWoWywaSHzMQc+T/leFQqqzp796gLj7DfH7HaNpX2Hohby0Y+UEFPEo62Ir672GadDD1a8OB3+JohN0WJrZtK9K+fw4bljxbiriVnmwpDBWefweQQ1QHaOASkJ/Is7SvWOjhY2uBz/tCVoHJgo8qYtlV6cvxMdJM/GjMtcN8cT3KEBlGGIP94hFk5uK8T5MypOgztk2wC04hrOaZSrXrk5+hDMQpLlGbNNMd17eSnGHSVucYpzSE4H5VSFk7zW12gjwiilrFPYGkaSSEab0fq5N9YvUBIwEtaRLESU8Q0n3BNks92h9LSy0w+Eqx+XAHhNunL9TYSRiv5YBiL30s/FfUe1Nka+O5qaCfF6TBJnTZEippD+CfwYb4m6E6kbLat9xaCLbPCA0ZCBWv4OrqBKOqduaqEe6amyqD5fKxD7OV0p05wx7XNCCJ4jxMgTu/Nxq2Slm2PnvTtkCj13UplHrxR6v3SYteOlJwG4QGWrkFBP31edJau0iml8ioKHh/Aj+Drol+QMpYc2cY4ZDNra1f61i3iXFlccL15LENwaHxJNqHgLyV48JfDYWglTApol2jfhNKflKy0zTvUKffqD14A0q2Zo5Sgs57Q9YysXBrCEYm51+IzAZdHHuwXTfecPpNIuMKUQnWth2tTtK8m6pMjcFrrovOxs3JAl5qADhFf+6Ia1ifgoLokbWbUh3xkGkECKKkMK1rZUc2cMB6nMEhTtqcsR2I3o3and6RczCszVNz9gkKh1QSOaOskPJZk0IxK+VFrHTe3CKG5uDkgeh2WMnJULw88rNIG/7ntgXugTjrZfMYPZLUsHo4elWeyPSqthu8+/NWFKeARDVT30AD7rYSJkVAM7W/Dp8kzPq7vQZgkEwAJDrb8twfqWFTxn4wa511ntnO8H/LYmsxoap+mfPJFmGzAH7FDlHAOEehTV6IE+Ol+TRF5kuAgpG1Q0WG1fzPbRudjzH3YnvQaHhjZ3VN52vy62sw5FXV32Ijm2K6UD74zC1nD9OUSj+Ykv5H+fjxWXCXT8M0fMQloNbOAbMRIPgyk5QQlMP6SBi2FWEacPnviCmf9MtdjVLUKKxdOU60OaOB6hq57cFsvb82VvVGjFBAoIHDdfiwfEUIKKcZEKusbwxJBDTBkD2OzkBuEpESBJklqFNMcmmc+15Zuo0N/MthTjsa17/PK0RinxIEtH+L/XgCSxXIiHHS8jS2eaH4XJGyT3Pdc7oU9Snrn01iW7SJxLV31pkV6oqNzkUiaoqeWy+KurYmKqJQmLHvYf9azOjNSD1I71aJPS51iSpSLjKsBHogTcoslFMbQXJhwFsPhftg2DbyUccVXIiPIhVY2ClmpLi3ISPf5i1TXEiSwyGjFQkPsfM0trYvtYhjniKUNNAPJRMkjcz/o8hfmKhWTdrxR/ks1T5UnnifY4+ScLWZ7cO9uhT9Q461savihqvmojbMWdaxO04l3ZAMaCN9VenkbovuEF1YztHV9Ei4D1RyNRd4USnusOnX2tr41Zt8Tj+Z8sc729JvAosrM9PiXUyOx1j6dxb94L7eaUNQA4VSTSO5k52q24KS0JwaiYm9j0RyGwBFi1kL8fMDRJsyItAVE4abbSAScBj24Q4YPn1XentisoKP+RB5hWsBI2ZHDi4dfuATsqPf5SQ8werCGbyi7wbnF7C0nXSkpN9SnthdJI4JDmCQATFVVgaL6ytFXmSd77dHbeW6LJ3KmU4gKNFgefUMpBlXeh8ERYjVEeRLc/7AmtFqS1DK4oitizKIeW7mS3q93/eIpshZ3WTJX6m4xKjSctd8oDXS1talAPwB/qH1Qso8dCWohlDs2ZXkbOWQuIdhE/wpHAWp0+Tk1Lj9KgdzZCLDJ00gKiTGz1UdJvEQdKBJLvBwhW1U+xKwy9YY+hdLs1JNvlVJwRu06pbE/3KmJjVyyBpxzMsAV1j4sGJnkLn8aXfFfOBLkzxo2Z9qzQF3kHH9nlO8NVE0g5cgiDyjiE4GlFWW23np2ery9DZTfU4QiwIeN6lw46jalS6DXyk9q9DDSdo2KclLQB0BKSbKS9aaUlmeWA+/NBUk0M0X6RczmfoOA7E8KVPMrN2w8q8SPryqv6eeebm2xxfL1kyUr/cWxyBACXl25wxuLAs3JlxNOVhgnRpH/ZNG3C/X/uV07QQS2i6OJ2FyzdpK97FVXRSRBZJ+IzKZPeHcrUlcv10sYqtUPR9NphBm8ka7N0l6it5ElcUt2KtNrijYj4pxvurrsOBG96pv+MTgdSdl11BqpBjxq8AH3zpHCqBUs+C9uMJIe87FMlkNUq/U3eVFn27yUtYulKiMtdIA6snKUizjmvN9YIVtgr+0wfstzQdldD/azZ50y3pCrKZMDelsioJrbkZVtZwgGRsFKQUIDlcM65x6cWhZGjlEdtW46QTJLiiWqdbZvm8t7X0hYqdBzWbZLzt/r1ELiK7kuwpAs7UWed0pBNvVrLNrh1OJf6Hqrc+uaY43BWFITqyEliUEmSTUyhNi3r1b/shU49EMzg5pQflIPpIVL/p645KiSbEcaGrtd+clkQUN/s7jXB0H68WpuS3fbs0yH+Qxv3AnBeLJCG1mlFY+DC5o2Z+EiNvfvxt1CpGc+iI8NS7XT/OuVWQgvWYXsy1mr8MlKIJ8kbDnpurmiPQzadr+QSf+oko55j5jasdtk9txnJSPKrk9K97SXkib4+RRESorOKW5pyC2r2ghS99agzAvSZcnoYXWWx7SgeEgeQjTuDmOSeU8pmkddF6OsV44mr9f7Un0IqeTCPAejsY5w1tYkOiNJQnk0KNEkGVJvaBKR5dT2fblHq8dPbO+PfppRKvi045Rqwo/9d6Xc/h0lKj4q0E5gjNbzOKuIyGl9l13lYdKSi5Ol5jWIUOU1LNW764CNA7s8bApQb04NNOUn5TjxnL7rK+E1rSRtvZbUzSNJBeny24UadIK2PC09Cr98Xu9d/xtJxpiLgEqQuWC29FOZ+72qAKl9vJO06rucAdc/cE0pqhnkLunPtrOHVh6jkkrFWIqOzfVr/aNUHBKr5dNCxUQ41Tfp1drOLGvTR2oMa4pwVRVNPD39dcVAT8HySq0MHIb2x00AlzEHxFrpr5Zk2UVUZ1T+NtkkbYwImYmCw+fq5Yirv20Ev+qBJUhvpMLWFhRhPaS7M5B7Z1NXdFSJoX0FDu+SGKAAXOvRBMpWJWDF3k/er4VuBccwsTK9fi6j9N6KgKxJrh9JGrsAYbCBrh9R2yVdA1WvekmqwblAq9tUTd/aZKGPhqlGp7RGq5XkVC+wWBKaextKKn1xSr+Q7+HHGRmCN8pdF3qYZxx3/DeUiT/OX8gZMqI51x2L2w1Hc/nPfS8kA9iEV8HaFHfHcQt4UioHNx481Qdtr+dTbb4Gorqla3ZJxcVyV+CUDppEntGzum6MrGfbU6z+DX7P5GN9hnnoMErao9Cifd+iAMx9YADuNRVA/K8eirzLO3p0k8XaFv9sH0a7AUjyaFtTe9RH0gxPe57JBGZ6QIWRJKvrSYI85Fyv4BBqKihNbaVrH5/4D6E/78YQydoZK8ZsWCJhSmL1CwzQ0vU3DStB2uoTK6q+vVaNy2FilbrGLSYicojt+TzxMAHCTjqI0lDSAWytPG3RxIQo6P4FU1hzC0lVswdtr/ZzGjxbj5SxyI2zcdnywo4tbYLzEDhf9Z5ZqJe5pmaJu8WkWAA/EDpEtsYBO5V0frMkYWgvwCyEogZhi9UKx+AkVLbSXxLf2QZMgfn1ntfn/6uv4y+ivnLioXBXa7Q74ed1HQ6/OX++uHyCSmPrUN/0LkfSeKr0L+BFWqbwdfmVfTPqPtDHoj46URoZMtHPj2ejf/TN1V+ssn2rw8qM3xSQ/ylS3co9mrMHM7JQ6Teh9fmrcI3K/4RB79fZelUyUyczh3n7gPiOkOK2i2Gg03S/Ph6Rj5R1OOm8zt/0ElydhjQWM2SnsTkbkRl2C7yFChWQg+JnShqEfR3DPQua5Ki//CuhNK7Fgf72cyEM7Xi4xLxVk1iAEP5yMCWQFGNoGVCNWgkbZwg7fJ6+C5Lj4Hc4ilRzlHvI7Puyl3ppY+Q16+Mgi8mshCRKjfvWQQgDr3HHQIWLTAplNAVqBPN+8beFLiKuaRSlaWF8r+uMEYs0pIdwbeZaixZgfyn7Q6bXixRM13k6adozO+tKBrz4iCbOiOpbvtFxUP965Woe6ceQsl7eupme9TUoB2ZsAj6HIkHGKOiA4XTEYEyarJZhCLYVPkxGvinSnaMSOV6/zlpD5GkEYbdLVwWr7lYcBuFzMHtKwGua/ldePxdP5LoEoZagBXdXeDvx7v+4q0eF3Yj+4tOc6SUUpiTuOZik5Wzyz9htu
457CGGTWrh9EGknnf+Vxn+GrRFuNow/lP0d7kGBiRRVh1otLpZhDVsfoqP9tEdSeOiE1cBONTsVb2HwBxQuXwQFsb97/lIhhNKJ0AOrLfJJzHQr2CGlQBiGk7WrD3qeUlJpBFdjBY2vdymUyHWCAZ6nnswztb1MqX8IWy6RICU4f6iLD2WK5ggRD8Ck0xJr9Qq+EfB9zx2RucJ2iVXvIqIZofJAi0wENv2eA2Lc2/uWhlwDhOY6fFm/gNFYVQMgoREbNdEJsj4VMqHhsu479ApN6RSxSGLFpEKrQ5UeXXc3GVQ4Yy3x0+S9+XHD6HLooN6eDLJp3rQHC9WaBombkXA5DkXf+20Uz8QwdLmjVcP2fjWrBx0DQbfwVSC+PXzMmOnyvd95pKz4nTXyOB4AopZjMfkFMuMEIsipP171paJjeoKuiY83Ggrdnsu2RjpoaxloHusnw38qnnmXLD1PCiYDnN14u6xYndbuHXj7Pxd+pDwiHwTrBveJUNncOZTn6FAFgKoumR32lSKSFgwYwoRuzY987x/qMZ7ibcKAqJf3CwC20WNLILGKTq42+zdSaTCIFBhXRsJjPe36AGj9KHnKQKjzYcRyHuZ7ybtifbDuqK2ZUkYBdSAVFrmvv2MIhjmyLTerPUN6Hisa/vueY/1EaF7r8tiJkC5IQ3J4grGd7VK8UzT7CdY6U65zchyGGT5htZG3eDwQjfPO0PDAnbZ/lrUJU8nJ4Zhbsq3kAfv1V2cwaa09K/GreYbR1fsYxd4Xd3zHoaz8Bj99QtFBNlbr8IK1wq+vvN1spbzWpQnVy0B95jqIkqYHks6EA6VBbv7z7ZLmqNBMlNRHc6//xfBQ3D//bH2sZPufJSK35/rx/JqwF1DAD5rxKxEFWyAte/fjIyn4w8QDJTc9JqXx+0e2nq+oD4Yz5l1ui/Q9Y8EGTidUdlIDz32Pn7wzUG76eg6JKbnQRHkYsgKYNFRboucpwH0zMKhD/ENQe8DSqpo5PpU9iLH51f04ouBbnjVGCo/PbaG/Wj/HV5XoDFkV9fdW086nCF25Hsx9v3JaGa7lwMNyPi+tYpIvfbi3j+1Hw1DIRR7KD/qb5TOl+f8iibb0GVqTbBfG0XGBkwy0iVelfTZrBiERqdO0DN+3RpPxbNi7hR8jmnG1wZ54uutN9qW44o9q0lXNNAWcP6OgqM14qJLwBA9hX4aIyL5Q588vZIa9YNI86Axl6posSrEFA325QzQqK+eWe3oQN0f50m38YcNEY4notRIVOJ30Hc/syt0Wc02DXSO+9AfEil86OaUfmohSxDrDWJwFlzADgnzKyE3W2UaTZRW0sCWVi4R5iJunP6Tw/AWbVW1AoXhad3ZrgynmJD0dMmgsP+091yT4ljzONQznfEmSF/IuRBaxKwLGMKZ/BKUDah2CMk6rioqAV58rBHtpPu7yDwxdfOkSIMKeP5JS4x3yMR9IG73nDaEC+6x8Hsn3LXbxVE+OhU/cKK9TNLW9MdBg9YhyQf9yTwAQs4yvx7azIxz1sQoegbBSs1fj2RsFCFDrK4Q2l83vX5TIXrcv9188d6k5p7pVoAmaX3bQWoiW+kDiaopRYaZFsv4UAaiCWVP0ClcMgboq1+QBoWS7xoyrqHkpl5Fwz7XxWW5jEC1l2upTEZPlFhNzbt3Fy8xX+3WeLedba0qjZg6wHqEmGRINkMdFIvjJGRJV8nm7VGEUxFOEe79n3a5qpLjOo6HBKUq/MSTNboTQxo01MmLuikNEfddm1BBqyHl5sUuDfg5KrHASfvkNuNtTAGoYlS7WOTvy+mivq52HHJtKjCJ1lUxApg/GVZjIERU6LdN/chqLyptwjPOMVk+ttB/39jYTv4riruySCwmCRvG/7S2tXcQcJqiulNa9Jr1fYsTa6xWJ1X4nGvHX2ct+tm5qMHPmMSnSgRm/QgbtnwhO373j+zuRYAZHy5KOPE9J+roWF/P6yjLzzqlZjPHq2usPV4F+X2p1NPj79DDqhj7AJVt2q5j6f5/bKt9SH3VWb1/Vvuh5IJmHbR1vgrucVNb8d5twXHPPPhZRChbBlE+BN2FDugM1ArqCwHWGtrxevWlKF0uzyecFTt7oRr2LkSp5/XsF+Iw4rYkinOff1kyytrb6Ypmx/u4M2XI9YekSw+k73is8ubD8XC1HLOoczctXMF+9id5oFPo3TP1IKtwj/w4on7EaYtfpQf4DK7mDh1VSpbdb1j8RoVkNXdiNo8jQ1/ELgtM7b+8eYBNZF7bDs1XZSWUicVH2K6D+d86KQFHaxNiDc8yzSImfI9TWjqSsqCc5K9BYk0grP3qEVAyz71HskLrAuPjOzxuuUT7y2mr5L5qtcXYyi99MRnuiaQdE55jN8HLPTXvizFF+GzhWtXY/5SMUlPeOz+GQuqmxV1TUOVtINrJeKHqwbislK7bjvAhxoKwhlGyl889TPK9I/c4zB+YulcDde6mJ9zqqp2I32aOYbi9/roNSpvY0LObK4suR9oFTrngXSt6EgNHDkmAPd5V9+vuRf1nAeYVRon/dxVqBtDGOcDCLnaiPbytmnulR+WEuhV1RXqLY2ItFQ7b2CjvQT4d3R25PFpkayAovN92YbX9ZJYzb02tulM5XY/pVPoP+SWyUjZGSgn7IeGuLvQK3gynCtEyty3ithdqkaJI4CXm3zJrpSvwlteKnvAU99gY5tcxvoCnLYQAZpZWzfhUxt1oSkJKlQbi+jG+ve7n947mrC4f9s4haPe8mW7DEnzTsZAVaBr+oQs5QMA7wa481baBYwR5i1czyGoh7dnQrvDHlJE/vsfmS4MP1mTZeM9u8hWi/z4gt0mBkoQZ+HDB6pL9Q+5iCS/rOrFRZ/hhVxZAFpqm+30A6epmz2wXqZEIaMqtz82lIw25tHA/YqouBWJonScO5rALZHlY+W2AgE3Ndaa8PHlHzCrQRyHlpPupBHPfMNj4dHkJaEInXtouCxrzvq1f5nrylR3WvqW/YjqnGQtuMmWYJ02KqBDZl8AY9mm6Pp4Qhg8WxYqzCeeV2VTKoiDXyHaGsupvsZfhbupZ5k5NSs4YvJyM4wFdndXzvv0U53k3g40n92A0/7Zi2IxvBYVwhuawYxHGX/lIOTDKEALdGjJ0CKExKGJAHVzXSIq2HHz4esHViDvR5pRyeVIg4/2OKhxNuHyAQMC/rmH/YaZ+aD0eN1yf24v+sMRu9R41izEMVjgIwTteUk/6xm4YcJi0FmaxgGlZeWY+btKKEjaIBWNkLaCniN5pmcVnQygM5fNwc7sn+4jR0RYDzQsjNEDMZoXC2kGkhm9QXfkbDNvY04s+C5CKPiUZsqU08JziMiJfo5FsIPjiHpJcAHUrUgkwnwz9YQ4SPa2TpE8XehvHAnoOAwUn8qhMQyETahYBI7mrucXnQhg/1vfm09egRRkuXLEcfPetTMeGYd71lk1pw+9Oma3mV3ZhSZ3jv5SYn9BXskaLapJrT4pmnqFnQTe8q2FlHf/ciwRrwkywDgP/jmIeDLXT36rvFNb7iYmbKgQYGpSAi80BEBMUCwE82UwCoWNh8pnXPAvmdqJQJCJbyZ41aucKN5HYTfMRY34xJWyZfBF9rHp7/7T39GVCdTRx+drIwlUa8/TUxXh0fWgukQyXf4BI9mcN5x4N+VD8TpmbgPmk6mLPPMDywl1OIVXKOK44b44r+S/jm5aMxPdSgVmwC7Rde6tnxc30MgTw0cHIOBMzquOebsYVDSCSGpqQ97Ij27bKqGUUoonlJAkq5OYzhzkikxqOeB1ZquPFaeqbR/u0g7g5Aj7ZEfQn+crjYvyjJPdqR6taO6nVfAbPoH/bEHyyWAAoScuphg/O/2iSNXxUKx/lTX9b+kMl82zzorJEYWQdB/4NjTKmGrTjvIwoBHFJHFUj+82vTAEE873XZEMxjnAaCJCw2OHMtuAAkXUMgifgibX7s9pxcAS/1+DMf0MfuOweUl/MRw0dabmqdznxoZlD7RUnUIK5VO8CgkPiRCbpRyX/R6FKPKVY+zE0QBa2XWc69fChHvpeUS2dRo7ZBN+ZTddjus1JLrKHe4aInGPcvKiPW4dHUe8By3hTp7VAVOCmmvUr1hWdf+dBeuBRY2zVGHRhV74Ho784mQtQS6cDyJT5d6cswFGW+ZzGiSGNtch/PATmE68kxuaam9YXRaeLLfVrWkC3j3hfx7U3pbvmTZTS+7RjrL0YBs1+Qk94FFeVXmNeTy/lS/4HxijYyhz0srE36ZcaUFc4eYO5Y0a09uQhzqWhSsSj//yXZU5Z5t3elsDXaHal48lZkD1/473TbCkzXeGLbdKlKJ8enDR4OPA0ih0x5njO+8U9N9qn0eXPQ0es2NW+empuoGM+sfxar3cPA75RQ9hehwO9+iOE8bMOwQlBgPEXrz/V9
457SE5BQ1Qiwswhcgua4s2INLbG9YMHdBa//e909vZW8aJCKNVowdOdmG0uhfAlTOmipAUOInkp5TBLnkk4U19nRYCIXov4Bq3i8Ez7NKVgLuZOAjrgL1WzZ8tJa2wMd+MlMtGtWvl0gG/6Bo/uq7qosfGY5qKcV8s+LWtyoKMGdJovwa8Clen477ItWAHnJraOPa1oyJIfDvRZHpgPpnWYkFMsNcFjSk8KYFDXRhnlWhOhKH7+9Dg868jepw/1rxeIE9+/jGKSx6+5dlvRxhAGHHB7WXCBKOEU5VTNWK/ODhZjTiqoPV/oOVMTtpjgdarqAFxCFcn+c+6hgFEkaOO7Rg2EubW5LKjP5mmzGs76u9AMmDdZY1lE58zHx+hgl+RdpuLHDn7GJE7v2vMJEoKV1alF8RfmwIZ1KBGbt6VOEFCIGnUin5cr7PPamLXPWYm0Ekgy0ObSFWx+7EbT8/5pvAhGOu4npd+B2pd2E1dFRGnjMmZ43RWAV9Y2DcR1eu7P3Yu86RkXal+2lj70fw8psC5+TT/Mq4C8Y/caGCIHrpKngF+tHJTRLjrnhuQJhyaXewktnCQIFQ+OFLy6HRl9tg11WaoBSmPNy0j0DzA0qc8BNMTs4b+FDv+2Bs7YWhxCP475+SiruriQtODTnJYFZC4rQrIi48NRo4MfRp798PsBbwYGH6ZKrISbq0Pk5LKk80MYSLuszK6YODdbBVM0ZdCD4KqGe07Ar33hRjZf1XM5OfUCSLTQyNHoX3z4VrIdVox2Qdyv50JZJ0hylauCiATUkaPF3YUqfmzSlMg4Ocn9DSPplzKrGVhN8/45frfQUdN/y2NfBWscfzcnK8VUi3uFtblJlWDuYt9R5FS6eHJ7J3bu+0U2hkXTpMPCo0EX7N6px6DEmPrJXJIgVeeoU8sSc2BOYqH4tHfAtMk6ooVWTMV4MoK6LRen166ueWzF6TyhTGnZDQ8JeZ8EvFbKXsn/AUnLuPDBhPB1vNbFoMem2+w2xWq91ulba5ml7BBSeg2azGao08ZwUDStGj7LjKDHrviJTi6Q6WGRnpcVIY/Yxoe14Sn8X4EN7BKBWu8HB1Pcg9Z01EDNIu9cLPU3xcBpP5zr4oyv8Ap3DkreoOEGgWxsi5VyhmbPY1M6d4XpjjU+nMsJiDCaqXo0Uf2LncRXW+STglqwdP2THTnWd7Xt30mTn/pyoFWXuNVpD+yCdb+mxfq8Id3X2Sa1UHfCT4/aUPoyAxqbD8XHZgWy+CPdNolhzzrZcf8bbsqr84lNKas+VsewO4Hv/RFVmcToKh/Zu8AeZm5/MIxlG1gFxOWk1FsKTFKMK1B87xX691j+shOC9doLXUjnUJzxmn2Oeq43/qL/BnpoMu3k4W8SQgZfUPD0u08p2d4kf/VLl7H/QqUyAVOHOddJ03iSj4FI4xwBIOyk+pDQoS5F6nhkispK+YWXLXKIM4k1AOu0/1IqiU9SFWxBbvVptQwQs8xqQCu+QJdBEpoutYAdJyXtZl7wBoUFVwMfMx7WrbWuWZOrMIcjbQkGe8Mw2o5VOL33EtbkgBO83ERedWu0ynWDwo1iFfk74Ma1lrKgkDE5r4RTBfJ0f9ytJGs132Cv0WNiVkich+Q0cAIkQynvBEK51l5Kn88F+pf1nv1O9s6jUvuTtylMVqXXlGuPRd+ROHD5QzYna3WD5C5FSRRzsnYrjZImP8GI9U5VBSG+ZLw8nmsjupDM2ZHxKFu9Ntlqxbs27g7PzTyikuKjl9AoE44WMmlXWjdztJXBYeR6i7RnJl37aKpbjshD1f46AzwOY438cLDVBXa2wtBAFOf2g3KHIAALH6g7B98cjiLD6aqs2U7oK9tOWC+yB8CScu/ncB5wJYxTKvyEhimdmclzwyHN1Sj3gZ/Ej0vpQVzRauPqtz2JE4rfzzXQUXtZRHuKn5cSQD4hrMaXBqhiGzUTUBKaQ/Yf12RdQe9dIsYdsy1tepY8vj2yI0ykYjNMJb8qXV/SSU3QHR15mhb30bJZvi+zNwz/fPZWKiT6dF+YkijsvH+LovD8jBga5KcabAx9YqcKm5S1vEv0pUZcJ1dWoar/IgBZkKBQmfE3k1SWhi8OETi2fH3XZFRSM74dvqRlLZbBfmfVC7MWs9dGeLgA1GuCk37ObXQDmJYDdh+9/PKkyL+jvlgKxHeay2V7vTPR0+/+61hb2ixQoHuXT1tKz7+CbuqdhSnB2oYc6Vdq/YJMw2JsHu1L0vvEbqrXM1KaF/6wZkpSWGwjBBRIF9+nFUmFkn/Edce+njLa508RfanYXEqJu7s84VAxk4nWRfKzOexDs4QKriebQfMHn6PwNJGhGsj5EM/Cv0GbHdYcMtzpzBZAb4Xmv4G4FFK9cCp4iVfivfTBLbWtiujSoDCLxLuBZzaJRNVeoUqHhqE+3jJZz8wOe6oPiL00F+OkMPONCM+pq+Qfp90BXo6vLxdfbfvFPq5JAzgBChzfplsdLfrBAXsWy4O/mtLi43NqZYoSvI9k4I9uo0Du6dBj7aydan94S0ghugrKmoK/NdFwpD9JvDt9t7ixvUuZlRaIE+VGgeE7gSWODRX9BaCc2/glwQsF8fDPxyAq8bMaaILzPVpzVvj5O8RflpRTWIZsQSihY4nHWM81zhJD8itVnv2w/rpNHOn9Kh8RMDKQmycmhgz1ltqJnU7frPNJE/x1FgSvQqMOz+k3FYIK+Rt2kXF6SptQO0gO3sOu6C+/YtjgQl6d1CUdvLLFU9ThvzvCCMoIqI/qIsuM9txGe4VAUxUPvYmRcDb8T2PBH99EUIeWGBBH7b7GAb5Rsn85J3sEzoehZHnJX2+9dY5CnS0eLxgmtK3N2nTrnyXHwJmA91zEBRGwyaUkogmQyQoTFliCVAYg1PH7L+KlKLEWxCndBwARf6IBYkV68R6ugOnTqV8j3LPMbFqSx8msHy7km9YVDAFInOzAKFxGskuGQ+KNLNeD8JtjMC2yED+RH94K0XCBjEHYKKTZUVTG6LkQ6LTJX3RCp5nR6PdZWDmRRh6wbQQSoviDVjVtNpWapgmrZPnACYhOb1py93WwUwbRMehzE9Te0KohMFCuHVbpmNQBkn6TY9UmLHVuWY1M/63fBvqZ17FjhhzbG6TjNYsqnPPynIXmgYxaBgeU2SUftO9phwUe7KA+TCb7EVWfVhuITZv4zArRXCnY34HraAA7xeuQWgsXZ7AYtSD1hbZ0LW6icI4wF+rH6kvA2FStBTt7SBCqk5HxPOLqgggBK2E2tpDLBkN6lBOJ8ZvUIHEcv1XePr0a0yRgA137H+k9gy9eClQoZhybA4FM0cHW5YSKIyFGjLjw0YJWOdMh73u56ZqYMy4t/6CStT2WBQDTM/UcA9VSNouAtVNH289Lrk9+AIs28Ulj/U6IL54yy1Uwp/uBFsAWxaOJkxFjS4d3u5TRtgJOuVymakpg68fkmaJaWwWDrvblODyf7zcOlIWjbSvJyHbU5JBFNxMZGC4QdkkItv1wO+Ti5MGXw3RT3yoGuvD7P7ePDf0CZAqWC+nX3GjSEeUlTBwq8taA+Fs6vdXGe6CUR+65yde09wyLV5YZ/jHw9CGdSUh2yVQ21UW48ogvGhlxGGflMA+6n4VjIf/FsZdwsAt7spFQFpFF6BIDwMoTrirvqZoml+GYv6R2kSgkYockbhFrOYKGVAm9mae5NCxG/pytJ2rKtoR467A6A6VA3CW10tRE3YLz9cXeIDJ+qbAm21q9JXMkbZO4ayEovxltp8tlpM8cu9V4cSGZcdm6hocgYMQalzoJB3Urjau+9fFRMQttTOn55nwrIHqu4pMzBYYBf3emhIJpkUmRQStO05W3IcwqdGZtvAjmsRC4hSSCeleou4H9r9QgLolsVwrJCkqTV+c0iqop903gAMzwLbm8EHZjLHTkE4wXGso+IsfIhHNBrAMGZjMfMxqWfnpcxBNLLoOwphn/n0NeMGXx1+0rSsriqY7skz0LgmxQD24mvjBc8Rx0riKVzpLPmSW+0kgJNcdrdupGsVjVOdtVaCw07hyNXeiOA6pERpZgN77Z4qoDairOxt7dyPW+xjbYxPi9f/JDbmIc6uKNK+01UGjOEuqjqy6LFlXplD3INldoMcOsRrxVdrI51lKdxuhC70VI9XFMLq/KvUyp6Y0ITRngDOfOCBBmf3y6xKPI9cv0azTAWv2fDkhr9/leX+TCyXacRjOy/9FYN75OdrQ/+S1+tJmWN4N61m53aRmFpp0oKAQvpidgfXqMCIWL3OY/FnoZinTLY0gMgN5EDqtlEik1Ao6r3C8sR6CEGOcL+8+DkgK0xW5dOBZ5PBvuOQvjeNZNkzVaFkZTzfKmlJPLUpBGjk+YkVS7xhylD7RBZ2xKFhOg4BHP4g5LPQnFZ+8y4SH8C+ARcF/QPlYNwZgYol2eGqmJ5rclrScgOFzt1VYYzr53WuVr1ism5b8RlOZD39rpzWjG1xxVf7MwW4ISbsjUmEYcrqVSp07EyuF+zgw/qiZILsE7u2jnzpnK4O8KSSAZbTPwW4vmmmAfCtR1zVZNi5LTs/125+7qbBa1gTm22kOIvAC+DCWAfO0v/r/O2Su0VNVdXXTyaLd+Pc6vngXyJvMOcZmpD81lRNxwXqfK0tErkpfF6pJ2UQAV/8q+049CGiw4CcMx9owGzNTEFy7/dWSYsf1Db7ZgyBZeRBg2GDvA70s+idVNqXHGAwc8RgIlb3pMshTjP339t4gz0iM9DMPMMp5NIt3fVuGH3meaVDxah80o4+ke3w7ws93KTiTdW3/2hsdy6R8mX/WgkqeZKT4mICWPwRt359vW/70nfdNcO4A1MF1Dg
4571K5N2TEtuyK9dck48865oT8ZgkYIFr+gqRH4tyKvUusg5EDZZ3jVh4hUQVm2h23bYSPwDhS7fAxERx0dAajPFQ4io1z5cW5M5p8kOdTVgiJFB4GEpzOdTPArl6GTS1X4ftMcaSH9owHOIHItOrtndao9T0/ClYxC3NnI7T/4k4Czxr0u+kCfG+s5yUYEjNfblj9tB0ndc7tZcGPme9JIC+0EciMVrPj8Hzbqi/47ARBELlOuynMkV3FCmAh7+c4C9uRNa2lwGMJXTMrVK2iLCFLwT3FUxzi3Z+G6+gBMzj5RS1cvIPuOD7tXugKLhOEn3b8eUs9Zz/t5ijMVLUDdxZcPyvKYQHtIaDSwK3b5G/N4Cn8YaVPe4lbc7rZ9TT16OfdcXsUJMQBQSIQnAxcSqjZ/CEIBkuHknDZmfWTiXun5edJgWM+VoOH6AnY3uGu+svdd3zrFR6BPjX9N+i7bJIy0U66wlXGHyOhlkV2dUJckgrKB1L0Vlh8zC7clHwCAyuJoUaK8zgpvfIfnfDT0E82XaufFezfOZkncSc08ot9nGAHAFJ2hUuTUvx2eJXyvu+ioyXYeNhD5A7e+Ntl6h+M5efM6TF3oh94v8cKM/aXTYAx8q/vyB9Y8tYz3O5YutJi2kigO5qWa18K5TMw57R5ccniJ5Ixjaer337Fp+uk0Z+/zRUtQkw5Be3w+WZ/av8EJ82jooJn+RTtolOw/x1a1sLhrjqEcQNzLDy+TqGoGFKNw2LVyjUxaVw0+Y+6UAmwioceZdmqv/mE0wnvkK5cVAynjZt1Uj1bikB+FO2KY8l47Owg27uteLuHCsa8OT+WODw71Vg/ozLz8uApL0JaLM3xW0fvVwUTDY4f4b4fw5xEiI1iTsoAz2qD+ucLUSo8XIisrjVh39nfqbMudMuzx9npZ5W/uHKMJjuDOAa9w/Y1oYqUCtsTU/S8G38AbfHBrqvb+LCY2EGuy++5FKjBh9WSVJcikL2bSUjya4plCwUPYzCM8hh3/U3+Yi1rk9lb+GDGCoUQxTiCvVz5QzYAaplStmWPBZimNt0oKOHbTOJTgzjMDl91lAsbRTfAN5lcGX7Kx54Zce5sdp17Yd9txcFNcWR9mglnAFFRSjASe6y1IjCeKYJiVYvyZveZG8gamzKBztI5F8MGJ3d03U0QS+XCDBTYOQlKFLmrEQvcOrVFwGlTkvlGb1wZj9iwpUceeEeJXsygbVW7KSXo8HkDeZ5cMxn8tV6DOez24wtEFzTPmc3EIIUDj6MDbGV2DFjA4r6N0nDH82NpH7FCkCDgmkdOOoWxPPxnDzr+K22twein5G7wOvfDSLD6lbPlPVIUsuW2BvTb8Kjm7k0MINb8S5JuIdirboTbGsdKDWKWHeCfq18QpjVI03jvc0bxdKyI5kjZ8kSXAd3S8gbbKKpIDCEMlY4ibigRL1Fxq/79JEENUkbt/a+xNRZZiGqCBQ5yZxTzOvvMbTT6ouK4pFoEIx1wB6H/wx8zv7voUco9w/OY5CKJCz9hHrTjwW0UwUn2r0BrSbkXZfUI7x9E1I7RY973Cak789UUN1tueiI2d48gzmVfSsJOD3umA7KlriaBTHpmKDXsm+hBHVCrj5cFF0pvyXafNtM0STE6VzbIxEVL/7m8mP4fSStGQRuIsDePKDtIQpzogeLNSXJhAvWqqg2aUv1UWwU3EAJz+l9nk5396gvXT31kL/1sZInoYAoTaWSM6ZRNlUysLsa8hRXhvE2l0pDGdkOzAvbOiIzhtVkc4UQH6AC+ni2aD7meQ7HfOj4tHfREgP/xy8dEM8yNkl0xg99xX5lCvLStAsF2X3oWSM3Z5SaknvUxe032VgFZB0KhdDLYlz0jxoH4rS8VMiNikmxSwik3iSIbQUJsDEdLOPfnxf9F4RgTViJWJE1o0A1Yx6uv67y18G5J1xqhzc+Nf0bP+BXWago/ghgx2owh/sKpx+6X4tcrepQBkk8ilcfeRrtIT+wKc+wTgb0MPa6cU375yKes2qbS2T0t+RZjmEWXjMsdv1uNTCbxVgvYeLDMfKLVpdApPHGj3l1A5EvO1gaTRFuEIk6QPw/Gk2SFTR70ocreUgINn+S49bPWoicDzEnuO5FKk7v2WU+VMvhi3A3AGWzuew60qfmjhbF78quawJn36lkxSK2Qzcop5ayVB7KoOMTrv9G5nFhWczVwSw3pUgnPcuDI+Y7eC3aRFVUU6g02fmNBjm0XJMOMAF5o50miBDOl7lYUvEyJ73+rEuXRKS3X2D1eO2QpbhrRkeHRGaQWJwWUlnfnUNznINJr7vy1kw5RQ3fKpldBOSQu6SvrUZj4c4XihT4gfjR7g48gopTotLM8c+nRbJhW8XCVRUqPVY8dhEWYVnp3+owvKNjXnuePgonVuHmGvxoatMRFP1MRH7ZG1seaGULgIqAg26A8gO+aEYWu5YO3MPrb28FPfxldTRBuvY+w2syhP9IhgnBGf0w4TDRIkGgP9DCAJRvmoaPCDQlhtEJxWkxDvWHTz2MH/J29PBQNu3Rx4bPIIKpSL06Pej8r17rm2NWIvu4dxG61PHGzT3NtitcpEgGFrqVD8e8AmrUbCNWtBdqUIVZuihvAIL3PKxjhSp45hRyezn3fkOU2zydTsGnM4Vkk5l2BUx7hdIX/fuAzaTbVWrdeSCrHb1bgnMsHMmYN3DFujOGxDsbbsem67mQvvt73u88SbNmdwgchjKY659mP68cG1IH8WgUczJ9bP4FTTa9M/R3uObhKPe0BVoR/7YGS/ptNg7ifRJ3NPcn0FqvCZnj6ygx128K91lsrudCqcKJ+j2kKgRa0ZePR+bf7GpMe/UkhF4WvOV3XRel352SFc3GE1hl6S1T4Q+lmv9UtzBGOODMTr/aA6V9LHJ798qp+o2LrPU4pbQcTHJdXf7k02m5wkYoaW4FIYXh+bXr0CxWfz91gqtWGU1n9G2nZD7hBPgDddW8aScSxS4yTalPv0VZmXNbA5AWjyQe+TGBiRoc6IVnHqaBxYexYXLe64XThSpZQuvPp5dCZzQpUNjlgaCkZSQNt3cbacy7DFezRBzJ7no+bBfq49rIF7k7zqV18xSRCoa9yyJddoEttlOECwp8yipSr8wxLMoeG3dTRNhURH5UhwxcVH/MItX7z3nhpO1Z+au/RazLQbeEzXsxlat/sjtq6UqkR0KDT/nKB2ghrfDSHzdJxrWxenWiSstmpb0X2ktc/u2RssPn57OCEBGzBvQvRcpCJycA2Vz0aL+FX5m4j+5M8eI0IUzQeI3nVADK5n6c11MC6rjPwXJMjf3Dya52IDjgzzA0QFitbU9Yl8SrBb0+5JfSBorN90LUbu97ynh+StHgqa9mXQqgEVjdCCGnqmcul3yxZV2TRJvIjClIDYyPXrgluM0InLEBUn9TfO78NW4qMIEjR15/pwTYsMqQqKywoSr2ff/B8Cqstcjnd++5WXTeD1DfhNSs59I3IFm04Eh2jdE7zJP81YwcRwP9xqgpUyAex+ulLV6BkwvAcmC5lbwT8IHKWwAzhHzipyc4tLcb95WhSdFgnGyZkyZ5E/fvtT+rrcPbggvftVBbF1/yrDQuc0Psz435wervG1eGnwv6RW2H/eJ3TF0yBXlpe5tLihTaM7b3syfYbzxrXrOTEAiDmDAe82sUqgteGMwRzrTUWdV4E4YztBCX/DOh5eNn3eXu+omeeefIgoijSqBGjWFkSe7TGPNb8pv9mDPYwOyOrMmyATRSyPI/J0AqL7+UT5uj/zhK2NfRl7r3i7PdQsOrJuw0qTz0YINMctt4MDaSJMOUaoQ/5iCMhJoL4RMh64w0nEFnv1F3ooAajTHC+JB3lyH0sVStXU33k/liOsqjCgPLytsCYuWjz2NND+s7AFO8xFO+NgmPG6U9Tn5ngR+tjG6/VgW3CLUJAZDwVdQznfwnPZr6qYLBmkKSNOhcWAOwZupbe3Y1mYS1ptcNLBcL5nnM9Zdm4dn9CZz+vkSsYPBKObrjODDEKA6aB7//9JZE6rt+h1o7HrpeXofzbNb7Sz77MqrUanf2eVGAkEFRhBkjZHm8pzQq1CIlvCWMslrq/454axzAB85Smu7ARhZyTiEdqrWS7sl4aezwAz0blT9tbrBEHoO4ogHVn5AxfS3bIBcgPz0iBIShpZP31KYb8YPJbrnry4hteacLXEXmZhZIeVmPxO4Rd7QHqERgCEwv2Oinj2koCH1ahDIg6v6Lr+YO+27whQGprMNFoWqMKFt0q1s1WvhvNVIl2rlplLqQYCfGzzlNS0hYAkAKh6T8uENv/g7uEZDB/rIahFta8YMhodejDfm0z8DagLlAZ2TvrZX91G4u/TTJGf+ogI6ZdwCA2FhqarFgjFi45KKQPFhcG5gQXhBEkRwMsgPacbAKU0TprgreJtx+TFyNnFSqCs/WwPbos3YQFUHEqKq+R/39WsBu6RUgiT1Z7FmH1w54vt4dBcHQWCaMsYNbhclsFNxrIE6ch+puDyqAy9q0p02fN0CZvYvY8h7WGpsidVOnRhgNiEDwaOeWAxjnY+r96QVJlGAAfXmnHQ1xxpkkBXowU+cI6JstFi9ye9Vsfaq07zohcaculZhCeW6rF3d
4577Z7lN0a8FofJI4wSKuqKWUs5zwC+Lo0aAjxvBUtytcNx0ZHaR2v2PV4wJeUg/yuP697bg+DbosHMDWTunGtUeuNjKnkNulg0E5KkjfG7Lh3c4+a2G0VPl6+xswdUExnkpSBaK0AYNeeyanZsOy0vTp4hnSqPt2fJTl9s6vCdELnRr4y8FzQ7+sdeaJSzOXimN2IK/22rn/Q8l/ctNndySll/Y/9S0M9me1WU9ggVUNSm27JrQRDC/Vrl2ZBELY1ME8cAjbUnjkv0bqxR3TOn5AVtwg3z+HB6IF0TUbXe2yiYQE8KIvm0lCPiidtsKllPmelcLf/EmIvUb01dPO1wNbmvCkxb4+ZzGiSVFStO/OBKWFjcdPT6r4SGHzdXUl6iHlVq2uAK5mIuDm6HhlSaPBgODDGsuQhIKbLYeJNLyCu4p0J+eyWdOPwSRAV689J6fVk6Y1RQP8l+N201Foh2KShsQM0JPc6kemEIBbIpuuxfoCTwmkc8OookBrDeOAEwyZG0+EdrkvqWT0GnFQfpJlMn2efoyCr+71Q+1lP+6e5SetTYjpvU97BsMcKO8qvUtxd6pciE5aVhYWVbOLys6C2H7kf+zziYK3D01/A55yT8lY5P9sERA9GDZg8VCgqbWFEMDQd91lLbypOpmxj4zTQEwo78NbXIl271UYqBSPgCMzf9t/WF1a9r+t/FoRrp/syBK4Jjt87CCUhtUTSkjP0srFEazpkfLN6/ALqKzqwFG2+u8RwbYiIL4RmtBm/ReNBuLH95ObBC2d8bLf0p++xWKWmShkJzvp0czXjphNDLzqqYk9ThppxCH0zBRrtvrsE7fGS6GKuWvfyqSoigmZiHZWqSqZqYlFbFqN1lsgpKyJ/j8CtkRTn4kyfUDRPKl6FGpsQC8vTGTad8zWJQBn2S+nKMhoxXMev2UzM9LLQSMIm2ZcWnUkfQud6sYgEMI5bsNWS1GV1DElNgLEnl43C3SEYqWyN+oGGf1EUTW+GinphEHLWc/GlTYufRHoXrdhX/r0GLd9LsYzsgYzIysyCtlMghRsuWc2tpb7I5i8feUJmkR3BTQ2jYBxYWRXvI9Eowu+X3W+xZAwM+RQENXTXp+qfL8BNyCkFo5upuE5mD3sq0M+yH20DoA5B0I4V3S7NOAmbvKVAPfpQQj9zKLJgk1Eyk5h7JH6GtZz5UYWZlBbGVtmVSSxDGk/roPp6/oRzpy60HRa2YZ1UO/wNz7g+fziLGXIJ58xxw1hARZRY4e8OWhSxQs7DEixhruegG/hCGUq6h2PlwbIlyrpGbgC0frW71bgOJiOK3jyMwL6ect4n1U0SzGtEHgD4y3vsWmwZ/vUCHNDt6oKJAt92EhnkNjEJbV87cZ5OKThGh5MCbbIY5YyH5b8mzoYEPaHunvp4e5oGhBCdS0PGEusIi9CtiaX45pEOcPoMGWQRa0GqdTNwoyZKXXyPUXhcEiWQouFDhDVFDjUwyC274ud4Q7CVUA3NYhQGwDP3lJIG1FAMcLuiPlhpTazcBwibiRSDcYyyvFEk5Cptk0a0lPZ4LgOFvwHaec5iOZVqXPFKsz2phwaCU9bQa3GrgWKlSgcYJmz2Hz0zvQzWC1AgN7345kQgUFQTuoui3uOLrvATAAxUHQgaf2A4QMzz2sEnZVHtg+MFU7Ihn9TKYe/gnGoMGYCmhfZri+hWsXry14vdUTm9lQfQXG2PUWHWf3XbHEGVPkhS4xAjMvRsMubB+8i7nLufQU2oMscae76LYOaHg1WZWAZafD7JMkxBk5nI62MNBoMln68se2yZzmZPOQ2G8+ikQIuJePaAT4JJYyivaYWL/TKIKVzsp6weJcsEt+YMFn5+Vajub/su33AXEiqYaI0pJ3Gqgeereht4ZXTlJyhsU99RD2QHdbyyx1EIeh1TcP8qGfk/SIMdmY8WzPrlkRBTIn1PXjwmbdiIrn92G+hIf/CGAD3l/YnURLKzV7smtFylTrlEjZJKrmdT0co6Q62A7tEPyAgXpEcOwH1XMU4vH3z/5Bz6ByFwtmVsJUFY8WIYRHBz82RiI6fUqQkKlGEWHubY4RmOjZaN5+N32gClom/vsLNii3Yo+vKR+OY2eLWvRn0ONPXCyTwCyThg1QwrtwbzaHMIHYGWajZ//qNYiXHFtAIf04EniQZKa3OJj/OXtTgMQVYxGJtFrssNVGH4zKpTioAwsst1wTuqtYf3ZxHpkMqDAPvY1ooDqFBZxPj3ZRGxuae7z/H9vbprO8U4/FJ4UY7J1M2SVOhtLcMOQNmlhkp8wnVgcUdQwI5IrtU643d6ZDWj6HHMdS/AFkKuJ2LZQWyyxO4o4j/AJ8ftwGoiFarSQa5muikqVPQSEhoije5a9nmMOsfpSG6dWmKZPCaMQG88toVkRtN5Mhe5omt15dzxreQI9A+T/MdYvfBYD3y2xWUKiCMFwEH0E4hh8xwTY5mxfvPNSHWjuyNyub7qSsAWzE1VygVcBqFbx3bV4eOAyuC4+9QGxenKlRxTJvZyutTZxPIAqeaDPUMqZuLtaj2/tL3BolBt6yqho/wt3PIQYBdvFbroYhy7nSWAWraARgsmEusBNvR5sb9w3Znq1SphogOHDAk/dE8GO/VyedwT/VZn+96NuvpDnH/P18tCqU57BKUWOoRq32UAsPNJNVf5DuLg1IcB2O/F+Pli+efUtLQXy9lfUSIDRRYKrVPsDw+JU9bvPYntaJKaPK9yLsXcePr/so4xj6Ei7b4Ang7P8BvKGO0WmpleRv+N8yT+FKqw1YwrVely3uURkFmyoDtVnYetMVRsYgx178v/zRZMqOmxnhYPnH5kKRlFldo3BzYRvDbS1lR+c2elT4fDwE9Y5OEkxAcFWnM2UifRxf/++U//97W///veDFqYiyYtk3X9ahX6dxSkl/LHsb4FCpnS4W0R8NWVPRUMjpA3hjNKO04JvE8cBSIKrkQyJexUuevWjtrHFAWy4VpzbzkYd/fd5KQ6EmgpzGciHdmO1+j7j10+9si1WkIUfxyEMaPyOb98ypSgSvndxRJlZIiWbxiEWp6sV9DX/ylya3AoLOCVuqqkYj5EgLsYd6Qqq1wUN7qyoQOKVhC27wU/JGYm/lSQO6LNlxyQFd1gYIq4LKzJwcRKflCGYKDnv67KKwubCUQ0Y0TP0plcRYGFlHz1pUutxC80kyOsaAwdlBiaTOhvsOXHF9wkVCCAEBXM6/udfzVCBbR4BCF7PxVsLGW1FjCpabLTVNHuYPUUsBqPU7uU2eBAv90S6d21loBwmT8ch1h36hvTFlS3HNCj7A0LqHFAs8zm+BAXRTRCIU0k2m+Kr/WNn0K3gstiCu9AY1dUXiDd4kKEO8NjWG7sDvquGF44ld6JrFwIGh5kLdXOIkoKRL5jADkgXmI5+Q4fi1ebBLmWEvJ1pptwXEw0sQ9Sc7JkJ2OAM9Jd92QZmWOWv6AQqumzl8+NDQ1cxGi1ba+9fAqK+kNNj0wS+9lAcn1OtWOTozVnCPRvRip84mCy1ijG54m1jis7HRugIF0lj0I6jggmmvxGvqejyuezHFqM/fjXaKGgqnMTLICH5eqUFp6b8kKVq+NuJVdyxBoB0kdjjJoBdH5CLf1zmreGNrMZHEhxwzsvWFfTMj8N+TTqt3YXxU/LhhxChKNCllGem2vTQsay3tMiPZWvndX9xFWRT+XkUmKKmy2d4meY+4N6i4as2jTSJTu/kTkWq3zzBVy/xuRpJ3FubSA3EUaUdi8YxfdlwnntAEUDDtqxJK+/2pxFBOmHgBXsJbzAe3Sr0/YOQBNyFcDYnbTGASNnB0EmmjBTevmChzD0tEOnTUlpxVl+G1rE8x5druiFB2tKzwRUBKws7ZBaTHJbTquQNHCqHuvu0uk/xangYwcLnPh0GKlFf3Et5WaZLoMglgx6NsukouoBRnh7pHYRSZtT9t89/YqVU4udAg73jry0iZdIowHZlQCCAD+E4mEMvm54lJFiE7E4KSQNKPTw53te0I+aEcPd6w9QvzuB8xsc+XrqLVoNfBfb+xQ/s7fZ+l7TPJrNMzzDr/UjBnFEM/l3mfoAvsP9kvN4tKHC47R07aG8fnbZ78gF2zcH8htYo+nKea0dhq2Hw+ldBcNJHd5okuE3+5l2f8S/hLZi9dm1KOXdGCK3jI2ncDJYt3K4zLjJ1aw5EJsKqOvlM+ZSq4kYDw1ftOJ4szFjwCwKYz8D+1XuyfOdYmzUpNdMTfoi2aGxAaqj9ynHq48sAKZu4AAAAAAAhT4gVGOU8iY3TCcZcGJWEskPbr3ch5J1MHgk3iJ4lSQMvuWzpYH1IVIiQen7w6LFc4uaPl73OXl9iBNyvCMWR6cezJOtbYrbD8g4VICZRU/76U/m0vezmtnwR1Qoe993SZWSQ3te8U0BTSFcQGdG1IaRuY4ur8un1Gk1jPz/xqbaWDEKIuOrdZYWZItzP01X1q1y0numYa5mcbFUBOfaje3z0jgkDPUy3/imFrTLjLOO/bntCBUyDHA3jX986hja9DuRL5djHAHoIIpZ
457BocRJao2BtGFnNxnhzd9sR709p24W2zA3TjKjka1C++kv/ybUSQAQgIzxQQJNYnE7E2bCarjDhKB+sQy/T4i2QQbWCTji+ouFE5T/7WhT+MWKHdpd+h9GIIY2vy+sL0e1El50Yz6cJesRDakzlqUBtLrAulopPd8Oyk7fuO5vbdSvxbT+1FlCGbHCnBSG+ZaYogg0mEefX1+gB+jlrZTlJNwGdyAQsdLFr5/pQ4SvsBgh4fDMnLs+wt1p3kQJBOm4lPG/Q3eeZTtH3Olr7fXqcw+GNQRIl/O3tvli4Dm0DnYfHL+E7oGtBmr0gcBLBsjlmDEkvyfscKdQLp0j2m7O0bhVwfWW/HjS0EYIB0PY+MomzVqdGq1PqLYWArNsP8iV0HomithoD7Kcv5M+rGAo4ULbVTIRV+FzbcFaCwnJTwLbZ2AAAF+ctd07WncNe24VkiKVKtT+kBPTC1JBklbLF8KVi8uzkmYMHATnRoJh0/g7heqag6QC+sJBO05+54CN//Yx5En3kVGs85/jOBsVVHJNt+zoTHrSq+Ob5U7nHocCAX7QismcTh7z0OVdTE1DGj5kPqE1wOnPA3BOMvPNqdfgCMxYAF+tlArvLcnNdcjnxo2EZ4TBwwfHSGsC6RyigJFy5oVbmdHhHfo1f3r+b4NJwEkgyreEHlxebDNn4e8015doMsHWsczpSzoC8I36uHWAyR3ONMbtIjWT1B+AUp6r3234oy3MOxkAzB/7tkhZQQupbWqSKaDnqLxiyJZ7lgD1cheOvyTI+8mxq4KLZdmSkyokzTUWCqZHHFS+C32xtRSd6S0za1SwsGr1RD2XYHN3B0TazzL6vjJoKprxHIZcBS8LIK5aVNWUO458MnEPeXci5MfALFXryulfGWks6aE1uBpnL6YKM7b5McxUxs7HG1wXFkoG/zFGrP8dmgLId8AAAAAAAAAO4QLcKWiwlUp7PDs+8y9ZwWrG+T1ZHgGe6hqfggXvxshzs9Nb/8Ucn0dsG34S5dFd2LDKD5iBm/h5yqLkc3ywr/vCzIQQxihW4Oi9dF+EPL3fr6Ggcnp835mz6E7TSu8m52MjuV7ocTMORw2ri7aCMJqdOyc/XYwicLege8eTkTV94W9UFCUL50bIY+c6Eoew2Wf6NNWNBI1fm0w6rDWQCWmMtrAzdBJPF+drAKps7HEAQPkI7LF5qE8Dcwh+VJ+wN07EVlKOR57qZiHxEZuTdVtOaLtB30bC82QRjFyE+fyKa3VEM2Xye6TpkB/c7KWCQi1Mfs1ts6CxlvMwNyu55yEq2IYIDX0ioLa1/lMtRu/VfWl+Pncno55v7Eu9f7Ug06yjbO1qVcWGIS2pj20EVebEjKa2j6z38DjvLY7J3Imq98dN5mirV9C5T8CBu2mxlueyzmnuDz2OJW/gCPRBo/DQCUmVBFhn3bK41B8jgPwKaMxBsugt8uLt4AFyJgDfrn/XwPZQRU0BigfizmP/qNNwT1P/4r7Bck6BinhYpYFAIQq2TqAwFYe4hr/76iOIo1S5W/eoguZhodLzJQ9N5lCbOCEqu2npNKBrpNd1oGokWdZMR2DoMSzREpy72tq6DdzyGx2coYs9dMf8AHHBXNi6Vk9k78bXitKEQV9sLmpGvWnGyTEJ5B7JJdjKduRbwditNPAW5IfMZxEsns2CSVP2FCWALG+1R03vK91tOjW3O0TsU4YSgzbrdXUKLnTzOlKALjHXKza+gfk3WhNy29WKgUBmmZNvh7hZKf4DFikVk6h8oabd8ymxQ9x+HpJ2aMBYFPaFkXp4R76ludQJk86xnwqniWU0eF5yPWJHDI1Gw49Eb2pfBUSqLKm14xIB670usNlThuwWCsP/g9ByGDKBHcnHSbwMQ4vf6M6/MqTz5Qo9tgl6YHNlkv/x0KFwLnP4E54qdxGEyg7TNHyXMHJzXHtDokPoYEw6LT4na9eLnKA3FmA0Mo6As7IqTIEoujB1Gi1R6qwxD1u96fhUUtKRvbRNOdBJQNROtM3hHDMSupJ60bkVH8wy/76i4fAsYCfqsAAAAACLNbkfQhUbci5HRIoINBQGyJSqcU1U0fsSs28UzWu/QZtIyZot6vQ5vOAG7SwtyYEDsQS897yWMwEQNUo2/k7o9zxIkd9Vg76fv9TevAvnIZk8p0GrP+irO/4X3A+aduLe+jVQQ0mNcUIFPasRL0lqnlCODkjQXLFqOFH/ROgclr4nlVvgbtM+G5xXOvr3PpJwpjl7gSu/1U1OL8x0nlN7x5Ws3/r15tRitQWZP+xftXXERosSlEuvGfA7JrRYOQgGcWVnBYAcHZfcEb/F0ZKMRGDdNLmdoEiyfjgdlm2n/OQms8Q1ljVI079U6BqzUPExPRqAzTXNNNlHscSJjRdYAi+ojBuj7DrxDQ4LCvuAwUoGLCQvwSCNg4N9OlrO3ScJS6H+e6nz1jC8hk13bS3/AtxTDhDpPxh9/8gfl1r0jrv65cf3eF9eFtaMvcyjkh2YyO/znWfwr0MBxKKOhPC/+caQfQyTPDyneyvgStG5V9aFDlFmEzqf6wvWKxBOrWJSeJpHEU3gMuydC2UMvSaUyJlVdzmymbP0VyzRWNF2X+YosPIeyiMyZe8eaDrHy1pPzq3pyVA49Q/1pLKetWxpTze+rFp75XfpTVXh+713YPcwQXKAhrHuXiS2HPODQ4cLkUskOs+ieMoxL3YouN+H6+zHNfa+s42M0A4MoUYpvPBhydKBirW3R3flK+iP2KxyH9aDc18SbQ2hXeVTg6Xvmth4leOd6D02SYyzhqlyjfLXBYtfnOXVxkXIUk8zGDjMW4Z3hF4xo52/HBc59Jd+C8qxIlZMuUMUdGMZfdw9PTaVqaawe0Elmh12lWd0MbqenpQZNj2I64XnFQWxtw7DUrDTEfyh/Icsv3+zNpbyxxO9rr+wwyJFtA98Q06kpzZRXtnC8vV5xoAAAAABNsLpRyPAVGfVFlEaXl6BepZtxJeXa5XgmpAFmwtyA//I8qzuhjcqLjDgdZRv4KtJoSYSt5LsSVh9kyahsvEGts21oN6hSrBjdHInyGRcy6TSOPo1XsFlQBCXnLEWP6q4R5IHpdUdPteotxSh5/J0/HT+1HZDeBtb0b/O8vhvCDNxetUjWxKigXSDLQwzCPR8eYoZX6iaJhgFyCr9CXyFcQ/9CJcF+zIFsJEqQThFzUxXttyTqjUh6/PhfFyQq9azeJKm6oclSyi18+cVFvhEAezB4VZrG5RYiVkvgWeTzvqBYAAAA==" alt="MySchoolHero.com — free educational games">
458  </a>
459</footer>
460
461<script>
462"use strict";
463
464/* ============================================================
465   STRINGS
466============================================================ */
467const STR = {
468  en:{
469    tagline:"Word Problem Generator · put your students in the math",
470    langBtn:"🌎 Español", print:"🖨️ Print",
471    lblRoster:"Your class list", lblStd:"Standard", lblCount:"How many problems",
472    hintRoster:"First names only, one per line. Nicknames are fine.",
473    gen:"Make my worksheet", save:"Save list", clear:"Clear",
474    emptyBig:"Put your students in the math.",
475    emptyBody:"Paste your class list, pick a standard, and press <b>Make my worksheet</b>. Every problem stars a kid from your room.",
476    privacy:"<b>Student names never leave this device.</b> Nothing is uploaded, and no account is needed. Your list is saved only in this browser.",
477    lockedH:"In the full version",
478    locked:["Exit tickets for your whole class","2 or 4 tickets per page","Save your class list to a file","Every new standard, free forever"],
479    name:"Name", date:"Date", show:"Show your work", answer:"Answer:",
480    keyTitle:"Answer Key", need:"Add at least one name to your class list first.",
481    saved:"Class list saved in this browser.", cleared:"Class list cleared.",
482    dok:"DOK", footer:"Free math games & worksheets at",
483    lblTheme:"Story theme", gradeWord:"Grade",
484    modeLabel:"What are you making",
485    modeWs:"Worksheet", modeWsSub:"Full page \u00b7 3 levels",
486    modeEt:"Exit ticket", modeEtSub:"4 per page, quick check",
487    etLocked:"Exit tickets are a paid feature. Here is one page so you can see how they work \u2014 the full version makes a set for your whole class, 2 or 4 to a page.",
488    etHead:"Exit ticket", etCut:"cut here",
489    etRamp:"Each ticket ramps DOK 1 \u2192 2 \u2192 3, so you can see where a student stopped.",
490    etKey:"Exit Ticket Key", etTicket:"Ticket",
491    sample:"SAMPLE", rerollTip:"New problem here",
492    pickAll:"All", pickNone:"None", pickCount:"{n} of {t} in the math",
493    ccssCredit:"Standard text © 2010 National Governors Association Center for Best Practices and Council of Chief State School Officers. All rights reserved.",
494    lvlNames:["Support","On level","Challenge"], setMarks:["\u25CF","\u25B2","\u25A0"], setWord:"Set",
495    lvlSub:["Smaller numbers, one step, with a hint","Grade-level problems","Two steps, plus explain your thinking"],
496    demoNote:"Every standard here prints in three levels \u2014 free, no account needed.",
497    pickLevel:"Pick a level to view and print", printAll:"🖨️ Print all three",
498    howTitle:"📖 Directions",
499    howBody:["<b>1.</b> Paste your class list — first names, one per line.",
500             "<b>2.</b> Pick a standard, a story theme, and how many problems you want.",
501             "<b>3.</b> Press <b>Make my worksheet</b>. Every problem stars one of your students.",
502             "<b>4.</b> Press <b>Print</b>. The answer key prints on its own page, so you can keep it.",
503             "<b>Tip:</b> press Make my worksheet again for a brand-new set of numbers.",
504             "<b>Privacy:</b> your class list is stored only in this browser. Nothing is uploaded."],
505    more:"🎮 Play free games"
506  },
507  es:{
508    tagline:"Generador de Problemas · pon a tus estudiantes en las matemáticas",
509    langBtn:"🌎 English", print:"🖨️ Imprimir",
510    lblRoster:"Tu lista de clase", lblStd:"Estándar", lblCount:"Cuántos problemas",
511    hintRoster:"Solo nombres, uno por línea. Los apodos están bien.",
512    gen:"Crear mi hoja", save:"Guardar lista", clear:"Borrar",
513    emptyBig:"Pon a tus estudiantes en las matemáticas.",
514    emptyBody:"Pega tu lista de clase, elige un estándar y presiona <b>Crear mi hoja</b>. Cada problema tendrá a un niño de tu salón.",
515    privacy:"<b>Los nombres nunca salen de este dispositivo.</b> No se sube nada y no se necesita cuenta. Tu lista se guarda solo en este navegador.",
516    lockedH:"En la versión completa",
517    locked:["Boletos de salida para toda la clase","2 o 4 boletos por página","Guarda tu lista en un archivo","Cada estándar nuevo, gratis para siempre"],
518    name:"Nombre", date:"Fecha", show:"Muestra tu trabajo", answer:"Respuesta:",
519    keyTitle:"Hoja de Respuestas", need:"Agrega al menos un nombre a tu lista primero.",
520    saved:"Lista guardada en este navegador.", cleared:"Lista borrada.",
521    dok:"DOK", footer:"Juegos y hojas de matemáticas gratis en",
522    lblTheme:"Tema de los problemas", gradeWord:"Grado",
523    modeLabel:"Qué vas a crear",
524    modeWs:"Hoja de trabajo", modeWsSub:"Página completa \u00b7 3 niveles",
525    modeEt:"Boleto de salida", modeEtSub:"4 por página, revisión rápida",
526    etLocked:"Los boletos de salida son de la versión completa. Aquí hay una página de muestra \u2014 la versión completa crea un juego para toda la clase, 2 o 4 por página.",
527    etHead:"Boleto de salida", etCut:"corta aquí",
528    etRamp:"Cada boleto sube de DOK 1 \u2192 2 \u2192 3, para ver dónde se detuvo el estudiante.",
529    etKey:"Respuestas de Boletos", etTicket:"Boleto",
530    sample:"MUESTRA", rerollTip:"Nuevo problema aquí",
531    pickAll:"Todos", pickNone:"Ninguno", pickCount:"{n} de {t} en los problemas",
532    ccssCredit:"Texto del estándar © 2010 National Governors Association Center for Best Practices and Council of Chief State School Officers. Todos los derechos reservados.",
533    lvlNames:["Apoyo","En nivel","Desafío"], setMarks:["\u25CF","\u25B2","\u25A0"], setWord:"Grupo",
534    lvlSub:["Números pequeños, un paso, con pista","Problemas del nivel de grado","Dos pasos y explica tu razonamiento"],
535    demoNote:"Cada estándar aquí se imprime en tres niveles \u2014 gratis, sin cuenta.",
536    pickLevel:"Elige un nivel para ver e imprimir", printAll:"🖨️ Imprimir los tres",
537    howTitle:"📖 Instrucciones",
538    howBody:["<b>1.</b> Pega tu lista de clase — solo nombres, uno por línea.",
539             "<b>2.</b> Elige un estándar, un tema y cuántos problemas quieres.",
540             "<b>3.</b> Presiona <b>Crear mi hoja</b>. Cada problema tendrá a un estudiante tuyo.",
541             "<b>4.</b> Presiona <b>Imprimir</b>. La hoja de respuestas sale en su propia página.",
542             "<b>Consejo:</b> presiona Crear mi hoja otra vez para números nuevos.",
543             "<b>Privacidad:</b> tu lista se guarda solo en este navegador. No se sube nada."],
544    more:"🎮 Juega gratis"
545  }
546};
547
548/* ============================================================
549   THEME (free edition ships one: back to school)
550============================================================ */
551/* Every theme follows the same rules, or the templates break:
552   - items must be countable, buyable, shareable, and packable in a box
553   - every container must be able to hold EVERY item in the theme
554   - every Spanish noun carries g:"m" or g:"f" for agreement          */
555const THEMES = {
556 school:{
557  label:{en:"Back to school", es:"Regreso a clases"},
558  items:[{en:"pencils", es:"lápices", one:{en:"pencil", es:"lápiz"}, g:"m", p:1},
559         {en:"crayons", es:"crayones", one:{en:"crayon", es:"crayón"}, g:"m", p:1},
560         {en:"stickers", es:"calcomanías", one:{en:"sticker", es:"calcomanía"}, g:"f", p:1},
561         {en:"notebooks", es:"cuadernos", one:{en:"notebook", es:"cuaderno"}, g:"m", p:2},
562         {en:"markers", es:"marcadores", one:{en:"marker", es:"marcador"}, g:"m", p:2},
563         {en:"erasers", es:"borradores", one:{en:"eraser", es:"borrador"}, g:"m", p:1},
564         {en:"glue sticks", es:"barras de pegamento", one:{en:"glue stick", es:"barra de pegamento"}, g:"f", p:1},
565         {en:"folders", es:"carpetas", one:{en:"folder", es:"carpeta"}, g:"f", p:2}],
566  bins:[{en:"supply bins", es:"cajas de útiles", one:{en:"supply bin", es:"caja de útiles"}, g:"f"},
567        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
568        {en:"backpacks", es:"mochilas", one:{en:"backpack", es:"mochila"}, g:"f"},
569        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"}],
570  spots:[{en:"desks", es:"pupitres", one:{en:"desk", es:"pupitre"}, g:"m"},
571         {en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"}],
572  place:{en:"the supply closet", es:"el armario de útiles"},
573  group:{en:"class", es:"clase", g:"f"}
574 },
575 sports:{
576  label:{en:"Sports day", es:"Día deportivo"},
577  items:[{en:"tennis balls", es:"pelotas de tenis", one:{en:"tennis ball", es:"pelota de tenis"}, g:"f", p:2},
578         {en:"jerseys", es:"camisetas", one:{en:"jersey", es:"camiseta"}, g:"f", p:3},
579         {en:"water bottles", es:"botellas de agua", one:{en:"water bottle", es:"botella de agua"}, g:"f", p:2},
580         {en:"cones", es:"conos", one:{en:"cone", es:"cono"}, g:"m", p:2},
581         {en:"medals", es:"medallas", one:{en:"medal", es:"medalla"}, g:"f", p:3},
582         {en:"whistles", es:"silbatos", one:{en:"whistle", es:"silbato"}, g:"m", p:2},
583         {en:"wristbands", es:"muñequeras", one:{en:"wristband", es:"muñequera"}, g:"f", p:1},
584         {en:"team stickers", es:"calcomanías del equipo", one:{en:"team sticker", es:"calcomanía del equipo"}, g:"f", p:1}],
585  bins:[{en:"gear bags", es:"bolsas de equipo", one:{en:"gear bag", es:"bolsa de equipo"}, g:"f"},
586        {en:"team bins", es:"cajas del equipo", one:{en:"team bin", es:"caja del equipo"}, g:"f"},
587        {en:"equipment boxes", es:"cajas de equipo", one:{en:"equipment box", es:"caja de equipo"}, g:"f"},
588        {en:"duffel bags", es:"bolsas de lona", one:{en:"duffel bag", es:"bolsa de lona"}, g:"f"}],
589  spots:[{en:"benches", es:"bancas", one:{en:"bench", es:"banca"}, g:"f"},
590         {en:"sideline tables", es:"mesas de la banca", one:{en:"sideline table", es:"mesa de la banca"}, g:"f"}],
591  place:{en:"the equipment room", es:"el cuarto de equipo"},
592  group:{en:"team", es:"equipo", g:"m"}
593 },
594 bakery:{
595  label:{en:"Bakery", es:"Panadería"},
596  items:[{en:"cookies", es:"galletas", one:{en:"cookie", es:"galleta"}, g:"f", p:1},
597         {en:"muffins", es:"panecillos", one:{en:"muffin", es:"panecillo"}, g:"m", p:1},
598         {en:"cupcakes", es:"pastelitos", one:{en:"cupcake", es:"pastelito"}, g:"m", p:1},
599         {en:"bagels", es:"bagels", one:{en:"bagel", es:"bagel"}, g:"m", p:1},
600         {en:"pretzels", es:"pretzels", one:{en:"pretzel", es:"pretzel"}, g:"m", p:1},
601         {en:"donuts", es:"donas", one:{en:"donut", es:"dona"}, g:"f", p:1},
602         {en:"dinner rolls", es:"bollos", one:{en:"dinner roll", es:"bollo"}, g:"m", p:1},
603         {en:"brownies", es:"brownies", one:{en:"brownie", es:"brownie"}, g:"m", p:1}],
604  bins:[{en:"bakery boxes", es:"cajas de panadería", one:{en:"bakery box", es:"caja de panadería"}, g:"f"},
605        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
606        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"},
607        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"}],
608  spots:[{en:"trays", es:"bandejas", one:{en:"tray", es:"bandeja"}, g:"f"},
609         {en:"counters", es:"mostradores", one:{en:"counter", es:"mostrador"}, g:"m"}],
610  place:{en:"the bakery kitchen", es:"la cocina de la panadería"},
611  group:{en:"class", es:"clase", g:"f"}
612 },
613 aquarium:{
614  label:{en:"Aquarium trip", es:"Viaje al acuario"},
615  items:[{en:"seashells", es:"conchas", one:{en:"seashell", es:"concha"}, g:"f", p:1},
616         {en:"postcards", es:"postales", one:{en:"postcard", es:"postal"}, g:"f", p:1},
617         {en:"tickets", es:"boletos", one:{en:"ticket", es:"boleto"}, g:"m", p:3},
618         {en:"fish stickers", es:"calcomanías de peces", one:{en:"fish sticker", es:"calcomanía de peces"}, g:"f", p:1},
619         {en:"magnets", es:"imanes", one:{en:"magnet", es:"imán"}, g:"m", p:1},
620         {en:"keychains", es:"llaveros", one:{en:"keychain", es:"llavero"}, g:"m", p:2},
621         {en:"wristbands", es:"muñequeras", one:{en:"wristband", es:"muñequera"}, g:"f", p:1},
622         {en:"snack packs", es:"bolsitas de merienda", one:{en:"snack pack", es:"bolsita de merienda"}, g:"f", p:2}],
623  bins:[{en:"tote bags", es:"bolsas de tela", one:{en:"tote bag", es:"bolsa de tela"}, g:"f"},
624        {en:"gift boxes", es:"cajas de regalo", one:{en:"gift box", es:"caja de regalo"}, g:"f"},
625        {en:"backpacks", es:"mochilas", one:{en:"backpack", es:"mochila"}, g:"f"},
626        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"}],
627  spots:[{en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"},
628         {en:"benches", es:"bancas", one:{en:"bench", es:"banca"}, g:"f"}],
629  place:{en:"the gift shop", es:"la tienda de regalos"},
630  group:{en:"class", es:"clase", g:"f"}
631 },
632 space:{
633  label:{en:"Space station", es:"Estación espacial"},
634  items:[{en:"moon rocks", es:"rocas lunares", one:{en:"moon rock", es:"roca lunar"}, g:"f", p:2},
635         {en:"star stickers", es:"calcomanías de estrellas", one:{en:"star sticker", es:"calcomanía de estrellas"}, g:"f", p:1},
636         {en:"mission patches", es:"parches de misión", one:{en:"mission patch", es:"parche de misión"}, g:"m", p:2},
637         {en:"batteries", es:"baterías", one:{en:"battery", es:"batería"}, g:"f", p:2},
638         {en:"space snacks", es:"meriendas espaciales", one:{en:"space snack", es:"merienda espacial"}, g:"f", p:1},
639         {en:"water pouches", es:"bolsas de agua", one:{en:"water pouch", es:"bolsa de agua"}, g:"f", p:1},
640         {en:"model rockets", es:"cohetes de juguete", one:{en:"model rocket", es:"cohete de juguete"}, g:"m", p:3},
641         {en:"glow sticks", es:"barras luminosas", one:{en:"glow stick", es:"barra luminosa"}, g:"f", p:1}],
642  bins:[{en:"supply crates", es:"cajones de suministros", one:{en:"supply crate", es:"cajón de suministros"}, g:"m"},
643        {en:"cargo bags", es:"bolsas de carga", one:{en:"cargo bag", es:"bolsa de carga"}, g:"f"},
644        {en:"sample boxes", es:"cajas de muestras", one:{en:"sample box", es:"caja de muestras"}, g:"f"},
645        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"}],
646  spots:[{en:"workbenches", es:"mesas de trabajo", one:{en:"workbench", es:"mesa de trabajo"}, g:"f"},
647         {en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"}],
648  place:{en:"the supply bay", es:"la bodega de suministros"},
649  group:{en:"crew", es:"tripulación", g:"f"}
650 },
651 market:{
652  label:{en:"Farmers market", es:"Mercado de agricultores"},
653  items:[{en:"apples", es:"manzanas", one:{en:"apple", es:"manzana"}, g:"f", p:1},
654         {en:"oranges", es:"naranjas", one:{en:"orange", es:"naranja"}, g:"f", p:1},
655         {en:"tomatoes", es:"tomates", one:{en:"tomato", es:"tomate"}, g:"m", p:1},
656         {en:"carrots", es:"zanahorias", one:{en:"carrot", es:"zanahoria"}, g:"f", p:1},
657         {en:"peaches", es:"duraznos", one:{en:"peach", es:"durazno"}, g:"m", p:1},
658         {en:"corn cobs", es:"mazorcas", one:{en:"corn cob", es:"mazorca"}, g:"f", p:1},
659         {en:"potatoes", es:"papas", one:{en:"potato", es:"papa"}, g:"f", p:1},
660         {en:"lemons", es:"limones", one:{en:"lemon", es:"limón"}, g:"m", p:1}],
661  bins:[{en:"crates", es:"cajones", one:{en:"crate", es:"cajón"}, g:"m"},
662        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"},
663        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
664        {en:"wooden boxes", es:"cajas de madera", one:{en:"wooden box", es:"caja de madera"}, g:"f"}],
665  spots:[{en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"},
666         {en:"market stands", es:"puestos", one:{en:"market stand", es:"puesto"}, g:"m"}],
667  place:{en:"the market stall", es:"el puesto del mercado"},
668  group:{en:"class", es:"clase", g:"f"}
669 },
670 arcade:{
671  label:{en:"Arcade", es:"Sala de juegos"},
672  items:[{en:"tokens", es:"fichas", one:{en:"token", es:"ficha"}, g:"f", p:1},
673         {en:"prize tickets", es:"boletos de premio", one:{en:"prize ticket", es:"boleto de premio"}, g:"m", p:1},
674         {en:"bouncy balls", es:"pelotas saltarinas", one:{en:"bouncy ball", es:"pelota saltarina"}, g:"f", p:1},
675         {en:"keychains", es:"llaveros", one:{en:"keychain", es:"llavero"}, g:"m", p:2},
676         {en:"stickers", es:"calcomanías", one:{en:"sticker", es:"calcomanía"}, g:"f", p:1},
677         {en:"mini figures", es:"figuritas", one:{en:"mini figure", es:"figurita"}, g:"f", p:2},
678         {en:"glow bracelets", es:"pulseras luminosas", one:{en:"glow bracelet", es:"pulsera luminosa"}, g:"f", p:1},
679         {en:"puzzle cubes", es:"cubos rompecabezas", one:{en:"puzzle cube", es:"cubo rompecabezas"}, g:"m", p:2}],
680  bins:[{en:"prize boxes", es:"cajas de premios", one:{en:"prize box", es:"caja de premios"}, g:"f"},
681        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
682        {en:"plastic bins", es:"cajas de plástico", one:{en:"plastic bin", es:"caja de plástico"}, g:"f"},
683        {en:"backpacks", es:"mochilas", one:{en:"backpack", es:"mochila"}, g:"f"}],
684  spots:[{en:"counters", es:"mostradores", one:{en:"counter", es:"mostrador"}, g:"m"},
685         {en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"}],
686  place:{en:"the prize counter", es:"el mostrador de premios"},
687  group:{en:"class", es:"clase", g:"f"}
688 },
689 camping:{
690  label:{en:"Camping trip", es:"Viaje de campamento"},
691  items:[{en:"marshmallows", es:"malvaviscos", one:{en:"marshmallow", es:"malvavisco"}, g:"m", p:1},
692         {en:"flashlights", es:"linternas", one:{en:"flashlight", es:"linterna"}, g:"f", p:3},
693         {en:"water bottles", es:"botellas de agua", one:{en:"water bottle", es:"botella de agua"}, g:"f", p:2},
694         {en:"granola bars", es:"barras de granola", one:{en:"granola bar", es:"barra de granola"}, g:"f", p:1},
695         {en:"tent stakes", es:"estacas de carpa", one:{en:"tent stake", es:"estaca de carpa"}, g:"f", p:1},
696         {en:"compasses", es:"brújulas", one:{en:"compass", es:"brújula"}, g:"f", p:3},
697         {en:"lanterns", es:"faroles", one:{en:"lantern", es:"farol"}, g:"m", p:3},
698         {en:"trail maps", es:"mapas de senderos", one:{en:"trail map", es:"mapa de senderos"}, g:"m", p:2}],
699  bins:[{en:"backpacks", es:"mochilas", one:{en:"backpack", es:"mochila"}, g:"f"},
700        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
701        {en:"gear bags", es:"bolsas de equipo", one:{en:"gear bag", es:"bolsa de equipo"}, g:"f"},
702        {en:"duffel bags", es:"bolsas de lona", one:{en:"duffel bag", es:"bolsa de lona"}, g:"f"}],
703  spots:[{en:"picnic tables", es:"mesas de picnic", one:{en:"picnic table", es:"mesa de picnic"}, g:"f"},
704         {en:"benches", es:"bancas", one:{en:"bench", es:"banca"}, g:"f"}],
705  place:{en:"the camp supply tent", es:"la carpa de suministros"},
706  group:{en:"group", es:"grupo", g:"m"}
707 },
708 art:{
709  label:{en:"Art class", es:"Clase de arte"},
710  items:[{en:"paintbrushes", es:"pinceles", one:{en:"paintbrush", es:"pincel"}, g:"m", p:2},
711         {en:"paint jars", es:"frascos de pintura", one:{en:"paint jar", es:"frasco de pintura"}, g:"m", p:2},
712         {en:"clay blocks", es:"bloques de arcilla", one:{en:"clay block", es:"bloque de arcilla"}, g:"m", p:2},
713         {en:"colored pencils", es:"lápices de colores", one:{en:"colored pencil", es:"lápiz de color"}, g:"m", p:2},
714         {en:"sketchbooks", es:"cuadernos de dibujo", one:{en:"sketchbook", es:"cuaderno de dibujo"}, g:"m", p:3},
715         {en:"glue sticks", es:"barras de pegamento", one:{en:"glue stick", es:"barra de pegamento"}, g:"f", p:1},
716         {en:"stamps", es:"sellos", one:{en:"stamp", es:"sello"}, g:"m", p:1},
717         {en:"ribbon spools", es:"carretes de cinta", one:{en:"ribbon spool", es:"carrete de cinta"}, g:"m", p:2}],
718  bins:[{en:"art bins", es:"cajas de arte", one:{en:"art bin", es:"caja de arte"}, g:"f"},
719        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
720        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
721        {en:"supply boxes", es:"cajas de materiales", one:{en:"supply box", es:"caja de materiales"}, g:"f"}],
722  spots:[{en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"},
723         {en:"desks", es:"pupitres", one:{en:"desk", es:"pupitre"}, g:"m"}],
724  place:{en:"the art cabinet", es:"el gabinete de arte"},
725  group:{en:"class", es:"clase", g:"f"}
726 },
727 pets:{
728  label:{en:"Pet shop", es:"Tienda de mascotas"},
729  items:[{en:"dog treats", es:"premios para perros", one:{en:"dog treat", es:"premio para perros"}, g:"m", p:1},
730         {en:"cat toys", es:"juguetes para gatos", one:{en:"cat toy", es:"juguete para gatos"}, g:"m", p:3},
731         {en:"chew bones", es:"huesos masticables", one:{en:"chew bone", es:"hueso masticable"}, g:"m", p:2},
732         {en:"collars", es:"collares", one:{en:"collar", es:"collar"}, g:"m", p:3},
733         {en:"leashes", es:"correas", one:{en:"leash", es:"correa"}, g:"f", p:3},
734         {en:"food bowls", es:"platos de comida", one:{en:"food bowl", es:"plato de comida"}, g:"m", p:2},
735         {en:"pet tags", es:"placas de mascota", one:{en:"pet tag", es:"placa de mascota"}, g:"f", p:1},
736         {en:"brushes", es:"cepillos", one:{en:"brush", es:"cepillo"}, g:"m", p:2}],
737  bins:[{en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
738        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
739        {en:"supply boxes", es:"cajas de materiales", one:{en:"supply box", es:"caja de materiales"}, g:"f"},
740        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"}],
741  spots:[{en:"shelves", es:"estantes", one:{en:"shelf", es:"estante"}, g:"m"},
742         {en:"counters", es:"mostradores", one:{en:"counter", es:"mostrador"}, g:"m"}],
743  place:{en:"the stock room", es:"la bodega"},
744  group:{en:"class", es:"clase", g:"f"}
745 },
746 pumpkin:{
747  label:{en:"Pumpkin patch", es:"Campo de calabazas"},
748  items:[{en:"pumpkins", es:"calabazas", one:{en:"pumpkin", es:"calabaza"}, g:"f", p:2},
749         {en:"gourds", es:"calabacines", one:{en:"gourd", es:"calabacín"}, g:"m", p:1},
750         {en:"apples", es:"manzanas", one:{en:"apple", es:"manzana"}, g:"f", p:1},
751         {en:"corn cobs", es:"mazorcas", one:{en:"corn cob", es:"mazorca"}, g:"f", p:1},
752         {en:"sunflowers", es:"girasoles", one:{en:"sunflower", es:"girasol"}, g:"m", p:2},
753         {en:"cider cups", es:"vasos de sidra", one:{en:"cider cup", es:"vaso de sidra"}, g:"m", p:1},
754         {en:"caramel apples", es:"manzanas acarameladas", one:{en:"caramel apple", es:"manzana acaramelada"}, g:"f", p:1},
755         {en:"pumpkin stickers", es:"calcomanías de calabaza", one:{en:"pumpkin sticker", es:"calcomanía de calabaza"}, g:"f", p:1}],
756  bins:[{en:"wagons", es:"carretas", one:{en:"wagon", es:"carreta"}, g:"f"},
757        {en:"crates", es:"cajones", one:{en:"crate", es:"cajón"}, g:"m"},
758        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"},
759        {en:"wooden boxes", es:"cajas de madera", one:{en:"wooden box", es:"caja de madera"}, g:"f"}],
760  spots:[{en:"hay bales", es:"pacas de heno", one:{en:"hay bale", es:"paca de heno"}, g:"f"},
761         {en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"}],
762  place:{en:"the patch barn", es:"el granero del campo"},
763  group:{en:"class", es:"clase", g:"f"}
764 },
765 winter:{
766  label:{en:"Winter wonderland", es:"País invernal"},
767  items:[{en:"mittens", es:"mitones", one:{en:"mitten", es:"mitón"}, g:"m", p:2},
768         {en:"scarves", es:"bufandas", one:{en:"scarf", es:"bufanda"}, g:"f", p:2},
769         {en:"snowflake stickers", es:"calcomanías de copos", one:{en:"snowflake sticker", es:"calcomanía de copo"}, g:"f", p:1},
770         {en:"cocoa packets", es:"sobres de cocoa", one:{en:"cocoa packet", es:"sobre de cocoa"}, g:"m", p:1},
771         {en:"marshmallows", es:"malvaviscos", one:{en:"marshmallow", es:"malvavisco"}, g:"m", p:1},
772         {en:"pinecones", es:"piñas", one:{en:"pinecone", es:"piña"}, g:"f", p:1},
773         {en:"snow globes", es:"globos de nieve", one:{en:"snow globe", es:"globo de nieve"}, g:"m", p:3},
774         {en:"wool socks", es:"calcetines de lana", one:{en:"wool sock", es:"calcetín de lana"}, g:"m", p:2}],
775  bins:[{en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
776        {en:"gift boxes", es:"cajas de regalo", one:{en:"gift box", es:"caja de regalo"}, g:"f"},
777        {en:"tote bags", es:"bolsas de tela", one:{en:"tote bag", es:"bolsa de tela"}, g:"f"},
778        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"}],
779  spots:[{en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"},
780         {en:"shelves", es:"estantes", one:{en:"shelf", es:"estante"}, g:"m"}],
781  place:{en:"the winter closet", es:"el armario de invierno"},
782  group:{en:"class", es:"clase", g:"f"}
783 },
784 friendship:{
785  label:{en:"Friendship week", es:"Semana de la amistad"},
786  items:[{en:"friendship bracelets", es:"pulseras de la amistad", one:{en:"friendship bracelet", es:"pulsera de la amistad"}, g:"f", p:2},
787         {en:"cards", es:"tarjetas", one:{en:"card", es:"tarjeta"}, g:"f", p:1},
788         {en:"heart stickers", es:"calcomanías de corazón", one:{en:"heart sticker", es:"calcomanía de corazón"}, g:"f", p:1},
789         {en:"bookmarks", es:"marcapáginas", one:{en:"bookmark", es:"marcapáginas"}, g:"m", p:1},
790         {en:"buttons", es:"botones", one:{en:"button", es:"botón"}, g:"m", p:1},
791         {en:"ribbons", es:"cintas", one:{en:"ribbon", es:"cinta"}, g:"f", p:1},
792         {en:"pencils", es:"lápices", one:{en:"pencil", es:"lápiz"}, g:"m", p:1},
793         {en:"candies", es:"dulces", one:{en:"candy", es:"dulce"}, g:"m", p:1}],
794  bins:[{en:"gift boxes", es:"cajas de regalo", one:{en:"gift box", es:"caja de regalo"}, g:"f"},
795        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"},
796        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"},
797        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"}],
798  spots:[{en:"tables", es:"mesas", one:{en:"table", es:"mesa"}, g:"f"},
799         {en:"desks", es:"pupitres", one:{en:"desk", es:"pupitre"}, g:"m"}],
800  place:{en:"the craft closet", es:"el armario de manualidades"},
801  group:{en:"class", es:"clase", g:"f"}
802 },
803 garden:{
804  label:{en:"Spring garden", es:"Jardín de primavera"},
805  items:[{en:"seed packets", es:"sobres de semillas", one:{en:"seed packet", es:"sobre de semillas"}, g:"m", p:1},
806         {en:"flower pots", es:"macetas", one:{en:"flower pot", es:"maceta"}, g:"f", p:3},
807         {en:"tulip bulbs", es:"bulbos de tulipán", one:{en:"tulip bulb", es:"bulbo de tulipán"}, g:"m", p:2},
808         {en:"watering cans", es:"regaderas", one:{en:"watering can", es:"regadera"}, g:"f", p:3},
809         {en:"garden gloves", es:"guantes de jardín", one:{en:"garden glove", es:"guante de jardín"}, g:"m", p:2},
810         {en:"seedlings", es:"plantitas", one:{en:"seedling", es:"plantita"}, g:"f", p:2},
811         {en:"plant markers", es:"letreros de plantas", one:{en:"plant marker", es:"letrero de plantas"}, g:"m", p:1},
812         {en:"sunflowers", es:"girasoles", one:{en:"sunflower", es:"girasol"}, g:"m", p:2}],
813  bins:[{en:"garden crates", es:"cajones de jardín", one:{en:"garden crate", es:"cajón de jardín"}, g:"m"},
814        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"},
815        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
816        {en:"paper bags", es:"bolsas de papel", one:{en:"paper bag", es:"bolsa de papel"}, g:"f"}],
817  spots:[{en:"garden tables", es:"mesas de jardín", one:{en:"garden table", es:"mesa de jardín"}, g:"f"},
818         {en:"benches", es:"bancas", one:{en:"bench", es:"banca"}, g:"f"}],
819  place:{en:"the garden shed", es:"la casita del jardín"},
820  group:{en:"class", es:"clase", g:"f"}
821 },
822 beach:{
823  label:{en:"Summer beach", es:"Playa de verano"},
824  items:[{en:"seashells", es:"conchas", one:{en:"seashell", es:"concha"}, g:"f", p:1},
825         {en:"sand buckets", es:"cubetas de arena", one:{en:"sand bucket", es:"cubeta de arena"}, g:"f", p:2},
826         {en:"beach balls", es:"pelotas de playa", one:{en:"beach ball", es:"pelota de playa"}, g:"f", p:3},
827         {en:"sunglasses", es:"lentes de sol", one:{en:"pair of sunglasses", es:"par de lentes de sol"}, g:"m", p:3},
828         {en:"beach towels", es:"toallas de playa", one:{en:"beach towel", es:"toalla de playa"}, g:"f", p:3},
829         {en:"flip-flops", es:"chanclas", one:{en:"pair of flip-flops", es:"par de chanclas"}, g:"f", p:2},
830         {en:"starfish stickers", es:"calcomanías de estrella de mar", one:{en:"starfish sticker", es:"calcomanía de estrella de mar"}, g:"f", p:1},
831         {en:"sand shovels", es:"palas de arena", one:{en:"sand shovel", es:"pala de arena"}, g:"f", p:2}],
832  bins:[{en:"beach bags", es:"bolsas de playa", one:{en:"beach bag", es:"bolsa de playa"}, g:"f"},
833        {en:"tote bags", es:"bolsas de tela", one:{en:"tote bag", es:"bolsa de tela"}, g:"f"},
834        {en:"storage tubs", es:"cajas de guardar", one:{en:"storage tub", es:"caja de guardar"}, g:"f"},
835        {en:"baskets", es:"canastas", one:{en:"basket", es:"canasta"}, g:"f"}],
836  spots:[{en:"picnic tables", es:"mesas de picnic", one:{en:"picnic table", es:"mesa de picnic"}, g:"f"},
837         {en:"benches", es:"bancas", one:{en:"bench", es:"banca"}, g:"f"}],
838  place:{en:"the beach shack", es:"la casita de la playa"},
839  group:{en:"class", es:"clase", g:"f"}
840 },
841};
842let THEME = THEMES.school;
843
844/* ============================================================
845   HELPERS
846============================================================ */
847const ri = (lo,hi)=>Math.floor(Math.random()*(hi-lo+1))+lo;
848const pick = a => a[Math.floor(Math.random()*a.length)];
849// When set, every problem in the current exit ticket uses this 
849same object.
850let ITEMLOCK = null;
851const pickItem = () => ITEMLOCK || pick(THEME.items);
852
853/* Spanish gender agreement. Every noun carries g:"m" or g:"f"; these keep
854   articles and question words matching it. Without this you get
855   "¿Cuántos calcomanías" and "cada uno de 5 mesas". */
856const gEs      = o => (o && o.g) === "m" ? "m" : "f";
857const cuantosEs= o => gEs(o)==="m" ? "Cuántos" : "Cuántas";
858const unoEs    = o => gEs(o)==="m" ? "uno" : "una";
859const elLaEs   = o => gEs(o)==="m" ? "el" : "la";
860const losLasEs = o => gEs(o)==="m" ? "los" : "las";
861const unUnaEs  = o => gEs(o)==="m" ? "un" : "una";
862const dibujaEs = o => gEs(o)==="m" ? "Dibújalos" : "Dibújalas";
863const isAre = n => n===1 ? "is" : "are";
864const estaN = n => n===1 ? "está" : "están";
865const aAn = w => /^[aeiou]/i.test(w) ? "An" : "A";
866const cuantosLc= o => gEs(o)==="m" ? "cuántos" : "cuántas";
867// Price bands: 1 = small consumable, 2 = ordinary supply, 3 = the pricey item.
868const BAND = { 1:[25,145], 2:[150,650], 3:[695,2400] };   // in cents
869const priceOf = it => { const [lo,hi] = BAND[it.p || 2]; return ri(lo,hi)/100; };
870// ---- rounding helper ----
871const rnd = (n,place)=> Math.round(n/place)*place;
872const placeEn = p => p===10?"ten":p===100?"hundred":"thousand";
873const placeEs = p => p===10?"decena":p===100?"centena":"millar";
874
875// ---- clock helper: h:mm arithmetic on a 12-hour face ----
876const clk = (h,m)=>{ h=((h-1)%12+12)%12+1; return h+":"+String(m).padStart(2,"0"); };
877const addMin = (h,m,plus)=>{ const t=h*60+m+plus; return clk(Math.floor(t/60), t%60); };
878
879// ---- fraction helpers ----
880const gcd = (a,b)=> b ? gcd(b,a%b) : a;
881const fr  = (n,d)=>{ const g=gcd(n,d); return (n/g)+"/"+(d/g); };      // simplified
882const frR = (n,d)=> n+"/"+d;                                            // as-is (grade 3)
883const mx  = (n,d)=>{ const g=gcd(n,d); n/=g; d/=g;
884  return n<d ? n+"/"+d : (n%d===0 ? String(n/d) : Math.floor(n/d)+" "+(n%d)+"/"+d); };
885const money = n => "$" + n.toFixed(2);
886const dinero = n => "$" + n.toFixed(2);   // US format: dual-language classrooms
887
888/* ============================================================
889   STANDARDS  —  each builder returns {q:{en,es}, a:{en,es}}
890============================================================ */
891const STANDARDS = [
892{
893  code:"K.CC.B.5", grade:"K", gradeNum:0, dok:1,
894  title:{en:"Count to answer how many",
895         es:"Contar para saber cuántos hay"},
896  text:{en:"Count to answer \"how many?\" questions about as many as 20 things arranged in a line, a rectangular array, or a circle, or as many as 10 things in a scattered configuration; given a number from 1–20, count out that many objects.",
897        es:"Cuenta para responder preguntas de \"¿cuántos hay?\" sobre hasta 20 objetos en una línea, un arreglo rectangular o un círculo, o hasta 10 objetos esparcidos; dado un número del 1 al 20, cuenta esa cantidad de objetos."},
898  build(n1,n2,lvl){
899    const it = pickItem();
900
901    /* ---- Support · DOK 1 : count to 10, in a line ---- */
902    if(lvl===1){
903      const k=ri(1,4);
904      if(k===1){
905        const a=ri(4,9);
906        return {
907          q:{en:`${n1} puts ${a} ${it.en} in a line. Draw them. How many?`,
908             es:`${n1} pone ${a} ${it.es} en una línea. ${dibujaEs(it)}. ¿${cuantosEs(it)} hay?`},
909          a:{en:`${a}`, es:`${a}`}
910        };
911      }
912      if(k===2){
913        const a=ri(5,10);
914        return {
915          q:{en:`${n1} needs ${a} ${it.en}. Draw exactly ${a}.`,
916             es:`${n1} necesita ${a} ${it.es}. Dibuja exactamente ${a}.`},
917          a:{en:`${a}`, es:`${a}`}
918        };
919      }
920      if(k===3){
921        const rows=2, per=ri(2,4);
922        return {
923          q:{en:`${n1} makes ${rows} rows of ${per} ${it.en}. Draw them. How many in all?`,
924             es:`${n1} hace ${rows} filas de ${per} ${it.es}. ${dibujaEs(it)}. ¿${cuantosEs(it)} hay en total?`},
925          a:{en:`${rows*per}`, es:`${rows*per}`}
926        };
927      }
928      const a=ri(3,8);
929      return {
930        q:{en:`${n1} counts ${a} ${it.en} in a circle. Draw the circle. How many?`,
931           es:`${n1} cuenta ${a} ${it.es} en un círculo. Dibuja el círculo. ¿${cuantosEs(it)} hay?`},
932        a:{en:`${a}`, es:`${a}`}
933      };
934    }
935
936    /* ---- Challenge · DOK 3 : count on, compare, arrange ---- */
937    if(lvl===3){
938      const k=ri(1,4);
939      if(k===1){
940        const a=ri(8,14), b=ri(2,5);
941        return {
942          q:{en:`${n1} counts ${a} ${it.en}. ${n2} brings ${b} more. Count on. How many now?`,
943             es:`${n1} cuenta ${a} ${it.es}. ${n2} trae ${b} más. Sigue contando. ¿${cuantosEs(it)} hay ahora?`},
944          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
945        };
946      }
947      if(k===2){
948        const a=ri(6,12), b=ri(6,12);
949        if(a===b) return this.build(n1,n2,lvl);
950        return {
951          q:{en:`${n1} counts ${a} ${it.en}. ${n2} counts ${b}. Who has more? How many more?`,
952             es:`${n1} cuenta ${a} ${it.es}. ${n2} cuenta ${b}. ¿Quién tiene más? ¿${cuantosEs(it)} más?`},
953          a:{en:`${a>b?n1:n2} by ${Math.abs(a-b)}`, es:`${a>b?n1:n2} por ${Math.abs(a-b)}`}
954        };
955      }
956      if(k===3){
957        const rows=ri(2,4), per=ri(3,5);
958        return {
959          q:{en:`${n1} puts ${it.en} in ${rows} rows of ${per}. Draw it. How many? Count a different way to check.`,
960             es:`${n1} pone ${it.es} en ${rows} filas de ${per}. Dibújalo. ¿${cuantosEs(it)} hay? Cuenta de otra manera para comprobar.`},
961          a:{en:`${rows*per}`, es:`${rows*per}`}
962        };
963      }
964      const a=ri(11,18);
965      return {
966        q:{en:`${n1} counted ${it.en} and said ${a}. ${n2} counted the same ones and said ${a+1}. How can they check who is right?`,
967           es:`${n1} contó ${it.es} y dijo ${a}. ${n2} contó los mismos y dijo ${a+1}. ¿Cómo pueden comprobar quién tiene razón?`},
968        a:{en:`Count again together, touching each one once`,
969           es:`Contar otra vez juntos, tocando cada uno una sola vez`}
970      };
971    }
972
973    /* ---- On level · DOK 2 : to 20 ---- */
974    const k=ri(1,4);
975    if(k===1){
976      const a=ri(11,20);
977      return {
978        q:{en:`${n1} puts ${a} ${it.en} in a line. How many ${it.en} is that?`,
979           es:`${n1} pone ${a} ${it.es} en una línea. ¿${cuantosEs(it)} ${it.es} son?`},
980        a:{en:`${a}`, es:`${a}`}
981      };
982    }
983    if(k===2){
984      const rows=ri(2,4), per=ri(3,5);
985      return {
986        q:{en:`${n1} makes ${rows} rows with ${per} ${it.en} in each row. How many in all?`,
987           es:`${n1} hace ${rows} filas con ${per} ${it.es} en cada fila. ¿${cuantosEs(it)} hay en total?`},
988        a:{en:`${rows*per}`, es:`${rows*per}`}
989      };
990    }
991    if(k===3){
992      const a=ri(12,20);
993      return {
994        q:{en:`${n2} asks ${n1} for ${a} ${it.en}. Draw exactly ${a}. Count to check.`,
995           es:`${n2} le pide a ${n1} ${a} ${it.es}. Dibuja exactamente ${a}. Cuenta para comprobar.`},
996        a:{en:`${a}`, es:`${a}`}
997      };
998    }
999    const a=ri(8,15), b=ri(2,4);
1000    return {
1001      q:{en:`${n1} has ${a} ${it.en}. ${n2} adds ${b} more. Count on to find how many.`,
1002         es:`${n1} tiene ${a} ${it.es}. ${n2} agrega ${b} más. Sigue contando para saber ${cuantosLc(it)} hay.`},
1003      a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1004    };
1005  }
1006},
1007{
1008  code:"K.MD.A.2", grade:"K", gradeNum:0, dok:2,
1009  title:{en:"Compare two objects — longer, shorter, heavier",
1010         es:"Comparar dos objetos — más largo, más corto, más pesado"},
1011  text:{en:"Directly compare two objects with a measurable attribute in common, to see which object has \"more of\"/\"less of\" the attribute, and describe the difference.",
1012        es:"Compara directamente dos objetos con un atributo medible en común, para ver cuál tiene \"más\" o \"menos\" del atributo, y describe la diferencia."},
1013  build(n1,n2,lvl){
1014    const it = pickItem();
1015
1016    /* ---- Support · DOK 1 : one clear comparison ---- */
1017    if(lvl===1){
1018      const k=ri(1,4);
1019      if(k===1){
1020        const a=ri(6,10), b=ri(2,5);
1021        return {
1022          q:{en:`${n1}'s row of ${it.en} is ${a} cubes long. ${n2}'s is ${b} cubes. Whose row is longer?`,
1023             es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} mide ${b}. ¿Cuál fila es más larga?`},
1024          a:{en:`${n1} (${a} > ${b})`, es:`${n1} (${a} > ${b})`}
1025        };
1026      }
1027      if(k===2){
1028        const a=ri(2,5), b=ri(6,10);
1029        return {
1030          q:{en:`${n1} stacks ${a} ${it.en}. ${n2} stacks ${b}. Whose stack is shorter?`,
1031             es:`${n1} apila ${a} ${it.es}. ${n2} apila ${b}. ¿Cuál pila es más baja?`},
1032          a:{en:`${n1} (${a} < ${b})`, es:`${n1} (${a} < ${b})`}
1033        };
1034      }
1035      if(k===3){
1036        const a=ri(3,8);
1037        return {
1038          q:{en:`${n1}'s line of ${it.en} is ${a} cubes long. Draw a shorter line for ${n2}.`,
1039             es:`La línea de ${it.es} de ${n1} mide ${a} cubos. Dibuja una línea más corta para ${n2}.`},
1040          a:{en:`any line less than ${a} cubes`, es:`cualquier línea menor que ${a} cubos`}
1041        };
1042      }
1043      const a=ri(4,9);
1044      return {
1045        q:{en:`${n1}'s bag of ${it.en} is heavy. ${n2}'s bag has ${a} fewer. Whose bag is lighter?`,
1046           es:`La bolsa de ${it.es} de ${n1} es pesada. La de ${n2} tiene ${a} menos. ¿Cuál bolsa es más ligera?`},
1047        a:{en:`${n2}`, es:`${n2}`}
1048      };
1049    }
1050
1051    /* ---- Challenge · DOK 3 : three objects, order, explain ---- */
1052    if(lvl===3){
1053      const k=ri(1,4);
1054      if(k===1){
1055        const a=ri(7,12), b=ri(2,6), c=ri(2,6);
1056        if(b===c) return this.build(n1,n2,lvl);
1057        return {
1058          q:{en:`${n1}'s row of ${it.en} is ${a} cubes. ${n2}'s is ${b}. A friend's is ${c}. Put them in order, shortest first.`,
1059             es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} mide ${b}. La de un amigo mide ${c}. Ponlas en orden, la más corta primero.`},
1060          a:{en:[[a,n1],[b,n2],[c,"friend"]].sort((x,y)=>x[0]-y[0]).map(x=>x[1]+" ("+x[0]+")").join(", "),
1061             es:[[a,n1],[b,n2],[c,"amigo"]].sort((x,y)=>x[0]-y[0]).map(x=>x[1]+" ("+x[0]+")").join(", ")}
1062        };
1063      }
1064      if(k===2){
1065        const a=ri(5,9), b=ri(5,9);
1066        if(a===b) return this.build(n1,n2,lvl);
1067        return {
1068          q:{en:`${n2} says a longer row of ${it.en} always has more. ${n1}'s row is ${a} cubes, ${n2}'s is ${b}. Is ${n2} right about who has more? Explain.`,
1069             es:`${n2} dice que una fila más larga de ${it.es} siempre tiene más. La fila de ${n1} mide ${a} cubos y la de ${n2} mide ${b}. ¿Tiene razón sobre quién tiene más? Explica.`},
1070          a:{en:`Yes here — ${a>b?n1:n2} has more (${Math.max(a,b)} > ${Math.min(a,b)})`,
1071             es:`Sí aquí — ${a>b?n1:n2} tiene más (${Math.max(a,b)} > ${Math.min(a,b)})`}
1072        };
1073      }
1074      if(k===3){
1075        const a=ri(6,11), diff=ri(2,4);
1076        return {
1077          q:{en:`${n1}'s row of ${it.en} is ${a} cubes. ${n2}'s row is ${diff} cubes shorter. How long is ${n2}'s row?`,
1078             es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} es ${diff} cubos más corta. ¿Cuánto mide la fila de ${n2}?`},
1079          a:{en:`${a} − ${diff} = ${a-diff} cubes`, es:`${a} − ${diff} = ${a-diff} cubos`}
1080        };
1081      }
1082      const a=ri(5,10);
1083      return {
1084        q:{en:`${n1} says a tall stack of ${it.en} is always heavier than a short one. Is that always true? Explain what else matters.`,
1085           es:`${n1} dice que una pila alta de ${it.es} siempre pesa más que una baja. ¿Es siempre cierto? Explica qué más importa.`},
1086        a:{en:`Not always — what the objects are made of matters too`,
1087           es:`No siempre — también importa de qué están hechos los objetos`}
1088      };
1089    }
1090
1091    /* ---- On level · DOK 2 ---- */
1092    const k=ri(1,4);
1093    if(k===1){
1094      const a=ri(5,12), b=ri(3,10);
1095      if(a===b) return this.build(n1,n2,lvl);
1096      return {
1097        q:{en:`${n1}'s row of ${it.en} is ${a} cubes long. ${n2}'s row is ${b} cubes. Who has the longer row? How much longer?`,
1098           es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} mide ${b}. ¿Quién tiene la fila más larga? ¿Cuánto más?`},
1099        a:{en:`${a>b?n1:n2} by ${Math.abs(a-b)} cubes`, es:`${a>b?n1:n2} por ${Math.abs(a-b)} cubos`}
1100      };
1101    }
1102    if(k===2){
1103      const a=ri(4,10), b=ri(4,10);
1104      if(a===b) return this.build(n1,n2,lvl);
1105      return {
1106        q:{en:`${n1} stacks ${a} ${it.en}. ${n2} stacks ${b}. Whose stack is taller? Draw both stacks.`,
1107           es:`${n1} apila ${a} ${it.es}. ${n2} apila ${b}. ¿Cuál pila es más alta? Dibuja las dos.`},
1108        a:{en:`${a>b?n1:n2} (${Math.max(a,b)} > ${Math.min(a,b)})`, es:`${a>b?n1:n2} (${Math.max(a,b)} > ${Math.min(a,b)})`}
1109      };
1110    }
1111    if(k===3){
1112      const a=ri(6,12), diff=ri(1,4);
1113      return {
1114        q:{en:`${n1}'s line of ${it.en} is ${a} cubes. ${n2}'s is ${diff} longer. How long is ${n2}'s line?`,
1115           es:`La línea de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} es ${diff} más larga. ¿Cuánto mide la de ${n2}?`},
1116        a:{en:`${a} + ${diff} = ${a+diff} cubes`, es:`${a} + ${diff} = ${a+diff} cubos`}
1117      };
1118    }
1119    const a=ri(5,11);
1120    return {
1121      q:{en:`${n1}'s row of ${it.en} is ${a} cubes long. Draw a row for ${n2} that is longer. How long is it?`,
1122         es:`La fila de ${it.es} de ${n1} mide ${a} cubos. Dibuja una fila más larga para ${n2}. ¿Cuánto mide?`},
1123      a:{en:`any length more than ${a} cubes`, es:`cualquier medida mayor que ${a} cubos`}
1124    };
1125  }
1126},
1127{
1128  code:"K.OA.A.1", grade:"K", gradeNum:0, dok:1,
1129  title:{en:"Show adding & taking away with drawings",
1130         es:"Mostrar sumar y quitar con dibujos"},
1131  text:{en:"Represent addition and subtraction with objects, fingers, mental images, drawings, sounds (e.g., claps), acting out situations, verbal explanations, expressions, or equations.",
1132        es:"Representa la suma y la resta con objetos, dedos, imágenes mentales, dibujos, sonidos (por ejemplo, palmadas), representaciones, explicaciones verbales, expresiones o ecuaciones."},
1133  build(n1,n2,lvl){
1134    const it = pickItem();
1135
1136    /* ---- Support · DOK 1 : within 5, draw it ---- */
1137    if(lvl===1){
1138      const k=ri(1,4);
1139      if(k===1){
1140        const a=ri(2,3), b=ri(1,2);
1141        return {
1142          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. Draw them all.`,
1143             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ${dibujaEs(it)} todos.`},
1144          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1145        };
1146      }
1147      if(k===2){
1148        const a=ri(3,5), b=ri(1,2);
1149        return {
1150          q:{en:`${n1} has ${a} ${it.en}. ${b} roll away. Draw what is left.`,
1151             es:`${n1} tiene ${a} ${it.es}. ${b} se ${b===1?"va":"van"}. ${dibujaEs(it)} ${losLasEs(it)} que quedan.`},
1152          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1153        };
1154      }
1155      if(k===3){
1156        const a=ri(2,3), b=ri(1,2);   // a>=2 keeps the noun plural
1157        return {
1158          q:{en:`${n1} draws ${a} ${it.en}. Then ${n1} draws ${b} more. How many now?`,
1159             es:`${n1} dibuja ${a} ${it.es}. Luego dibuja ${b} más. ¿${cuantosEs(it)} hay ahora?`},
1160          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1161        };
1162      }
1163      const a=ri(2,4);
1164      return {
1165        q:{en:`${n1} claps ${a} times. Draw ${a} ${it.en} to match.`,
1166           es:`${n1} da ${a} palmadas. ${dibujaEs(it)}: dibuja ${a} ${it.es}.`},
1167        a:{en:`${a}`, es:`${a}`}
1168      };
1169    }
1170
1171    /* ---- Challenge · DOK 3 : match the picture to the number sentence ---- */
1172    if(lvl===3){
1173      const k=ri(1,4);
1174      if(k===1){
1175        const a=ri(3,6), b=ri(1,3);
1176        return {
1177          q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} away. Draw it. Then write the number sentence.`,
1178             es:`${n1} tiene ${a} ${it.es}. Regala ${b}. Dibújalo. Luego escribe la operación.`},
1179          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1180        };
1181      }
1182      if(k===2){
1183        const a=ri(2,4), b=ri(2,4);
1184        return {
1185          q:{en:`${n1} drew ${a} ${it.en}. ${n2} drew ${b}. Who drew more? Draw both.`,
1186             es:`${n1} dibujó ${a} ${it.es}. ${n2} dibujó ${b}. ¿Quién dibujó más? Dibuja los dos.`},
1187          a:{en:`${a===b?"same":(a>b?n1:n2)} (${a} and ${b})`, es:`${a===b?"iguales":(a>b?n1:n2)} (${a} y ${b})`}
1188        };
1189      }
1190      if(k===3){
1191        const a=ri(2,5), b=ri(1,3);
1192        return {
1193          q:{en:`${n1} says ${a} + ${b} makes ${a+b+1}. Draw it. Is ${n1} right?`,
1194             es:`${n1} dice que ${a} + ${b} son ${a+b+1}. Dibújalo. ¿Tiene razón?`},
1195          a:{en:`No. ${a} + ${b} = ${a+b}`, es:`No. ${a} + ${b} = ${a+b}`}
1196        };
1197      }
1198      const tot=ri(4,7);
1199      return {
1200        q:{en:`${n1} has ${tot} ${it.en} in two hands. Draw one way. How many in each hand?`,
1201           es:`${n1} tiene ${tot} ${it.es} en dos manos. Dibuja una manera. ¿${cuantosEs(it)} hay en cada mano?`},
1202        a:{en:`any two that make ${tot} (e.g. ${Math.floor(tot/2)} and ${tot-Math.floor(tot/2)})`,
1203           es:`dos que sumen ${tot} (por ejemplo ${Math.floor(tot/2)} y ${tot-Math.floor(tot/2)})`}
1204      };
1205    }
1206
1207    /* ---- On level · DOK 2 : within 10 ---- */
1208    const k=ri(1,4);
1209    if(k===1){
1210      const a=ri(3,6), b=ri(2,4);
1211      return {
1212        q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. Draw them. How many?`,
1213           es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ${dibujaEs(it)}. ¿${cuantosEs(it)} hay?`},
1214        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1215      };
1216    }
1217    if(k===2){
1218      const a=ri(5,9), b=ri(2,4);
1219      return {
1220        q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} to ${n2}. Draw what is left.`,
1221           es:`${n1} tiene ${a} ${it.es}. Le da ${b} a ${n2}. ${dibujaEs(it)} ${losLasEs(it)} que quedan.`},
1222        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1223      };
1224    }
1225    if(k===3){
1226      const a=ri(2,5), b=ri(2,4);
1227      return {
1228        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b}. Draw them all. How many together?`,
1229           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b}. ${dibujaEs(it)} todos. ¿${cuantosEs(it)} hay juntos?`},
1230        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1231      };
1232    }
1233    const a=ri(4,8), b=ri(1,3);
1234    return {
1235      q:{en:`${n1} had ${a} ${it.en}. ${b} fell down. Draw the rest. How many?`,
1236         es:`${n1} tenía ${a} ${it.es}. ${b} se ${b===1?"cayó":"cayeron"}. Dibuja el resto. ¿${cuantosEs(it)} hay?`},
1237      a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1238    };
1239  }
1240},
1241{
1242  code:"K.OA.A.2", grade:"K", gradeNum:0, dok:2,
1243  title:{en:"Add & subtract within 10 — word problems",
1244         es:"Sumar y restar hasta 10 — problemas"},
1245  text:{en:"Solve addition and subtraction word problems, and add and subtract within 10, e.g., by using objects or drawings to represent the problem.",
1246        es:"Resuelve problemas verbales de suma y resta, y suma y resta hasta 10, por ejemplo, usando objetos o dibujos para representar el problema."},
1247  build(n1,n2,lvl){
1248    const it = pickItem();
1249
1250    /* ---- Support · DOK 1 : within 5, one step ---- */
1251    if(lvl===1){
1252      const k=ri(1,4);
1253      if(k===1){
1254        const a=ri(1,3), b=ri(1,2), aN = a===1 ? it.one : it;
1255        return {
1256          q:{en:`${n1} has ${a} ${aN.en}. ${n2} gives ${b} more. How many now? Draw them.`,
1257             es:`${n1} tiene ${a} ${aN.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} hay ahora? ${dibujaEs(it)}.`},
1258          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1259        };
1260      }
1261      if(k===2){
1262        const a=ri(3,5), b=ri(1,2);
1263        return {
1264          q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} to ${n2}. How many are left? Draw them.`,
1265             es:`${n1} tiene ${a} ${it.es}. ${n1} le da ${b} a ${n2}. ¿${cuantosEs(it)} quedan? ${dibujaEs(it)}.`},
1266          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1267        };
1268      }
1269      if(k===3){
1270        const a=ri(2,3), b=ri(1,2);   // a>=2 so the noun stays plural
1271        return {
1272          q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b}. How many do they have altogether? Draw them.`,
1273             es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen en total? ${dibujaEs(it)}.`},
1274          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1275        };
1276      }
1277      const a=ri(2,4), b=ri(1,2);
1278      return {
1279        q:{en:`${n1} counts ${a} ${it.en}. Then ${n1} finds ${b} more. Count on to find how many.`,
1280           es:`${n1} cuenta ${a} ${it.es}. Luego ${n1} encuentra ${b} más. Cuenta hacia adelante para saber ${cuantosLc(it)} hay.`},
1281        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1282      };
1283    }
1284
1285    /* ---- Challenge · DOK 3 : unknown in a different place ---- */
1286    if(lvl===3){
1287      const k=ri(1,4);
1288      if(k===1){
1289        const tot=ri(6,10), a=ri(2,tot-2);
1290        return {
1291          q:{en:`${n1} needs ${tot} ${it.en}. ${n1} has ${a}. How many more are needed? Show how you know.`,
1292             es:`${n1} necesita ${tot} ${it.es}. ${n1} tiene ${a}. ¿${cuantosEs(it)} más faltan? Muestra cómo lo sabes.`},
1293          a:{en:`${a} + ___ = ${tot}, so ${tot-a}`, es:`${a} + ___ = ${tot}, entonces ${tot-a}`}
1294        };
1295      }
1296      if(k===2){
1297        const tot=ri(5,10), a=ri(1,tot-1);
1298        return {
1299          q:{en:`${n1} has ${tot} ${it.en} in two bags. ${a} ${isAre(a)} in the first bag. How many are in the other bag? Draw them.`,
1300             es:`${n1} tiene ${tot} ${it.es} en dos bolsas. ${a} ${estaN(a)} en la primera bolsa. ¿${cuantosEs(it)} hay en la otra bolsa? ${dibujaEs(it)}.`},
1301          a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
1302        };
1303      }
1304      if(k===3){
1305        const start=ri(2,6), got=ri(2,4), tot=start+got;
1306        return {
1307          q:{en:`${n1} had some ${it.en}. ${n2} gave ${n1} ${got} more. Now ${n1} has ${tot}. How many did ${n1} start with? Show how you know.`,
1308             es:`${n1} tenía algunos ${it.es}. ${n2} le dio ${got} más. Ahora ${n1} tiene ${tot}. ¿Con ${cuantosLc(it)} empezó ${n1}? Muestra cómo lo sabes.`},
1309          a:{en:`___ + ${got} = ${tot}, so ${start}`, es:`___ + ${got} = ${tot}, entonces ${start}`}
1310        };
1311      }
1312      const tot=ri(6,10);
1313      return {
1314        q:{en:`${n1} wants to put ${tot} ${it.en} into two bags. Show one way to do it. How many go in each bag?`,
1315           es:`${n1} quiere poner ${tot} ${it.es} en dos bolsas. Muestra una manera de hacerlo. ¿${cuantosEs(it)} van en cada bolsa?`},
1316        a:{en:`any two numbers that make ${tot} (e.g. ${Math.floor(tot/2)} and ${tot-Math.floor(tot/2)})`,
1317           es:`dos números que sumen ${tot} (por ejemplo ${Math.floor(tot/2)} y ${tot-Math.floor(tot/2)})`}
1318      };
1319    }
1320
1321    /* ---- On level · DOK 2 : within 10 ---- */
1322    const k=ri(1,4);
1323    if(k===1){
1324      const a=ri(2,6), b=ri(1,4);
1325      return {
1326        q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many ${it.en} now?`,
1327           es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
1328        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1329      };
1330    }
1331    if(k===2){
1332      const a=ri(5,10), b=ri(1,4);
1333      return {
1334        q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} to ${n2}. How many are left?`,
1335           es:`${n1} tiene ${a} ${it.es}. ${n1} le da ${b} a ${n2}. ¿${cuantosEs(it)} quedan?`},
1336        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1337      };
1338    }
1339    if(k===3){
1340      const a=ri(2,5), b=ri(2,5);
1341      return {
1342        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many do they have altogether?`,
1343           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen en total?`},
1344        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1345      };
1346    }
1347    const on=ri(3,6), inBin=ri(2,4);
1348    return {
1349      q:{en:`${n1} sees ${on} ${it.en} on the table and ${inBin} more in a bag. How many ${it.en} in all?`,
1350         es:`${n1} ve ${on} ${it.es} en la mesa y ${inBin} más en una bolsa. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1351      a:{en:`${on} + ${inBin} = ${on+inBin}`, es:`${on} + ${inBin} = ${on+inBin}`}
1352    };
1353  }
1354},
1355{
1356  code:"K.OA.A.3", grade:"K", gradeNum:0, dok:2,
1357  title:{en:"Break numbers into two parts",
1358         es:"Separar números en dos partes"},
1359  text:{en:"Decompose numbers less than or equal to 10 into pairs in more than one way, e.g., by using objects or drawings, and record each decomposition by a drawing or equation.",
1360        es:"Descompón números menores o iguales a 10 en pares de más de una manera, por ejemplo, usando objetos o dibujos, y registra cada descomposición con un dibujo o una e
1360cuación."},
1361  build(n1,n2,lvl){
1362    const it = pickItem();
1363
1364    /* ---- Support · DOK 1 : one part shown ---- */
1365    if(lvl===1){
1366      const k=ri(1,4);
1367      if(k===1){
1368        const tot=ri(3,5), a=ri(1,tot-1);
1369        return {
1370          q:{en:`${n1} has ${tot} ${it.en}. ${a} are in the box. Draw the rest.`,
1371             es:`${n1} tiene ${tot} ${it.es}. ${a} están en la caja. Dibuja el resto.`},
1372          a:{en:`${a} and ${tot-a}`, es:`${a} y ${tot-a}`}
1373        };
1374      }
1375      if(k===2){
1376        const tot=ri(4,6), a=ri(1,tot-1);
1377        return {
1378          q:{en:`${n1} holds ${tot} ${it.en}. ${a} are in one hand. How many in the other?`,
1379             es:`${n1} tiene ${tot} ${it.es}. ${a} están en una mano. ¿${cuantosEs(it)} hay en la otra?`},
1380          a:{en:`${tot-a}`, es:`${tot-a}`}
1381        };
1382      }
1383      if(k===3){
1384        const tot=5, a=ri(1,4);
1385        return {
1386          q:{en:`${n1} has ${tot} ${it.en}. ${a} are red. The rest are blue. How many are blue?`,
1387             es:`${n1} tiene ${tot} ${it.es}. ${a} son rojos. El resto son azules. ¿${cuantosEs(it)} son azules?`},
1388          a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
1389        };
1390      }
1391      const tot=ri(3,5);
1392      return {
1393        q:{en:`${n1} puts ${tot} ${it.en} in two piles. Draw one way.`,
1394           es:`${n1} pone ${tot} ${it.es} en dos montones. Dibuja una manera.`},
1395        a:{en:`any pair that makes ${tot} (e.g. 1 and ${tot-1})`,
1396           es:`cualquier par que sume ${tot} (por ejemplo 1 y ${tot-1})`}
1397      };
1398    }
1399
1400    /* ---- Challenge · DOK 3 : more than one way ---- */
1401    if(lvl===3){
1402      const k=ri(1,4);
1403      if(k===1){
1404        const tot=ri(6,9);
1405        return {
1406          q:{en:`${n1} has ${tot} ${it.en}. Show TWO different ways to split them into two piles.`,
1407             es:`${n1} tiene ${tot} ${it.es}. Muestra DOS maneras distintas de ponerlos en dos montones.`},
1408          a:{en:`e.g. 1 and ${tot-1}; 2 and ${tot-2}`, es:`por ejemplo 1 y ${tot-1}; 2 y ${tot-2}`}
1409        };
1410      }
1411      if(k===2){
1412        const tot=ri(6,10), a=ri(2,tot-2);
1413        return {
1414          q:{en:`${n1} says ${a} and ${tot-a-1} make ${tot}. Draw it. Is ${n1} right? Fix it if not.`,
1415             es:`${n1} dice que ${a} y ${tot-a-1} son ${tot}. Dibújalo. ¿Tiene razón? Arréglalo si no.`},
1416          a:{en:`No — ${a} and ${tot-a} make ${tot}`, es:`No — ${a} y ${tot-a} son ${tot}`}
1417        };
1418      }
1419      if(k===3){
1420        const tot=ri(6,8);
1421        return {
1422          q:{en:`${n1} and ${n2} share ${tot} ${it.en}. They must get the same amount. How many each?`,
1423             es:`${n1} y ${n2} comparten ${tot} ${it.es}. Deben recibir lo mismo. ¿${cuantosEs(it)} recibe cada uno?`},
1424          a:{en:`${tot%2===0 ? (tot/2)+" each" : "cannot split "+tot+" evenly"}`,
1425             es:`${tot%2===0 ? (tot/2)+" cada uno" : "no se puede repartir "+tot+" en partes iguales"}`}
1426        };
1427      }
1428      const tot=ri(7,10), a=ri(2,tot-2);
1429      return {
1430        q:{en:`${n1} has ${tot} ${it.en}. ${a} are in the bag. Write the number sentence for the rest.`,
1431           es:`${n1} tiene ${tot} ${it.es}. ${a} están en la bolsa. Escribe la operación para el resto.`},
1432        a:{en:`${a} + ${tot-a} = ${tot}`, es:`${a} + ${tot-a} = ${tot}`}
1433      };
1434    }
1435
1436    /* ---- On level · DOK 2 : within 10 ---- */
1437    const k=ri(1,4);
1438    if(k===1){
1439      const tot=ri(6,10), a=ri(1,tot-1);
1440      return {
1441        q:{en:`${n1} has ${tot} ${it.en}. ${a} are on the desk. How many are in the bag?`,
1442           es:`${n1} tiene ${tot} ${it.es}. ${a} están en el pupitre. ¿${cuantosEs(it)} hay en la bolsa?`},
1443        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
1444      };
1445    }
1446    if(k===2){
1447      const tot=ri(6,10), a=ri(2,tot-2);
1448      return {
1449        q:{en:`${n1} splits ${tot} ${it.en} with ${n2}. ${n1} takes ${a}. How many does ${n2} get?`,
1450           es:`${n1} reparte ${tot} ${it.es} con ${n2}. ${n1} toma ${a}. ¿${cuantosEs(it)} recibe ${n2}?`},
1451        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
1452      };
1453    }
1454    if(k===3){
1455      const tot=ri(5,9);
1456      return {
1457        q:{en:`${n1} puts ${tot} ${it.en} in two boxes. Draw one way. Write the numbers.`,
1458           es:`${n1} pone ${tot} ${it.es} en dos cajas. Dibuja una manera. Escribe los números.`},
1459        a:{en:`any pair that makes ${tot} (e.g. ${Math.floor(tot/2)} and ${tot-Math.floor(tot/2)})`,
1460           es:`cualquier par que sume ${tot} (por ejemplo ${Math.floor(tot/2)} y ${tot-Math.floor(tot/2)})`}
1461      };
1462    }
1463    const tot=ri(6,10), a=ri(2,tot-2);
1464    return {
1465      q:{en:`${n1} has ${tot} ${it.en}. ${a} are big. The rest are small. How many are small?`,
1466         es:`${n1} tiene ${tot} ${it.es}. ${a} son grandes. El resto son pequeños. ¿${cuantosEs(it)} son pequeños?`},
1467      a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
1468    };
1469  }
1470},
1471{
1472  code:"K.OA.A.4", grade:"K", gradeNum:0, dok:2,
1473  title:{en:"Make 10",
1474         es:"Formar 10"},
1475  text:{en:"For any number from 1 to 9, find the number that makes 10 when added to the given number, e.g., by using objects or drawings, and record the answer with a drawing or equation.",
1476        es:"Para cualquier número del 1 al 9, halla el número que forma 10 al sumarse al número dado, por ejemplo, usando objetos o dibujos, y registra la respuesta con un dibujo o una ecuación."},
1477  build(n1,n2,lvl){
1478    const it = pickItem();
1479
1480    /* ---- Support · DOK 1 : small starting numbers ---- */
1481    if(lvl===1){
1482      const k=ri(1,4);
1483      if(k===1){
1484        const a=ri(6,9);
1485        return {
1486          q:{en:`${n1} has ${a} ${it.en}. ${n1} needs 10. Draw how many more.`,
1487             es:`${n1} tiene ${a} ${it.es}. Necesita 10. Dibuja ${cuantosLc(it)} más faltan.`},
1488          a:{en:`${a} + ${10-a} = 10`, es:`${a} + ${10-a} = 10`}
1489        };
1490      }
1491      if(k===2){
1492        const a=ri(7,9);
1493        return {
1494          q:{en:`${n1} counts ${a} ${it.en}. How many more make 10?`,
1495             es:`${n1} cuenta ${a} ${it.es}. ¿${cuantosEs(it)} más faltan para 10?`},
1496          a:{en:`${10-a}`, es:`${10-a}`}
1497        };
1498      }
1499      if(k===3){
1500        const a=5;
1501        return {
1502          q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${a} too. How many together?`,
1503             es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${a} también. ¿${cuantosEs(it)} hay juntos?`},
1504          a:{en:`${a} + ${a} = 10`, es:`${a} + ${a} = 10`}
1505        };
1506      }
1507      const a=ri(6,8);
1508      return {
1509        q:{en:`${n1} put ${a} ${it.en} in a ten frame. How many boxes are empty?`,
1510           es:`${n1} puso ${a} ${it.es} en un marco de diez. ¿Cuántas casillas están vacías?`},
1511        a:{en:`${10-a}`, es:`${10-a}`}
1512      };
1513    }
1514
1515    /* ---- Challenge · DOK 3 ---- */
1516    if(lvl===3){
1517      const k=ri(1,4);
1518      if(k===1){
1519        const a=ri(2,8);
1520        return {
1521          q:{en:`${n1} says ${a} and ${10-a+1} make 10. Draw it. Is ${n1} right? Fix it if not.`,
1522             es:`${n1} dice que ${a} y ${10-a+1} son 10. Dibújalo. ¿Tiene razón? Arréglalo si no.`},
1523          a:{en:`No — ${a} + ${10-a} = 10`, es:`No — ${a} + ${10-a} = 10`}
1524        };
1525      }
1526      if(k===2){
1527        const a=ri(3,7), b=ri(1,10-a-1);
1528        return {
1529          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many more to make 10?`,
1530             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} más faltan para 10?`},
1531          a:{en:`${a}+${b}=${a+b}, needs ${10-a-b}`, es:`${a}+${b}=${a+b}, faltan ${10-a-b}`}
1532        };
1533      }
1534      if(k===3){
1535        const a=ri(2,8);
1536        return {
1537          q:{en:`${n1} needs 10 ${it.en} and has ${a}. ${n2} needs 10 and has ${10-a}. Who needs more?`,
1538             es:`${n1} necesita 10 ${it.es} y tiene ${a}. ${n2} necesita 10 y tiene ${10-a}. ¿Quién necesita más?`},
1539          a:{en:`${a===5?"same":(a<10-a?n1:n2)} (needs ${Math.max(10-a,a)})`,
1540             es:`${a===5?"iguales":(a<10-a?n1:n2)} (faltan ${Math.max(10-a,a)})`}
1541        };
1542      }
1543      const a=ri(3,7);
1544      return {
1545        q:{en:`${n1} has ${a} ${it.en}. Write the number sentence that makes 10. Then draw it.`,
1546           es:`${n1} tiene ${a} ${it.es}. Escribe la operación que forma 10. Luego dibújala.`},
1547        a:{en:`${a} + ${10-a} = 10`, es:`${a} + ${10-a} = 10`}
1548      };
1549    }
1550
1551    /* ---- On level · DOK 2 ---- */
1552    const k=ri(1,4);
1553    if(k===1){
1554      const a=ri(2,9);
1555      return {
1556        q:{en:`${n1} has ${a} ${it.en}. How many more make 10?`,
1557           es:`${n1} tiene ${a} ${it.es}. ¿${cuantosEs(it)} más faltan para 10?`},
1558        a:{en:`${a} + ${10-a} = 10`, es:`${a} + ${10-a} = 10`}
1559      };
1560    }
1561    if(k===2){
1562      const a=ri(2,9);
1563      return {
1564        q:{en:`${n1} wants 10 ${it.en}. ${n1} has ${a}. How many does ${n2} need to give?`,
1565           es:`${n1} quiere 10 ${it.es}. Tiene ${a}. ¿${cuantosEs(it)} le debe dar ${n2}?`},
1566        a:{en:`${10-a}`, es:`${10-a}`}
1567      };
1568    }
1569    if(k===3){
1570      const a=ri(3,8);
1571      return {
1572        q:{en:`${n1} filled ${a} spots in a ten frame with ${it.en}. How many spots are left?`,
1573           es:`${n1} llenó ${a} casillas de un marco de diez con ${it.es}. ¿Cuántas casillas quedan?`},
1574        a:{en:`${10-a}`, es:`${10-a}`}
1575      };
1576    }
1577    const a=ri(2,8);
1578    return {
1579      q:{en:`${n1} and ${n2} want 10 ${it.en} in all. ${n1} brings ${a}. How many does ${n2} bring?`,
1580         es:`${n1} y ${n2} quieren 10 ${it.es} en total. ${n1} trae ${a}. ¿${cuantosEs(it)} trae ${n2}?`},
1581      a:{en:`${a} + ${10-a} = 10`, es:`${a} + ${10-a} = 10`}
1582    };
1583  }
1584},
1585{
1586  code:"1.MD.A.1", grade:1, dok:2,
1587  title:{en:"Order & compare lengths",
1588         es:"Ordenar y comparar longitudes"},
1589  text:{en:"Order three objects by length; compare the lengths of two objects indirectly by using a third object.",
1590        es:"Ordena tres objetos por longitud; compara las longitudes de dos objetos indirectamente usando un tercer objeto."},
1591  build(n1,n2,lvl){
1592    const it = pickItem();
1593
1594    /* ---- Support · DOK 1 : two objects, clear gap ---- */
1595    if(lvl===1){
1596      const k=ri(1,4);
1597      if(k===1){
1598        const a=ri(7,12), b=ri(2,5);
1599        return {
1600          q:{en:`${n1}'s row of ${it.en} is ${a} cubes long. ${n2}'s is ${b} cubes. Whose row is longer?`,
1601             es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} mide ${b}. ¿Cuál fila es más larga?`},
1602          a:{en:`${n1} (${a} > ${b})`, es:`${n1} (${a} > ${b})`}
1603        };
1604      }
1605      if(k===2){
1606        const a=ri(3,6), b=ri(8,12);
1607        return {
1608          q:{en:`${n1} lines up ${a} ${it.en}. ${n2} lines up ${b}. Whose line is shorter?`,
1609             es:`${n1} alinea ${a} ${it.es}. ${n2} alinea ${b}. ¿Cuál línea es más corta?`},
1610          a:{en:`${n1} (${a} < ${b})`, es:`${n1} (${a} < ${b})`}
1611        };
1612      }
1613      if(k===3){
1614        const a=ri(5,10), d=ri(2,4);
1615        return {
1616          q:{en:`${n1}'s strip is ${a} cubes long. ${n2}'s is ${d} cubes longer. How long is ${n2}'s strip?`,
1617             es:`La tira de ${n1} mide ${a} cubos. La de ${n2} es ${d} cubos más larga. ¿Cuánto mide la de ${n2}?`},
1618          a:{en:`${a} + ${d} = ${a+d} cubes`, es:`${a} + ${d} = ${a+d} cubos`}
1619        };
1620      }
1621      const a=ri(6,11);
1622      return {
1623        q:{en:`${n1}'s line of ${it.en} is ${a} cubes long. Draw a shorter line for ${n2}. How long is it?`,
1624           es:`La línea de ${it.es} de ${n1} mide ${a} cubos. Dibuja una línea más corta para ${n2}. ¿Cuánto mide?`},
1625        a:{en:`any length less than ${a} cubes`, es:`cualquier medida menor que ${a} cubos`}
1626      };
1627    }
1628
1629    /* ---- Challenge · DOK 3 : indirect comparison ---- */
1630    if(lvl===3){
1631      const k=ri(1,4);
1632      if(k===1){
1633        const a=ri(9,14), b=ri(6,8), c=ri(2,5);
1634        return {
1635          q:{en:`${n1}'s row of ${it.en} is longer than ${n2}'s. ${n2}'s is longer than a friend's. Who has the longest row? Explain without measuring.`,
1636             es:`La fila de ${it.es} de ${n1} es más larga que la de ${n2}. La de ${n2} es más larga que la de un amigo. ¿Quién tiene la fila más larga? Explica sin medir.`},
1637          a:{en:`${n1} — if ${n1} > ${n2} and ${n2} > friend, then ${n1} is longest`,
1638             es:`${n1} — si ${n1} > ${n2} y ${n2} > amigo, entonces ${n1} es la más larga`}
1639        };
1640      }
1641      if(k===2){
1642        const a=ri(8,14), b=ri(3,7), c=ri(3,7);
1643        if(b===c) return this.build(n1,n2,lvl);
1644        return {
1645          q:{en:`Three strips: ${n1}'s is ${a} cubes, ${n2}'s is ${b}, a friend's is ${c}. Put them in order from shortest to longest.`,
1646             es:`Tres tiras: la de ${n1} mide ${a} cubos, la de ${n2} mide ${b}, la de un amigo mide ${c}. Ponlas en orden de la más corta a la más larga.`},
1647          a:{en:[[a,n1],[b,n2],[c,"friend"]].sort((x,y)=>x[0]-y[0]).map(x=>x[1]+" ("+x[0]+")").join(", "),
1648             es:[[a,n1],[b,n2],[c,"amigo"]].sort((x,y)=>x[0]-y[0]).map(x=>x[1]+" ("+x[0]+")").join(", ")}
1649        };
1650      }
1651      if(k===3){
1652        const a=ri(10,16), d=ri(3,6);
1653        return {
1654          q:{en:`${n1}'s row of ${it.en} is ${a} cubes. ${n2}'s is ${d} cubes shorter. A friend's is 2 cubes longer than ${n2}'s. How long is the friend's row?`,
1655             es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} es ${d} más corta. La de un amigo es 2 cubos más larga que la de ${n2}. ¿Cuánto mide la del amigo?`},
1656          a:{en:`${a}−${d}=${a-d}, +2 = ${a-d+2} cubes`, es:`${a}−${d}=${a-d}, +2 = ${a-d+2} cubos`}
1657        };
1658      }
1659      const a=ri(8,13);
1660      return {
1661        q:{en:`${n2} says a row with more ${it.en} is always longer. ${n1} says the ${it.en} must be the same size first. Who is right? Explain.`,
1662           es:`${n2} dice que una fila con más ${it.es} siempre es más larga. ${n1} dice que primero deben ser del mismo tamaño. ¿Quién tiene razón? Explica.`},
1663        a:{en:`${n1} — the units must match to compare fairly`,
1664           es:`${n1} — las unidades deben ser iguales para comparar bien`}
1665      };
1666    }
1667
1668    /* ---- On level · DOK 2 ---- */
1669    const k=ri(1,4);
1670    if(k===1){
1671      const a=ri(6,14), b=ri(4,12);
1672      if(a===b) return this.build(n1,n2,lvl);
1673      return {
1674        q:{en:`${n1}'s row of ${it.en} is ${a} cubes. ${n2}'s is ${b} cubes. Who has the longer row? How much longer?`,
1675           es:`La fila de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} mide ${b}. ¿Quién tiene la fila más larga? ¿Cuánto más?`},
1676        a:{en:`${a>b?n1:n2} by ${Math.abs(a-b)} cubes`, es:`${a>b?n1:n2} por ${Math.abs(a-b)} cubos`}
1677      };
1678    }
1679    if(k===2){
1680      const a=ri(7,13), b=ri(4,9), c=ri(4,9);
1681      if(b===c) return this.build(n1,n2,lvl);
1682      return {
1683        q:{en:`${n1}'s strip is ${a} cubes, ${n2}'s is ${b}, and a friend's is ${c}. Which strip is longest?`,
1684           es:`La tira de ${n1} mide ${a} cubos, la de ${n2} mide ${b} y la de un amigo mide ${c}. ¿Cuál tira es la más larga?`},
1685        a:{en:`${Math.max(a,b,c)===a?n1:(Math.max(a,b,c)===b?n2:"friend")} (${Math.max(a,b,c)})`,
1686           es:`${Math.max(a,b,c)===a?n1:(Math.max(a,b,c)===b?n2:"amigo")} (${Math.max(a,b,c)})`}
1687      };
1688    }
1689    if(k===3){
1690      const a=ri(8,15), d=ri(2,5);
1691      return {
1692        q:{en:`${n1}'s line of ${it.en} is ${a} cubes long. ${n2}'s is ${d} cubes shorter. How long is ${n2}'s line?`,
1693           es:`La línea de ${it.es} de ${n1} mide ${a} cubos. La de ${n2} es ${d} cubos más corta. ¿Cuánto mide la de ${n2}?`},
1694        a:{en:`${a} − ${d} = ${a-d} cubes`, es:`${a} − ${d} = ${a-d} cubos`}
1695      };
1696    }
1697    const a=ri(6,12), d=ri(2,5);
1698    return {
1699      q:{en:`${n1} and ${n2} line up ${it.en}. ${n1}'s line is ${a} cubes. ${n2}'s is ${d} longer. How long is ${n2}'s line?`,
1700         es:`${n1} y ${n2} alinean ${it.es}. La línea de ${n1} mide ${a} cubos. La de ${n2} es ${d} más larga. ¿Cuánto mide la de ${n2}?`},
1701      a:{en:`${a} + ${d} = ${a+d} cubes`, es:`${a} + ${d} = ${a+d} cubos`}
1702    };
1703  }
1704},
1705{
1706  code:"1.NBT.C.4", grade:1, dok:2,
1707  title:{en:"Add within 100 — tens and ones",
1708         es:"Sumar hasta 100 — decenas y unidades"},
1709  text:{en:"Add within 100, including adding a two-digit number and a one-digit number, and adding a two-digit number and a multiple of 10, using concrete models or drawings and strategies based on place value.",
1710        es:"Suma hasta 100, incluyendo sumar un número de dos dígitos y uno de un dígito, y sumar un número de dos dígitos y un múltiplo de 10, usando modelos concretos o dibujos y estrategias basadas en el valor posicional."},
1711  build(n1,n2,lvl){
1712    const it = pickItem();
1713
1714    /* ---- Support · DOK 1 : no regrouping ---- */
1715    if(lvl===1){
1716      const k=ri(1,4);
1717      if(k===1){
1718        const tens=ri(2,4)*10, a=ri(2,7), b=ri(1,2);
1719        return {
1720          q:{en:`${n1} has ${tens+a} ${it.en}. ${n2} gives ${b} more. How many now?`,
1721             es:`${n1} tiene ${tens+a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} hay ahora?`},
1722          a:{en:`${tens+a} + ${b} = ${tens+a+b}`, es:`${tens+a} + ${b} = ${tens+a+b}`}
1723        };
1724      }
1725      if(k===2){
1726        const a=ri(21,45), tens=ri(1,3)*10;
1727        return {
1728          q:{en:`${n1} counts ${a} ${it.en}. ${n2} brings ${tens} more. How many ${it.en} in all?`,
1729             es:`${n1} cuenta ${a} ${it.es}. ${n2} trae ${tens} más. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1730          a:{en:`${a} + ${tens} = ${a+tens}`, es:`${a} + ${tens} = ${a+tens}`}
1731        };
1732      }
1733      if(k===3){
1734        const t1=ri(2,4)*10, t2=ri(2,4)*10;
1735        return {
1736          q:{en:`${n1} has ${t1} ${it.en} and ${n2} has ${t2}. How many do they have together?`,
1737             es:`${n1} tiene ${t1} ${it.es} y ${n2} tiene ${t2}. ¿${cuantosEs(it)} tienen juntos?`},
1738          a:{en:`${t1} + ${t2} = ${t1+t2}`, es:`${t1} + ${t2} = ${t1+t2}`}
1739        };
1740      }
1741      const tens=ri(2,5)*10, ones=ri(2,6);
1742      return {
1743        q:{en:`${n1} has ${tens} ${it.en} in bags and ${ones} loose. How many ${it.en} in all?`,
1744           es:`${n1} tiene ${tens} ${it.es} en bolsas y ${ones} sueltos. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1745        a:{en:`${tens} + ${ones} = ${tens+ones}`, es:`${tens} + ${ones} = ${tens+ones}`}
1746      };
1747    }
1748
1749    /* ---- Challenge · DOK 3 : regrouping, explain, missing part ---- */
1750    if(lvl===3){
1751      const k=ri(1,4);
1752      if(k===1){
1753        const a=ri(26,58), b=ri(5,9);
1754        return {
1755          q:{en:`${n1} has ${a} ${it.en} and gets ${b} more. Adding the ones makes a new ten. Explain what happens, then give the total.`,
1756             es:`${n1} tiene ${a} ${it.es} y recibe ${b} más. Al sumar las unidades se forma una decena nueva. Explica qué pasa y da el total.`},
1757          a:{en:`${a%10}+${b}=${a%10+b} → regroup one ten; ${a} + ${b} = ${a+b}`,
1758             es:`${a%10}+${b}=${a%10+b} → se reagrupa una decena; ${a} + ${b} = ${a+b}`}
1759        };
1760      }
1761      if(k===2){
1762        const tot=ri(50,90), a=ri(20,tot-20);
1763        return {
1764          q:{en:`${n1} and ${n2} need ${tot} ${it.en}. ${n1} brings ${a}. How many must ${n2} bring? Show how you know.`,
1765             es:`${n1} y ${n2} necesitan ${tot} ${it.es}. ${n1} trae ${a}. ¿${cuantosEs(it)} debe traer ${n2}? Muestra cómo lo sabes.`},
1766          a:{en:`${a} + ___ = ${tot}, so ${tot-a}`, es:`${a} + ___ = ${tot}, entonces ${tot-a}`}
1767        };
1768      }
1769      if(k===3){
1770        const a=ri(23,47), tens=ri(2,4)*10;
1771        return {
1772          q:{en:`${n2} says ${a} + ${tens} changes the ones digit. Is ${n2} right? Add and explain which digits change.`,
1773             es:`${n2} dice que ${a} + ${tens} cambia el dígito de las unidades. ¿Tiene razón? Suma y explica cuáles dígitos cambian.`},
1774          a:{en:`No — only the tens change: ${a} + ${tens} = ${a+tens}`,
1775             es:`No — solo cambian las decenas: ${a} + ${tens} = ${a+tens}`}
1776        };
1777      }
1778      const a=ri(24,46), b=ri(6,9), c=ri(10,30);
1779      return {
1780        q:{en:`${n1} had ${a} ${it.en}, found ${b} more, then ${n2} gave ${c}. How many now? Show both steps.`,
1781           es:`${n1} tenía ${a} ${it.es}, encontró ${b} más y luego ${n2} le dio ${c}. ¿${cuantosEs(it)} hay ahora? Muestra los dos pasos.`},
1782        a:{en:`${a}+${b}=${a+b}, +${c} = ${a+b+c}`, es:`${a}+${b}=${a+b}, +${c} = ${a+b+c}`}
1783      };
1784    }
1785
1786    /* ---- On level · DOK 2 ---- */
1787    const k=ri(1,4);
1788    if(k===1){
1789      const a=ri(23,68), b=ri(3,9);
1790      return {
1791        q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many ${it.en} does ${n1} have now?`,
1792           es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} ${it.es} tiene ahora?`},
1793        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1794      };
1795    }
1796    if(k===2){
1797      const a=ri(24,58), tens=ri(2,4)*10;
1798      return {
1799        q:{en:`${n1} counted ${a} ${it.en}. ${n2} brought ${tens} more. How many ${it.en} in all?`,
1800           es:`${n1} contó ${a} ${it.es}. ${n2} trajo ${tens} más. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1801        a:{en:`${a} + ${tens} = ${a+tens}`, es:`${a} + ${tens} = ${a+tens}`}
1802      };
1803    }
1804    if(k===3){
1805      const a=ri(20,45), b=ri(20,45);
1806      return {
1807        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many do they have altogether?`,
1808           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen en total?`},
1809        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1810      };
1811    }
1812    const tens=ri(3,6)*10, ones=ri(3,9);
1813    return {
1814      q:{en:`${n1} has ${tens} ${it.en} in bags and ${n2} adds ${ones} loose ones. How many ${it.en} in all?`,
1815         es:`${n1} tiene ${tens} ${it.es} en bolsas y ${n2} agrega ${ones} sueltos. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1816      a:{en:`${tens} + ${ones} = ${tens+ones}`, es:`${tens} + ${ones} = ${tens+ones}`}
1817    };
1818  }
1819},
1820{
1821  code:"1.NBT.C.6", grade:1, dok:2,
1822  title:{en:"Subtract multiples of 10",
1823         es:"Restar múltiplos de 10"},
1824  text:{en:"Subtract multiples of 10 in the range 10–90 from multiples of 10 in the range 10–90 (positive or zero differences), using concrete models or drawings and strategies based on place value.",
1825        es:"Resta múltiplos de 10 del rango 10–90 de múltiplos de 10 del rango 10–90 (diferencias positivas o cero), usando modelos concretos o dibujos y estrategias basadas en el valor posicional."},
1826  build(n1,n2,lvl){
1827    const it = pickItem();
1828
1829    /* ---- Support · DOK 1 : small tens ---- */
1830    if(lvl===1){
1831      const k=ri(1,4);
1832      if(k===1){
1833        const a=ri(3,6)*10, b=ri(1,2)*10;
1834        return {
1835          q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} to ${n2}. How many are left?`,
1836             es:`${n1} tiene ${a} ${it.es}. Le da ${b} a ${n2}. ¿${cuantosEs(it)} quedan?`},
1837          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1838        };
1839      }
1840      if(k===2){
1841        const a=ri(4,7)*10, b=ri(1,3)*10;
1842        return {
1843          q:{en:`${n1} counted ${a} ${it.en}. ${b} were used. How many ${it.en} are left?`,
1844             es:`${n1} contó ${a} ${it.es}. Se usaron ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
1845          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1846        };
1847      }
1848      if(k===3){
1849        const a=ri(2,5)*10;
1850        return {
1851          q:{en:`${n1} has ${a} ${it.en} and gives all ${a} away. How many are left? Count by tens to check.`,
1852             es:`${n1} tiene ${a} ${it.es} y regala los ${a}. ¿${cuantosEs(it)} quedan? Cuenta de diez en diez para comprobar.`},
1853          a:{en:`${a} − ${a} = 0`, es:`${a} − ${a} = 0`}
1854        };
1855      }
1856      const a=ri(3,6)*10, b=10;
1857      return {
1858        q:{en:`${n1} has ${a} ${it.en}. ${n2} takes one bag of ${b}. How many ${it.en} are left?`,
1859           es:`${n1} tiene ${a} ${it.es}. ${n2} toma una bolsa de ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
1860        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1861      };
1862    }
1863
1864    /* ---- Challenge · DOK 3 ---- */
1865    if(lvl===3){
1866      const k=ri(1,4);
1867      if(k===1){
1868        const a=ri(5,9)*10, b=ri(2,4)*10;
1869        return {
1870          q:{en:`${n2} says ${a} − ${b} is ${a-b+10}. Count back by tens to check. Is ${n2} right?`,
1871             es:`${n2} dice que ${a} − ${b} es ${a-b+10}. Cuenta hacia atrás de diez en diez para comprobar. ¿Tiene razón?`},
1872          a:{en:`No — ${a} − ${b} = ${a-b}`, es:`No — ${a} − ${b} = ${a-b}`}
1873        };
1874      }
1875      if(k===2){
1876        const a=ri(6,9)*10, left=ri(1,4)*10;
1877        return {
1878          q:{en:`${n1} had ${a} ${it.en} and now has ${left}. How many did ${n1} give ${n2}? Show how you know.`,
1879             es:`${n1} tenía ${a} ${it.es} y ahora tiene ${left}. ¿${cuantosEs(it)} le dio a ${n2}? Muestra cómo lo sabes.`},
1880          a:{en:`${a} − ___ = ${left}, so ${a-left}`, es:`${a} − ___ = ${left}, entonces ${a-left}`}
1881        };
1882      }
1883      if(k===3){
1884        const a=ri(6,9)*10, b=ri(1,2)*10, c=ri(1,2)*10;
1885        return {
1886          q:{en:`${n1} has ${a} ${it.en}, gives ${b} to ${n2}, then gives ${c} more away. How many are left? Show both steps.`,
1887             es:`${n1} tiene ${a} ${it.es}, le da ${b} a ${n2} y luego regala ${c} más. ¿${cuantosEs(it)} quedan? Muestra los dos pasos.`},
1888          a:{en:`${a}−${b}=${a-b}, −${c} = ${a-b-c}`, es:`${a}−${b}=${a-b}, −${c} = ${a-b-c}`}
1889        };
1890      }
1891      const a=ri(5,8)*10, b=ri(2,4)*10;
1892      return {
1893        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more does ${n1} have? Explain using tens.`,
1894           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} más tiene ${n1}? Explica usando decenas.`},
1895        a:{en:`${a} − ${b} = ${a-b} (${(a-b)/10} tens)`, es:`${a} − ${b} = ${a-b} (${(a-b)/10} decenas)`}
1896      };
1897    }
1898
1899    /* ---- On level · DOK 2 ---- */
1900    const k=ri(1,4);
1901    if(k===1){
1902      const a=ri(4,9)*10, b=ri(1,3)*10;
1903      return {
1904        q:{en:`${n1} has ${a} ${it.en}. ${n1} gives ${b} to ${n2}. How many ${it.en} are left?`,
1905           es:`${n1} tiene ${a} ${it.es}. Le da ${b} a ${n2}. ¿${cuantosEs(it)} ${it.es} quedan?`},
1906        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1907      };
1908    }
1909    if(k===2){
1910      const a=ri(5,9)*10, b=ri(2,4)*10;
1911      return {
1912        q:{en:`${n1} counted ${a} ${it.en}. ${b} were packed away by ${n2}. How many are left out?`,
1913           es:`${n1} contó ${a} ${it.es}. ${n2} guardó ${b}. ¿${cuantosEs(it)} quedan afuera?`},
1914        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1915      };
1916    }
1917    if(k===3){
1918      const a=ri(4,9)*10, b=ri(1,3)*10;
1919      return {
1920        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more ${it.en} does ${n1} have?`,
1921           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} ${it.es} más tiene ${n1}?`},
1922        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1923      };
1924    }
1925    const a=ri(5,9)*10, left=ri(1,3)*10;
1926    return {
1927      q:{en:`${n1} started with ${a} ${it.en} and now has ${left}. How many ${it.en} did ${n1} give away?`,
1928         es:`${n1} empezó con ${a} ${it.es} y ahora tiene ${left}. ¿${cuantosEs(it)} ${it.es} regaló?`},
1929      a:{en:`${a} − ${left} = ${a-left}`, es:`${a} − ${left} = ${a-left}`}
1930    };
1931  }
1932},
1933{
1934  code:"1.OA.A.1", grade:1, gradeNum:1, dok:2, _k:5,
1935  title:{en:"Add & subtract within 20 — word problems",
1936         es:"Sumar y restar hasta 20 — problemas"},
1937  text:{en:"Use addition and subtraction within 20 to solve word problems involving situations of adding to, taking from, putting together, taking apart, and comparing, with unknowns in all positions, e.g., by using objects, drawings, and equations with a symbol for the unknown number to represent the problem.",
1938        es:"Usa la suma y la resta hasta 20 para resolver problemas verbales de agregar, quitar, juntar, separar y comparar, con incógnitas en todas las posiciones, por ejemplo, usando objetos, dibujos y ecuaciones con un símbolo para el número desconocido."},
1939  build(n1,n2,lvl){
1940    const it = pickItem();
1941    let kind = ri(1,5);   // feeds Challenge (5 templates); On-level reassigns
1942
1943    /* ---- Support · DOK 1 : within 10 ---- */
1944    if(lvl===1){
1945      const k=ri(1,4);
1946      if(k===1){
1947        const a=ri(2,6), b=ri(2,4);
1948        return {
1949          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many ${it.en} in all?`,
1950             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} ${it.es} hay en total?`},
1951          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1952        };
1953      }
1954      if(k===2){
1955        const a=ri(6,10), b=ri(2,5);
1956        return {
1957          q:{en:`${n1} had ${a} ${it.en} and used ${b}. How many are left?`,
1958             es:`${n1} tenía ${a} ${it.es} y usó ${b}. ¿${cuantosEs(it)} quedan?`},
1959          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1960        };
1961      }
1962      if(k===3){
1963        const a=ri(2,5), b=ri(2,5);
1964        return {
1965          q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many do they have altogether?`,
1966             es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen en total?`},
1967          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
1968        };
1969      }
1970      const a=ri(5,9), b=ri(2,4);
1971      return {
1972        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b} ${it.en}. How many more does ${n1} have?`,
1973           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b} ${it.es}. ¿${cuantosEs(it)} más tiene ${n1}?`},
1974        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
1975      };
1976    }
1977
1978    /* ---- Challenge · DOK 3 : missing part, three addends, explain ---- */
1979    if(lvl===3){
1980      if(kind===1){
1981        const tot=ri(14,20), a=ri(5,tot-5);
1982        return {
1983          q:{en:`${n1} wants ${tot} ${it.en} and already has ${a}. How many more are needed? Explain how you figured it out.`,
1984             es:`${n1} quiere ${tot} ${it.es} y ya tiene ${a}. ¿${cuantosEs(it)} más faltan? Explica cómo lo averiguaste.`},
1985          a:{en:`${a} + ___ = ${tot}, so ${tot-a}`, es:`${a} + ___ = ${tot}, entonces ${tot-a}`}
1986        };
1987      }
1988      if(kind===2){
1989        const a=ri(3,7), b=ri(3,7), c=ri(3,6);
1990        return {
1991          q:{en:`${n1} has ${a} ${it.en}, ${n2} has ${b}, and a classmate has ${c}. How many altogether? Tell which two you added first and why.`,
1992             es:`${n1} tiene ${a} ${it.es}, ${n2} tiene ${b} y un compañero tiene ${c}. ¿${cuantosEs(it)} hay en total? Di cuáles dos sumaste primero y por qué.`},
1993          a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
1994        };
1995      }
1996      if(kind===3){
1997        const a=ri(12,20), b=ri(4,9);
1998        return {
1999          q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. ${n2} says ${n1} has ${a-b+ri(1,3)} more. Is ${n2} right? Explain.`,
2000             es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ${n2} dice que ${n1} tiene ${a-b+ri(1,3)} más. ¿Tiene razón? Explica.`},
2001          a:{en:`No — ${a}−${b} = ${a-b} more`, es:`No — ${a}−${b} = ${a-b} más`}
2002        };
2003      }
2004      if(kind===4){
2005        const start=ri(6,12), got=ri(4,8), tot=start+got;
2006        return {
2007          q:{en:`${n1} had some ${it.en}. ${n2} gave ${n1} ${got} more, and now ${n1} has ${tot}. ${n2} says ${n1} started with ${start+ri(1,3)}. Is ${n2} right? Show how you know.`,
2008             es:`${n1} tenía algunos ${it.es}. ${n2} le dio ${got} más y ahora tiene ${tot}. ${n2} dice que ${n1} empezó con ${start+ri(1,3)}. ¿Tiene razón? Muestra cómo lo sabes.`},
2009          a:{en:`No — ___ + ${got} = ${tot}, so ${start}`, es:`No — ___ + ${got} = ${tot}, entonces ${start}`}
2010        };
2011      }
2012      const b=ri(3,7), half=ri(2,5), a=b+2*half;   // even gap -> whole answer
2013      return {
2014        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many should ${n1} give ${n2} so they have the same amount? Explain your thinking.`,
2015           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} debe darle ${n1} a ${n2} para que tengan lo mismo? Explica tu razonamiento.`},
2016        a:{en:`(${a}−${b})÷2 = ${half}; both end with ${b+half}`,
2017           es:`(${a}−${b})÷2 = ${half}; los dos quedan con ${b+half}`}
2018      };
2019    }
2020
2021    /* ---- On level · DOK 2 : within 20 ---- */
2022    kind = ri(1,5);   // more variety at the tier teachers use most
2023    if(kind===1){
2024      const a=ri(6,13), b=ri(3,7);
2025      return {
2026        q:{en:`${n1} had ${a} ${it.en}. ${n2} gave ${n1} ${b} more. How many ${it.en} does ${n1} have now?`,
2027           es:`${n1} tenía ${a} ${it.es}. ${n2} le dio ${b} más. ¿${cuantosEs(it)} ${it.es} tiene ${n1} ahora?`},
2028        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2029      };
2030    }
2031    if(kind===2){
2032      const a=ri(12,20), b=ri(4,9);
2033      return {
2034        q:{en:`${n1} had ${a} ${it.en} and gave ${b} away. How many ${it.en} are left?`,
2035           es:`${n1} tenía ${a} ${it.es} y regaló ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
2036        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2037      };
2038    }
2039    if(kind===3){
2040      const a=ri(11,19), b=ri(4,9);
2041      return {
2042        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b} ${it.en}. How many more does ${n1} have?`,
2043           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b} ${it.es}. ¿${cuantosEs(it)} más tiene ${n1}?`},
2044        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2045      };
2046    }
2047    if(kind===4){
2048      const start=ri(5,12), got=ri(3,8), tot=start+got;
2049      return {
2050        q:{en:`${n1} had some ${it.en}. ${n2} gave ${n1} ${got} more. Now ${n1} has ${tot}. How many did ${n1} start with?`,
2051           es:`${n1} tenía algunos ${it.es}. ${n2} le dio ${got} más. Ahora ${n1} tiene ${tot}. ¿Con ${cuantosLc(it)} empezó ${n1}?`},
2052        a:{en:`___ + ${got} = ${tot}, so ${start}`, es:`___ + ${got} = ${tot}, entonces ${start}`}
2053      };
2054    }
2055    const big=ri(12,20), diff=ri(3,8);
2056    return {
2057      q:{en:`${n1} has ${big} ${it.en}. ${n1} has ${diff} more than ${n2}. How many ${it.en} does ${n2} have?`,
2058         es:`${n1} tiene ${big} ${it.es}. ${n1} tiene ${diff} más que ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n2}?`},
2059      a:{en:`${big} − ${diff} = ${big-diff}`, es:`${big} − ${diff} = ${big-diff}`}
2060    };
2061  }
2062},
2063{
2064  code:"1.OA.A.2", grade:1, dok:2,
2065  title:{en:"Add three numbers — word problems to 20",
2066         es:"Sumar tres números — problemas hasta 20"},
2067  text:{en:"Solve word problems that call for addition of three whole numbers whose sum is less than or equal to 20, e.g., by using objects, drawings, and equations with a symbol for the unknown number to represent the problem.",
2068        es:"Resuelve problemas verbales que requieren la suma de tres números enteros cuya suma es menor o igual a 20, por ejemplo, usando objetos, dibujos y ecuaciones con un símbolo para el número desconocido."},
2069  build(n1,n2,lvl){
2070    const it = pickItem();
2071
2072    /* ---- Support · DOK 1 : small triples, scaffolded ---- */
2073    if(lvl===1){
2074      const k=ri(1,4);
2075      if(k===1){
2076        const a=ri(2,4), b=ri(2,4), c=ri(1,3);
2077        return {
2078          q:{en:`${n1} has ${a} ${it.en}, ${n2} has ${b}, and a friend has ${c}. Add ${a} + ${b} first, then add ${c}. How many in all?`,
2079             es:`${n1} tiene ${a} ${it.es}, ${n2} tiene ${b} y un amigo tiene ${c}. Suma ${a} + ${b} primero y luego suma ${c}. ¿${cuantosEs(it)} hay en total?`},
2080          a:{en:`${a}+${b}=${a+b}, +${c} = ${a+b+c}`, es:`${a}+${b}=${a+b}, +${c} = ${a+b+c}`}
2081        };
2082      }
2083      if(k===2){
2084        const a=ri(2,5), c=ri(2,5);
2085        return {
2086          q:{en:`${n1} found ${a} ${it.en} in the morning, ${a} more at lunch, and ${c} after school. How many ${it.en} did ${n1} find? (Hint: start with the double ${a} + ${a}.)`,
2087             es:`${n1} encontró ${a} ${it.es} por la mañana, ${a} más al almuerzo y ${c} después de la escuela. ¿${cuantosEs(it)} ${it.es} encontró? (Pista: empieza con el doble ${a} + ${a}.)`},
2088          a:{en:`${a}+${a}=${2*a}, +${c} = ${2*a+c}`, es:`${a}+${a}=${2*a}, +${c} = ${2*a+c}`}
2089        };
2090      }
2091      if(k===3){
2092        const a=ri(1,4), b=ri(1,4), c=ri(1,4);
2093        return {
2094          q:{en:`Three friends put ${it.en} in ${n1}'s box: ${a}, ${b}, and ${c}. Draw them and count. How many ${it.en} are in the box?`,
2095             es:`Tres amigos pusieron ${it.es} en la caja de ${n1}: ${a}, ${b} y ${c}. Dibújalos y cuenta. ¿${cuantosEs(it)} ${it.es} hay en la caja?`},
2096          a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2097        };
2098      }
2099      const a=ri(2,6), b=10-a, c=ri(2,5);
2100      return {
2101        q:{en:`${n1} has ${a} ${it.en}, ${n2} has ${b}, and a classmate has ${c}
2101. Make a ten first (${a} + ${b}), then add the rest. How many in all?`,
2102           es:`${n1} tiene ${a} ${it.es}, ${n2} tiene ${b} y un compañero tiene ${c}. Forma una decena primero (${a} + ${b}) y luego suma el resto. ¿${cuantosEs(it)} hay en total?`},
2103        a:{en:`${a}+${b}=10, +${c} = ${10+c}`, es:`${a}+${b}=10, +${c} = ${10+c}`}
2104      };
2105    }
2106
2107    /* ---- Challenge · DOK 3 ---- */
2108    if(lvl===3){
2109      const k=ri(1,5);
2110      if(k===1){
2111        const a=ri(3,7), b=ri(2,6), c=ri(2,6), tot=a+b+c;
2112        return {
2113          q:{en:`${n1}, ${n2}, and a friend collected ${tot} ${it.en} together. ${n1} brought ${a} and ${n2} brought ${b}. Write an equation with n for the friend's ${it.en}, then solve.`,
2114             es:`${n1}, ${n2} y un amigo juntaron ${tot} ${it.es}. ${n1} trajo ${a} y ${n2} trajo ${b}. Escribe una ecuación con n para ${losLasEs(it)} ${it.es} del amigo y resuélvela.`},
2115          a:{en:`${a}+${b}+n=${tot}; n=${c}`, es:`${a}+${b}+n=${tot}; n=${c}`}
2116        };
2117      }
2118      if(k===2){
2119        const a=ri(3,6), b=ri(3,6), c=ri(2,5);
2120        return {
2121          q:{en:`${n1} counted ${a}, ${b}, and ${c} ${it.en} in three cups but only added the first two and said ${a+b}. What did ${n1} forget? Give the real total.`,
2122             es:`${n1} contó ${a}, ${b} y ${c} ${it.es} en tres vasos pero solo sumó los dos primeros y dijo ${a+b}. ¿Qué olvidó ${n1}? Da el total real.`},
2123          a:{en:`Forgot the third cup — ${a}+${b}+${c}=${a+b+c}`, es:`Olvidó el tercer vaso — ${a}+${b}+${c}=${a+b+c}`}
2124        };
2125      }
2126      if(k===3){
2127        const tot=ri(12,18);
2128        return {
2129          q:{en:`${n1} wants exactly ${tot} ${it.en} in three bags. Show one way to fill the bags. Write your addition equation.`,
2130             es:`${n1} quiere exactamente ${tot} ${it.es} en tres bolsas. Muestra una manera de llenar las bolsas. Escribe tu ecuación de suma.`},
2131          a:{en:`any three numbers that make ${tot} (e.g. ${tot-8}+4+4=${tot})`,
2132             es:`tres números cualesquiera que sumen ${tot} (p. ej. ${tot-8}+4+4=${tot})`}
2133        };
2134      }
2135      if(k===4){
2136        const a=ri(4,8), b=10-a, c=ri(3,7);
2137        return {
2138          q:{en:`${n1} adds ${a} + ${c} + ${b} by grouping ${a} with ${b} first. Why is that a smart order? Find the total.`,
2139             es:`${n1} suma ${a} + ${c} + ${b} agrupando ${a} con ${b} primero. ¿Por qué es un orden inteligente? Halla el total.`},
2140          a:{en:`${a}+${b}=10 (makes a ten), +${c} = ${10+c}`, es:`${a}+${b}=10 (forma una decena), +${c} = ${10+c}`}
2141        };
2142      }
2143      const a=ri(2,5), b=ri(2,5), c=ri(2,5), a2=ri(2,5), b2=ri(2,5), c2=ri(2,5);
2144      const t1=a+b+c, t2=a2+b2+c2;
2145      return {
2146        q:{en:`${n1}'s three cups hold ${a}, ${b}, and ${c} ${it.en}. ${n2}'s hold ${a2}, ${b2}, and ${c2}. Who has more? Show both totals.`,
2147           es:`Los tres vasos de ${n1} tienen ${a}, ${b} y ${c} ${it.es}. Los de ${n2} tienen ${a2}, ${b2} y ${c2}. ¿Quién tiene más? Muestra los dos totales.`},
2148        a:{en:`${t1} vs ${t2} — ${t1===t2?"equal":(t1>t2?n1:n2)}`, es:`${t1} vs ${t2} — ${t1===t2?"iguales":(t1>t2?n1:n2)}`}
2149      };
2150    }
2151
2152    /* ---- On level · DOK 2 : sums to 20 ---- */
2153    const k=ri(1,5);
2154    if(k===1){
2155      const a=ri(3,7), b=ri(3,7), c=ri(2,6);
2156      return {
2157        q:{en:`${n1} has ${a} ${it.en}, ${n2} has ${b}, and a classmate has ${c}. How many ${it.en} do they have in all?`,
2158           es:`${n1} tiene ${a} ${it.es}, ${n2} tiene ${b} y un compañero tiene ${c}. ¿${cuantosEs(it)} ${it.es} tienen en total?`},
2159        a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2160      };
2161    }
2162    if(k===2){
2163      const a=ri(3,7), b=ri(2,6), c=ri(2,6), tot=a+b+c;
2164      return {
2165        q:{en:`${n1}, ${n2}, and a friend need ${tot} ${it.en} for the game. ${n1} brings ${a} and ${n2} brings ${b}. How many must the friend bring?`,
2166           es:`${n1}, ${n2} y un amigo necesitan ${tot} ${it.es} para el juego. ${n1} trae ${a} y ${n2} trae ${b}. ¿${cuantosEs(it)} debe traer el amigo?`},
2167        a:{en:`${tot}−${a}−${b} = ${c}`, es:`${tot}−${a}−${b} = ${c}`}
2168      };
2169    }
2170    if(k===3){
2171      const a=ri(4,8), b=ri(3,7), c=ri(2,5);
2172      return {
2173        q:{en:`${n1} put ${it.en} on three shelves: ${a} on top, ${b} in the middle, and ${c} on the bottom. How many ${it.en} are on the shelves?`,
2174           es:`${n1}
2174 puso ${it.es} en tres estantes: ${a} arriba, ${b} en medio y ${c} abajo. ¿${cuantosEs(it)} ${it.es} hay en los estantes?`},
2175        a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2176      };
2177    }
2178    if(k===4){
2179      const a=ri(2,6), b=10-a, c=ri(3,8);
2180      return {
2181        q:{en:`${n1} scored ${a}, ${c}, and ${b} points in three rounds of the ${it.en} game. Use a ten to add quickly. What is the total?`,
2182           es:`${n1} anotó ${a}, ${c} y ${b} puntos en tres rondas del juego de ${it.es}. Usa una decena para sumar rápido. ¿Cuál es el total?`},
2183        a:{en:`${a}+${b}=10, +${c} = ${10+c}`, es:`${a}+${b}=10, +${c} = ${10+c}`}
2184      };
2185    }
2186    const a=ri(3,6), b=ri(3,6), c=ri(3,6);
2187    return {
2188      q:{en:`Over three days ${n1} collected ${a}, ${b}, and ${c} ${it.en} for ${n2}'s project. How many ${it.en} did ${n1} collect?`,
2189         es:`En tres días ${n1} juntó ${a}, ${b} y ${c} ${it.es} para el proyecto de ${n2}. ¿${cuantosEs(it)} ${it.es} juntó?`},
2190      a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2191    };
2192  }
2193},
2194{
2195  code:"1.OA.C.6", grade:1, dok:2,
2196  title:{en:"Add & subtract within 20",
2197         es:"Sumar y restar hasta 20"},
2198  text:{en:"Add and subtract within 20, demonstrating fluency for addition and subtraction within 10. Use strategies such as counting on; making ten; decomposing a number leading to a ten; using the relationship between addition and subtraction; and creating equivalent but easier or known sums.",
2199        es:"Suma y resta hasta 20, demostrando fluidez con la suma y la resta hasta 10. Usa estrategias como contar hacia adelante; formar diez; descomponer un número para llegar a diez; usar la relación entre la suma y la resta; y crear sumas equivalentes más fáciles o conocidas."},
2200  build(n1,n2,lvl){
2201    const it = pickItem();
2202
2203    /* ---- Support · DOK 1 : within 10, count on ---- */
2204    if(lvl===1){
2205      const k=ri(1,4);
2206      if(k===1){
2207        const a=ri(4,7), b=ri(2,3);
2208        return {
2209          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. Count on to find how many.`,
2210             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. Cuenta hacia adelante para saber ${cuantosLc(it)} hay.`},
2211          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2212        };
2213      }
2214      if(k===2){
2215        const a=ri(7,10), b=ri(2,4);
2216        return {
2217          q:{en:`${n1} has ${a} ${it.en} and uses ${b}. How many are left?`,
2218             es:`${n1} tiene ${a} ${it.es} y usa ${b}. ¿${cuantosEs(it)} quedan?`},
2219          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2220        };
2221      }
2222      if(k===3){
2223        const a=ri(6,9), b=10-a>0?10-a:2;
2224        return {
2225          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more to make 10. How many ${it.en} now?`,
2226             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más para formar 10. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
2227          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2228        };
2229      }
2230      const a=ri(3,5);
2231      return {
2232        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${a} too. How many together? (Think doubles.)`,
2233           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${a} también. ¿${cuantosEs(it)} hay juntos? (Piensa en dobles.)`},
2234        a:{en:`${a} + ${a} = ${2*a}`, es:`${a} + ${a} = ${2*a}`}
2235      };
2236    }
2237
2238    /* ---- Challenge · DOK 3 : strategy, missing part, related facts ---- */
2239    if(lvl===3){
2240      const k=ri(1,4);
2241      if(k===1){
2242        const a=ri(7,9), b=ri(4,8);
2243        return {
2244          q:{en:`${n1} has ${a} ${it.en} and gets ${b}
2244 more. Make a ten first, then finish. Show your steps.`,
2245             es:`${n1} tiene ${a} ${it.es} y recibe ${b} más. Forma diez primero y luego termina. Muestra tus pasos.`},
2246          a:{en:`${a}+${10-a}=10, then +${b-(10-a)} = ${a+b}`, es:`${a}+${10-a}=10, luego +${b-(10-a)} = ${a+b}`}
2247        };
2248      }
2249      if(k===2){
2250        const tot=ri(13,20), a=ri(5,tot-5);
2251        return {
2252          q:{en:`${n1} needs ${tot} ${it.en} and has ${a}. How many more? Write the addition AND the subtraction.`,
2253             es:`${n1} necesita ${tot} ${it.es} y tiene ${a}. ¿${cuantosEs(it)} más faltan? Escribe la suma Y la resta.`},
2254          a:{en:`${a} + ${tot-a} = ${tot}; ${tot} − ${a} = ${tot-a}`, es:`${a} + ${tot-a} = ${tot}; ${tot} − ${a} = ${tot-a}`}
2255        };
2256      }
2257      if(k===3){
2258        const a=ri(11,17), b=ri(4,8);
2259        return {
2260          q:{en:`${n2} says ${a} − ${b} is ${a-b+1}. Check it with addition. Is ${n2} right?`,
2261             es:`${n2} dice que ${a} − ${b} es ${a-b+1}. Compruébalo con una suma. ¿Tiene razón?`},
2262          a:{en:`No — ${a-b} + ${b} = ${a}, so ${a} − ${b} = ${a-b}`,
2263             es:`No — ${a-b} + ${b} = ${a}, entonces ${a} − ${b} = ${a-b}`}
2264        };
2265      }
2266      const a=ri(5,8), b=ri(4,7), c=ri(2,5);
2267      return {
2268        q:{en:`${n1} has ${a} ${it.en}, ${n2} has ${b}, and a friend has ${c}. How many in all? Add the two that make ten first.`,
2269           es:`${n1} tiene ${a} ${it.es}, ${n2} tiene ${b} y un amigo tiene ${c}. ¿${cuantosEs(it)} hay en total? Suma primero los dos que formen diez.`},
2270        a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2271      };
2272    }
2273
2274    /* ---- On level · DOK 2 : within 20 ---- */
2275    const k=ri(1,4);
2276    if(k===1){
2277      const a=ri(8,13), b=ri(3,7);
2278      return {
2279        q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many ${it.en} now?`,
2280           es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
2281        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2282      };
2283    }
2284    if(k===2){
2285      const a=ri(12,20), b=ri(4,9);
2286      return {
2287        q:{en:`${n1} had ${a} ${it.en} and gave ${b} to ${n2}. How many are left?`,
2288           es:`${n1} tenía ${a} ${it.es} y le dio ${b} a ${n2}. ¿${cuantosEs(it)} quedan?`},
2289        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2290      };
2291    }
2292    if(k===3){
2293      const tot=ri(12,18), a=ri(4,tot-4);
2294      return {
2295        q:{en:`${n1} wants ${tot} ${it.en} and has ${a}. How many more does ${n1} need?`,
2296           es:`${n1} quiere ${tot} ${it.es} y tiene ${a}. ¿${cuantosEs(it)} más necesita?`},
2297        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
2298      };
2299    }
2300    const a=ri(9,14), b=ri(4,8);
2301    return {
2302      q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more does ${n1} have?`,
2303         es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} más tiene ${n1}?`},
2304      a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2305    };
2306  }
2307},
2308{
2309  code:"2.MD.C.8", grade:2, dok:2,
2310  title:{en:"Money — dollars, quarters, dimes, nickels, pennies",
2311         es:"Dinero — dólares, monedas de 25, 10, 5 y 1"},
2312  text:{en:"Solve word problems involving dollar bills, quarters, dimes, nickels, and pennies, using $ and ¢ symbols appropriately.",
2313        es:"Resuelve problemas verbales con billetes de dólar y monedas de 25, 10, 5 y 1 centavos, usando los símbolos $ y ¢ correctamente."},
2314  build(n1,n2,lvl){
2315    const it = pickItem();
2316    const cents = c => c + "\u00a2";
2317
2318    /* ---- Support · DOK 1 : one coin type ---- */
2319    if(lvl===1){
2320      const k=ri(1,4);
2321      if(k===1){
2322        const n=ri(3,8);
2323        return {
2324          q:{en:`${n1} has ${n} dimes to buy ${it.en}. How many cents is that?`,
2325             es:`${n1} tiene ${n} monedas de 10 centavos para comprar ${it.es}. ¿Cuántos centavos son?`},
2326          a:{en:`${n} × 10 = ${cents(n*10)}`, es:`${n} × 10 = ${cents(n*10)}`}
2327        };
2328      }
2329      if(k===2){
2330        const n=ri(2,4);
2331        return {
2332          q:{en:`${n1} has ${n} quarters. How many cents does ${n1} have?`,
2333             es:`${n1} tiene ${n} monedas de 25 centavos. ¿Cuántos centavos tiene?`},
2334          a:{en:`${n} × 25 = ${cents(n*25)}`, es:`${n} × 25 = ${cents(n*25)}`}
2335        };
2336      }
2337      if(k===3){
2338        const n=ri(3,9);
2339        return {
2340          q:{en:`${n1} has ${n} nickels for the ${it.en} sale. How many cents is that?`,
2341             es:`${n1} tiene ${n} monedas de 5 centavos para la venta de ${it.es}. ¿Cuántos centavos son?`},
2342          a:{en:`${n} × 5 = ${cents(n*5)}`, es:`${n} × 5 = ${cents(n*5)}`}
2343        };
2344      }
2345      const d=ri(2,5), p=ri(2,6);
2346      return {
2347        q:{en:`${n1} has ${d} dimes and ${p} pennies. How many cents in all?`,
2348           es:`${n1} tiene ${d} monedas de 10 y ${p} de 1 centavo. ¿Cuántos centavos hay en total?`},
2349        a:{en:`${d*10} + ${p} = ${cents(d*10+p)}`, es:`${d*10} + ${p} = ${cents(d*10+p)}`}
2350      };
2351    }
2352
2353    /* ---- Challenge · DOK 3 : make an amount, compare, change ---- */
2354    if(lvl===3){
2355      const k=ri(1,4);
2356      if(k===1){
2357        const target=pick([40,55,65,70,85]);
2358        return {
2359          q:{en:`${n1} needs exactly ${cents(target)} for ${it.en}. Show TWO different sets of coins that make ${cents(target)}.`,
2360             es:`${n1} necesita exactamente ${cents(target)} para ${it.es}. Muestra DOS grupos distintos de monedas que sumen ${cents(target)}.`},
2361          a:{en:`e.g. ${Math.floor(target/25)} quarters + rest in dimes/nickels; or ${target/5} nickels`,
2362             es:`p. ej. ${Math.floor(target/25)} de 25 + el resto en 10 y 5; o ${target/5} de 5 centavos`}
2363        };
2364      }
2365      if(k===2){
2366        const q1=ri(1,3), d1=ri(1,4), tot1=q1*25+d1*10;
2367        const n5=ri(2,6), d2=ri(1,4), tot2=n5*5+d2*10;
2368        if(tot1===tot2) return this.build(n1,n2,lvl);
2369        return {
2370          q:{en:`${n1} has ${q1} quarters and ${d1} dimes. ${n2} has ${n5} nickels and ${d2} dimes. Who has more money? By how much?`,
2371             es:`${n1} tiene ${q1} de 25 y ${d1} de 10 centavos. ${n2} tiene ${n5} de 5 y ${d2} de 10. ¿Quién tiene más dinero? ¿Por cuánto?`},
2372          a:{en:`${cents(tot1)} vs ${cents(tot2)} — ${tot1>tot2?n1:n2} by ${cents(Math.abs(tot1-tot2))}`,
2373             es:`${cents(tot1)} vs ${cents(tot2)} — ${tot1>tot2?n1:n2} por ${cents(Math.abs(tot1-tot2))}`}
2374        };
2375      }
2376      if(k===3){
2377        const cost=ri(35,85), paid=100;
2378        return {
2379          q:{en:`${n1} buys ${it.en} for ${cents(cost)} and pays with $1.00. How much change should ${n1} get? Explain how you counted up.`,
2380             es:`${n1} compra ${it.es} por ${cents(cost)} y paga con $1.00. ¿Cuánto cambio debe recibir? Explica cómo contaste hacia adelante.`},
2381          a:{en:`${paid} − ${cost} = ${cents(paid-cost)}`, es:`${paid} − ${cost} = ${cents(paid-cost)}`}
2382        };
2383      }
2384      const q1=ri(2,3), d1=ri(1,3), need=q1*25+d1*10+ri(10,30);
2385      return {
2386        q:{en:`${n1} has ${q1} quarters and ${d1} dimes but needs ${cents(need)} for ${it.en}. How much more money does ${n1} need?`,
2387           es:`${n1} tiene ${q1} de 25 y ${d1} de 10 centavos pero necesita ${cents(need)} para ${it.es}. ¿Cuánto dinero más necesita?`},
2388        a:{en:`has ${cents(q1*25+d1*10)}; needs ${cents(need-(q1*25+d1*10))} more`,
2389           es:`tiene ${cents(q1*25+d1*10)}; faltan ${cents(need-(q1*25+d1*10))}`}
2390      };
2391    }
2392
2393    /* ---- On level · DOK 2 : mixed coins ---- */
2394    const k=ri(1,4);
2395    if(k===1){
2396      const q1=ri(1,3), d=ri(1,4), n5=ri(1,3);
2397      const tot=q1*25+d*10+n5*5;
2398      return {
2399        q:{en:`${n1} has ${q1} quarters, ${d} dimes, and ${n5} nickels. How many cents does ${n1} have?`,
2400           es:`${n1} tiene ${q1} monedas de 25, ${d} de 10 y ${n5} de 5 centavos. ¿Cuántos centavos tiene?`},
2401        a:{en:`${q1*25} + ${d*10} + ${n5*5} = ${cents(tot)}`, es:`${q1*25} + ${d*10} + ${n5*5} = ${cents(tot)}`}
2402      };
2403    }
2404    if(k===2){
2405      const cost=ri(25,70), paid=Math.ceil((cost+ri(10,25))/5)*5;
2406      return {
2407        q:{en:`${it.en.charAt(0).toUpperCase()+it.en.slice(1)} cost ${cents(cost)}. ${n1} pays with ${cents(paid)}. How much change does ${n1} get?`,
2408           es:`${losLasEs(it)==="los"?"Los":"Las"} ${it.es} cuestan ${cents(cost)}. ${n1} paga con ${cents(paid)}. ¿Cuánto cambio recibe?`},
2409        a:{en:`${paid} − ${cost} = ${cents(paid-cost)}`, es:`${paid} − ${cost} = ${cents(paid-cost)}`}
2410      };
2411    }
2412    if(k===3){
2413      const a=ri(20,45), b=ri(20,45);
2414      return {
2415        q:{en:`${n1} spends ${cents(a)} on ${it.en} and ${n2} spends ${cents(b)}. How much did they spend together?`,
2416           es:`${n1} gasta ${cents(a)} en ${it.es} y ${n2} gasta ${cents(b)}. ¿Cuánto gastaron juntos?`},
2417        a:{en:`${a} + ${b} = ${cents(a+b)}`, es:`${a} + ${b} = ${cents(a+b)}`}
2418      };
2419    }
2420    const d=ri(3,7), n5=ri(2,5), p=ri(1,4);
2421    const tot=d*10+n5*5+p;
2422    return {
2423      q:{en:`${n1} counted ${d} dimes, ${n5} nickels, and ${p} pennies. How many cents does ${n1} have for ${it.en}?`,
2424         es:`${n1} contó ${d} monedas de 10, ${n5} de 5 y ${p} de 1 centavo. ¿Cuántos centavos tiene para ${it.es}?`},
2425      a:{en:`${d*10} + ${n5*5} + ${p} = ${cents(tot)}`, es:`${d*10} + ${n5*5} + ${p} = ${cents(tot)}`}
2426    };
2427  }
2428},
2429{
2430  code:"2.MD.D.10", grade:2, dok:2,
2431  title:{en:"Read & compare picture and bar graphs",
2432         es:"Leer y comparar pictogramas y gráficas de barras"},
2433  text:{en:"Draw a picture graph and a bar graph (with single-unit scale) to represent a data set with up to four categories. Solve simple put-together, take-apart, and compare problems using information presented in a bar graph.",
2434        es:"Dibuja un pictograma y una gráfica de barras (con escala de una unidad) para representar un conjunto de datos de hasta cuatro categorías. Resuelve problemas sencillos de juntar, separar y comparar usando la información de una gráfica de barras."},
2435  build(n1,n2,lvl){
2436    const it = pickItem();
2437    let it2 = pick(THEME.items); while(it2.en===it.en) it2 = pick(THEME.items);
2438    let it3 = pick(THEME.items); while(it3.en===it.en||it3.en===it2.en) it3 = pick(THEME.items);
2439
2440    /* ---- Support · DOK 1 : two categories ---- */
2441    if(lvl===1){
2442      const k=ri(1,4);
2443      if(k===1){
2444        const a=ri(4,9), b=ri(2,7);
2445        if(a===b) return this.build(n1,n2,lvl);
2446        return {
2447          q:{en:`${n1}'s graph shows ${a} ${it.en} and ${b} ${it2.en}. Which bar is taller? How many more?`,
2448             es:`La gráfica de ${n1} muestra ${a} ${it.es} y ${b} ${it2.es}. ¿Cuál barra es más alta? ¿${cuantosEs(it)} más?`},
2449          a:{en:`${a>b?it.en:it2.en} by ${Math.abs(a-b)}`, es:`${a>b?it.es:it2.es} por ${Math.abs(a-b)}`}
2450        };
2451      }
2452      if(k===2){
2453        const a=ri(3,8), b=ri(3,8);
2454        return {
2455          q:{en:`${n1} counted ${a} ${it.en} and ${b} ${it2.en} for a bar graph. How many did ${n1} count in all?`,
2456             es:`${n1} contó ${a} ${it.es} y ${b} ${it2.es} para una gráfica de barras. ¿${cuantosEs(it)} contó en total?`},
2457          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2458        };
2459      }
2460      if(k===3){
2461        const b=ri(2,4), a=b+ri(2,6);
2462        return {
2463          q:{en:`On ${n1}'s picture graph, ${it.en} has ${a} pictures and ${it2.en} has ${b}. How many fewer ${it2.en}?`,
2464             es:`En el pictograma de ${n1}, ${it.es} tiene ${a} dibujos y ${it2.es} tiene ${b}. ¿${cuantosEs(it2)} ${it2.es} menos hay?`},
2465          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2466        };
2467      }
2468      const a=ri(4,9);
2469      return {
2470        q:{en:`${n1}'s bar for ${it.en} shows ${a}. ${n2}'s bar shows 3 more. How tall is ${n2}'s bar?`,
2471           es:`La barra de ${it.es} de ${n1} muestra ${a}. La de ${n2} muestra 3 más. ¿Cuánto muestra la barra de ${n2}?`},
2472        a:{en:`${a} + 3 = ${a+3}`, es:`${a} + 3 = ${a+3}`}
2473      };
2474    }
2475
2476    /* ---- Challenge · DOK 3 : four categories, multi-step ---- */
2477    if(lvl===3){
2478      const k=ri(1,4);
2479      if(k===1){
2480        const b=ri(4,9), c=ri(3,7), a=b+c+ri(2,8);   // a must exceed b+c
2481        return {
2482          q:{en:`${n1}'s graph shows ${a} ${it.en}, ${b} ${it2.en}, and ${c} ${it3.en}. How many more ${it.en} than ${it2.en} and ${it3.en}
2482 combined? Show your steps.`,
2483             es:`La gráfica de ${n1} muestra ${a} ${it.es}, ${b} ${it2.es} y ${c} ${it3.es}. ¿${cuantosEs(it)} ${it.es} más que ${it2.es} y ${it3.es} juntos? Muestra tus pasos.`},
2484          a:{en:`${b}+${c}=${b+c}; ${a}−${b+c} = ${a-(b+c)}`, es:`${b}+${c}=${b+c}; ${a}−${b+c} = ${a-(b+c)}`}
2485        };
2486      }
2487      if(k===2){
2488        const a=ri(8,15), b=ri(4,10), tot=ri(25,40);
2489        const rest = tot - a - b;
2490        if(rest < 2) return this.build(n1,n2,lvl);
2491        return {
2492          q:{en:`${n1}'s graph has ${tot} ${it.en} in all across three bars. Two bars show ${a} and ${b}. How tall is the third bar? Explain how you know.`,
2493             es:`La gráfica de ${n1} tiene ${tot} ${it.es} en tres barras. Dos barras muestran ${a} y ${b}. ¿Cuánto muestra la tercera? Explica cómo lo sabes.`},
2494          a:{en:`${a}+${b}=${a+b}; ${tot}−${a+b} = ${rest}`, es:`${a}+${b}=${a+b}; ${tot}−${a+b} = ${rest}`}
2495        };
2496      }
2497      if(k===3){
2498        const b=ri(3,6), a=b+ri(3,8);
2499        return {
2500          q:{en:`${n2} looks at ${n1}'s graph and says ${it.en} (${a}) has ${a-b+2} more than ${it2.en} (${b}). Is ${n2} right? Give the correct difference.`,
2501             es:`${n2} mira la gráfica de ${n1} y dice que ${it.es} (${a}) tiene ${a-b+2} más que ${it2.es} (${b}). ¿Tiene razón? Da la diferencia correcta.`},
2502          a:{en:`No — ${a} − ${b} = ${a-b}`, es:`No — ${a} − ${b} = ${a-b}`}
2503        };
2504      }
2505      const a=ri(6,12), b=ri(6,12), c=ri(4,9), d=ri(4,9);
2506      return {
2507        q:{en:`${n1} graphed ${a} ${it.en}, ${b} ${it2.en}, ${c} ${it3.en}. ${n2} adds ${d} more ${it3.en}. Which category has the most now? Show the totals.`,
2508           es:`${n1} graficó ${a} ${it.es}, ${b} ${it2.es}, ${c} ${it3.es}. ${n2} agrega ${d} ${it3.es} más. ¿Qué categoría tiene más ahora? Muestra los totales.`},
2509        a:{en:`${a}, ${b}, ${c+d} → ${Math.max(a,b,c+d)===a?it.en:(Math.max(a,b,c+d)===b?it2.en:it3.en)} (${Math.max(a,b,c+d)})`,
2510           es:`${a}, ${b}, ${c+d} → ${Math.max(a,b,c+d)===a?it.es:(Math.max(a,b,c+d)===b?it2.es:it3.es)} (${Math.max(a,b,c+d)})`}
2511      };
2512    }
2513
2514    /* ---- On level · DOK 2 : three categories ---- */
2515    const k=ri(1,4);
2516    if(k===1){
2517      const a=ri(6,14), b=ri(4,12), c=ri(3,10);
2518      return {
2519        q:{en:`${n1}'s bar graph shows ${a} ${it.en}, ${b} ${it2.en}, and ${c} ${it3.en}. How many are there in all?`,
2520           es:`La gráfica de barras de ${n1} muestra ${a} ${it.es}, ${b} ${it2.es} y ${c} ${it3.es}. ¿${cuantosEs(it)} hay en total?`},
2521        a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
2522      };
2523    }
2524    if(k===2){
2525      const b=ri(3,7), a=b+ri(3,9);
2526      return {
2527        q:{en:`On ${n1}'s graph, ${it.en} shows ${a} and ${it2.en} shows ${b}. How many more ${it.en} are there?`,
2528           es:`En la gráfica de ${n1}, ${it.es} muestra ${a} y ${it2.es} muestra ${b}. ¿${cuantosEs(it)} ${it.es} más hay?`},
2529        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2530      };
2531    }
2532    if(k===3){
2533      const a=ri(5,12), b=ri(5,12), c=ri(5,12);
2534      const mx2=Math.max(a,b,c), mn=Math.min(a,b,c);
2535      if(mx2===mn) return this.build(n1,n2,lvl);
2536      return {
2537        q:{en:`${n1} graphed ${a} ${it.en}, ${b} ${it2.en}, and ${c} ${it3.en}. Which has the most, and which has the fewest?`,
2538           es:`${n1} graficó ${a} ${it.es}, ${b} ${it2.es} y ${c} ${it3.es}. ¿Cuál tiene más y cuál tiene menos?`},
2539        a:{en:`most: ${mx2===a?it.en:(mx2===b?it2.en:it3.en)} (${mx2}); fewest: ${mn===a?it.en:(mn===b?it2.en:it3.en)} (${mn})`,
2540           es:`más: ${mx2===a?it.es:(mx2===b?it2.es:it3.es)} (${mx2}); menos: ${mn===a?it.es:(mn===b?it2.es:it3.es)} (${mn})`}
2541      };
2542    }
2543    const b=ri(4,10), a=b+ri(2,7);   // it must exceed it2 to "match up"
2544    return {
2545      q:{en:`${n1} and ${n2} made a graph: ${it.en} has ${a} and ${it2.en} has ${b}. How many would ${it2.en} need to match ${it.en}?`,
2546         es:`${n1} y ${n2} hicieron una gráfica: ${it.es} tiene ${a} y ${it2.es} tiene ${b}. ¿${cuantosEs(it2)} necesita ${it2.es} para igualar a ${it.es}?`},
2547      a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2548    };
2549  }
2550},
2551{
2552  code:"2.NBT.B.5", grade:2, dok:2,
2553  title:{en:"Add & subtract within 100",
2554         es:"Sumar y restar hasta 100"},
2555  text:{en:"Fluently add and subtract within 100 using strategies based on place value, properties of operations, and/or the relationship between addition and subtraction.",
2556        es:"Suma y resta con fluidez hasta 100 usando estrategias basadas en el valor posicional, las propiedades de las operaciones y/o la relación entre la suma y la resta."},
2557  build(n1,n2,lvl){
2558    const it = pickItem();
2559
2560    /* ---- Support · DOK 1 : no regrouping ---- */
2561    if(lvl===1){
2562      const k=ri(1,4);
2563      if(k===1){
2564        const a=ri(21,45), b=ri(11,30);
2565        return {
2566          q:{en:`${n1} has ${a} ${it.en}. ${n2} gives ${b} more. How many ${it.en} now?`,
2567             es:`${n1} tiene ${a} ${it.es}. ${n2} le da ${b} más. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
2568          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2569        };
2570      }
2571      if(k===2){
2572        const a=ri(45,89), b=ri(11,30);
2573        return {
2574          q:{en:`${n1} had ${a} ${it.en} and used ${b}. How many are left?`,
2575             es:`${n1} tenía ${a} ${it.es} y usó ${b}. ¿${cuantosEs(it)} quedan?`},
2576          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2577        };
2578      }
2579      if(k===3){
2580        const t=ri(2,5)*10, a=ri(11,35);
2581        return {
2582          q:{en:`${n1} counted ${a} ${it.en}. ${n2} brought ${t} more. How many in all?`,
2583             es:`${n1} contó ${a} ${it.es}. ${n2} trajo ${t} más. ¿${cuantosEs(it)} hay en total?`},
2584          a:{en:`${a} + ${t} = ${a+t}`, es:`${a} + ${t} = ${a+t}`}
2585        };
2586      }
2587      const a=ri(30,60), b=ri(10,20);
2588      return {
2589        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more does ${n1} have?`,
2590           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} más tiene ${n1}?`},
2591        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2592      };
2593    }
2594
2595    /* ---- Challenge · DOK 3 ---- */
2596    if(lvl===3){
2597      const k=ri(1,4);
2598      if(k===1){
2599        const a=ri(34,68), b=ri(15,28);
2600        const wrong = (Math.floor(a/10)-Math.floor(b/10))*10 + Math.abs(a%10 - b%10);
2601        if(wrong===a-b) return this.build(n1,n2,lvl);
2602        return {
2603          q:{en:`${n2} computed ${a} − ${b} for the ${it.en} count and got ${wrong}, taking the smaller ones digit from the larger. Why does that fail? Give the correct answer.`,
2604             es:`${n2} calculó ${a} − ${b} para el conteo de ${it.es} y obtuvo ${wrong}, restando el dígito menor del mayor en las unidades. ¿Por qué falla? Da la respuesta correcta.`},
2605          a:{en:`Needs regrouping — ${a} − ${b} = ${a-b}`, es:`Hay que reagrupar — ${a} − ${b} = ${a-b}`}
2606        };
2607      }
2608      if(k===2){
2609        const tot=ri(60,98), a=ri(20,tot-20);
2610        return {
2611          q:{en:`${n1} and ${n2} need ${tot} ${it.en} in all. ${n1} brings ${a}. Write an equation with n for what ${n2} must bring, then solve.`,
2612             es:`${n1} y ${n2} necesitan ${tot} ${it.es} en total. ${n1} trae ${a}. Escribe una ecuación con n para lo que debe traer ${n2} y resuélvela.`},
2613          a:{en:`${a} + n = ${tot}; n = ${tot-a}`, es:`${a} + n = ${tot}; n = ${tot-a}`}
2614        };
2615      }
2616      if(k===3){
2617        const a=ri(30,55), b=ri(15,30), c=ri(10,20);
2618        return {
2619          q:{en:`${n1} had ${a} ${it.en}, got ${b} more, then gave ${c} to ${n2}. How many now? Show both steps.`,
2620             es:`${n1} tenía ${a} ${it.es}, recibió ${b} más y le dio ${c} a ${n2}. ¿${cuantosEs(it)} hay ahora? Muestra los dos pasos.`},
2621          a:{en:`${a}+${b}=${a+b}, −${c} = ${a+b-c}`, es:`${a}+${b}=${a+b}, −${c} = ${a+b-c}`}
2622        };
2623      }
2624      const a=ri(25,48), b=ri(25,48), claim=a+b+(ri(0,1)?ri(11,20):-ri(11,20));
2625      return {
2626        q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. ${n2} says the total is ${claim}. Round to the nearest ten to check. Is that reasonable?`,
2627           es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. ${n2} dice que el total es ${claim}. Redondea a la decena para comprobar. ¿Es razonable?`},
2628        a:{en:`≈${rnd(a,10)}+${rnd(b,10)}=${rnd(a,10)+rnd(b,10)}; exact ${a+b} — not reasonable`,
2629           es:`≈${rnd(a,10)}+${rnd(b,10)}=${rnd(a,10)+rnd(b,10)}; exacto ${a+b} — no es razonable`}
2630      };
2631    }
2632
2633    /* ---- On level · DOK 2 : with regrouping ---- */
2634    const k=ri(1,4);
2635    if(k===1){
2636      const a=ri(26,58), b=ri(17,39);
2637      return {
2638        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many do they have together?`,
2639           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen juntos?`},
2640        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2641      };
2642    }
2643    if(k===2){
2644      const a=ri(52,95), b=ri(17,38);
2645      return {
2646        q:{en:`${n1} had ${a} ${it.en} and gave ${b} to ${n2}. How many ${it.en} are left?`,
2647           es:`${n1} tenía ${a} ${it.es} y le dio ${b} a ${n2}. ¿${cuantosEs(it)} ${it.es} quedan?`},
2648        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2649      };
2650    }
2651    if(k===3){
2652      const tot=ri(55,95), a=ri(18,tot-18);
2653      return {
2654        q:{en:`${n1} needs ${tot} ${it.en} and already has ${a}. How many more does ${n1} need?`,
2655           es:`${n1} necesita ${tot} ${it.es} y ya tiene ${a}. ¿${cuantosEs(it)} más necesita?`},
2656        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
2657      };
2658    }
2659    const a=ri(40,75), b=ri(18,35);
2660    return {
2661      q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more ${it.en} does ${n1} have than ${n2}?`,
2662         es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} ${it.es} más tiene ${n1} que ${n2}?`},
2663      a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2664    };
2665  }
2666},
2667{
2668  code:"2.NBT.B.7", grade:2, dok:2,
2669  title:{en:"Add & subtract within 1,000",
2670         es:"Sumar y restar hasta 1,000"},
2671  text:{en:"Add and subtract within 1000, using concrete models or drawings and strategies based on place value, properties of operations, and/or the relationship between addition and subtraction; relate the strategy to a written method.",
2672        es:"Suma y resta hasta 1000, usando modelos concretos o dibujos y estrategias basadas en el valor posicional, las propiedades de las operaciones y/o la relación entre la suma y la resta; relaciona la estrategia con un método escrito."},
2673  build(n1,n2,lvl){
2674    const it = pickItem();
2675    const g = THEME.group;
2676
2677    /* ---- Support · DOK 1 : hundreds and tens, no regrouping ---- */
2678    if(lvl===1){
2679      const k=ri(1,4);
2680      if(k===1){
2681        const a=ri(2,6)*100, b=ri(1,3)*100;
2682        return {
2683          q:{en:`${n1}'s ${g.en} collected ${a} ${it.en}. ${n2} added ${b} more. How many in all?`,
2684             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} juntó ${a} ${it.es}. ${n2} agregó ${b} más. ¿${cuantosEs(it)} hay en total?`},
2685          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2686        };
2687      }
2688      if(k===2){
2689        const a=ri(3,7)*100, b=ri(1,2)*100;
2690        return {
2691          q:{en:`${n1} counted ${a} ${it.en}. ${b} were given away. How many are left?`,
2692             es:`${n1} contó ${a} ${it.es}. Se regalaron ${b}. ¿${cuantosEs(it)} quedan?`},
2693          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2694        };
2695      }
2696      if(k===3){
2697        const h=ri(2,5)*100, t=ri(2,8)*10;
2698        return {
2699          q:{en:`${n1} has ${h} ${it.en} in boxes and ${t} loose. How many ${it.en} in all?`,
2700             es:`${n1} tiene ${h} ${it.es} en cajas y ${t} sueltos. ¿${cuantosEs(it)} ${it.es} hay en total?`},
2701          a:{en:`${h} + ${t} = ${h+t}`, es:`${h} + ${t} = ${h+t}`}
2702        };
2703      }
2704      const a=ri(120,450), b=ri(100,300);
2705      return {
2706        q:{en:`${n1} collected ${a} ${it.en} and ${n2} collected ${b}. How many did they collect together?`,
2707           es:`${n1} juntó ${a} ${it.es} y ${n2} juntó ${b}. ¿${cuantosEs(it)} juntaron entre los dos?`},
2708        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2709      };
2710    }
2711
2712    /* ---- Challenge · DOK 3 ---- */
2713    if(lvl===3){
2714      const k=ri(1,4);
2715      if(k===1){
2716        const a=ri(320,680), b=ri(130,290);
2717        return {
2718          q:{en:`${n1} has ${a} ${it.en} and gives ${b} to ${n2}. Explain how you regrouped, then give the answer.`,
2719             es:`${n1} tiene ${a} ${it.es} y le da ${b} a ${n2}. Explica cómo reagrupaste y da la respuesta.`},
2720          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2721        };
2722      }
2723      if(k===2){
2724        const tot=ri(500,950), a=ri(150,tot-150);
2725        return {
2726          q:{en:`${n1}'s ${g.en} wants ${tot} ${it.en} and has ${a} so far. Write an equation with n for how many more are needed, then solve.`,
2727             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} quiere ${tot} ${it.es} y tiene ${a}. Escribe una ecuación con n para ${cuantosLc(it)} faltan y resuélvela.`},
2728          a:{en:`${a} + n = ${tot}; n = ${tot-a}`, es:`${a} + n = ${tot}; n = ${tot-a}`}
2729        };
2730      }
2731      if(k===3){
2732        const a=ri(300,600), b=ri(120,250), c=ri(80,180);
2733        return {
2734          q:{en:`${n1} started with ${a} ${it.en}, gave ${b} away, then ${n2} brought ${c} more. How many now? Show both steps.`,
2735             es:`${n1} empezó con ${a} ${it.es}, regaló ${b} y luego ${n2} trajo ${c} más. ¿${cuantosEs(it)} hay ahora? Muestra los dos pasos.`},
2736          a:{en:`${a}−${b}=${a-b}, +${c} = ${a-b+c}`, es:`${a}−${b}=${a-b}, +${c} = ${a-b+c}`}
2737        };
2738      }
2739      const a=ri(240,480), b=ri(150,320), claim=a+b+(ri(0,1)?ri(60,120):-ri(60,120));
2740      return {
2741        q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. ${n2} says the total is ${claim}. Round to the nearest hundred to check. Is ${n2} reasonable?`,
2742           es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. ${n2} dice que el total es ${claim}. Redondea a la centena para comprobar. ¿Es razonable?`},
2743        a:{en:`≈${rnd(a,100)}+${rnd(b,100)}=${rnd(a,100)+rnd(b,100)}; exact ${a+b} — not reasonable`,
2744           es:`≈${rnd(a,100)}+${rnd(b,100)}=${rnd(a,100)+rnd(b,100)}; exacto ${a+b} — no es razonable`}
2745      };
2746    }
2747
2748    /* ---- On level · DOK 2 ---- */
2749    const k=ri(1,4);
2750    if(k===1){
2751      const a=ri(150,480), b=ri(150,420);
2752      return {
2753        q:{en:`${n1} collected ${a} ${it.en} and ${n2} collected ${b} for the ${g.en}. How many ${it.en} in all?`,
2754           es:`${n1} juntó ${a} ${it.es} y ${n2} juntó ${b} para ${elLaEs(g)==="el"?"el":"la"} ${g.es}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
2755        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2756      };
2757    }
2758    if(k===2){
2759      const a=ri(420,900), b=ri(160,390);
2760      return {
2761        q:{en:`${n1} had ${a} ${it.en} and handed out ${b}. How many ${it.en} are left?`,
2762           es:`${n1} tenía ${a} ${it.es} y repartió ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
2763        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2764      };
2765    }
2766    if(k===3){
2767      const tot=ri(500,950), a=ri(180,tot-180);
2768      return {
2769        q:{en:`${n1}'s ${g.en} counted ${tot} ${it.en} in all. ${n1} counted ${a} of them. How many did ${n2} and the others count?`,
2770           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} contó ${tot} ${it.es}. ${n1} contó ${a}. ¿${cuantosEs(it)} contaron ${n2} y los demás?`},
2771        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
2772      };
2773    }
2774    const a=ri(200,600), b=ri(150,400);
2775    return {
2776      q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many more ${it.en} does ${a>b?n1:n2} have?`,
2777         es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} ${it.es} más tiene ${a>b?n1:n2}?`},
2778      a:{en:`${Math.max(a,b)} − ${Math.min(a,b)} = ${Math.abs(a-b)}`,
2779         es:`${Math.max(a,b)} − ${Math.min(a,b)} = ${Math.abs(a-b)}`}
2780    };
2781  }
2782},
2783{
2784  code:"2.OA.A.1", grade:2, dok:2, _k:5,
2785  title:{en:"Add & subtract within 100 — word problems",
2786         es:"Sumar y restar hasta 100 — problemas"},
2787  text:{en:"Use addition and subtraction within 100 to solve one- and two-step word problems involving situations of adding to, taking from, putting together, taking apart, and comparing, with unknowns in all positions, e.g., by using drawings and equations with a symbol for the unknown number to represent the problem.",
2788        es:"Usa la suma y la resta hasta 100 para resolver problemas verbales de uno y dos pasos de agregar, quitar, juntar, separar y comparar, con incógnitas en todas las posiciones, por ejemplo, usando dibujos y ecuaciones con un símbolo para el número desconocido."},
2789  build(n1,n2,lvl){
2790    const it = pickItem(), bin = pick(THEME.bins);
2791    let kind = ri(1,5);   // feeds Challenge (5 templates); On-level reassigns
2792
2793    /* ---- Support · DOK 1 : within 20, one step ---- */
2794    if(lvl===1){
2795      const k=ri(1,4);
2796      if(k===1){
2797        const a=ri(4,11), b=ri(3,9);
2798        return {
2799          q:{en:`${n1} had ${a} ${it.en}. ${n2} gave ${n1} ${b} more. How many ${it.en} does ${n1} have now?`,
2800             es:`${n1} tenía ${a} ${it.es}. ${n2} le dio ${b} más. ¿${cuantosEs(it)} ${it.es} tiene ${n1} ahora?`},
2801          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2802        };
2803      }
2804      if(k===2){
2805        const a=ri(11,20), b=ri(3,9);
2806        return {
2807          q:{en:`${n1} had ${a} ${it.en} and gave away ${b}. How many ${it.en} are left?`,
2808             es:`${n1} tenía ${a} ${it.es} y regaló ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
2809          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2810        };
2811      }
2812      if(k===3){
2813        const a=ri(6,14), b=ri(5,12);
2814        return {
2815          q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. How many do they have altogether?`,
2816             es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ¿${cuantosEs(it)} tienen en total?`},
2817          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
2818        };
2819      }
2820      const a=ri(12,20), b=ri(4,9);
2821      return {
2822        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b} ${it.en}. How many more ${it.en} does ${n1} have?`,
2823           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b} ${it.es}. ¿${cuantosEs(it)} ${it.es} más tiene ${n1}?`},
2824        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
2825      };
2826    }
2827
2828    /* ---- Challenge · DOK 3 : two steps + explain ---- */
2829    if(lvl===3){
2830      if(kind===1){
2831        const a=ri(30,60), b=ri(15,30), c=ri(10,25);
2832        return {
2833          q:{en:`${n1} started with ${a} ${it.en}, got ${b} more from ${n2}, then gave ${c} to the ${THEME.group.en}. How many ${it.en} does ${n1} have now? Show both steps.`,
2834             es:`${n1} empezó con ${a} ${it.es}, recibió ${b} más de ${n2} y luego dio ${c} a ${elLaEs(THEME.group)} ${THEME.group.es}. ¿${cuantosEs(it)} ${it.es} tiene ahora? Muestra los dos pasos.`},
2835          a:{en:`${a}+${b}=${a+b}, then ${a+b}−${c}=${a+b-c}`, es:`${a}+${b}=${a+b}, luego ${a+b}−${c}=${a+b-c}`}
2836        };
2837      }
2838      if(kind===2){
2839        const a=ri(40,70), b=ri(15,35);
2840        return {
2841          q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${b}. ${n2} says they need ${a-b+ri(2,6)} more to have the same amount. Is ${n2} right? Explain how you know.`,
2842             es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${b}. ${n2} dice que necesita ${a-b+ri(2,6)} más para tener lo mismo. ¿Tiene razón? Explica cómo lo sabes.`},
2843          a:{en:`No — ${a}−${b}=${a-b} is what's needed`, es:`No — ${a}−${b}=${a-b} es lo que falta`}
2844        };
2845      }
2846      if(kind===3){
2847        const b=ri(3,6), each=ri(8,15), tot=b*each;
2848        const used=ri(10, Math.min(25, tot-5));   // must never exceed what was packed
2849        return {
2850          q:{en:`${n1} filled ${b} ${bin.en} with ${each} ${it.en} each, then used ${used}. How many ${it.en} are left? Explain which step you did first and why.`,
2851             es:`${n1} llenó ${b} ${bin.es} con ${each} ${it.es} cada ${unoEs(bin)} y luego usó ${used}. ¿${cuantosEs(it)} ${it.es} quedan? Explica qué paso hiciste primero y por qué.`},
2852          a:{en:`${tot} total − ${used} = ${tot-used}`, es:`${tot} en total − ${used} = ${tot-used}`}
2853        };
2854      }
2855      if(kind===4){
2856        const start=ri(25,55), got=ri(12,30), tot=start+got;
2857        return {
2858          q:{en:`${n1} had some ${it.en}. After ${n2} gave ${n1} ${got} more, ${n1} had ${tot}. How many did ${n1} start with? Write the equation you used.`,
2859             es:`${n1} tenía algunos ${it.es}. Después de que ${n2} le dio ${got} más, ${n1} tenía ${tot}. ¿Con ${cuantosLc(it)} empezó? Escribe la ecuación que usaste.`},
2860          a:{en:`___ + ${got} = ${tot}, so ${start}`, es:`___ + ${got} = ${tot}, entonces ${start}`}
2861        };
2862      }
2863      // the wrong claim is off by 12-25 so estimation decisively catches it
2864      const a=ri(30,60), b=ri(12,25);
2865      const claim=a+b+ (ri(0,1)? ri(12,25) : -ri(12,25));
2866      return {
2867        q:{en:`${n1} has ${a} ${it.en} and buys ${b} more. ${n2} says ${n1} now has ${claim}. Without adding exactly, is ${n2}'s answer reasonable? Explain using estimation.`,
2868           es:`${n1} tiene ${a} ${it.es} y compra ${b} más. ${n2}
2868 dice que ahora tiene ${claim}. Sin sumar con exactitud, ¿es razonable la respuesta de ${n2}? Explica usando la estimación.`},
2869        a:{en:`Not reasonable — estimate ${Math.round(a/10)*10}+${Math.round(b/10)*10}=${Math.round(a/10)*10+Math.round(b/10)*10}; exact is ${a+b}`,
2870           es:`No es razonable — estima ${Math.round(a/10)*10}+${Math.round(b/10)*10}=${Math.round(a/10)*10+Math.round(b/10)*10}; exacto es ${a+b}`}
2871      };
2872    }
2873
2874    /* ---- On level · DOK 2 ---- */
2875    kind = ri(1,5);   // more variety at the tier teachers use most
2876    if(kind===1){
2877      const a=ri(14,48), b=ri(11,39);
2878      return {
2879        q:{en:`${n1} counted ${a} ${it.en} in the ${bin.one.en}. Then ${n1} found ${b} more ${it.en} in a desk. How many ${it.en} does ${n1} have in all?`,
2880           es:`${n1} contó ${a} ${it.es} en ${elLaEs(bin)} ${bin.one.es}. Luego ${n1} encontró ${b} ${it.es} más en un pupitre. ¿${cuantosEs(it)} ${it.es} tiene ${n1} en total?`},
2881        a:{en:`${a+b} ${it.en}`, es:`${a+b} ${it.es}`}
2882      };
2883    }
2884    if(kind===2){
2885      const a=ri(45,95), b=ri(12,40);
2886      return {
2887        q:{en:`${n1} started the day with ${a} ${it.en}. ${n1} handed out ${b} of them to the ${THEME.group.en}. How many ${it.en} are left?`,
2888           es:`${n1} empezó el día con ${a} ${it.es}. ${n1} repartió ${b} a ${elLaEs(THEME.group)} ${THEME.group.es}. ¿${cuantosEs(it)} ${it.es} quedan?`},
2889        a:{en:`${a-b} ${it.en}`, es:`${a-b} ${it.es}`}
2890      };
2891    }
2892    if(kind===3){
2893      const a=ri(30,70), b=ri(12,28);
2894      return {
2895        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${b} ${it.en}. How many more ${it.en} does ${n1} have than ${n2}?`,
2896           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${b} ${it.es}. ¿${cuantosEs(it)} ${it.es} más tiene ${n1} que ${n2}?`},
2897        a:{en:`${a-b} more ${it.en}`, es:`${a-b} ${it.es} más`}
2898      };
2899    }
2900    if(kind===4){
2901      const start=ri(25,55), got=ri(10,30), tot=start+got;
2902      return {
2903        q:{en:`${n1} had some ${it.en}. ${n2} gave ${n1} ${got} more. Now ${n1} has ${tot}. How many did ${n1} start with?`,
2904           es:`${n1} tenía algunos ${it.es}. ${n2} le dio ${got} más. Ahora ${n1} tiene ${tot}. ¿Con ${cuantosLc(it)} empezó ${n1}?`},
2905        a:{en:`___ + ${got} = ${tot}, so ${start}`, es:`___ + ${got} = ${tot}, entonces ${start}`}
2906      };
2907    }
2908    const morning=ri(20,45), afternoon=ri(15,35);
2909    return {
2910      q:{en:`${n1} counted ${morning} ${it.en} in the morning and ${afternoon} more in the afternoon. How many ${it.en} did ${n1} count in all?`,
2911         es:`${n1} contó ${morning} ${it.es} en la mañana y ${afternoon} más en la tarde. ¿${cuantosEs(it)} ${it.es} contó ${n1} en total?`},
2912      a:{en:`${morning+afternoon} ${it.en}`, es:`${morning+afternoon} ${it.es}`}
2913    };
2914  }
2915},
2916{
2917  code:"2.OA.C.4", grade:2, dok:2,
2918  title:{en:"Arrays & repeated addition",
2919         es:"Arreglos y suma repetida"},
2920  text:{en:"Use addition to find the total number of objects arranged in rectangular arrays with up to 5 rows and up to 5 columns; write an equation to express the total as a sum of equal addends.",
2921        es:"Usa la suma para hallar el número total de objetos organizados en arreglos rectangulares de hasta 5 filas y 5 columnas; escribe una ecuación que exprese el total como una suma de sumandos iguales."},
2922  build(n1,n2,lvl){
2923    const it = pickItem(), sp = pick(THEME.spots);
2924    const sumStr = (c,r)=>Array(r).fill(c).join(" + ");
2925
2926    /* ---- Support · DOK 1 : tiny arrays, addition modeled ---- */
2927    if(lvl===1){
2928      const k=ri(1,4);
2929      if(k===1){
2930        const r=2, c=ri(2,4);
2931        return {
2932          q:{en:`${n1} put ${it.en} in ${r} rows with ${c} in each row. Add ${c} + ${c} to find how many in all.`,
2933             es:`${n1} puso ${it.es} en ${r} filas con ${c} en cada fila. Suma ${c} + ${c} para hallar ${cuantosLc(it)} hay en total.`},
2934          a:{en:`${c} + ${c} = ${r*c}`, es:`${c} + ${c} = ${r*c}`}
2935        };
2936      }
2937      if(k===2){
2938        const r=3, c=ri(2,3);
2939        return {
2940          q:{en:`${n1} set ${it.en} on ${r} ${sp.en} with ${c} on each one. Count by ${c}s to find the total.`,
2941             es:`${n1}
2941 puso ${it.es} en ${r} ${sp.es} con ${c} en cada ${unoEs(sp)}. Cuenta de ${c} en ${c} para hallar el total.`},
2942          a:{en:`${sumStr(c,r)} = ${r*c}`, es:`${sumStr(c,r)} = ${r*c}`}
2943        };
2944      }
2945      if(k===3){
2946        const r=ri(2,3), c=ri(2,4);
2947        return {
2948          q:{en:`${n1} made ${r} rows of ${it.en} with ${c} in each row. Draw the rows. How many ${it.en} in all?`,
2949             es:`${n1} hizo ${r} filas de ${it.es} con ${c} en cada fila. Dibuja las filas. ¿${cuantosEs(it)} ${it.es} hay en total?`},
2950          a:{en:`${sumStr(c,r)} = ${r*c}`, es:`${sumStr(c,r)} = ${r*c}`}
2951        };
2952      }
2953      const r=ri(2,4), c=2;
2954      return {
2955        q:{en:`${n1} lined up ${it.en} in ${r} rows of ${c}. Write the addition equation and solve it.`,
2956           es:`${n1} alineó ${it.es} en ${r} filas de ${c}. Escribe la ecuación de suma y resuélvela.`},
2957        a:{en:`${sumStr(c,r)} = ${r*c}`, es:`${sumStr(c,r)} = ${r*c}`}
2958      };
2959    }
2960
2961    /* ---- Challenge · DOK 3 : judge, compare, construct ---- */
2962    if(lvl===3){
2963      const k=ri(1,5);
2964      if(k===1){
2965        const r=ri(3,5), c=ri(2,5), wrongR=r+(ri(0,1)?1:-1);
2966        return {
2967          q:{en:`${n1} arranged ${it.en} in ${r} rows of ${c}. ${n2} wrote ${sumStr(c,Math.max(2,wrongR))} to find the total. Is ${n2}'s equation right? Explain and fix it if needed.`,
2968             es:`${n1} organizó ${it.es} en ${r} filas de ${c}. ${n2} escribió ${sumStr(c,Math.max(2,wrongR))} para hallar el total. ¿Está bien la ecuación de ${n2}? Explica y corrígela si hace falta.`},
2969          a:{en:`No — ${r} rows need ${r} addends: ${sumStr(c,r)} = ${r*c}`,
2970             es:`No — ${r} filas necesitan ${r} sumandos: ${sumStr(c,r)} = ${r*c}`}
2971        };
2972      }
2973      if(k===2){
2974        const r=ri(2,4), c=ri(2,5);
2975        while(r===c) return this.build(n1,n2,lvl);
2976        return {
2977          q:{en:`${n2} says ${r} rows of ${c} ${it.en} holds a different total than ${c} rows of ${r}. Is ${n2} right? Draw both arrays and explain.`,
2978             es:`${n2} dice que ${r} filas de ${c} ${it.es} da un total diferente que ${c} filas de ${r}. ¿Tiene razón? Dibuja los dos arreglos y explica.`},
2979          a:{en:`No — both make ${r*c}`, es:`No — los dos dan ${r*c}`}
2980        };
2981      }
2982      if(k===3){
2983        const c=ri(2,5), r=ri(2,5), tot=r*c;
2984        return {
2985          q:{en:`${n1} has ${tot} ${it.en} and wants equal rows of ${c}. How many rows can ${n1} make? Write the addition equation that proves it.`,
2986             es:`${n1} tiene ${tot} ${it.es} y quiere filas iguales de ${c}. ¿Cuántas filas puede hacer? Escribe la ecuación de suma que lo comprueba.`},
2987          a:{en:`${r} rows — ${sumStr(c,r)} = ${tot}`, es:`${r} filas — ${sumStr(c,r)} = ${tot}`}
2988        };
2989      }
2990      if(k===4){
2991        const r=ri(3,5), c=ri(3,5), miss=ri(1,c-1);
2992        return {
2993          q:{en:`${n1} started an array of ${it.en} with ${r} rows of ${c}, but the last row only has ${miss}. How many ${it.en} are there? Explain how the equation changes.`,
2994             es:`${n1} empezó un arreglo de ${it.es} con ${r} filas de ${c}, pero la última fila solo tiene ${miss}. ¿${cuantosEs(it)} ${it.es} hay? Explica cómo cambia la ecuación.`},
2995          a:{en:`${sumStr(c,r-1)} + ${miss} = ${(r-1)*c+miss}`, es:`${sumStr(c,r-1)} + ${miss} = ${(r-1)*c+miss}`}
2996        };
2997      }
2998      const tot=pick([4,6,8,9,10,12,16,20,25]);
2999      return {
3000        q:{en:`${n1} has ${tot} ${it.en}. Show one way to arrange all of them in equal rows. Write the addition equation for your array.`,
3001           es:`${n1} tiene ${tot} ${it.es}. Muestra una manera de organizarlos todos en filas iguales. Escribe la ecuación de suma de tu arreglo.`},
3002        a:{en:`any equal rows work — e.g. ${tot%2===0? sumStr(tot/2,2)+" = "+tot : sumStr(tot/3,3)+" = "+tot}`,
3003           es:`cualquier arreglo de filas iguales — p. ej. ${tot%2===0? sumStr(tot/2,2)+" = "+tot : sumStr(tot/3,3)+" = "+tot}`}
3004      };
3005    }
3006
3007    /* ---- On level · DOK 2 : arrays up to 5×5 ---- */
3008    const k=ri(1,5);
3009    if(k===1){
3010      const r=ri(2,5), c=ri(2,5);
3011      return {
3012        q:{en:`${n1} arranged ${it.en} in ${r} rows with ${c} in each row. Write an addition equation and find the total.`,
3013           es:`${n1} organizó ${it.es} en ${r} filas con ${c} en cada fila. Escribe una ecuación de suma y halla el total.`},
3014        a:{en:`${sumStr(c,r)} = ${r*c}`, es:`${sumStr(c,r)} = ${r*c}`}
3015      };
3016    }
3017    if(k===2){
3018      const r=ri(2,5), c=ri(2,5);
3019      return {
3020        q:{en:`${n1} put ${c} ${it.en} on each of ${r} ${sp.en}. Write the total as a sum of equal addends.`,
3021           es:`${n1}
3021 puso ${c} ${it.es} en cada ${unoEs(sp)} de ${r} ${sp.es}. Escribe el total como una suma de sumandos iguales.`},
3022        a:{en:`${sumStr(c,r)} = ${r*c}`, es:`${sumStr(c,r)} = ${r*c}`}
3023      };
3024    }
3025    if(k===3){
3026      const c=ri(2,5), r=ri(3,5), tot=r*c;
3027      return {
3028        q:{en:`${n1} wrote ${sumStr(c,r)} for an array of ${it.en}. How many rows does the array have, and what is the total?`,
3029           es:`${n1} escribió ${sumStr(c,r)} para un arreglo de ${it.es}. ¿Cuántas filas tiene el arreglo y cuál es el total?`},
3030        a:{en:`${r} rows; total ${tot}`, es:`${r} filas; total ${tot}`}
3031      };
3032    }
3033    if(k===4){
3034      const r1=ri(2,4), c=ri(2,5), r2=ri(2,4);
3035      return {
3036        q:{en:`${n1} made ${r1} rows of ${c} ${it.en}. ${n2} made ${r2} rows of ${c}. How many ${it.en} did they use altogether?`,
3037           es:`${n1} hizo ${r1} filas de ${c} ${it.es}. ${n2} hizo ${r2} filas de ${c}. ¿${cuantosEs(it)} ${it.es} usaron en total?`},
3038        a:{en:`${r1*c} + ${r2*c} = ${(r1+r2)*c}`, es:`${r1*c} + ${r2*c} = ${(r1+r2)*c}`}
3039      };
3040    }
3041    const r=ri(2,5), c=ri(2,5);
3042    return {
3043      q:{en:`A tray of ${it.en} has ${r} rows and ${c} columns. ${n1} says the total is ${r*c}. Write the equal-addends equation that checks it.`,
3044         es:`Una bandeja de ${it.es} tiene ${r} filas y ${c} columnas. ${n1} dice que el total es ${r*c}. Escribe la ecuación de sumandos iguales que lo comprueba.`},
3045      a:{en:`${sumStr(c,r)} = ${r*c} ✓`, es:`${sumStr(c,r)} = ${r*c} ✓`}
3046    };
3047  }
3048},
3049{
3050  code:"2.MD.B.5", grade:2, dok:2,
3051  title:{en:"Length word problems — same units",
3052         es:"Problemas de longitud — mismas unidades"},
3053  text:{en:"Use addition and subtraction within 100 to solve word problems involving lengths that are given in the same units, e.g., by using drawings (such as drawings of rulers) and equations with a symbol for the unknown number to represent the problem.",
3054        es:"Usa la suma y la resta hasta 100 para resolver problemas verbales de longitudes dadas en las mismas unidades, por ejemplo, usando dibujos (como dibujos de reglas) y ecuaciones con un símbolo para el número desconocido."},
3055  build(n1,n2,lvl){
3056    const it = pickItem();
3057    // Exit tickets lock one object per ticket; lock the unit too, so a
3058    // three-problem ticket never mixes cm with inches.
3059    const u = ITEMLOCK ? {en:"cm",es:"cm"} : pick([{en:"cm",es:"cm"},{en:"inches",es:"pulgadas"}]);
3060
3061    /* ---- Support · DOK 1 : one step, small lengths ---- */
3062    if(lvl===1){
3063      const k=ri(1,4);
3064      if(k===1){
3065        const a=ri(5,12), b=ri(3,8);
3066        return {
3067          q:{en:`${n1}'s row of ${it.en} is ${a} ${u.en} long. ${n1} adds more to make it ${b} ${u.en} longer. How long is the row now?`,
3068             es:`La fila de ${it.es} de ${n1} mide ${a} ${u.es}. ${n1} agrega más para hacerla ${b} ${u.es} más larga. ¿Cuánto mide la fila ahora?`},
3069          a:{en:`${a} + ${b} = ${a+b} ${u.en}`, es:`${a} + ${b} = ${a+b} ${u.es}`}
3070        };
3071      }
3072      if(k===2){
3073        const a=ri(10,20), b=ri(3,8);
3074        return {
3075          q:{en:`${n1} had a piece of ribbon ${a} ${u.en} long for the ${it.en} display and cut off ${b} ${u.en}. How long is the ribbon now?`,
3076             es:`${n1} tenía una cinta de ${a} ${u.es} para la exhibición de ${it.es} y cortó ${b} ${u.es}. ¿Cuánto mide la cinta ahora?`},
3077          a:{en:`${a} − ${b} = ${a-b} ${u.en}`, es:`${a} − ${b} = ${a-b} ${u.es}`}
3078        };
3079      }
3080      if(k===3){
3081        const a=ri(8,18), b=ri(3,7);
3082        return {
3083          q:{en:`${n1}'s line of ${it.en} is ${a} ${u.en} long. ${n2}'s line is ${b} ${u.en} long. How much longer is ${n1}'s line?`,
3084             es:`La línea de ${it.es} de ${n1} mide ${a} ${u.es}. La de ${n2} mide ${b} ${u.es}. ¿Cuánto más larga es la de ${n1}?`},
3085          a:{en:`${a} − ${b} = ${a-b} ${u.en}`, es:`${a} − ${b} = ${a-b} ${u.es}`}
3086        };
3087      }
3088      const a=ri(4,10), b=ri(4,10);
3089      return {
3090        q:{en:`${n1} lined up ${it.en} for ${a} ${u.en} and ${n2} continued for ${b} more ${u.en}. How long is the whole line?`,
3091           es:`${n1} alineó ${it.es} por ${a} ${u.es} y ${n2} continuó ${b} ${u.es} más. ¿Cuánto mide toda la línea?`},
3092        a:{en:`${a} + ${b} = ${a+b} ${u.en}`, es:`${a} + ${b} = ${a+b} ${u.es}`}
3093      };
3094    }
3095
3096    /* ---- Challenge · DOK 3 ---- */
3097    if(lvl===3){
3098      const k=ri(1,5);
3099      if(k===1){
3100        const tot=ri(40,90), a=ri(15,tot-15);
3101        return {
3102          q:{en:`${n1} and ${n2} need a banner ${tot} ${u.en} long for the ${it.en} table. ${n1}'s piece is ${a} ${u.en}. Write an equation with n for ${n2}'s piece, then solve.`,
3103             es:`${n1} y ${n2} necesitan un cartel de ${tot} ${u.es} para la mesa de ${it.es}. El pedazo de ${n1} mide ${a} ${u.es}. Escribe una ecuación con n para el pedazo de ${n2} y resuélvela.`},
3104          a:{en:`${a} + n = ${tot}; n = ${tot-a} ${u.en}`, es:`${a} + n = ${tot}; n = ${tot-a} ${u.es}`}
3105        };
3106      }
3107      if(k===2){
3108        const a=ri(30,60), b=ri(12,25);
3109        return {
3110          q:{en:`${n1}'s string for the ${it.en} display is ${a} ${u.en} and ${n2}'s is ${b} ${u.en}. ${n2} says the difference is ${a+b} ${u.en} because "difference means put together." What mistake is that, and what is the real difference?`,
3111             es:`El cordel de ${n1} para la exhibición de ${it.es} mide ${a} ${u.es} y el de ${n2} mide ${b} ${u.es}. ${n2} dice que la diferencia es ${a+b} ${u.es} porque "diferencia es juntar." ¿Qué error es ese y cuál es la diferencia real?`},
3112          a:{en:`Added instead of subtracted — ${a} − ${b} = ${a-b} ${u.en}`,
3113             es:`Sumó en vez de restar — ${a} − ${b} = ${a-b} ${u.es}`}
3114        };
3115      }
3116      if(k===3){
3117        const b=ri(10,25), half=ri(4,12), a=b+2*half;
3118        return {
3119          q:{en:`${n1}'s paper strip for the ${it.en} sign is ${a} ${u.en}; ${n2}'s is ${b} ${u.en}. How much should ${n1} cut off and give to ${n2} so the strips are equal? Explain.`,
3120             es:`La tira de papel de ${n1} para el letrero de ${it.es} mide ${a} ${u.es}; la de ${n2} mide ${b} ${u.es}. ¿Cuánto debe cortar ${n1} y darle a ${n2} para que las tiras sean iguales? Explica.`},
3121          a:{en:`(${a}−${b})÷2 = ${half} ${u.en}; both end at ${b+half}`,
3122             es:`(${a}−${b})÷2 = ${half} ${u.es}; las dos quedan en ${b+half}`}
3123        };
3124      }
3125      if(k===4){
3126        const a=ri(25,45), b=ri(20,40), claim=a+b+(ri(0,1)?ri(12,20):-ri(12,20));
3127        return {
3128          q:{en:`${n1} measured two shelves for ${it.en}: ${a} ${u.en} and ${b} ${u.en}. ${n2} says together they span ${claim} ${u.en}. Round to the nearest ten to check — is ${n2} reasonable?`,
3129             es:`${n1} midió dos estantes para ${it.es}: ${a} ${u.es} y ${b} ${u.es}. ${n2} dice que juntos miden ${claim} ${u.es}. Redondea a la decena para comprobar — ¿es razonable?`},
3130          a:{en:`≈${Math.round(a/10)*10}+${Math.round(b/10)*10}=${Math.round(a/10)*10+Math.round(b/10)*10}; exact ${a+b} — not reasonable`,
3131             es:`≈${Math.round(a/10)*10}+${Math.round(b/10)*10}=${Math.round(a/10)*10+Math.round(b/10)*10}; exacto ${a+b} — no es razonable`}
3132        };
3133      }
3134      const a=ri(20,40), add=ri(10,25), cut=ri(8, a+add-10);
3135      return {
3136        q:{en:`${n1}'s string for the ${it.en} display was ${a} ${u.en}. ${n2} tied on ${add} ${u.en} more, then ${n1} trimmed ${cut} ${u.en}. How long is it now? Show both steps.`,
3137           es:`El cordel de ${n1} para la exhibición de ${it.es} medía ${a} ${u.es}. ${n2} amarró ${add} ${u.es} más y luego ${n1} cortó ${cut} ${u.es}. ¿Cuánto mide ahora? Muestra los dos pasos.`},
3138        a:{en:`${a}+${add}=${a+add}, −${cut} = ${a+add-cut} ${u.en}`,
3139           es:`${a}+${add}=${a+add}, −${cut} = ${a+add-cut} ${u.es}`}
3140      };
3141    }
3142
3143    /* ---- On level · DOK 2 : within 100 ---- */
3144    const k=ri(1,5);
3145    if(k===1){
3146      const a=ri(20,55), b=ri(15,40);
3147      return {
3148        q:{en:`${n1}'s row of ${it.en} is ${a} ${u.en} long, and ${n2}'s row is ${b} ${u.en}. If they join the rows end to end, how long is the whole row?`,
3149           es:`La fila de ${it.es} de ${n1} mide ${a} ${u.es} y la de ${n2} mide ${b} ${u.es}. Si juntan las filas, ¿cuánto mide la fila completa?`},
3150        a:{en:`${a} + ${b} = ${a+b} ${u.en}`, es:`${a} + ${b} = ${a+b} ${u.es}`}
3151      };
3152    }
3153    if(k===2){
3154      const a=ri(45,95), b=ri(12,35);
3155      return {
3156        q:{en:`${n1} had ${a} ${u.en} of ribbon for wrapping ${it.en} and used ${b} ${u.en}. How much ribbon is left?`,
3157           es:`${n1} tenía ${a} ${u.es} de cinta para envolver ${it.es} y usó ${b} ${u.es}. ¿Cuánta cinta queda?`},
3158        a:{en:`${a} − ${b} = ${a-b} ${u.en}`, es:`${a} − ${b} = ${a-b} ${u.es}`}
3159      };
3160    }
3161    if(k===3){
3162      const a=ri(35,80), b=ri(12,30);
3163      return {
3164        q:{en:`${n1} jumped ${a} ${u.en} in the ${it.en} game, and ${n2} jumped ${b} ${u.en}. How much farther did ${n1} jump?`,
3165           es:`${n1} saltó ${a} ${u.es} en el juego de ${it.es} y ${n2} saltó ${b} ${u.es}. ¿Cuánto más lejos saltó ${n1}?`},
3166        a:{en:`${a} − ${b} = ${a-b} ${u.en}`, es:`${a} − ${b} = ${a-b} ${u.es}`}
3167      };
3168    }
3169    if(k===4){
3170      const tot=ri(40,90), a=ri(12,tot-12);
3171      return {
3172        q:{en:`A shelf for ${it.en} is ${tot} ${u.en} long. ${n1}'s ${it.en} take up ${a} ${u.en}. How many ${u.en} of shelf are left for ${n2}?`,
3173           es:`Un estante para ${it.es} mide ${tot} ${u.es}. ${losLasEs(it)==="los"?"Los":"Las"} ${it.es} de ${n1} ocupan ${a} ${u.es}. ¿Cuántos ${u.es} de estante quedan para ${n2}?`},
3174        a:{en:`${tot} − ${a} = ${tot-a} ${u.en}`, es:`${tot} − ${a} = ${tot-a} ${u.es}`}
3175      };
3176    }
3177    const a=ri(15,35), b=ri(10,30), c=ri(8,25);
3178    return {
3179      q:{en:`${n1} taped three strips for the ${it.en} poster: ${a} ${u.en}, ${b} ${u.en}, and ${c} ${u.en}. How long is the taped strip altogether?`,
3180         es:`${n1} pegó tres tiras para el cartel de ${it.es}: ${a} ${u.es}, ${b} ${u.es} y ${c} ${u.es}
3180. ¿Cuánto mide la tira completa?`},
3181      a:{en:`${a}+${b}+${c} = ${a+b+c} ${u.en}`, es:`${a}+${b}+${c} = ${a+b+c} ${u.es}`}
3182    };
3183  }
3184},
3185{
3186  code:"3.OA.A.3", grade:3, dok:2, _k:5,
3187  title:{en:"Multiply & divide within 100 — word problems",
3188         es:"Multiplicar y dividir hasta 100 — problemas"},
3189  text:{en:"Use multiplication and division within 100 to solve word problems in situations involving equal groups, arrays, and measurement quantities, e.g., by using drawings and equations with a symbol for the unknown number to represent the problem.",
3190        es:"Usa la multiplicación y la división hasta 100 para resolver problemas verbales de grupos iguales, arreglos y cantidades de medición, por ejemplo, usando dibujos y ecuaciones con un símbolo para el número desconocido."},
3191  build(n1,n2,lvl){
3192    const it = pickItem(), sp = pick(THEME.spots), bin = pick(THEME.bins);
3193    let kind = ri(1,5);   // feeds Challenge (5 templates); On-level reassigns
3194
3195    if(lvl===1){
3196      const k=ri(1,4);
3197      if(k===1){
3198        const a=ri(2,5), b=ri(2,5);
3199        return {
3200          q:{en:`${n1} put ${a} ${it.en} on each of ${b} ${sp.en}. How many ${it.en} in all? (Hint: draw ${b} groups of ${a}.)`,
3201             es:`${n1} puso ${a} ${it.es} en cada ${unoEs(sp)} de ${b} ${sp.es}. ¿${cuantosEs(it)} ${it.es} hay en total? (Pista: dibuja ${b} grupos de ${a}.)`},
3202          a:{en:`${a} × ${b} = ${a*b}`, es:`${a} × ${b} = ${a*b}`}
3203        };
3204      }
3205      if(k===2){
3206        const rows=ri(2,5), cols=ri(2,5);
3207        return {
3208          q:{en:`${n1} set up ${it.en} in ${rows} rows with ${cols} in each row. How many ${it.en} in all? (Hint: draw the rows.)`,
3209             es:`${n1} acomodó ${it.es} en ${rows} filas con ${cols} en cada fila. ¿${cuantosEs(it)} ${it.es} hay en total? (Pista: dibuja las filas.)`},
3210          a:{en:`${rows} × ${cols} = ${rows*cols}`, es:`${rows} × ${cols} = ${rows*cols}`}
3211        };
3212      }
3213      if(k===3){
3214        const b=ri(2,4), each=ri(2,5), tot=b*each;
3215        return {
3216          q:{en:`${n1} shared ${tot} ${it.en} equally among ${b} friends. How many did each friend get? (Hint: draw ${b} groups.)`,
3217             es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${b} amigos. ¿${cuantosEs(it)} recibió cada amigo? (Pista: dibuja ${b} grupos.)`},
3218          a:{en:`${tot} ÷ ${b} = ${each}`, es:`${tot} ÷ ${b} = ${each}`}
3219        };
3220      }
3221      const a=ri(2,5), b=ri(2,4);
3222      return {
3223        q:{en:`${n1} filled ${b} ${bin.en} with ${a} ${it.en} in each one. How many ${it.en} in all?`,
3224           es:`${n1} llenó ${b} ${bin.es} con ${a} ${it.es} en cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
3225        a:{en:`${a} × ${b} = ${a*b}`, es:`${a} × ${b} = ${a*b}`}
3226      };
3227    }
3228
3229    if(lvl===3){
3230      if(kind===1){
3231        const a=ri(6,9), b=ri(5,9), gave=ri(4,15);
3232        return {
3233          q:{en:`${n1} filled ${b} ${bin.en} with ${a} ${it.en} in each one, then gave ${gave} ${it.en} to ${n2}. How many ${it.en} does ${n1} have left? Show both steps and explain which one you did first.`,
3234             es:`${n1} llenó ${b} ${bin.es} con ${a} ${it.es} en cada ${unoEs(bin)} y luego le dio ${gave} ${it.es} a ${n2}. ¿${cuantosEs(it)} ${it.es} le quedan a ${n1}? Muestra los dos pasos y explica cuál hiciste primero.`},
3235          a:{en:`${a}×${b}=${a*b}, then ${a*b}−${gave}=${a*b-gave}`, es:`${a}×${b}=${a*b}, luego ${a*b}−${gave}=${a*b-gave}`}
3236        };
3237      }
3238      if(kind===2){
3239        const each=ri(6,9), b=ri(4,8), tot=each*b;
3240        return {
3241          q:{en:`${n1} shared ${tot} ${it.en} equally among ${b} friends. ${n2} says each friend got ${each+1}. Is ${n2} right? Explain how you know.`,
3242             es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${b} amigos. ${n2} dice que cada amigo recibió ${each+1}. ¿Tiene razón ${n2}? Explica cómo lo sabes.`},
3243          a:{en:`No — ${tot}÷${b}=${each}, not ${each+1}`, es:`No — ${tot}÷${b}=${each}, no ${each+1}`}
3244        };
3245      }
3246      if(kind===3){
3247        const rows=ri(5,8), cols=ri(5,9), extra=ri(3,12);
3248        return {
3249          q:{en:`${n1} and ${n2} set up ${it.en} in ${rows} rows of ${cols}, then added ${extra} more. How many ${it.en} are there now? Explain why you multiplied before you added.`,
3250             es:`${n1} y ${n2} acomodaron ${it.es} en ${rows} filas de ${cols}
3250 y luego agregaron ${extra} más. ¿${cuantosEs(it)} ${it.es} hay ahora? Explica por qué multiplicaste antes de sumar.`},
3251          a:{en:`${rows}×${cols}=${rows*cols}, +${extra} = ${rows*cols+extra}`, es:`${rows}×${cols}=${rows*cols}, +${extra} = ${rows*cols+extra}`}
3252        };
3253      }
3254      if(kind===4){
3255        const groups=ri(3,8), each=ri(4,9), tot=groups*each;
3256        return {
3257          q:{en:`${n1} has ${tot} ${it.en} and wants equal groups of ${each}. ${n2} says ${n1} can make ${groups+ri(1,2)} groups. Is ${n2} right? Explain how you know without counting one by one.`,
3258             es:`${n1} tiene ${tot} ${it.es} y quiere grupos iguales de ${each}. ${n2} dice que puede hacer ${groups+ri(1,2)} grupos. ¿Tiene razón? Explica cómo lo sabes sin contar de uno en uno.`},
3259          a:{en:`No — ${tot}÷${each}=${groups} groups`, es:`No — ${tot}÷${each}=${groups} grupos`}
3260        };
3261      }
3262      const aR=ri(3,6), aC=ri(4,8), bR=ri(3,6), bC=ri(4,8);
3263      return {
3264        q:{en:`${n1} arranged ${it.en} in ${aR} rows of ${aC}. ${n2} arranged ${it.en} in ${bR} rows of ${bC}. Who used more ${it.en}, and how many more? Show your reasoning.`,
3265           es:`${n1} acomodó ${it.es} en ${aR} filas de ${aC}. ${n2} acomodó ${it.es} en ${bR} filas de ${bC}. ¿Quién usó más ${it.es} y ${cuantosLc(it)} más? Muestra tu razonamiento.`},
3266        a:{en:`${aR}×${aC}=${aR*aC} vs ${bR}×${bC}=${bR*bC} → ${aR*aC===bR*bC?"equal!":(aR*aC>bR*bC?n1:n2)+" by "+Math.abs(aR*aC-bR*bC)}`,
3267           es:`${aR}×${aC}=${aR*aC} vs ${bR}×${bC}=${bR*bC} → ${aR*aC===bR*bC?"¡iguales!":(aR*aC>bR*bC?n1:n2)+" por "+Math.abs(aR*aC-bR*bC)}`}
3268      };
3269    }
3270
3271    kind = ri(1,5);   // more variety at the tier teachers use most
3272    if(kind===1){
3273      const a=ri(3,9), b=ri(4,9);
3274      return {
3275        q:{en:`${n1} put ${a} ${it.en} on each of ${b} ${sp.en}. How many ${it.en} did ${n1} use in all?`,
3276           es:`${n1} puso ${a} ${it.es} en cada ${unoEs(sp)} de ${b} ${sp.es}. ¿${cuantosEs(it)} ${it.es} usó ${n1} en total?`},
3277        a:{en:`${a*b} ${it.en}`, es:`${a*b} ${it.es}`}
3278      };
3279    }
3280    if(kind===2){
3281      const b=ri(3,8), each=ri(4,9), tot=b*each;
3282      return {
3283        q:{en:`${n1} shared ${tot} ${it.en} equally among ${b} friends. How many ${it.en} did each friend get?`,
3284           es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${b} amigos. ¿${cuantosEs(it)} ${it.es} recibió cada amigo?`},
3285        a:{en:`${each} ${it.en} each`, es:`${each} ${it.es} cada ${unoEs(it)}`}
3286      };
3287    }
3288    if(kind===3){
3289      const rows=ri(4,8), cols=ri(3,9);
3290      return {
3291        q:{en:`${n1} and ${n2} set up ${it.en} in ${rows} rows with ${cols} in each row. How many ${it.en} are there altogether?`,
3292           es:`${n1} y ${n2} acomodaron ${it.es} en ${rows} filas con ${cols} en cada fila. ¿${cuantosEs(it)} ${it.es} hay en total?`},
3293        a:{en:`${rows*cols} ${it.en}`, es:`${rows*cols} ${it.es}`}
3294      };
3295    }
3296    if(kind===4){
3297      const per=ri(4,9), boxes=ri(3,8), tot=per*boxes;
3298      return {
3299        q:{en:`${n1} has ${tot} ${it.en} and puts ${per} in each ${bin.one.en}. How many ${bin.en} does ${n1} need?`,
3300           es:`${n1} tiene ${tot} ${it.es} y pone ${per} en cada ${bin.one.es}. ¿${cuantosEs(bin)} ${bin.es} necesita ${n1}?`},
3301        a:{en:`${tot} ÷ ${per} = ${boxes}`, es:`${tot} ÷ ${per} = ${boxes}`}
3302      };
3303    }
3304    const each=ri(3,8), groups=ri(4,9), total=each*groups;
3305    return {
3306      q:{en:`${n1} needs ${total} ${it.en} for ${groups} equal groups. How many ${it.en} go in each group?`,
3307         es:`${n1} necesita ${total} ${it.es} para ${groups} grupos iguales. ¿${cuantosEs(it)} ${it.es} van en cada grupo?`},
3308      a:{en:`${total} ÷ ${groups} = ${each}`, es:`${total} ÷ ${groups} = ${each}`}
3309    };
3310  }
3311},
3312{
3313  code:"3.OA.A.4", grade:3, dok:2,
3314  title:{en:"Find the unknown in a multiplication or division equation",
3315         es:"Hallar el número desconocido en una ecuación"},
3316  text:{en:"Determine the unknown whole number in a multiplication or division equation relating three whole numbers.",
3317        es:"Determina el número entero desconocido en una ecuación de multiplicación o división que relaciona tres números enteros."},
3318  build(n1,n2,lvl){
3319    const it = pickItem(), bin = pick(THEME.bins);
3320
3321    /* ---- Support · DOK 1 : small facts, unknown at the end ---- */
3322    if(lvl===1){
3323      const k=ri(1,4);
3324      if(k===1){
3325        const a=ri(2,5), b=ri(2,5);
3326        return {
3327          q:{en:`${n1} filled ${a} ${bin.en} with ${b} ${it.en} each. Complete: ${a} × ${b} = ___`,
3328             es:`${n1} llenó ${a} ${bin.es} con ${b} ${it.es} cada ${unoEs(bin)}. Completa: ${a} × ${b} = ___`},
3329          a:{en:`${a*b}`, es:`${a*b}`}
3330        };
3331      }
3332      if(k===2){
3333        const a=ri(2,5), b=ri(2,5);
3334        return {
3335          q:{en:`${n1} has ${a*b} ${it.en} in ${a} equal groups. Complete: ${a} × ___ = ${a*b}`,
3336             es:`${n1} tiene ${a*b} ${it.es} en ${a} grupos iguales. Completa: ${a} × ___ = ${a*b}`},
3337          a:{en:`${b}`, es:`${b}`}
3338        };
3339      }
3340      if(k===3){
3341        const a=ri(2,5), b=ri(2,5);
3342        return {
3343          q:{en:`${n1} shared ${a*b} ${it.en} into groups of ${b}. Complete: ${a*b} ÷ ${b} = ___`,
3344             es:`${n1} repartió ${a*b} ${it.es} en grupos de ${b}. Completa: ${a*b} ÷ ${b} = ___`},
3345          a:{en:`${a}`, es:`${a}`}
3346        };
3347      }
3348      const a=ri(2,5), b=ri(3,6);
3349      return {
3350        q:{en:`${n1} put ${it.en} in ${a} rows. There are ${a*b} in all. How many are in each row?`,
3351           es:`${n1} puso ${it.es} en ${a} filas. Hay ${a*b} en total. ¿${cuantosEs(it)} hay en cada fila?`},
3352        a:{en:`${a} × ${b} = ${a*b}, so ${b} per row`, es:`${a} × ${b} = ${a*b}, entonces ${b} por fila`}
3353      };
3354    }
3355
3356    /* ---- Challenge · DOK 3 : unknown in any position, justify ---- */
3357    if(lvl===3){
3358      const k=ri(1,4);
3359      if(k===1){
3360        const a=ri(4,9), b=ri(4,9);
3361        return {
3362          q:{en:`${n1} wrote ___ × ${b} = ${a*b} for the ${it.en} array. What number goes in the blank? Explain how you used division to find it.`,
3363             es:`${n1} escribió ___ × ${b} = ${a*b} para el arreglo de ${it.es}. ¿Qué número va en el espacio? Explica cómo usaste la división para hallarlo.`},
3364          a:{en:`${a} — because ${a*b} ÷ ${b} = ${a}`, es:`${a} — porque ${a*b} ÷ ${b} = ${a}`}
3365        };
3366      }
3367      if(k===2){
3368        const a=ri(4,8), b=ri(4,8);
3369        return {
3370          q:{en:`${n2} says ${a} × ___ = ${a*b} has the answer ${b+2}. Check with multiplication. What went wrong, and what is the right number?`,
3371             es:`${n2} dice que en ${a} × ___ = ${a*b} la respuesta es ${b+2}. Comprueba con la multiplicación. ¿Qué salió mal y cuál es el número correcto?`},
3372          a:{en:`${a}×${b+2}=${a*(b+2)}, not ${a*b} — the answer is ${b}`,
3373             es:`${a}×${b+2}=${a*(b+2)}, no ${a*b} — la respuesta es ${b}`}
3374        };
3375      }
3376      if(k===3){
3377        const a=ri(3,7), b=ri(4,8);
3378        return {
3379          q:{en:`${n1} has ${a*b} ${it.en}. Write ONE multiplication equation and ONE division equation that both describe putting them in ${a} equal groups.`,
3380             es:`${n1} tiene ${a*b} ${it.es}. Escribe UNA ecuación de multiplicación y UNA de división que describan ponerlos en ${a} grupos iguales.`},
3381          a:{en:`${a} × ${b} = ${a*b} and ${a*b} ÷ ${a} = ${b}`, es:`${a} × ${b} = ${a*b} y ${a*b} ÷ ${a} = ${b}`}
3382        };
3383      }
3384      const a=ri(3,6), b=ri(4,8), extra=ri(2,6);
3385      return {
3386        q:{en:`${n1} needs ${a*b+extra} ${it.en}. So far ${n1} filled ${a} ${bin.en} with ${b} each. Write an equation with n for how many more are needed, then solve.`,
3387           es:`${n1} necesita ${a*b+extra} ${it.es}. Hasta ahora llenó ${a} ${bin.es} con ${b} cada ${unoEs(bin)}. Escribe una ecuación con n para ${cuantosLc(it)} faltan y resuélvela.`},
3388        a:{en:`${a}×${b}+n=${a*b+extra}; n=${extra}`, es:`${a}×${b}+n=${a*b+extra}; n=${extra}`}
3389      };
3390    }
3391
3392    /* ---- On level · DOK 2 ---- */
3393    const k=ri(1,4);
3394    if(k===1){
3395      const a=ri(3,9), b=ri(3,9);
3396      return {
3397        q:{en:`${n1} put ${a*b} ${it.en} into ${a} equal groups. Complete: ${a} × ___ = ${a*b}. How many in each group?`,
3398           es:`${n1} puso ${a*b} ${it.es} en ${a} grupos iguales. Completa: ${a} × ___ = ${a*b}. ¿${cuantosEs(it)} hay en cada grupo?`},
3399        a:{en:`${b}`, es:`${b}`}
3400      };
3401    }
3402    if(k===2){
3403      const a=ri(3,9), b=ri(3,9);
3404      return {
3405        q:{en:`${n1} shared ${a*b} ${it.en} with ${n2} into groups of ${b}. Complete: ${a*b} ÷ ___ = ${a}`,
3406           es:`${n1} repartió ${a*b} ${it.es} con ${n2} en grupos de ${b}. Completa: ${a*b} ÷ ___ = ${a}`},
3407        a:{en:`${b}`, es:`${b}`}
3408      };
3409    }
3410    if(k===3){
3411      const a=ri(4,9), b=ri(3,8);
3412      return {
3413        q:{en:`${n1} filled ${bin.en} with ${b} ${it.en} each and used ${a*b} ${it.en} in all. How many ${bin.en} did ${n1} fill?`,
3414           es:`${n1} llenó ${bin.es} con ${b} ${it.es} cada ${unoEs(bin)} y usó ${a*b} ${it.es} en total. ¿${cuantosEs(bin)} ${bin.es} llenó?`},
3415        a:{en:`${a*b} ÷ ${b} = ${a}`, es:`${a*b} ÷ ${b} = ${a}`}
3416      };
3417    }
3418    const a=ri(3,8), b=ri(4,9);
3419    return {
3420      q:{en:`${n1} arranged ${it.en} in equal rows of ${b} and used ${a*b} in all. How many rows did ${n1} make?`,
3421         es:`${n1} acomodó ${it.es} en filas iguales de ${b} y usó ${a*b} en total. ¿Cuántas filas hizo?`},
3422      a:{en:`${a*b} ÷ ${b} = ${a} rows`, es:`${a*b} ÷ ${b} = ${a} filas`}
3423    };
3424  }
3425},
3426{
3427  code:"3.OA.D.8", grade:3, dok:3,
3428  title:{en:"Two-step word problems (all four operations)",
3429         es:"Problemas de dos pasos (las cuatro operaciones)"},
3430  text:{en:"Solve two-step word problems using the four operations. Represent these problems using equations with a letter standing for the unknown quantity. Assess the reasonableness of answers using mental computation and estimation strategies including rounding.",
3431        es:"Resuelve problemas verbales de dos pasos usando las cuatro operaciones. Representa estos problemas con ecuaciones usando una letra para la cantidad desconocida. Evalúa si las respuestas son razonables usando cálculo mental y estrategias de estimación, incluyendo el redondeo."},
3432  build(n1,n2,lvl){
3433    const it = pickItem(), bin = pick(THEME.bins);
3434
3435    /* ---- Support · DOK 1 : two clean steps, small numbers ---- */
3436    if(lvl===1){
3437      const k=ri(1,4);
3438      if(k===1){
3439        const g=ri(2,4), each=ri(2,5), plus=ri(2,6);
3440        return {
3441          q:{en:`${n1} filled ${g} ${bin.en} with ${each} ${it.en} each, then found ${plus} more. How many ${it.en} in all? (Step 1: multiply. Step 2: add.)`,
3442             es:`${n1} llenó ${g} ${bin.es} con ${each} ${it.es} cada ${unoEs(bin)} y luego encontró ${plus} más. ¿${cuantosEs(it)} ${it.es} hay en total? (Paso 1: multiplica. Paso 2: suma.)`},
3443          a:{en:`${g}×${each}=${g*each}, +${plus} = ${g*each+plus}`, es:`${g}×${each}=${g*each}, +${plus} = ${g*each+plus}`}
3444        };
3445      }
3446      if(k===2){
3447        const g=ri(2,4), each=ri(3,5), used=ri(2,5);
3448        return {
3449          q:{en:`${n1} made ${g} groups of ${each} ${it.en}, then used ${used}. How many ${it.en} are left?`,
3450             es:`${n1} hizo ${g} grupos de ${each} ${it.es} y luego usó ${used}. ¿${cuantosEs(it)} ${it.es} quedan?`},
3451          a:{en:`${g}×${each}=${g*each}, −${used} = ${g*each-used}`, es:`${g}×${each}=${g*each}, −${used} = ${g*each-used}`}
3452        };
3453      }
3454      if(k===3){
3455        const share=ri(2,4), each=ri(2,5), tot=share*each, plus=ri(2,5);
3456        return {
3457          q:{en:`${n1} shared ${tot} ${it.en} equally among ${share} friends, then gave each friend ${plus} more. How many does each friend have now?`,
3458             es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${share} amigos y luego le dio ${plus} más a cada uno. ¿${cuantosEs(it)} tiene cada amigo ahora?`},
3459          a:{en:`${tot}÷${share}=${each}, +${plus} = ${each+plus}`, es:`${tot}÷${share}=${each}, +${plus} = ${each+plus}`}
3460        };
3461      }
3462      const a=ri(8,15), b=ri(3,7), g=2;
3463      const tot=a+b, half=Math.floor(tot/2)*2===tot ? tot/2 : null;
3464      if(half===null) return this.build(n1,n2,lvl);
3465      return {
3466        q:{en:`${n1} had ${a} ${it.en} and got ${b} more from ${n2}. Then ${n1} split them into ${g} equal boxes. How many in each box?`,
3467           es:`${n1} tenía ${a} ${it.es} y recibió ${b} más de ${n2}. Luego los repartió en ${g} cajas iguales. ¿${cuantosEs(it)} hay en cada caja?`},
3468        a:{en:`${a}+${b}=${tot}, ÷${g} = ${half}`, es:`${a}+${b}=${tot}, ÷${g} = ${half}`}
3469      };
3470    }
3471
3472    /* ---- Challenge · DOK 3 : letters, reasonableness, judgment ---- */
3473    if(lvl===3){
3474      const k=ri(1,5);
3475      if(k===1){
3476        const g=ri(4,8), each=ri(6,9), gave=ri(8,20), ans=g*each-gave;
3477        return {
3478          q:{en:`${n1} bought ${g} packs of ${it.en} with ${each} in each pack, then gave ${gave} to ${n2}. Write an equation using n for the ${it.en} ${n1} has left, then solve it.`,
3479             es:`${n1} compró ${g} paquetes de ${it.es} con ${each} en cada uno y luego le dio ${gave} a ${n2}. Escribe una ecuación usando n para ${losLasEs(it)} ${it.es} que le quedan y resuélvela.`},
3480          a:{en:`${g}×${each}−${gave}=n; n=${ans}`, es:`${g}×${each}−${gave}=n; n=${ans}`}
3481        };
3482      }
3483      if(k===2){
3484        const g=ri(4,8), each=ri(6,9), plus=ri(5,15), exact=g*each+plus;
3485        const claim=exact + (ri(0,1)? ri(15,30) : -ri(15,30));
3486        return {
3487          q:{en:`${n1} filled ${g} ${bin.en} with ${each} ${it.en} each and added ${plus} extras. ${n2} says the total is ${claim}. Round to estimate, then say whether ${n2} is reasonable.`,
3488             es:`${n1} llenó ${g} ${bin.es} con ${each} ${it.es} cada ${unoEs(bin)} y agregó ${plus} extras. ${n2} dice que el total es ${claim}. Redondea para estimar y di si la respuesta de ${n2} es razonable.`},
3489          a:{en:`Estimate ${g}×${Math.round(each/5)*5}≈${g*Math.round(each/5)*5}; exact ${exact} — ${claim} is not reasonable`,
3490             es:`Estima ${g}×${Math.round(each/5)*5}≈${g*Math.round(each/5)*5}; exacto ${exact} — ${claim} no es razonable`}
3491        };
3492      }
3493      if(k===3){
3494        const a=ri(30,60), used=ri(8,15), g=ri(2,4);
3495        const tot=a-used, each=Math.floor(tot/g)*g===tot ? tot/g : null;
3496        if(each===null) return this.build(n1,n2,lvl);
3497        return {
3498          q:{en:`${n1} had ${a} ${it.en}, used ${used}, then packed the rest equally into ${g} ${bin.en}. ${n2} divided first and got a different answer. Explain why the order of steps matters here.`,
3499             es:`${n1} tenía ${a} ${it.es}, usó ${used} y luego empacó el resto en ${g} ${bin.es} iguales. ${n2} dividió primero y obtuvo otra respuesta. Explica por qué el orden de los pasos importa aquí.`},
3500          a:{en:`(${a}−${used})÷${g} = ${each}; subtract first`, es:`(${a}−${used})÷${g} = ${each}; primero se resta`}
3501        };
3502      }
3503      if(k===4){
3504        const pA=ri(3,6), eA=ri(6,9), pB=ri(4,8), eB=ri(5,8);
3505        const tA=pA*eA, tB=pB*eB;
3506        return {
3507          q:{en:`Plan A: ${pA} packs of ${eA} ${it.en}. Plan B: ${pB} packs of ${eB}. ${n1} needs the most ${it.en}. Which plan should ${n1} pick, and by how many? Show both totals.`,
3508             es:`Plan A: ${pA} paquetes de ${eA} ${it.es}. Plan B: ${pB} paquetes de ${eB}. ${n1}
3508 necesita la mayor cantidad. ¿Qué plan debe elegir y por ${cuantosLc(it)} más? Muestra los dos totales.`},
3509          a:{en:`A=${tA}, B=${tB} → ${tA===tB?"equal":(tA>tB?"A":"B")+" by "+Math.abs(tA-tB)}`,
3510             es:`A=${tA}, B=${tB} → ${tA===tB?"iguales":(tA>tB?"A":"B")+" por "+Math.abs(tA-tB)}`}
3511        };
3512      }
3513      const g=ri(3,6), each=ri(4,8), missing=ri(5,12), tot=g*each+missing;
3514      return {
3515        q:{en:`${n1} is collecting ${tot} ${it.en}. So far ${n1} filled ${g} ${bin.en} with ${each} in each one. Write an equation with n for how many more ${it.en} ${n1} needs, then solve.`,
3516           es:`${n1} está juntando ${tot} ${it.es}. Hasta ahora llenó ${g} ${bin.es} con ${each} en cada ${unoEs(bin)}. Escribe una ecuación con n para ${cuantosLc(it)} más necesita y resuélvela.`},
3517        a:{en:`${g}×${each}+n=${tot}; n=${missing}`, es:`${g}×${each}+n=${tot}; n=${missing}`}
3518      };
3519    }
3520
3521    /* ---- On level · DOK 2 : two steps within 100 ---- */
3522    const k=ri(1,5);
3523    if(k===1){
3524      const g=ri(3,7), each=ri(4,9), plus=ri(5,20);
3525      return {
3526        q:{en:`${n1} packed ${g} ${bin.en} with ${each} ${it.en} in each one, then added ${plus} more ${it.en}. How many ${it.en} in all?`,
3527           es:`${n1} empacó ${g} ${bin.es} con ${each} ${it.es} en cada ${unoEs(bin)} y luego agregó ${plus} ${it.es} más. ¿${cuantosEs(it)} ${it.es} hay en total?`},
3528        a:{en:`${g}×${each}=${g*each}, +${plus} = ${g*each+plus}`, es:`${g}×${each}=${g*each}, +${plus} = ${g*each+plus}`}
3529      };
3530    }
3531    if(k===2){
3532      const g=ri(3,7), each=ri(5,9);
3533      const used=ri(6, Math.min(18, g*each-3));   // never exceed what exists
3534      return {
3535        q:{en:`${n1} made ${g} rows of ${each} ${it.en}, then took ${used} away for ${n2}. How many ${it.en} are left?`,
3536           es:`${n1} hizo ${g} filas de ${each} ${it.es} y luego quitó ${used} para ${n2}. ¿${cuantosEs(it)} ${it.es} quedan?`},
3537        a:{en:`${g}×${each}=${g*each}, −${used} = ${g*each-used}`, es:`${g}×${each}=${g*each}, −${used} = ${g*each-used}`}
3538      };
3539    }
3540    if(k===3){
3541      const share=ri(3,6), each=ri(4,9), tot=share*each, plus=ri(3,9);
3542      return {
3543        q:{en:`${n1} and ${n2} shared ${tot} ${it.en} equally among ${share} friends, then each friend earned ${plus} more. How many does each friend have now?`,
3544           es:`${n1} y ${n2} repartieron ${tot} ${it.es} en partes iguales entre ${share} amigos y luego cada amigo ganó ${plus} más. ¿${cuantosEs(it)} tiene cada amigo ahora?`},
3545        a:{en:`${tot}÷${share}=${each}, +${plus} = ${each+plus}`, es:`${tot}÷${share}=${each}, +${plus} = ${each+plus}`}
3546      };
3547    }
3548    if(k===4){
3549      const a=ri(20,50), b=ri(10,30), g=ri(2,5);
3550      const tot=a+b, each=Math.floor(tot/g)*g===tot ? tot/g : null;
3551      if(each===null) return this.build(n1,n2,lvl);
3552      return {
3553        q:{en:`${n1} had ${a} ${it.en} and collected ${b} more, then packed them equally into ${g} ${bin.en}. How many ${it.en} in each ${bin.one.en}?`,
3554           es:`${n1} tenía ${a} ${it.es}, juntó ${b} más y luego los empacó en partes iguales en ${g} ${bin.es}. ¿${cuantosEs(it)} ${it.es} hay en cada ${bin.one.es}?`},
3555        a:{en:`${a}+${b}=${tot}, ÷${g} = ${each}`, es:`${a}+${b}=${tot}, ÷${g} = ${each}`}
3556      };
3557    }
3558    const gA=ri(2,5), eA=ri(4,9), gB=ri(2,5), eB=ri(4,9);
3559    return {
3560      q:{en:`${n1} filled ${gA} ${bin.en} with ${eA} ${it.en} each, and ${n2} filled ${gB} with ${eB} each. How many ${it.en} did they pack altogether?`,
3561         es:`${n1} llenó ${gA} ${bin.es} con ${eA} ${it.es} cada ${unoEs(bin)} y ${n2} llenó ${gB} con ${eB} cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} empacaron en total?`},
3562      a:{en:`${gA*eA} + ${gB*eB} = ${gA*eA+gB*eB}`, es:`${gA*eA} + ${gB*eB} = ${gA*eA+gB*eB}`}
3563    };
3564  }
3565},
3566{
3567  code:"3.NBT.A.2", grade:3, dok:2,
3568  title:{en:"Add & subtract within 1,000",
3569         es:"Sumar y restar hasta 1,000"},
3570  text:{en:"Fluently add and subtract within 1000 using strategies and algorithms based on place value, properties of operations, and/or the relationship between addition and subtraction.",
3571        es:"Suma y resta con fluidez hasta 1000 usando estrategias y algoritmos basad
3571os en el valor posicional, las propiedades de las operaciones y/o la relación entre la suma y la resta."},
3572  build(n1,n2,lvl){
3573    const it = pickItem();
3574    const g = THEME.group;
3575
3576    /* ---- Support · DOK 1 : friendly numbers, light regrouping ---- */
3577    if(lvl===1){
3578      const k=ri(1,4);
3579      if(k===1){
3580        const a=ri(11,40)*10, b=ri(2,5)*10;
3581        return {
3582          q:{en:`${n1}'s ${g.en} collected ${a} ${it.en} for the drive. ${n1} brought ${b} more. How many ${it.en} are there now?`,
3583             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} juntó ${a} ${it.es} para la colecta. ${n1} trajo ${b} más. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
3584          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
3585        };
3586      }
3587      if(k===2){
3588        const a=ri(15,45)*10, b=ri(2,6)*10;
3589        return {
3590          q:{en:`${n1} counted ${a} ${it.en} in the big box. The ${g.en} used ${b}. How many ${it.en} are left?`,
3591             es:`${n1} contó ${a} ${it.es} en la caja grande. ${elLaEs(g)==="el"?"El":"La"} ${g.es} usó ${b}. ¿${cuantosEs(it)} ${it.es} quedan?`},
3592          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
3593        };
3594      }
3595      if(k===3){
3596        const a=ri(120,450), b=ri(100,300);
3597        return {
3598          q:{en:`${n1} collected ${a} ${it.en} and ${n2} collected ${b}. How many did they collect together? (Add the hundreds, then the tens, then the ones.)`,
3599             es:`${n1} juntó ${a} ${it.es} y ${n2} juntó ${b}. ¿${cuantosEs(it)} juntaron entre los dos? (Suma las centenas, luego las decenas, luego las unidades.)`},
3600          a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
3601        };
3602      }
3603      const a=ri(300,700), b=ri(100,250);
3604      return {
3605        q:{en:`The ${it.en} bin held ${a}. ${n1} handed out ${b} at the fair. How many ${it.en} are left in the bin?`,
3606           es:`La caja de ${it.es} tenía ${a}. ${n1} repartió ${b} en la feria. ¿${cuantosEs(it)} ${it.es} quedan en la caja?`},
3607        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
3608      };
3609    }
3610
3611    /* ---- Challenge · DOK 3 ---- */
3612    if(lvl===3){
3613      const k=ri(1,5);
3614      if(k===1){
3615        const a=ri(400,850), b=ri(150,380);
3616        // classic no-regroup error: subtract the smaller digit from the larger in each column
3617        const wrongDigits = (x,y)=>{ let r="",xs=String(x).padStart(3,"0"),ys=String(y).padStart(3,"0");
3618          for(let i=0;i<3;i++) r+=Math.abs(+xs[i]-+ys[i]); return parseInt(r); };
3619        const wrong=wrongDigits(a,b);
3620        if(wrong===a-b) return this.build(n1,n2,lvl);
3621        return {
3622          q:{en:`${n1} computed ${a} − ${b} for the ${it.en} count and got ${wrong}, subtracting the smaller digit from the larger in every column. Why does that fail here? Give the correct difference.`,
3623             es:`${n1} calculó ${a} − ${b} para el conteo de ${it.es} y obtuvo ${wrong}, restando el dígito menor del mayor en cada columna. ¿Por qué falla eso aquí? Da la diferencia correcta.`},
3624          a:{en:`Needs regrouping — ${a} − ${b} = ${a-b}`, es:`Hay que reagrupar — ${a} − ${b} = ${a-b}`}
3625        };
3626      }
3627      if(k===2){
3628        const tot=ri(500,950), a=ri(150,tot-150);
3629        return {
3630          q:{en:`The ${g.en} needs ${tot} ${it.en} for the festival. ${n1} and ${n2} have gathered ${a} so far. Write an equation with n for how many more are needed, then solve.`,
3631             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} necesita ${tot} ${it.es} para el festival. ${n1} y ${n2} han juntado ${a}. Escribe una ecuación con n para ${cuantosLc(it)} más se necesitan y resuélvela.`},
3632          a:{en:`${a} + n = ${tot}; n = ${tot-a}`, es:`${a} + n = ${tot}; n = ${tot-a}`}
3633        };
3634      }
3635      if(k===3){
3636        const a=ri(250,600), b=ri(120,320), claim=a+b+(ri(0,1)?ri(60,120):-ri(60,120));
3637        return {
3638          q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. ${n2} says the total is ${claim}. Round both to the nearest hundred to check — is that reasonable? Then find the exact total.`,
3639             es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. ${n2} dice que el total es ${claim}. Redondea a la centena para comprobar — ¿es razonable? Luego halla el total exacto.`},
3640          a:{en:`≈${rnd(a,100)}+${rnd(b,100)}=${rnd(a,100)+rnd(b,100)}; exact ${a+b} — not reasonable`,
3641             es:`≈${rnd(a,100)}+${rnd(b,100)}=${rnd(a,100)+rnd(b,100)}; exacto ${a+b} — no es razonable`}
3642        };
3643      }
3644      if(k===4){
3645        const b=ri(150,350), half=ri(30,90), a=b+2*half;
3646        return {
3647          q:{en:`${n1}'s ${it.en} jar shows ${a} and ${n2}'s shows ${b}. How many should ${n1} move to ${n2}'s jar so both jars match? Explain your steps.`,
3648             es:`El frasco de ${it.es} de ${n1} muestra ${a} y el de ${n2} muestra ${b}. ¿${cuantosEs(it)} debe pasar ${n1} al frasco de ${n2} para que queden iguales? Explica tus pasos.`},
3649          a:{en:`(${a}−${b})÷2 = ${half}; both at ${b+half}`, es:`(${a}−${b})÷2 = ${half}; los dos en ${b+half}`}
3650        };
3651      }
3652      const start=ri(400,800), out=ri(120,280), back=ri(60,180);
3653      return {
3654        q:{en:`The ${it.en} drive started with ${start}. The ${g.en} gave out ${out}, then ${n1} collected ${back} more. How many ${it.en} are there now? Show both steps.`,
3655           es:`La colecta de ${it.es} empezó con ${start}. ${elLaEs(g)==="el"?"El":"La"} ${g.es} repartió ${out} y luego ${n1} juntó ${back} más. ¿${cuantosEs(it)} ${it.es} hay ahora? Muestra los dos pasos.`},
3656        a:{en:`${start}−${out}=${start-out}, +${back} = ${start-out+back}`,
3657           es:`${start}−${out}=${start-out}, +${back} = ${start-out+back}`}
3658      };
3659    }
3660
3661    /* ---- On level · DOK 2 : full range with regrouping ---- */
3662    const k=ri(1,5);
3663    if(k===1){
3664      const a=ri(150,480), b=ri(150,480);
3665      return {
3666        q:{en:`${n1} collected ${a} ${it.en} and ${n2} collected ${b} for the ${g.en} drive. How many ${it.en} did they collect in all?`,
3667           es:`${n1} juntó ${a} ${it.es} y ${n2} juntó ${b} para la colecta ${elLaEs(g)==="el"?"del":"de la"} ${g.es}. ¿${cuantosEs(it)} ${it.es} juntaron en total?`},
3668        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
3669      };
3670    }
3671    if(k===2){
3672      const a=ri(400,900), b=ri(150,380);
3673      return {
3674        q:{en:`The ${it.en} box started with ${a}. ${n1} handed out ${b} at the fair. How many ${it.en} remain?`,
3675           es:`La caja de ${it.es} empezó con ${a}. ${n1} repartió ${b} en la feria. ¿${cuantosEs(it)} ${it.es} quedan?`},
3676        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
3677      };
3678    }
3679    if(k===3){
3680      const tot=ri(500,950), a=ri(180,tot-180);
3681      return {
3682        q:{en:`The ${g.en} counted ${tot} ${it.en} in all. ${n1}'s table counted ${a} of them. How many did the other tables count?`,
3683           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} contó ${tot} ${it.es} en total. La mesa de ${n1} contó ${a}. ¿${cuantosEs(it)} contaron las otras mesas?`},
3684        a:{en:`${tot} − ${a} = ${tot-a}`, es:`${tot} − ${a} = ${tot-a}`}
3685      };
3686    }
3687    if(k===4){
3688      const a=ri(300,700), b=ri(150,a-80);
3689      return {
3690        q:{en:`${n1} scored ${a} points in the ${it.en} game and ${n2} scored ${b}. How many more points did ${n1} score?`,
3691           es:`${n1} anotó ${a} puntos en el juego de ${it.es} y ${n2} anotó ${b}. ¿Cuántos puntos más anotó ${n1}?`},
3692        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
3693      };
3694    }
3695    const a=ri(120,320), b=ri(120,320), c=ri(80,260);
3696    return {
3697      q:{en:`Three tables sorted ${it.en} for ${n1}'s ${g.en}: ${a}, ${b}, and ${c}. How many ${it.en} did they sort altogether?`,
3698         es:`Tres mesas ordenaron ${it.es} para ${elLaEs(g)==="el"?"el":"la"} ${g.es} de ${n1}: ${a}, ${b} y ${c}. ¿${cuantosEs(it)} ${it.es} ordenaron en total?`},
3699      a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
3700    };
3701  }
3702},
3703{
3704  code:"3.NBT.A.1", grade:3, dok:2,
3705  title:{en:"Round to the nearest 10 or 100",
3706         es:"Redondear a la decena o centena más cercana"},
3707  text:{en:"Use place value understanding to round whole numbers to the nearest 10 or 100.",
3708        es:"Usa la comprensión del valor posicional para redondear números enteros a la decena o centena más cercana."},
3709  build(n1,n2,lvl){
3710    const it = pickItem();
3711    const g = THEME.group;
3712
3713    /* ---- Support · DOK 1 ---- */
3714    if(lvl===1){
3715      const k=ri(1,4);
3716      if(k===1){
3717        const n=ri(2,9)*10+ri(1,9);
3718        return {
3719          q:{en:`${n1} counted ${n} ${it.en}. Round to the nearest ten. (Which two tens is ${n} between?)`,
3720             es:`${n1} contó ${n} ${it.es}. Redondea a la decena más cercana. (¿Entre qué dos decenas está ${n}?)`},
3721          a:{en:`${rnd(n,10)}`, es:`${rnd(n,10)}`}
3722        };
3723      }
3724      if(k===2){
3725        const n=ri(1,8)*100+ri(11,89);
3726        return {
3727          q:{en:`${n1}'s ${g.en} collected ${n} ${it.en}. Round to the nearest hundred.`,
3728             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} juntó ${n} ${it.es}. Redondea a la centena más cercana.`},
3729          a:{en:`${rnd(n,100)}`, es:`${rnd(n,100)}`}
3730        };
3731      }
3732      if(k===3){
3733        const n=ri(3,9)*10+5;
3734        return {
3735          q:{en:`${n1} has ${n} ${it.en}. It ends in 5. Which ten does it round to? Say the rule.`,
3736             es:`${n1} tiene ${n} ${it.es}. Termina en 5. ¿A qué decena se redondea? Di la regla.`},
3737          a:{en:`${rnd(n,10)} — a 5 rounds up`, es:`${rnd(n,10)} — el 5 redondea hacia arriba`}
3738        };
3739      }
3740      const n=ri(110,890);
3741      return {
3742        q:{en:`About how many ${it.en} does ${n1} have if the exact count is ${n}? Round to the nearest ten.`,
3743           es:`¿Como ${cuantosLc(it)} ${it.es} tiene ${n1} si el conteo exacto es ${n}? Redondea a la decena.`},
3744        a:{en:`${rnd(n,10)}`, es:`${rnd(n,10)}`}
3745      };
3746    }
3747
3748    /* ---- Challenge · DOK 3 ---- */
3749    if(lvl===3){
3750      const k=ri(1,4);
3751      if(k===1){
3752        const target=ri(2,8)*100;
3753        return {
3754          q:{en:`${n1} says a number of ${it.en} rounds to ${target} at the nearest hundred. What are the smallest and largest whole numbers it could be? Explain.`,
3755             es:`${n1} dice que un número de ${it.es} se redondea a ${target} en la centena más cercana. ¿Cuál es el menor y el mayor número entero posible? Explica.`},
3756          a:{en:`${target-50} to ${target+49}`, es:`de ${target-50} a ${target+49}`}
3757        };
3758      }
3759      if(k===2){
3760        const n=ri(2,8)*100+ri(30,79);
3761        return {
3762          q:{en:`${n2} rounded ${n} ${it.en} to the nearest ten and got ${rnd(n,100)}. What place did ${n2} actually round to? Give the correct nearest ten.`,
3763             es:`${n2} redondeó ${n} ${it.es} a la decena más cercana y obtuvo ${rnd(n,100)}. ¿A qué posición redondeó en realidad? Da la decena correcta.`},
3764          a:{en:`Rounded to hundreds — nearest ten is ${rnd(n,10)}`,
3765             es:`Redondeó a la centena — la decena más cercana es ${rnd(n,10)}`}
3766        };
3767      }
3768      if(k===3){
3769        const n=ri(120,880);
3770        return {
3771          q:{en:`${n1} counted ${n} ${it.en}. Round it to the nearest ten AND the nearest hundred. Why are the answers different?`,
3772             es:`${n1} contó ${n} ${it.es}. Redondéalo a la decena Y a la centena. ¿Por qué son diferentes las respuestas?`},
3773          a:{en:`${rnd(n,10)} / ${rnd(n,100)} — bigger place, rougher estimate`,
3774             es:`${rnd(n,10)} / ${rnd(n,100)} — a mayor posición, estimación más gruesa`}
3775        };
3776      }
3777      const a=ri(130,380), b=ri(130,380);
3778      return {
3779        q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. Estimate the total by rounding each to the nearest hundred, then find the exact total. How far off was the estimate?`,
3780           es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. Estima el total redondeando cada uno a la centena, luego halla el total exacto. ¿Por cuánto difiere?`},
3781        a:{en:`≈${rnd(a,100)+rnd(b,100)}; exact ${a+b}; off by ${Math.abs(rnd(a,100)+rnd(b,100)-(a+b))}`,
3782           es:`≈${rnd(a,100)+rnd(b,100)}; exacto ${a+b}; difiere por ${Math.abs(rnd(a,100)+rnd(b,100)-(a+b))}`}
3783      };
3784    }
3785
3786    /* ---- On level · DOK 2 ---- */
3787    const k=ri(1,4);
3788    if(k===1){
3789      const n=ri(2,9)*100+ri(11,99);
3790      return {
3791        q:{en:`${n1} counted ${n} ${it.en} at the fair. Round to the nearest hundred.`,
3792           es:`${n1} contó ${n} ${it.es} en la feria. Redondea a la centena más cercana.`},
3793        a:{en:`${rnd(n,100)}`, es:`${rnd(n,100)}`}
3794      };
3795    }
3796    if(k===2){
3797      const n=ri(110,980);
3798      return {
3799        q:{en:`${n1}'s ${g.en} counted ${n} ${it.en}. Round it to the nearest ten.`,
3800           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} contó ${n} ${it.es}. Redondéalo a la decena más cercana.`},
3801        a:{en:`${rnd(n,10)}`, es:`${rnd(n,10)}`}
3802      };
3803    }
3804    if(k===3){
3805      const n=ri(150,850);
3806      return {
3807        q:{en:`${n1} counted ${n} ${it.en}. Round to the nearest ten AND the nearest hundred.`,
3808           es:`${n1} contó ${n} ${it.es}. Redondea a la decena Y a la centena.`},
3809        a:{en:`${rnd(n,10)} / ${rnd(n,100)}`, es:`${rnd(n,10)} / ${rnd(n,100)}`}
3810      };
3811    }
3812    const a=ri(120,460), b=ri(120,460);
3813    return {
3814      q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. About how many together? Round each to the nearest hundred first.`,
3815         es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. ¿Como ${cuantosLc(it)} hay juntos? Redondea cada uno a la centena primero.`},
3816      a:{en:`${rnd(a,100)} + ${rnd(b,100)} = about ${rnd(a,100)+rnd(b,100)}`,
3817         es:`${rnd(a,100)} + ${rnd(b,100)} = como ${rnd(a,100)+rnd(b,100)}`}
3818    };
3819  }
3820},
3821{
3822  code:"3.NBT.A.3", grade:3, dok:2,
3823  title:{en:"Multiply by multiples of 10",
3824         es:"Multiplicar por múltiplos de 10"},
3825  text:{en:"Multiply one-digit whole numbers by multiples of 10 in the range 10–90 using strategies based on place value and properties of operations.",
3826        es:"Multiplica números enteros de un dígito por múltiplos de 10 del rango 10–90 usando estrategias basadas en el valor posicional y las propiedades de las operaciones."},
3827  build(n1,n2,lvl){
3828    const it = pickItem(), bin = pick(THEME.bins);
3829
3830    /* ---- Support · DOK 1 : small factors ---- */
3831    if(lvl===1){
3832      const k=ri(1,4);
3833      if(k===1){
3834        const a=ri(2,4), t=ri(1,3)*10;
3835        return {
3836          q:{en:`${n1} filled ${a} ${bin.en} with ${t} ${it.en} each. How many ${it.en} in all? (Think: ${a} × ${t/10} tens.)`,
3837             es:`${n1} llenó ${a} ${bin.es} con ${t} ${it.es} cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} hay en total? (Piensa: ${a} × ${t/10} decenas.)`},
3838          a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3839        };
3840      }
3841      if(k===2){
3842        const a=ri(2,5), t=20;
3843        return {
3844          q:{en:`${n1} has ${a} bags with ${t} ${it.en} in each. How many ${it.en} does ${n1} have?`,
3845             es:`${n1} tiene ${a} bolsas con ${t} ${it.es} en cada una. ¿${cuantosEs(it)} ${it.es} tiene?`},
3846          a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3847        };
3848      }
3849      if(k===3){
3850        const a=ri(3,6), t=10;
3851        return {
3852          q:{en:`${n1} counted ${a} groups of ${t} ${it.en}. How many ${it.en} in all?`,
3853             es:`${n1} contó ${a} grupos de ${t} ${it.es}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
3854          a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3855        };
3856      }
3857      const a=ri(2,4), t=ri(2,4)*10;
3858      return {
3859        q:{en:`${n2} gives ${n1} ${a} boxes of ${t} ${it.en}. How many ${it.en} is that?`,
3860           es:`${n2} le da a ${n1} ${a} cajas de ${t} ${it.es}. ¿${cuantosEs(it)} ${it.es} son?`},
3861        a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3862      };
3863    }
3864
3865    /* ---- Challenge · DOK 3 ---- */
3866    if(lvl===3){
3867      const k=ri(1,4);
3868      if(k===1){
3869        const a=ri(4,9), t=ri(3,9)*10;
3870        const wrong=a*(t/10);
3871        return {
3872          q:{en:`${n2} says ${a} × ${t} ${it.en} is ${wrong}, forgetting the zero. Explain the place-value mistake and give the correct product.`,
3873             es:`${n2} dice que ${a} × ${t} ${it.es} es ${wrong}, olvidando el cero. Explica el error de valor posicional y da el producto correcto.`},
3874          a:{en:`${a}×${t/10}=${wrong} tens = ${a*t}`, es:`${a}×${t/10}=${wrong} decenas = ${a*t}`}
3875        };
3876      }
3877      if(k===2){
3878        const a=ri(3,8), t=ri(2,8)*10;
3879        return {
3880          q:{en:`${n1} has ${a*t} ${it.en} in ${a} equal boxes. How many are in each box? Explain using tens.`,
3881             es:`${n1} tiene ${a*t} ${it.es} en ${a} cajas iguales. ¿${cuantosEs(it)} hay en cada caja? Explica usando decenas.`},
3882          a:{en:`${a*t} ÷ ${a} = ${t} (${t/10} tens)`, es:`${a*t} ÷ ${a} = ${t} (${t/10} decenas)`}
3883        };
3884      }
3885      if(k===3){
3886        const aA=ri(3,8), tA=ri(2,6)*10, aB=ri(3,8), tB=ri(2,6)*10;
3887        if(aA*tA===aB*tB) return this.build(n1,n2,lvl);
3888        return {
3889          q:{en:`${n1} packs ${aA} boxes of ${tA} ${it.en}. ${n2} packs ${aB} boxes of ${tB}. Who packed more? Show both products.`,
3890             es:`${n1} empaca ${aA} cajas de ${tA} ${it.es}. ${n2} empaca ${aB} cajas de ${tB}. ¿Quién empacó más? Muestra los dos productos.`},
3891          a:{en:`${aA*tA} vs ${aB*tB} — ${aA*tA>aB*tB?n1:n2} by ${Math.abs(aA*tA-aB*tB)}`,
3892             es:`${aA*tA} vs ${aB*tB} — ${aA*tA>aB*tB?n1:n2} por ${Math.abs(aA*tA-aB*tB)}`}
3893        };
3894      }
3895      const a=ri(3,7), t=ri(2,7)*10, extra=ri(5,30);
3896      return {
3897        q:{en:`${n1} filled ${a} boxes with ${t} ${it.en} each, then found ${extra} more. How many ${it.en} now? Show both steps.`,
3898           es:`${n1} llenó ${a} cajas con ${t} ${it.es} cada una y luego encontró ${extra} más. ¿${cuantosEs(it)} ${it.es} hay ahora? Muestra los dos pasos.`},
3899        a:{en:`${a}×${t}=${a*t}, +${extra} = ${a*t+extra}`, es:`${a}×${t}=${a*t}, +${extra} = ${a*t+extra}`}
3900      };
3901    }
3902
3903    /* ---- On level · DOK 2 ---- */
3904    const k=ri(1,4);
3905    if(k===1){
3906      const a=ri(3,9), t=ri(2,9)*10;
3907      return {
3908        q:{en:`${n1} filled ${a} ${bin.en} with ${t} ${it.en} in each. How many ${it.en} in all?`,
3909           es:`${n1} llenó ${a} ${bin.es} con ${t} ${it.es} en cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
3910        a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3911      };
3912    }
3913    if(k===2){
3914      const a=ri(3,9), t=ri(3,9)*10;
3915      return {
3916        q:{en:`${n1} and ${n2} counted ${a} groups of ${t} ${it.en}. How many ${it.en} did they count?`,
3917           es:`${n1} y ${n2} contaron ${a} grupos de ${t} ${it.es}. ¿${cuantosEs(it)} ${it.es} contaron?`},
3918        a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3919      };
3920    }
3921    if(k===3){
3922      const a=ri(3,8), t=ri(2,8)*10;
3923      return {
3924        q:{en:`${n1} has ${a*t} ${it.en} packed in boxes of ${t}. How many boxes does ${n1} have?`,
3925           es:`${n1} tiene ${a*t} ${it.es} empacados en cajas de ${t}. ¿Cuántas cajas tiene?`},
3926        a:{en:`${a*t} ÷ ${t} = ${a}`, es:`${a*t} ÷ ${t} = ${a}`}
3927      };
3928    }
3929    const a=ri(4,9), t=ri(2,7)*10;
3930    return {
3931      q:{en:`Each day ${n1} sorts ${t} ${it.en}. After ${a} days, how many ${it.en} has ${n1} sorted?`,
3932         es:`Cada día ${n1} ordena ${t} ${it.es}. Después de ${a} días, ¿${cuantosEs(it)} ${it.es} ha ordenado?`},
3933      a:{en:`${a} × ${t} = ${a*t}`, es:`${a} × ${t} = ${a*t}`}
3934    };
3935  }
3936},
3937{
3938  code:"3.NF.A.1", grade:3, dok:2,
3939  title:{en:"Understand fractions — equal parts of a whole",
3940         es:"Comprender fracciones — partes iguales de un todo"},
3941  text:{en:"Understand a fraction 1/b as the quantity formed by 1 part when a whole is partitioned into b equal parts; understand a fraction a/b as the quantity formed by a parts of size 1/b.",
3942        es:"Comprende una fracción 1/b como la cantidad formada por 1 parte cuando un todo se divide en b partes iguales; comprende una fracción a/b como la cantidad formada por a partes de tamaño 1/b."},
3943  build(n1,n2,lvl){
3944    const it = pickItem(), bin = pick(THEME.bins);
3945
3946    /* ---- Support · DOK 1 : unit fractions, read the parts ---- */
3947    if(lvl===1){
3948      const k=ri(1,4);
3949      if(k===1){
3950        const d=pick([2,3,4]);
3951        return {
3952          q:{en:`${n1}'s ${bin.one.en} has ${d} equal sections. ${it.en.charAt(0).toUpperCase()+it.en.slice(1)} fill 1 section. What fraction of the ${bin.one.en} is filled?`,
3953             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${n1} tiene ${d} secciones iguales. 1 sección tiene ${it.es}. ¿Qué fracción está llena?`},
3954          a:{en:frR(1,d), es:frR(1,d)}
3955        };
3956      }
3957      if(k===2){
3958        const d=pick([2,4]);
3959        return {
3960          q:{en:`${n1} split a row of ${it.en} into ${d} equal parts and took 1 part. What fraction of the row did ${n1} take?`,
3961             es:`${n1} dividió una fila de ${it.es} en ${d} partes iguales y tomó 1 parte. ¿Qué fracción de la fila tomó?`},
3962          a:{en:frR(1,d), es:frR(1,d)}
3963        };
3964      }
3965      if(k===3){
3966        const d=pick([3,4]), a=ri(2,d-1);
3967        return {
3968          q:{en:`${n1}'s ${bin.one.en} has ${d} equal sections. ${n1} filled ${a} sections with ${it.en}. What fraction is filled? (Hint: count the filled parts.)`,
3969             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${n1} tiene ${d} secciones iguales. ${n1} llenó ${a} con ${it.es}. ¿Qué fracción está llena? (Pista: cuenta las partes llenas.)`},
3970          a:{en:frR(a,d), es:frR(a,d)}
3971        };
3972      }
3973      const d=pick([2,3,4]);
3974      return {
3975        q:{en:`${n1} shares a tray of ${it.en} equally with ${d-1} ${d===2?"friend":"friends"}, so the tray is cut into ${d} equal parts. What fraction does each person get?`,
3976           es:`${n1} comparte una bandeja de ${it.es} en partes iguales con ${d-1} ${d===2?"amigo":"amigos"}, así que la bandeja se corta en ${d} partes iguales. ¿Qué fracción recibe cada persona?`},
3977        a:{en:frR(1,d), es:frR(1,d)}
3978      };
3979    }
3980
3981    /* ---- Challenge · DOK 3 : judge, compare, construct ---- */
3982    if(lvl===3){
3983      const k=ri(1,5);
3984      if(k===1){
3985        const d=pick([6,8]), filled=ri(2,d-2), empty=d-filled;
3986        return {
3987          q:{en:`${n1}'s ${bin.one.en} has ${d} equal sections, and ${filled} hold ${it.en}. ${n2} says the filled fraction is ${frR(empty,d)} because ${empty} sections are empty. What mistake did ${n2} make?`,
3988             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${n1} tiene ${d} secciones iguales y ${filled} tienen ${it.es}. ${n2} dice que la fracción llena es ${frR(empty,d)} porque ${empty} secciones están vacías. ¿Qué error cometió ${n2}?`},
3989          a:{en:`Counted the empty parts — filled is ${frR(filled,d)}`,
3990             es:`Contó las partes vacías — la fracción llena es ${frR(filled,d)}`}
3991        };
3992      }
3993      if(k===2){
3994        const dA=pick([3,4]), dB=dA*2;
3995        return {
3996          q:{en:`${n1} cut a row of ${it.en} into ${dA} equal parts. ${n2} cut the same-size row into ${dB} equal parts. Whose parts are bigger? Explain how you know without measuring.`,
3997             es:`${n1} cortó una fila de ${it.es} en ${dA} partes iguales. ${n2} cortó una fila del mismo tamaño en ${dB} partes iguales. ¿Quién tiene partes más grandes? Explica cómo lo sabes sin medir.`},
3998          a:{en:`${n1} — fewer parts of the same whole means bigger parts (1/${dA} > 1/${dB})`,
3999             es:`${n1} — menos partes del mismo todo son partes más grandes (1/${dA} > 1/${dB})`}
4000        };
4001      }
4002      if(k===3){
4003        const d=pick([4,6,8]);
4004        return {
4005          q:{en:`${n1} filled every section of a ${bin.one.en} that has ${d} equal sections with ${it.en}. ${n2} says that is ${frR(d,d)} and also 1 whole. Is ${n2} right? Explain.`,
4006             es:`${n1} llenó todas las secciones de ${unUnaEs(bin)} ${bin.one.es} de ${d} secciones iguales con ${it.es}. ${n2} dice que eso es ${frR(d,d)} y también 1 entero. ¿Tiene razón? Explica.`},
4007          a:{en:`Yes — ${d} parts of ${d} is the whole: ${frR(d,d)} = 1`,
4008             es:`Sí — ${d} partes de ${d} es el todo: ${frR(d,d)} = 1`}
4009        };
4010      }
4011      if(k===4){
4012        const d=pick([4,6]);
4013        return {
4014          q:{en:`${n2} cut a tray of ${it.en} into ${d} pieces, but the pieces are different sizes. ${n2} calls one piece ${frR(1,d)}. Why is that not correct? What has to be true first?`,
4015             es:`${n2} cortó una bandeja de ${it.es} en ${d} pedazos, pero los pedazos son de diferentes tamaños. ${n2} llama a un pedazo ${frR(1,d)}. ¿Por qué no es correcto? ¿Qué tiene que ser cierto primero?`},
4016          a:{en:`Parts must be EQUAL before naming ${frR(1,d)}`,
4017             es:`Las partes deben ser IGUALES antes de llamarla ${frR(1,d)}`}
4018        };
4019      }
4020      const d=pick([4,6,8]), a=ri(2,d-1);
4021      return {
4022        q:{en:`Draw ${n1}'s ${bin.one.en} with ${d} equal sections. Shade sections to show ${frR(a,d)} filled with ${it.en}. Then write the fraction that is NOT shaded.`,
4023           es:`Dibuja ${elLaEs(bin)} ${bin.one.es} de ${n1} con ${d} secciones iguales. Sombrea secciones para mostrar ${frR(a,d)} con ${it.es}. Luego escribe la fracción que NO está sombreada.`},
4024        a:{en:`Shaded ${frR(a,d)}; not shaded ${frR(d-a,d)}`,
4025           es:`Sombreada ${frR(a,d)}; sin sombrear ${frR(d-a,d)}`}
4026      };
4027    }
4028
4029    /* ---- On level · DOK 2 : a/b of a partitioned whole ---- */
4030    const k=ri(1,5);
4031    if(k===1){
4032      const d=pick([3,4,6,8]), a=ri(1,d-1);
4033      return {
4034        q:{en:`${n1}'s ${bin.one.en} has ${d} equal sections. ${a} ${a===1?"section holds":"sections hold"} ${it.en}. What fraction of the ${bin.one.en} holds ${it.en}?`,
4035           es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${n1} tiene ${d} secciones iguales. ${a} ${a===1?"sección tiene":"secciones tienen"} ${it.es}. ¿Qué fracción tiene ${it.es}?`},
4036        a:{en:frR(a,d), es:frR(a,d)}
4037      };
4038    }
4039    if(k===2){
4040      const d=pick([4,6,8]), a=ri(1,d-1);
4041      return {
4042        q:{en:`A row of ${it.en} is split into ${d} equal parts. ${n1} takes ${a} ${a===1?"part":"parts"}. What fraction does ${n1} take, and what fraction is left?`,
4043           es:`Una fila de ${it.es} se divide en ${d} partes iguales. ${n1} toma ${a} ${a===1?"parte":"partes"}. ¿Qué fracción toma ${n1} y qué fracción queda?`},
4044        a:{en:`takes ${frR(a,d)}, leaves ${frR(d-a,d)}`, es:`toma ${frR(a,d)}, queda ${frR(d-a,d)}`}
4045      };
4046    }
4047    if(k===3){
4048      const d=pick([6,8]), a=ri(1,3), b=ri(1,d-a-1);
4049      return {
4050        q:{en:`${n1} and ${n2} filled a ${bin.one.en} with ${d} equal sections. ${n1} filled ${a} with ${it.en} and ${n2} filled ${b}. What fraction did each fill?`,
4051           es:`${n1} y ${n2} llenaron ${unUnaEs(bin)} ${bin.one.es} de ${d} secciones iguales. ${n1} llenó ${a} con ${it.es} y ${n2} llenó ${b}. ¿Qué fracción llenó cada uno?`},
4052        a:{en:`${n1}: ${frR(a,d)}, ${n2}: ${frR(b,d)}`, es:`${n1}: ${frR(a,d)}, ${n2}: ${frR(b,d)}`}
4053      };
4054    }
4055    if(k===4){
4056      const d=pick([3,4,6]), a=ri(1,d-1);
4057      return {
4058        q:{en:`Each section of ${n1}'s tray is ${frR(1,d)} of the whole tray. ${n1} covered ${a} ${a===1?"section":"sections"} with ${it.en}. What fraction of the tray is covered?`,
4059           es:`Cada sección de la bandeja de ${n1} es ${frR(1,d)} del total. ${n1} cubrió ${a} ${a===1?"sección":"secciones"} con ${it.es}. ¿Qué fracción de la bandeja está cubierta?`},
4060        a:{en:`${a} × ${frR(1,d)} = ${frR(a,d)}`, es:`${a} × ${frR(1,d)} = ${frR(a,d)}`}
4061      };
4062    }
4063    const d=pick([4,6,8]), used=ri(1,d-1);
4064    return {
4065      q:{en:`${n1} split a pack of ${it.en} into ${d} equal groups and used ${used} ${used===1?"group":"groups"}. What fraction of the pack did ${n1} use?`,
4066         es:`${n1} dividió un paquete de ${it.es} en ${d} grupos iguales y usó ${used} ${used===1?"grupo":"grupos"}. ¿Qué fracción del paquete usó?`},
4067      a:{en:frR(used,d), es:frR(used,d)}
4068    };
4069  }
4070},
4071{
4072  code:"3.NF.A.3", grade:3, dok:3,
4073  title:{en:"Equivalent fractions & comparing fractions",
4074         es:"Fracciones equivalentes y comparación"},
4075  text:{en:"Explain equivalence of fractions in special cases, and compare fractions by reasoning about their size. Compare two fractions with the same numerator or the same denominator by reasoning about their size. Recognize that comparisons are valid only when the two fractions refer to the same whole.",
4076        es:"Explica la equivalencia de fracciones en casos especiales y compara fracciones razonando sobre su tamaño. Compara dos fracciones con el mismo numerador o el mismo denominador. Reconoce que las comparaciones son válidas solo cuando las fracciones se refieren al mismo todo."},
4077  build(n1,n2,lvl){
4078    const it = pickItem(), bin = pick(THEME.bins);
4079
4080    /* ---- Support · DOK 1 : same denominator ---- */
4081    if(lvl===1){
4082      const k=ri(1,4);
4083      if(k===1){
4084        const d=pick([4,6,8]), a=ri(1,d-2), b=a+ri(1,d-a-1);
4085        return {
4086          q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en}. ${n2} filled ${frR(b,d)}. Who filled more?`,
4087             es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ${n2} llenó ${frR(b,d)}. ¿Quién llenó más?`},
4088          a:{en:`${n2} — ${frR(b,d)} > ${frR(a,d)}`, es:`${n2} — ${frR(b,d)} > ${frR(a,d)}`}
4089        };
4090      }
4091      if(k===2){
4092        const d=pick([2,3,4]);
4093        return {
4094          q:{en:`${n1} says ${frR(d,d)} of a tray of ${it.en} is the whole tray. Is that right? Explain.`,
4095             es:`${n1} dice que ${frR(d,d)} de una bandeja de ${it.es} es toda la bandeja. ¿Es correcto? Explica.`},
4096          a:{en:`Yes — ${frR(d,d)} = 1 whole`, es:`Sí — ${frR(d,d)} = 1 entero`}
4097        };
4098      }
4099      if(k===3){
4100        const d=pick([4,6]);
4101        return {
4102          q:{en:`${n1} ate ${frR(1,2)} of a tray of ${it.en}. ${n2} ate ${frR(d/2,d)}. Did they eat the same amount? Draw it.`,
4103             es:`${n1} comió ${frR(1,2)} de una bandeja de ${it.es}. ${n2} comió ${frR(d/2,d)}. ¿Comieron lo mismo? Dibújalo.`},
4104          a:{en:`Yes — ${frR(1,2)} = ${frR(d/2,d)}`, es:`Sí — ${frR(1,2)} = ${frR(d/2,d)}`}
4105        };
4106      }
4107      const d=pick([3,4,6]), a=ri(1,d-1);
4108      return {
4109        q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en}. What fraction is NOT filled?`,
4110           es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ¿Qué fracción NO está llena?`},
4111        a:{en:`${frR(d-a,d)}`, es:`${frR(d-a,d)}`}
4112      };
4113    }
4114
4115    /* ---- Challenge · DOK 3 : same numerator, same whole rule ---- */
4116    if(lvl===3){
4117      const k=ri(1,4);
4118      if(k===1){
4119        const dA=pick([3,4]), dB=dA*2, a=1;
4120        return {
4121          q:{en:`${n2} says ${frR(a,dB)} is bigger than ${frR(a,dA)} because ${dB} is bigger than ${dA}. Draw both and explain why ${n2} is wrong.`,
4122             es:`${n2} dice que ${frR(a,dB)} es mayor que ${frR(a,dA)} porque ${dB} es mayor que ${dA}. Dibuja las dos y explica por qué ${n2} se equivoca.`},
4123          a:{en:`More parts means smaller parts — ${frR(a,dA)} > ${frR(a,dB)}`,
4124             es:`Más partes significa partes más pequeñas — ${frR(a,dA)} > ${frR(a,dB)}`}
4125        };
4126      }
4127      if(k===2){
4128        const d=pick([4,6,8]), a=ri(1,d-1);
4129        return {
4130          q:{en:`${n1} filled ${frR(a,d)} of a SMALL ${bin.one.en} and ${n2} filled ${frR(a,d)} of a LARGE one with ${it.en}. ${n2} says they filled the same amount. Why is that comparison not valid?`,
4131             es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} PEQUEÑA y ${n2} llenó ${frR(a,d)} de una GRANDE con ${it.es}. ${n2} dice que llenaron lo mismo. ¿Por qué no es válida esa comparación?`},
4132          a:{en:`Fractions compare only within the SAME whole`,
4133             es:`Las fracciones se comparan solo dentro del MISMO todo`}
4134        };
4135      }
4136      if(k===3){
4137        const d=pick([4,6,8]);
4138        return {
4139          q:{en:`${n1} says ${frR(1,2)} of a tray of ${it.en} equals ${frR(d/2,d)}. Draw both and explain why the different-looking fractions are equal.`,
4140             es:`${n1} dice que ${frR(1,2)} de una bandeja de ${it.es} es igual a ${frR(d/2,d)}. Dibuja las dos y explica por qué fracciones distintas son iguales.`},
4141          a:{en:`Same amount, more but smaller parts — ${frR(1,2)} = ${frR(d/2,d)}`,
4142             es:`La misma cantidad, más partes pero más pequeñas — ${frR(1,2)} = ${frR(d/2,d)}`}
4143        };
4144      }
4145      const d=pick([6,8]), a=ri(2,d-2);
4146      return {
4147        q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en}. Name a fraction that is MORE than ${frR(a,d)} and one that is LESS, both in ${d}ths. Explain your choices.`,
4148           es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. Nombra una fracción MAYOR que ${frR(a,d)} y otra MENOR, las dos en ${d>=8?"octavos":"sextos"}. Explica.`},
4149        a:{en:`more: ${frR(a+1,d)}; less: ${frR(a-1,d)}`, es:`mayor: ${frR(a+1,d)}; menor: ${frR(a-1,d)}`}
4150      };
4151    }
4152
4153    /* ---- On level · DOK 2 ---- */
4154    const k=ri(1,4);
4155    if(k===1){
4156      const d=pick([4,6,8]), a=ri(1,d-2), b=a+ri(1,d-a-1);
4157      return {
4158        q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en} and ${n2} filled ${frR(b,d)}. Who filled more? Write the comparison with > or <.`,
4159           es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y ${n2} llenó ${frR(b,d)}. ¿Quién llenó más? Escribe la comparación con > o <.`},
4160        a:{en:`${frR(b,d)} > ${frR(a,d)} — ${n2}`, es:`${frR(b,d)} > ${frR(a,d)} — ${n2}`}
4161      };
4162    }
4163    if(k===2){
4164      const dA=pick([3,4,6]), dB=pick([8,12]).valueOf();
4165      const small = dA < 8 ? dA : 4;
4166      return {
4167        q:{en:`${n1} took ${frR(1,small)} of a tray of ${it.en}. ${n2} took ${frR(1,8)}. Who took more? Explain using the size of the parts.`,
4168           es:`${n1} tomó ${frR(1,small)} de una bandeja de ${it.es}. ${n2} tomó ${frR(1,8)}. ¿Quién tomó más? Explica usando el tamaño de las partes.`},
4169        a:{en:`${small<8 ? n1+" — "+frR(1,small)+" > "+frR(1,8) : "equal"}`,
4170           es:`${small<8 ? n1+" — "+frR(1,small)+" > "+frR(1,8) : "iguales"}`}
4171      };
4172    }
4173    if(k===3){
4174      const d=pick([4,6,8]);
4175      return {
4176        q:{en:`${n1} filled ${frR(1,2)} of a ${bin.one.en} with ${it.en}. Write that same amount as a fraction in ${d}ths.`,
4177           es:`${n1} llenó ${frR(1,2)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. Escribe esa misma cantidad como fracción en ${d>=8?"octavos":(d===6?"sextos":"cuartos")}.`},
4178        a:{en:`${frR(1,2)} = ${frR(d/2,d)}`, es:`${frR(1,2)} = ${frR(d/2,d)}`}
4179      };
4180    }
4181    const d=pick([4,6,8]), a=ri(1,d-1);
4182    return {
4183      q:{en:`${n1} used ${frR(a,d)} of a pack of ${it.en}. ${n2} used ${frR(d-a,d)}. Together did they use the whole pack? Explain.`,
4184         es:`${n1} usó ${frR(a,d)} de un paquete de ${it.es}. ${n2} usó ${frR(d-a,d)}. ¿Juntos usaron todo el paquete? Explica.`},
4185      a:{en:`Yes — ${frR(a,d)} + ${frR(d-a,d)} = ${frR(d,d)} = 1`,
4186         es:`Sí — ${frR(a,d)} + ${frR(d-a,d)} = ${frR(d,d)} = 1`}
4187    };
4188  }
4189},
4190{
4191  code:"3.MD.A.1", grade:3, dok:2,
4192  title:{en:"Elapsed time word problems",
4193         es:"Problemas de tiempo transcurrido"},
4194  text:{en:"Tell and write time to the nearest minute and measure time intervals in minutes. Solve word problems involving addition and subtraction of time intervals in minutes, e.g., by representing the problem on a number line diagram.",
4195        es:"Di y escribe la hora al minuto más cercano y mide intervalos de tiempo en minutos. Resuelve problemas verbales de suma y resta de intervalos de tiempo en minutos, por ejemplo, representando el problema en una recta numérica."},
4196  build(n1,n2,lvl){
4197    const it = pickItem();
4198
4199    /* ---- Support · DOK 1 : within the hour ---- */
4200    if(lvl===1){
4201      const k=ri(1,4);
4202      if(k===1){
4203        const h=ri(1,11), m=pick([0,10,15]), dur=pick([10,15,20]);
4204        return {
4205          q:{en:`${n1} started sorting ${it.en} at ${clk(h,m)} and worked for ${dur} minutes. What time did ${n1} finish? (Count on by fives.)`,
4206             es:`${n1} empezó a ordenar ${it.es} a las ${clk(h,m)} y trabajó ${dur} minutos. ¿A qué hora terminó? (Cuenta de cinco en cinco.)`},
4207          a:{en:addMin(h,m,dur), es:addMin(h,m,dur)}
4208        };
4209      }
4210      if(k===2){
4211        const h=ri(1,11), m1=pick([5,10,15]), dur=pick([15,20,25]);
4212        return {
4213          q:{en:`${n1}'s ${it.en} game began at ${clk(h,m1)} and ended at ${clk(h,m1+dur)}. How many minutes did it last?`,
4214             es:`El juego de ${it.es} de ${n1} empezó a las ${clk(h,m1)} y terminó a las ${clk(h,m1+dur)}. ¿Cuántos minutos duró?`},
4215          a:{en:`${dur} minutes`, es:`${dur} minutos`}
4216        };
4217      }
4218      if(k===3){
4219        const h=ri(1,11), dur=pick([20,30]);
4220        return {
4221          q:{en:`${n2} handed out ${it.en} starting at ${clk(h,0)}. It took ${dur} minutes. Draw a number line from ${clk(h,0)} and find the end time.`,
4222             es:`${n2} repartió ${it.es} desde las ${clk(h,0)}. Tardó ${dur} minutos. Dibuja una recta numérica desde las ${clk(h,0)} y halla la hora final.`},
4223          a:{en:addMin(h,0,dur), es:addMin(h,0,dur)}
4224        };
4225      }
4226      const h=ri(1,11), m=pick([30,35,40]), dur=pick([10,15]);
4227      return {
4228        q:{en:`${n1} began cleaning the ${it.en} shelf at ${clk(h,m)}. ${dur} minutes later ${n2} came to help. What time did ${n2} arrive?`,
4229           es:`${n1} empezó a limpiar el estante de ${it.es} a las ${clk(h,m)}. ${dur} minutos después llegó ${n2} a ayudar. ¿A qué hora llegó ${n2}?`},
4230        a:{en:addMin(h,m,dur), es:addMin(h,m,dur)}
4231      };
4232    }
4233
4234    /* ---- Challenge · DOK 3 ---- */
4235    if(lvl===3){
4236      const k=ri(1,5);
4237      if(k===1){
4238        const h=ri(1,9), m=50, endM=15, wrong=Math.abs(m-endM);
4239        const real=60-m+endM;
4240        return {
4241          q:{en:`${n1}'s ${it.en} practice ran from ${clk(h,m)} to ${clk(h+1,endM)}. ${n2} subtracts the minutes and says it lasted ${wrong} minutes. Why is that wrong? Use the next hour mark to find the real time.`,
4242             es:`La práctica de ${it.es} de ${n1} fue de ${clk(h,m)} a ${clk(h+1,endM)}. ${n2} resta los minutos y dice que duró ${wrong} minutos. ¿Por qué está mal? Usa la hora en punto para hallar el tiempo real.`},
4243          a:{en:`${60-m} min to ${clk(h+1,0)}, then ${endM} more = ${real} minutes`,
4244             es:`${60-m} min hasta ${clk(h+1,0)}, luego ${endM} más = ${real} minutos`}
4245        };
4246      }
4247      if(k===2){
4248        const h=ri(1,9), m=pick([10,20,30]), d1=pick([25,35]), brk=10, d2=pick([20,30]);
4249        return {
4250          q:{en:`${n1} sorted ${it.en} for ${d1} minutes starting at ${clk(h,m)}, took a ${brk}-minute break, then worked ${d2} more minutes. What time did ${n1} finish? Show each hop on a number line.`,
4251             es:`${n1} ordenó ${it.es} durante ${d1} minutos desde las ${clk(h,m)}, descansó ${brk} minutos y trabajó ${d2} minutos más. ¿A qué hora terminó? Muestra cada salto en una recta numérica.`},
4252          a:{en:addMin(h,m,d1+brk+d2), es:addMin(h,m,d1+brk+d2)}
4253        };
4254      }
4255      if(k===3){
4256        const h=ri(1,9), m=pick([15,30]), dur=pick([40,50,65]);
4257        const dead=addMin(h,m,dur+(ri(0,1)?10:-10));
4258        const makes = dead===addMin(h,m,dur+10);
4259        return {
4260          q:{en:`${n1} starts the ${it.en} setup at ${clk(h,m)}. It takes ${dur} minutes, and the doors open at ${dead}. Will ${n1} finish in time? Prove it with the end time.`,
4261             es:`${n1} empieza a preparar ${losLasEs(it)} ${it.es} a las ${clk(h,m)}. Tarda ${dur} minutos y las puertas abren a las ${dead}. ¿Terminará a tiempo? Compruébalo con la hora final.`},
4262          a:{en:`Ends ${addMin(h,m,dur)}
4262 — ${makes?"yes, in time":"no, too late"}`,
4263             es:`Termina ${addMin(h,m,dur)} — ${makes?"sí, a tiempo":"no, tarde"}`}
4264        };
4265      }
4266      if(k===4){
4267        const h=ri(1,9), m=pick([20,40]), dur=pick([45,55,70]);
4268        return {
4269          q:{en:`${n2}'s ${it.en} shift ended at ${addMin(h,m,dur)} after ${dur} minutes of work. Write an equation with n for the start time in minutes, then give the start time.`,
4270             es:`El turno de ${it.es} de ${n2} terminó a las ${addMin(h,m,dur)} después de ${dur} minutos. Escribe una ecuación con n para el inicio en minutos y da la hora de inicio.`},
4271          a:{en:`n + ${dur} = end; started ${clk(h,m)}`, es:`n + ${dur} = final; empezó ${clk(h,m)}`}
4272        };
4273      }
4274      const h=ri(1,9), mA=pick([10,15]), dA=pick([35,45]), mB=pick([20,30]), dB=pick([25,40]);
4275      return {
4276        q:{en:`${n1} practiced ${it.en} from ${clk(h,mA)} for ${dA} minutes. ${n2} practiced from ${clk(h,mB)} for ${dB} minutes. Who finished later, and at what time? Show both end times.`,
4277           es:`${n1} practicó ${it.es} desde las ${clk(h,mA)} durante ${dA} minutos. ${n2} practicó desde las ${clk(h,mB)} durante ${dB} minutos. ¿Quién terminó más tarde y a qué hora? Muestra las dos horas finales.`},
4278        a:{en:`${addMin(h,mA,dA)} vs ${addMin(h,mB,dB)} — ${(mA+dA)===(mB+dB)?"same time":((mA+dA)>(mB+dB)?n1:n2)} later`,
4279           es:`${addMin(h,mA,dA)} vs ${addMin(h,mB,dB)} — ${(mA+dA)===(mB+dB)?"a la misma hora":((mA+dA)>(mB+dB)?n1:n2)} más tarde`}
4280      };
4281    }
4282
4283    /* ---- On level · DOK 2 : crossing the hour ---- */
4284    const k=ri(1,5);
4285    if(k===1){
4286      const h=ri(1,10), m=pick([25,35,40,45]), dur=pick([30,35,40,45]);
4287      return {
4288        q:{en:`${n1}'s ${it.en} workshop started at ${clk(h,m)} and lasted ${dur} minutes. What time did it end?`,
4289           es:`El taller de ${it.es} de ${n1} empezó a las ${clk(h,m)} y duró ${dur} minutos. ¿A qué hora terminó?`},
4290        a:{en:addMin(h,m,dur), es:addMin(h,m,dur)}
4291      };
4292    }
4293    if(k===2){
4294      const h=ri(1,10), m=pick([35,40,45,50]), dur=pick([25,30,40]);
4295      return {
4296        q:{en:`${n1} started packing ${it.en} at ${clk(h,m)} and finished at ${addMin(h,m,dur)}. How many minutes did the packing take?`,
4297           es:`${n1} empezó a empacar ${it.es} a las ${clk(h,m)} y terminó a las ${addMin(h,m,dur)}. ¿Cuántos minutos tardó?`},
4298        a:{en:`${dur} minutes`, es:`${dur} minutos`}
4299      };
4300    }
4301    if(k===3){
4302      const h=ri(2,10), m=pick([10,20,30]), dur=pick([35,45,50]);
4303      return {
4304        q:{en:`${n1}'s ${it.en} sale ends at ${addMin(h,m,dur)}. It runs for ${dur} minutes. What time does it start? (Work backward.)`,
4305           es:`La venta de ${it.es} de ${n1} termina a las ${addMin(h,m,dur)}. Dura ${dur} minutos. ¿A qué hora empieza? (Trabaja hacia atrás.)`},
4306        a:{en:clk(h,m), es:clk(h,m)}
4307      };
4308    }
4309    if(k===4){
4310      const d1=pick([25,35,40]), d2=pick([15,20,30]);
4311      return {
4312        q:{en:`${n1} spent ${d1} minutes setting up the ${it.en} table and ${n2} spent ${d2} minutes decorating it. How many minutes did they spend in all?`,
4313           es:`${n1} pasó ${d1} minutos preparando la mesa de ${it.es} y ${n2} pasó ${d2} minutos decorándola. ¿Cuántos minutos pasaron en total?`},
4314        a:{en:`${d1} + ${d2} = ${d1+d2} minutes`, es:`${d1} + ${d2} = ${d1+d2} minutos`}
4315      };
4316    }
4317    const dA=pick([40,55,65]), dB=pick([20,25,30,35]);   // dB always < dA
4318    return {
4319      q:{en:`${n1} practiced with the ${it.en} for ${dA} minutes and ${n2} practiced for ${dB} minutes. How many more minutes did ${n1} practice?`,
4320         es:`${n1} practicó con ${losLasEs(it)} ${it.es} durante ${dA} minutos y ${n2} durante ${dB} minutos. ¿Cuántos minutos más practicó ${n1}?`},
4321      a:{en:`${dA} − ${dB} = ${dA-dB} minutes`, es:`${dA} − ${dB} = ${dA-dB} minutos`}
4322    };
4323  }
4324},
4325{
4326  code:"3.MD.A.2", grade:3, dok:2,
4327  title:{en:"Mass & liquid volume word problems",
4328         es:"Problemas de masa y volumen líquido"},
4329  text:{en:"Measure and estimate liquid volumes and masses of objects using standard units of grams (g), kilograms (kg), and liters (l). Add, subtract, multiply, or divide to solve one-step word problems involving masses or volumes that are given in the same units.",
4330        es:"Mide y estima volúmenes líquidos y masas de objetos usando unidades estándar de gramos (g), kilogramos (kg) y litros (l). Suma, resta, multiplica o divide para resolver problemas de un paso con masas o volúmenes dados en las mismas unidades."},
4331  build(n1,n2,lvl){
4332    const it = pickItem(), bin = pick(THEME.bins);
4333
4334    /* ---- Support · DOK 1 ---- */
4335    if(lvl===1){
4336      const k=ri(1,4);
4337      if(k===1){
4338        const a=ri(10,40), b=ri(10,30);
4339        return {
4340          q:{en:`One of ${n1}'s ${it.en} has a mass of ${a} grams and another has ${b} grams. What is the total mass?`,
4341             es:`${unoEs(it)==="uno"?"Uno":"Una"} de ${losLasEs(it)} ${it.es} de ${n1} tiene una masa de ${a} gramos y ${unoEs(it)==="uno"?"otro":"otra"} tiene ${b} gramos. ¿Cuál es la masa total?`},
4342          a:{en:`${a} + ${b} = ${a+b} g`, es:`${a} + ${b} = ${a+b} g`}
4343        };
4344      }
4345      if(k===2){
4346        const a=ri(6,10), b=ri(2,4);
4347        return {
4348          q:{en:`${n1}'s watering jug held ${a} liters. ${n1} poured out ${b} liters. How many liters are left?`,
4349             es:`La jarra de ${n1} tenía ${a} litros. ${n1} sirvió ${b} litros. ¿Cuántos litros quedan?`},
4350          a:{en:`${a} − ${b} = ${a-b} liters`, es:`${a} − ${b} = ${a-b} litros`}
4351        };
4352      }
4353      if(k===3){
4354        const each=ri(3,6), n=ri(2,4);
4355        return {
4356          q:{en:`Each of ${n1}'s ${it.en} has a mass of ${each} grams. What is the mass of ${n} of them? (Hint: multiply.)`,
4357             es:`Cada ${unoEs(it)} de ${losLasEs(it)} ${it.es} de ${n1} tiene una masa de ${each} gramos. ¿Cuál es la masa de ${n}? (Pista: multiplica.)`},
4358          a:{en:`${n} × ${each} = ${n*each} g`, es:`${n} × ${each} = ${n*each} g`}
4359        };
4360      }
4361      const a=ri(12,30), b=ri(4,10);
4362      return {
4363        q:{en:`${n1}'s ${bin.one.en} of ${it.en} has a mass of ${a} kilograms. ${n2}'s has ${b} kilograms. How much heavier is ${n1}'s?`,
4364           es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${it.es} de ${n1} tiene una masa de ${a} kilogramos. ${elLaEs(bin)} de ${n2} tiene ${b}. ¿Cuánto más pesa ${elLaEs(bin)} de ${n1}?`},
4365        a:{en:`${a} − ${b} = ${a-b} kg`, es:`${a} − ${b} = ${a-b} kg`}
4366      };
4367    }
4368
4369    /* ---- Challenge · DOK 3 ---- */
4370    if(lvl===3){
4371      const k=ri(1,5);
4372      if(k===1){
4373        const g=ri(4,8), each=ri(6,9), tot=g*each;
4374        return {
4375          q:{en:`${g} of ${n1}'s ${it.en} together have a mass of ${tot} grams, and each one has the same mass. ${n2} multiplies and gets ${tot*g} g each. What operation should ${n2} have used? Give the correct mass.`,
4376             es:`${g} de ${losLasEs(it)} ${it.es} de ${n1} tienen juntos una masa de ${tot} gramos, y cada uno tiene la misma masa. ${n2} multiplica y obtiene ${tot*g} g cada uno. ¿Qué operación debía usar? Da la masa correcta.`},
4377          a:{en:`Divide — ${tot} ÷ ${g} = ${each} g each`, es:`Dividir — ${tot} ÷ ${g} = ${each} g cada ${unoEs(it)}`}
4378        };
4379      }
4380      if(k===2){
4381        const each=ri(3,6), tot=each*ri(5,9);
4382        return {
4383          q:{en:`${n1} has ${tot} liters of water and bottles that each hold ${each} liters. Write an equation with n for the number of bottles ${n1} can fill, then solve.`,
4384             es:`${n1} tiene ${tot} litros de agua y botellas que guardan ${each} litros cada una. Escribe una ecuación con n para el número de botellas que puede llenar y resuélvela.`},
4385          a:{en:`${each} × n = ${tot}; n = ${tot/each}`, es:`${each} × n = ${tot}; n = ${tot/each}`}
4386        };
4387      }
4388      if(k===3){
4389        const b=ri(8,20), half=ri(3,8), a=b+2*half;
4390        return {
4391          q:{en:`${n1}'s ${bin.one.en} of ${it.en} has a mass of ${a} kg and ${n2}'s has ${b} kg. How many kg should ${n1} move into ${n2}'s so they balance? Explain.`,
4392             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${it.es} de ${n1} tiene ${a} kg y ${elLaEs(bin)} de ${n2} tiene ${b} kg. ¿Cuántos kg debe pasar ${n1} para que queden iguales? Explica.`},
4393          a:{en:`(${a}−${b})÷2 = ${half} kg; both at ${b+half}`, es:`(${a}−${b})÷2 = ${half} kg; los dos en ${b+half}`}
4394        };
4395      }
4396      if(k===4){
4397        const each=ri(6,9), n=ri(6,9), claim=each*n+(ri(0,1)?ri(15,25):-ri(15,25));
4398        return {
4399          q:{en:`Each of ${n1}'s ${it.en} has a mass of about ${each} grams. ${n2} says ${n} of them have a mass of ${claim} g. Estimate with rounding — is that reasonable? Then compute exactly.`,
4400             es:`Cada ${unoEs(it)} de ${losLasEs(it)} ${it.es} de ${n1} tiene una masa de unos ${each} gramos. ${n2} dice que ${n} tienen una masa de ${claim} g. Estima redondeando — ¿es razonable? Luego calcula exacto.`},
4401          a:{en:`≈${n}×${Math.round(each/5)*5}=${n*Math.round(each/5)*5}; exact ${n*each} — not reasonable`,
4402             es:`≈${n}×${Math.round(each/5)*5}=${n*Math.round(each/5)*5}; exacto ${n*each} — no es razonable`}
4403        };
4404      }
4405      const jug=ri(12,20), cup=ri(2,4), fills=Math.floor(jug/cup), left=jug-fills*cup;
4406      return {
4407        q:{en:`${n1}'s jug holds ${jug} liters and each pitcher holds ${cup}
4407 liters. How many pitchers can ${n1} fill completely, and how many liters remain? Explain what the leftover means.`,
4408           es:`La jarra de ${n1} tiene ${jug} litros y cada jarra pequeña guarda ${cup} litros. ¿Cuántas puede llenar por completo y cuántos litros sobran? Explica qué significa lo que sobra.`},
4409        a:{en:`${fills} pitchers, ${left} liter${left===1?"":"s"} left`, es:`${fills} jarras, ${left} litro${left===1?"":"s"} sobrante${left===1?"":"s"}`}
4410      };
4411    }
4412
4413    /* ---- On level · DOK 2 : one-step, all four operations ---- */
4414    const k=ri(1,5);
4415    if(k===1){
4416      const each=ri(4,9), n=ri(3,8);
4417      return {
4418        q:{en:`Each of ${n1}'s ${it.en} has a mass of ${each} grams. What is the total mass of ${n} of them?`,
4419           es:`Cada ${unoEs(it)} de ${losLasEs(it)} ${it.es} de ${n1} tiene una masa de ${each} gramos. ¿Cuál es la masa total de ${n}?`},
4420        a:{en:`${n} × ${each} = ${n*each} g`, es:`${n} × ${each} = ${n*each} g`}
4421      };
4422    }
4423    if(k===2){
4424      const share=ri(3,6), each=ri(4,9), tot=share*each;
4425      return {
4426        q:{en:`${n1} split ${tot} grams of ${it.en} equally into ${share} bags. What is the mass in each bag?`,
4427           es:`${n1} repartió ${tot} gramos de ${it.es} en ${share} bolsas iguales. ¿Cuál es la masa de cada bolsa?`},
4428        a:{en:`${tot} ÷ ${share} = ${each} g`, es:`${tot} ÷ ${share} = ${each} g`}
4429      };
4430    }
4431    if(k===3){
4432      const a=ri(25,60), b=ri(10, a-5);   // "after" must be less than "before"
4433      return {
4434        q:{en:`${n1}'s ${bin.one.en} of ${it.en} has a mass of ${a} kg. After ${n2} takes some out, it has ${b} kg. How many kg did ${n2} take?`,
4435           es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${it.es} de ${n1} tiene ${a} kg. Después de que ${n2} saca una parte, tiene ${b} kg. ¿Cuántos kg sacó ${n2}?`},
4436        a:{en:`${a} − ${b} = ${a-b} kg`, es:`${a} − ${b} = ${a-b} kg`}
4437      };
4438    }
4439    if(k===4){
4440      const a=ri(8,15), b=ri(6,14);
4441      return {
4442        q:{en:`${n1} filled a cooler with ${a} liters of water, then ${n2} added ${b} more liters. How many liters are in the cooler?`,
4443           es:`${n1} llenó una hielera con ${a} litros de agua y luego ${n2} agregó ${b} litros más. ¿Cuántos litros hay en la hielera?`},
4444        a:{en:`${a} + ${b} = ${a+b} liters`, es:`${a} + ${b} = ${a+b} litros`}
4445      };
4446    }
4447    const each=ri(2,5), tot=each*ri(4,9);
4448    return {
4449      q:{en:`${n1} has ${tot} liters of juice for the ${THEME.group.en} and pours it into jugs that each hold ${each} liters. How many jugs does ${n1} fill?`,
4450         es:`${n1} tiene ${tot} litros de jugo para ${elLaEs(THEME.group)} ${THEME.group.es} y los sirve en jarras de ${each} litros. ¿Cuántas jarras llena?`},
4451      a:{en:`${tot} ÷ ${each} = ${tot/each} jugs`, es:`${tot} ÷ ${each} = ${tot/each} jarras`}
4452    };
4453  }
4454},
4455{
4456  code:"3.MD.B.3", grade:3, dok:3,
4457  title:{en:"Scaled bar & picture graphs",
4458         es:"Gráficas de barras y pictogramas con escala"},
4459  text:{en:"Draw a scaled picture graph and a scaled bar graph to represent a data set with several categories. Solve one- and two-step \"how many more\" and \"how many less\" problems using information presented in scaled bar graphs.",
4460        es:"Dibuja un pictograma y una gráfica de barras con escala para representar un conjunto de datos con varias categorías. Resuelve problemas de uno y dos pasos de \"cuántos más\" y \"cuántos menos\" usando la información de gráficas de barras con escala."},
4461  build(n1,n2,lvl){
4462    const it = pickItem();
4463    let it2 = pick(THEME.items); while(it2.en===it.en) it2 = pick(THEME.items);
4464    let it3 = pick(THEME.items); while(it3.en===it.en||it3.en===it2.en) it3 = pick(THEME.items);
4465
4466    /* ---- Support · DOK 1 : scale of 2 ---- */
4467    if(lvl===1){
4468      const k=ri(1,4);
4469      if(k===1){
4470        const sym=ri(3,6), scale=2;
4471        return {
4472          q:{en:`On ${n1}'s picture graph each picture means ${scale} ${it.en}. ${it.en.charAt(0).toUpperCase()+it.en.slice(1)} has ${sym} pictures. How many ${it.en} is that?`,
4473             es:`En el pictograma de ${n1} cada dibujo vale ${scale} ${it.es}. ${losLasEs(it)==="los"?"Los":"Las"} ${it.es} tienen ${sym} dibujos. ¿${cuantosEs(it)} son?`},
4474          a:{en:`${sym} × ${scale}
4474 = ${sym*scale}`, es:`${sym} × ${scale} = ${sym*scale}`}
4475        };
4476      }
4477      if(k===2){
4478        const scale=2, a=ri(4,9)*scale, b=ri(1,3)*scale;
4479        return {
4480          q:{en:`${n1}'s bar graph counts by ${scale}s. ${it.en} shows ${a} and ${it2.en} shows ${b}. How many more ${it.en}?`,
4481             es:`La gráfica de ${n1} cuenta de ${scale} en ${scale}. ${it.es} muestra ${a} y ${it2.es} muestra ${b}. ¿${cuantosEs(it)} ${it.es} más hay?`},
4482          a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
4483        };
4484      }
4485      if(k===3){
4486        const scale=5, sym=ri(2,5);
4487        return {
4488          q:{en:`Each picture on ${n1}'s graph means ${scale} ${it.en}. ${n1} drew ${sym} pictures. How many ${it.en} in all?`,
4489             es:`Cada dibujo en la gráfica de ${n1} vale ${scale} ${it.es}. ${n1} dibujó ${sym} dibujos. ¿${cuantosEs(it)} ${it.es} hay en total?`},
4490          a:{en:`${sym} × ${scale} = ${sym*scale}`, es:`${sym} × ${scale} = ${sym*scale}`}
4491        };
4492      }
4493      const scale=2, a=ri(3,8)*scale, b=ri(2,6)*scale;
4494      return {
4495        q:{en:`${n1}'s graph shows ${a} ${it.en} and ${b} ${it2.en}. How many are there altogether?`,
4496           es:`La gráfica de ${n1} muestra ${a} ${it.es} y ${b} ${it2.es}. ¿${cuantosEs(it)} hay en total?`},
4497        a:{en:`${a} + ${b} = ${a+b}`, es:`${a} + ${b} = ${a+b}`}
4498      };
4499    }
4500
4501    /* ---- Challenge · DOK 3 : two-step with scale ---- */
4502    if(lvl===3){
4503      const k=ri(1,4);
4504      if(k===1){
4505        const scale=pick([4,5]), symA=ri(5,9), symB=ri(2,4);
4506        return {
4507          q:{en:`Each picture on ${n1}'s graph means ${scale} ${it.en}. ${it.en} has ${symA} pictures and ${it2.en} has ${symB}. How many more ${it.en} than ${it2.en}? Show both steps.`,
4508             es:`Cada dibujo en la gráfica de ${n1} vale ${scale} ${it.es}. ${it.es} tiene ${symA} dibujos y ${it2.es} tiene ${symB}. ¿${cuantosEs(it)} ${it.es} más? Muestra los dos pasos.`},
4509          a:{en:`${symA}×${scale}=${symA*scale}, ${symB}×${scale}=${symB*scale}; difference ${(symA-symB)*scale}`,
4510             es:`${symA}×${scale}=${symA*scale}, ${symB}×${scale}=${symB*scale}; diferencia ${(symA-symB)*scale}`}
4511        };
4512      }
4513      if(k===2){
4514        const scale=pick([2,5]), b=ri(3,6)*scale, c=ri(2,4)*scale;
4515        const a=b+c+ri(2,6)*scale;   // a must exceed b+c
4516        return {
4517          q:{en:`${n1}'s scaled graph shows ${a} ${it.en}, ${b} ${it2.en}, and ${c} ${it3.en}. How many more ${it.en} than the other two combined? Show your work.`,
4518             es:`La gráfica con escala de ${n1} muestra ${a} ${it.es}, ${b} ${it2.es} y ${c} ${it3.es}. ¿${cuantosEs(it)} ${it.es} más que los otros dos juntos? Muestra tu trabajo.`},
4519          a:{en:`${b}+${c}=${b+c}; ${a}−${b+c} = ${a-(b+c)}`, es:`${b}+${c}=${b+c}; ${a}−${b+c} = ${a-(b+c)}`}
4520        };
4521      }
4522      if(k===3){
4523        const scale=5, sym=ri(4,8), wrong=sym;
4524        return {
4525          q:{en:`Each picture on ${n1}'s graph means ${scale} ${it.en}. ${n2} counts ${sym} pictures and says there are ${wrong} ${it.en}. What did ${n2} forget? Give the correct number.`,
4526             es:`Cada dibujo en la gráfica de ${n1} vale ${scale} ${it.es}. ${n2} cuenta ${sym} dibujos y dice que hay ${wrong} ${it.es}. ¿Qué olvidó ${n2}? Da el número correcto.`},
4527          a:{en:`Forgot the scale — ${sym} × ${scale} = ${sym*scale}`,
4528             es:`Olvidó la escala — ${sym} × ${scale} = ${sym*scale}`}
4529        };
4530      }
4531      const scale=pick([2,4]), tot=ri(12,20)*scale, a=ri(4,8)*scale, b=ri(3,6)*scale;
4532      const rest=tot-a-b;
4533      if(rest<scale) return this.build(n1,n2,lvl);
4534      return {
4535        q:{en:`${n1}'s graph shows ${tot} ${it.en} in all across three bars. Two bars show ${a} and ${b}. How tall is the third bar? Explain how you know.`,
4536           es:`La gráfica de ${n1} muestra ${tot} ${it.es} en tres barras. Dos muestran ${a} y ${b}. ¿Cuánto muestra la tercera? Explica cómo lo sabes.`},
4537        a:{en:`${a}+${b}=${a+b}; ${tot}−${a+b} = ${rest}`, es:`${a}+${b}=${a+b}; ${tot}−${a+b} = ${rest}`}
4538      };
4539    }
4540
4541    /* ---- On level · DOK 2 ---- */
4542    const k=ri(1,4);
4543    if(k===1){
4544      const scale=pick([2,5]), sym=ri(3,8);
4545      return {
4546        q:{en:`Each picture on ${n1}'s graph means ${scale} ${it.en}. ${it.en} has ${sym} pictures. How many ${it.en} does that show?`,
4547           es:`Cada dibujo en la gráfica de ${n1} vale ${scale} ${it.es}. ${it.es} tiene ${sym} dibujos. ¿${cuantosEs(it)} ${it.es} muestra?`},
4548        a:{en:`${sym} × ${scale} = ${sym*scale}`, es:`${sym} × ${scale} = ${sym*scale}`}
4549      };
4550    }
4551    if(k===2){
4552      const scale=pick([2,5]), b=ri(2,5)*scale, a=b+ri(2,6)*scale;
4553      return {
4554        q:{en:`${n1}'s bar graph shows ${a} ${it.en} and ${b} ${it2.en}. How many more ${it.en} are there?`,
4555           es:`La gráfica de ${n1} muestra ${a} ${it.es} y ${b} ${it2.es}. ¿${cuantosEs(it)} ${it.es} más hay?`},
4556        a:{en:`${a} − ${b} = ${a-b}`, es:`${a} − ${b} = ${a-b}`}
4557      };
4558    }
4559    if(k===3){
4560      const scale=pick([2,5]), a=ri(3,8)*scale, b=ri(2,7)*scale, c=ri(2,6)*scale;
4561      return {
4562        q:{en:`${n1} and ${n2} graphed ${a} ${it.en}, ${b} ${it2.en}, and ${c} ${it3.en}. How many are shown in all?`,
4563           es:`${n1} y ${n2} graficaron ${a} ${it.es}, ${b} ${it2.es} y ${c} ${it3.es}. ¿${cuantosEs(it)} se muestran en total?`},
4564        a:{en:`${a}+${b}+${c} = ${a+b+c}`, es:`${a}+${b}+${c} = ${a+b+c}`}
4565      };
4566    }
4567    const scale=pick([4,5]), symA=ri(4,9), symB=ri(2,4);
4568    return {
4569      q:{en:`On ${n1}'s picture graph each picture means ${scale} ${it.en}. ${it.en} has ${symA} pictures, ${it2.en} has ${symB}. How many ${it.en} and ${it2.en} altogether?`,
4570         es:`En el pictograma de ${n1} cada dibujo vale ${scale} ${it.es}. ${it.es} tiene ${symA} dibujos y ${it2.es} tiene ${symB}. ¿${cuantosEs(it)} hay en total?`},
4571      a:{en:`(${symA}+${symB}) × ${scale} = ${(symA+symB)*scale}`, es:`(${symA}+${symB}) × ${scale} = ${(symA+symB)*scale}`}
4572    };
4573  }
4574},
4575{
4576  code:"3.MD.C.7.b", grade:3, dok:2,
4577  title:{en:"Area of rectangles — real-world problems",
4578         es:"Área de rectángulos — problemas del mundo real"},
4579  text:{en:"Multiply side lengths to find areas of rectangles with whole-number side lengths in the context of solving real world and mathematical problems, and represent whole-number products as rectangular areas in mathematical reasoning.",
4580        es:"Multiplica las longitudes de los lados para hallar áreas de rectángulos con lados de números enteros en el contexto de problemas del mundo real y matemáticos, y representa productos de números enteros como áreas rectangulares en el razonamiento matemático."},
4581  build(n1,n2,lvl){
4582    const it = pickItem();
4583    const u = ITEMLOCK ? {en:"cm",es:"cm"} : pick([{en:"cm",es:"cm"},{en:"inches",es:"pulgadas"}]);
4584    const sq = {en:"square "+u.en, es:u.es+" cuadrados"};
4585
4586    /* ---- Support · DOK 1 : small sides, tiling link ---- */
4587    if(lvl===1){
4588      const k=ri(1,4);
4589      if(k===1){
4590        const L=ri(3,6), W=ri(2,4);
4591        return {
4592          q:{en:`${n1}'s ${it.en} mat is ${L} ${u.en} long and ${W} ${u.en} wide. Multiply to find the area. (Hint: picture ${W} rows of ${L} squares.)`,
4593             es:`El tapete de ${it.es} de ${n1} mide ${L} ${u.es} de largo y ${W} ${u.es} de ancho. Multiplica para hallar el área. (Pista: imagina ${W} filas de ${L} cuadritos.)`},
4594          a:{en:`${L} × ${W} = ${L*W} ${sq.en}`, es:`${L} × ${W} = ${L*W} ${sq.es}`}
4595        };
4596      }
4597      if(k===2){
4598        const sd=ri(3,6);
4599        return {
4600          q:{en:`${n1} cut a square card for the ${it.en} shelf. Each side is ${sd} ${u.en}. What is its area?`,
4601             es:`${n1} cortó una tarjeta cuadrada para el estante de ${it.es}. Cada lado mide ${sd} ${u.es}. ¿Cuál es su área?`},
4602          a:{en:`${sd} × ${sd} = ${sd*sd} ${sq.en}`, es:`${sd} × ${sd} = ${sd*sd} ${sq.es}`}
4603        };
4604      }
4605      if(k===3){
4606        const L=ri(4,7), W=ri(2,3);
4607        return {
4608          q:{en:`${n2} covered a ${it.en} tray with unit squares: ${W} rows with ${L} squares in each row. How many squares cover the tray, and what is its area?`,
4609             es:`${n2} cubrió una bandeja de ${it.es} con cuadritos: ${W} filas con ${L} cuadritos cada una. ¿Cuántos cuadritos la cubren y cuál es su área?`},
4610          a:{en:`${W} × ${L} = ${L*W} ${sq.en}`, es:`${W} × ${L} = ${L*W} ${sq.es}`}
4611        };
4612      }
4613      const L=ri(4,8), W=2;
4614      return {
4615        q:{en:`${n1}'s bookmark for the ${it.en} fair is ${L} ${u.en} by ${W} ${u.en}. Skip-count by ${L}s to find the area.`,
4616           es:`El marcapáginas de ${n1} para la feria de ${it.es} mide ${L} por ${W} ${u.es}. Cuenta de ${L} en ${L} para hallar el área.`},
4617        a:{en:`${L} × ${W} = ${L*W} ${sq.en}`, es:`${L} × ${W} = ${L*W} ${sq.es}`}
4618      };
4619    }
4620
4621    /* ---- Challenge · DOK 3 ---- */
4622    if(lvl===3){
4623      const k=ri(1,5);
4624      if(k===1){
4625        const A=pick([12,16,24,36]);
4626        const p1=[A/2,2], p2=[A/4,4];
4627        return {
4628          q:{en:`${n1} and ${n2} each design a ${it.en} banner with an area of exactly ${A} ${sq.en}. Give two DIFFERENT rectangles that work, and show the multiplication for each.`,
4629             es:`${n1} y ${n2} diseñan cada uno un cartel de ${it.es} con un área de exactamente ${A} ${sq.es}. Da dos rectángulos DIFERENTES que funcionen y muestra la multiplicación de cada uno.`},
4630          a:{en:`e.g. ${p1[0]}×${p1[1]}=${A} and ${p2[0]}×${p2[1]}=${A} — any pair with product ${A}`,
4631             es:`p. ej. ${p1[0]}×${p1[1]}=${A} y ${p2[0]}×${p2[1]}=${A} — cualquier par con producto ${A}`}
4632        };
4633      }
4634      if(k===2){
4635        const L=ri(5,9), W=ri(3,6);
4636        return {
4637          q:{en:`${n2} says the area of ${n1}'s ${L} by ${W} ${u.en} ${it.en} poster is ${L+W} ${sq.en}, adding the sides. What did ${n2} confuse area with? Give the correct area.`,
4638             es:`${n2} dice que el área del cartel de ${it.es} de ${n1}, de ${L} por ${W} ${u.es}, es ${L+W} ${sq.es}, sumando los lados. ¿Con qué confundió el área? Da el área correcta.`},
4639          a:{en:`Confused with adding sides — area is ${L}×${W} = ${L*W} ${sq.en}`,
4640             es:`Lo confundió con sumar los lados — el área es ${L}×${W} = ${L*W} ${sq.es}`}
4641        };
4642      }
4643      if(k===3){
4644        const W=ri(3,7), L=ri(4,9), A=L*W;
4645        return {
4646          q:{en:`${n1}'s rectangular ${it.en} rug has an area of ${A} ${sq.en} and a width of ${W} ${u.en}. Write an equation with n for the length, then solve it.`,
4647             es:`El tapete rectangular de ${it.es} de ${n1} tiene un área de ${A} ${sq.es} y un ancho de ${W} ${u.es}. Escribe una ecuación con n para el largo y resuélvela.`},
4648          a:{en:`${W} × n = ${A}; n = ${L} ${u.en}`, es:`${W} × n = ${A}; n = ${L} ${u.es}`}
4649        };
4650      }
4651      if(k===4){
4652        const L=ri(5,8), W=ri(3,5), cL=L+ri(0,1), cW=W+ri(1,2);
4653        return {
4654          q:{en:`${n1}'s ${it.en} display space is ${L} by ${W} ${u.en}. A poster measures ${cL} by ${cW} ${u.en}. Compare the areas — will the poster fit flat in the space? Explain.`,
4655             es:`El espacio de exhibición de ${it.es} de ${n1} mide ${L} por ${W} ${u.es}. Un cartel mide ${cL} por ${cW} ${u.es}. Compara las áreas — ¿cabe el cartel extendido en el espacio? Explica.`},
4656          a:{en:`${L*W} vs ${cL*cW} ${sq.en} — ${cL<=L&&cW<=W?"fits":"does not fit (and side lengths matter, not just area)"}`,
4657             es:`${L*W} vs ${cL*cW} ${sq.es} — ${cL<=L&&cW<=W?"cabe":"no cabe (importan los lados, no solo el área)"}`}
4658        };
4659      }
4660      const L1=ri(5,9), W1=ri(3,6), L2=ri(5,9), W2=ri(3,6);
4661      const A1=L1*W1, A2=L2*W2;
4662      if(A1===A2) return this.build(n1,n2,lvl);
4663      return {
4664        q:{en:`${n1}'s garden plot for the ${it.en} stand is ${L1} by ${W1} ${u.en}; ${n2}'s is ${L2} by ${W2} ${u.en}. Whose plot has more area, and by how many ${sq.en}? Show both products.`,
4665           es:`La parcela de ${n1} para el puesto de ${it.es} mide ${L1} por ${W1} ${u.es}; la de ${n2} mide ${L2} por ${W2} ${u.es}. ¿Cuál parcela tiene más área y por cuántos ${sq.es}? Muestra los dos productos.`},
4666        a:{en:`${A1} vs ${A2} — ${A1>A2?n1:n2} by ${Math.abs(A1-A2)} ${sq.en}`,
4667           es:`${A1} vs ${A2} — ${A1>A2?n1:n2} por ${Math.abs(A1-A2)} ${sq.es}`}
4668      };
4669    }
4670
4671    /* ---- On level · DOK 2 ---- */
4672    const k=ri(1,5);
4673    if(k===1){
4674      const L=ri(5,12), W=ri(3,8);
4675      return {
4676        q:{en:`${n1}'s rectangular ${it.en} table cover is ${L} ${u.en} by ${W} ${u.en}. What is its area?`,
4677           es:`El mantel rectangular de ${it.es} de ${n1} mide ${L} por ${W} ${u.es}. ¿Cuál es su área?`},
4678        a:{en:`${L} × ${W} = ${L*W} ${sq.en}`, es:`${L} × ${W} = ${L*W} ${sq.es}`}
4679      };
4680    }
4681    if(k===2){
4682      const W=ri(3,8), L=ri(4,9), A=L*W;
4683      return {
4684        q:{en:`${n1}'s ${it.en} poster has an area of ${A} ${sq.en}. Its width is ${W} ${u.en}. How long is it?`,
4685           es:`El cartel de ${it.es} de ${n1} tiene un área de ${A} ${sq.es}. Su ancho es ${W} ${u.es}. ¿Cuánto mide de largo?`},
4686        a:{en:`${A} ÷ ${W} = ${L} ${u.en}`, es:`${A} ÷ ${W} = ${L} ${u.es}`}
4687      };
4688    }
4689    if(k===3){
4690      const sd=ri(4,9);
4691      return {
4692        q:{en:`${n2} painted a square sign for the ${it.en} sale with ${sd} ${u.en} sides. What area did ${n2} paint?`,
4693           es:`${n2} pintó un letrero cuadrado para la venta de ${it.es} con lados de ${sd} ${u.es}. ¿Qué área pintó?`},
4694        a:{en:`${sd} × ${sd} = ${sd*sd} ${sq.en}`, es:`${sd} × ${sd} = ${sd*sd} ${sq.es}`}
4695      };
4696    }
4697    if(k===4){
4698      const L1=ri(4,8), W1=ri(3,6), L2=ri(4,8), W2=ri(2,5);
4699      return {
4700        q:{en:`${n1} tapes two rectangles of paper for the ${it.en} mural: one ${L1} by ${W1} ${u.en} and one ${L2} by ${W2} ${u.en}. What is the total area covered?`,
4701           es:`${n1} pega dos rectángulos de papel para el mural de ${it.es}: uno de ${L1} por ${W1} ${u.es} y otro de ${L2} por ${W2} ${u.es}
4701. ¿Cuál es el área total cubierta?`},
4702        a:{en:`${L1*W1} + ${L2*W2} = ${L1*W1+L2*W2} ${sq.en}`, es:`${L1*W1} + ${L2*W2} = ${L1*W1+L2*W2} ${sq.es}`}
4703      };
4704    }
4705    const L=ri(6,12), W=ri(3,7);
4706    return {
4707      q:{en:`Each ${it.one.en} sticker covers 1 ${sq.en}. ${n1}'s board is ${L} by ${W} ${u.en}. How many stickers would cover the whole board?`,
4708         es:`Cada calcomanía de ${it.one.es} cubre 1 ${u.es} cuadrado. El tablero de ${n1} mide ${L} por ${W} ${u.es}. ¿Cuántas calcomanías cubrirían todo el tablero?`},
4709      a:{en:`${L} × ${W} = ${L*W}`, es:`${L} × ${W} = ${L*W}`}
4710    };
4711  }
4712},
4713{
4714  code:"3.MD.D.8", grade:3, dok:3,
4715  title:{en:"Perimeter word problems",
4716         es:"Problemas de perímetro"},
4717  text:{en:"Solve real world and mathematical problems involving perimeters of polygons, including finding the perimeter given the side lengths, finding an unknown side length, and exhibiting rectangles with the same perimeter and different areas or with the same area and different perimeters.",
4718        es:"Resuelve problemas del mundo real y matemáticos sobre perímetros de polígonos, incluyendo hallar el perímetro dadas las longitudes de los lados, hallar la longitud de un lado desconocido, y mostrar rectángulos con el mismo perímetro y diferentes áreas o con la misma área y diferentes perímetros."},
4719  build(n1,n2,lvl){
4720    const it = pickItem();
4721    const u = ITEMLOCK ? {en:"cm",es:"cm"} : pick([{en:"cm",es:"cm"},{en:"inches",es:"pulgadas"}]);
4722
4723    /* ---- Support · DOK 1 ---- */
4724    if(lvl===1){
4725      const k=ri(1,4);
4726      if(k===1){
4727        const L=ri(4,9), W=ri(2,5);
4728        return {
4729          q:{en:`${n1}'s tray for ${it.en} is a rectangle ${L} ${u.en} long and ${W} ${u.en} wide. Add all four sides to find the perimeter.`,
4730             es:`La bandeja de ${it.es} de ${n1} es un rectángulo de ${L} ${u.es} de largo y ${W} ${u.es} de ancho. Suma los cuatro lados para hallar el perímetro.`},
4731          a:{en:`${L}+${W}+${L}+${W} = ${2*(L+W)} ${u.en}`, es:`${L}+${W}+${L}+${W} = ${2*(L+W)} ${u.es}`}
4732        };
4733      }
4734      if(k===2){
4735        const sd=ri(3,8);
4736        return {
4737          q:{en:`${n1} made a square frame for the ${it.en} poster. Each side is ${sd} ${u.en}. What is the perimeter? (Hint: 4 equal sides.)`,
4738             es:`${n1} hizo un marco cuadrado para el cartel de ${it.es}. Cada lado mide ${sd} ${u.es}. ¿Cuál es el perímetro? (Pista: 4 lados iguales.)`},
4739          a:{en:`4 × ${sd} = ${4*sd} ${u.en}`, es:`4 × ${sd} = ${4*sd} ${u.es}`}
4740        };
4741      }
4742      if(k===3){
4743        const a=ri(3,7), b=ri(3,7), c=ri(3,7);
4744        return {
4745          q:{en:`${n1} taped a triangle border for the ${it.en} table with sides ${a}, ${b}, and ${c} ${u.en}. What is the perimeter?`,
4746             es:`${n1} pegó un borde triangular para la mesa de ${it.es} con lados de ${a}, ${b} y ${c} ${u.es}. ¿Cuál es el perímetro?`},
4747          a:{en:`${a}+${b}+${c} = ${a+b+c} ${u.en}`, es:`${a}+${b}+${c} = ${a+b+c} ${u.es}`}
4748        };
4749      }
4750      const L=ri(5,10), W=ri(2,5);
4751      return {
4752        q:{en:`${n1} walks the edge of a rectangular ${it.en} display mat: ${L} ${u.en}, then ${W} ${u.en}, then ${L}, then ${W}. How far around is that?`,
4753           es:`${n1} recorre el borde de un tapete rectangular de ${it.es}: ${L} ${u.es}, luego ${W} ${u.es}, luego ${L}, luego ${W}. ¿Cuánto mide la vuelta completa?`},
4754        a:{en:`${2*(L+W)} ${u.en}`, es:`${2*(L+W)} ${u.es}`}
4755      };
4756    }
4757
4758    /* ---- Challenge · DOK 3 ---- */
4759    if(lvl===3){
4760      const k=ri(1,5);
4761      if(k===1){
4762        const P=pick([16,20,24]), L1=P/2-2, W1=2, L2=P/4, W2=P/4;
4763        return {
4764          q:{en:`${n1} and ${n2} each have ${P} ${u.en} of border for a rectangular ${it.en} pen. ${n1} makes it ${L1} by ${W1}; ${n2} makes it ${L2} by ${W2}. Check that both use ${P} ${u.en}, then explain how the same perimeter gives different shapes.`,
4765             es:`${n1} y ${n2} tienen ${P} ${u.es} de borde cada uno para un corral rectangular de ${it.es}. ${n1} lo hace de ${L1} por ${W1}; ${n2} de ${L2} por ${W2}. Comprueba que ambos usan ${P} ${u.es} y explica cómo el mismo perímetro da formas diferentes.`},
4766          a:{en:`2(${L1}+${W1})=${P} and 2(${L2}+${W2})=${P} — same perimeter, different rectangles`,
4767             es:`2(${L1}+${W1})=${P} y 2(${L2}+${W2})=${P} — mismo perímetro, rectángulos diferentes`}
4768        };
4769      }
4770      if(k===2){
4771        const L=ri(6,12), W=ri(3,8), P=2*(L+W);
4772        return {
4773          q:{en:`A rectangular ${it.en} mat has a perimeter of ${P} ${u.en}. One side is ${L} ${u.en}. ${n1} writes n for the missing side. Solve for n and explain your steps.`,
4774             es:`Un tapete rectangular de ${it.es} tiene un perímetro de ${P} ${u.es}. Un lado mide ${L} ${u.es}. ${n1} escribe n para el lado que falta. Resuelve n y explica tus pasos.`},
4775          a:{en:`${P}÷2−${L} = ${W} ${u.en}`, es:`${P}÷2−${L} = ${W} ${u.es}`}
4776        };
4777      }
4778      if(k===3){
4779        const L=ri(6,11), W=ri(3,7);
4780        return {
4781          q:{en:`${n2} computed the perimeter of ${n1}'s ${L} by ${W} ${u.en} ${it.en} board as ${L+W} ${u.en}, adding one length and one width. What did ${n2} miss? Give the correct perimeter.`,
4782             es:`${n2} calculó el perímetro del tablero de ${it.es} de ${n1}, de ${L} por ${W} ${u.es}, como ${L+W} ${u.es}, sumando un largo y un ancho. ¿Qué le faltó? Da el perímetro correcto.`},
4783          a:{en:`Only 2 of 4 sides — 2×(${L}+${W}) = ${2*(L+W)} ${u.en}`,
4784             es:`Solo 2 de 4 lados — 2×(${L}+${W}) = ${2*(L+W)} ${u.es}`}
4785        };
4786      }
4787      if(k===4){
4788        const W=ri(3,6), L=ri(7,12);
4789        return {
4790          q:{en:`${n1} is fencing three sides of a rectangular ${it.en} patch against a wall: two sides of ${W} ${u.en} and one of ${L} ${u.en}. How much fencing is needed? Why is this NOT the full perimeter?`,
4791             es:`${n1} cerca tres lados de un terreno rectangular de ${it.es} contra una pared: dos lados de ${W} ${u.es} y uno de ${L} ${u.es}. ¿Cuánta cerca necesita? ¿Por qué NO es el perímetro completo?`},
4792          a:{en:`${W}+${W}+${L} = ${2*W+L} ${u.en} — the wall covers the fourth side`,
4793             es:`${W}+${W}+${L} = ${2*W+L} ${u.es} — la pared cubre el cuarto lado`}
4794        };
4795      }
4796      const P=pick([12,16,20]);
4797      return {
4798        q:{en:`${n1} has exactly ${P} ${u.en} of ribbon to border a rectangular ${it.en} card. Give one pair of side lengths that works, and show why it uses all ${P} ${u.en}.`,
4799           es:`${n1} tiene exactamente ${P} ${u.es} de cinta para bordear una tarjeta rectangular de ${it.es}. Da un par de medidas que funcione y muestra por qué usa los ${P} ${u.es}.`},
4800        a:{en:`any L+W=${P/2} works — e.g. ${P/2-2} by 2: 2(${P/2-2}+2)=${P}`,
4801           es:`cualquier L+W=${P/2} — p. ej. ${P/2-2} por 2: 2(${P/2-2}+2)=${P}`}
4802      };
4803    }
4804
4805    /* ---- On level · DOK 2 ---- */
4806    const k=ri(1,5);
4807    if(k===1){
4808      const L=ri(6,14), W=ri(3,9);
4809      return {
4810        q:{en:`${n1}'s rectangular ${it.en} board is ${L} ${u.en} by ${W} ${u.en}. What is its perimeter?`,
4811           es:`El tablero rectangular de ${it.es} de ${n1} mide ${L} ${u.es} por ${W} ${u.es}. ¿Cuál es su perímetro?`},
4812        a:{en:`2×(${L}+${W}) = ${2*(L+W)} ${u.en}`, es:`2×(${L}+${W}) = ${2*(L+W)} ${u.es}`}
4813      };
4814    }
4815    if(k===2){
4816      const sd=ri(4,9), P=4*sd;
4817      return {
4818        q:{en:`${n1}'s square ${it.en} mat has a perimeter of ${P} ${u.en}. How long is each side?`,
4819           es:`El tapete cuadrado de ${it.es} de ${n1} tiene un perímetro de ${P} ${u.es}. ¿Cuánto mide cada lado?`},
4820        a:{en:`${P} ÷ 4 = ${sd} ${u.en}`, es:`${P} ÷ 4 = ${sd} ${u.es}`}
4821      };
4822    }
4823    if(k===3){
4824      const L=ri(6,12), W=ri(3,8), P=2*(L+W);
4825      return {
4826        q:{en:`A rectangular frame for ${n1}'s ${it.en} photo has a perimeter of ${P} ${u.en} and a length of ${L} ${u.en}. What is the width?`,
4827           es:`Un marco rectangular para la foto de ${it.es} de ${n1} tiene un perímetro de ${P} ${u.es} y un largo de ${L} ${u.es}. ¿Cuál es el ancho?`},
4828        a:{en:`${P}÷2 − ${L} = ${W} ${u.en}`, es:`${P}÷2 − ${L} = ${W} ${u.es}`}
4829      };
4830    }
4831    if(k===4){
4832      const a=ri(4,9), b=ri(4,9), c=ri(4,9), d=ri(4,9);
4833      return {
4834        q:{en:`${n1} tapes a border around a four-sided ${it.en} sign with sides ${a}, ${b}, ${c}, and ${d} ${u.en}. How much tape is that?`,
4835           es:`${n1} pega un borde alrededor de un letrero de ${it.es} de cuatro lados: ${a}, ${b}, ${c} y ${d} ${u.es}. ¿Cuánta cinta es?`},
4836        a:{en:`${a}+${b}+${c}+${d} = ${a+b+c+d} ${u.en}`, es:`${a}+${b}+${c}+${d} = ${a+b+c+d} ${u.es}`}
4837      };
4838    }
4839    const L1=ri(6,12), W1=ri(3,8), L2=ri(6,12), W2=ri(3,8);
4840    const P1=2*(L1+W1), P2=2*(L2+W2);
4841    return {
4842      q:{en:`${n1}'s ${it.en} mat is ${L1} by ${W1} ${u.en}; ${n2}'s is ${L2} by ${W2} ${u.en}. Whose mat has the greater perimeter? Show both.`,
4843         es:`El tapete de ${it.es} de ${n1} mide ${L1} por ${W1} ${u.es}; el de ${n2} mide ${L2} por ${W2} ${u.es}. ¿Cuál tapete tiene mayor perímetro? Muestra los dos.`},
4844      a:{en:`${P1} vs ${P2} — ${P1===P2?"equal":(P1>P2?n1:n2)}`, es:`${P1} vs ${P2} — ${P1===P2?"iguales":(P1>P2?n1:n2)}`}
4845    };
4846  }
4847},
4848{
4849  code:"4.OA.A.2", grade:4, dok:2,
4850  title:{en:"Multiplicative comparison — times as many",
4851         es:"Comparación multiplicativa — veces la cantidad"},
4852  text:{en:"Multiply or divide to solve word problems involving multiplicative comparison, e.g., by using drawings and equations with a symbol for the unknown number to represent the problem, distinguishing multiplicative comparison from additive comparison.",
4853        es:"Multiplica o divide para resolver problemas verbales de comparación multiplicativa, por ejemplo, usando dibujos y ecuaciones con un símbolo para el número desconocido, distinguiendo la comparación multiplicativa de la comparación aditiva."},
4854  build(n1,n2,lvl){
4855    const it = pickItem();
4856
4857    /* ---- Support · DOK 1 : small factors, forward only ---- */
4858    if(lvl===1){
4859      const k=ri(1,4);
4860      if(k===1){
4861        const small=ri(2,5), times=ri(2,4);
4862        return {
4863          q:{en:`${n2} has ${small} ${it.en}. ${n1} has ${times} times as many. How many ${it.en} does ${n1} have? (Hint: draw ${times} groups of ${small}.)`,
4864             es:`${n2} tiene ${small} ${it.es}. ${n1} tiene ${times} veces esa cantidad. ¿${cuantosEs(it)} ${it.es} tiene ${n1}? (Pista: dibuja ${times} grupos de ${small}.)`},
4865          a:{en:`${times} × ${small} = ${times*small}`, es:`${times} × ${small} = ${times*small}`}
4866        };
4867      }
4868      if(k===2){
4869        const small=ri(2,5);
4870        return {
4871          q:{en:`${n2} found ${small} ${it.en}. ${n1} found twice as many. How many ${it.en} did ${n1} find?`,
4872             es:`${n2} encontró ${small} ${it.es}. ${n1} encontró el doble. ¿${cuantosEs(it)} ${it.es} encontró ${n1}?`},
4873          a:{en:`2 × ${small} = ${2*small}`, es:`2 × ${small} = ${2*small}`}
4874        };
4875      }
4876      if(k===3){
4877        const small=ri(2,4), times=3;
4878        return {
4879          q:{en:`${n2} packed ${small} ${it.en}. ${n1} packed ${times} times as many. Write the multiplication and solve it.`,
4880             es:`${n2} empacó ${small} ${it.es}. ${n1} empacó ${times} veces esa cantidad. Escribe la multiplicación y resuélvela.`},
4881          a:{en:`${times} × ${small} = ${times*small}`, es:`${times} × ${small} = ${times*small}`}
4882        };
4883      }
4884      const small=ri(2,5), times=ri(2,4), big=small*times;
4885      return {
4886        q:{en:`${n1} has ${big} ${it.en}, which is ${times} times as many as ${n2}. How many ${it.en} does ${n2}
4886 have? (Hint: divide.)`,
4887           es:`${n1} tiene ${big} ${it.es}, que es ${times} veces la cantidad de ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n2}? (Pista: divide.)`},
4888        a:{en:`${big} ÷ ${times} = ${small}`, es:`${big} ÷ ${times} = ${small}`}
4889      };
4890    }
4891
4892    /* ---- Challenge · DOK 3 : additive vs multiplicative, chains, judgment ---- */
4893    if(lvl===3){
4894      const k=ri(1,5);
4895      if(k===1){
4896        const small=ri(4,8), times=ri(3,6), big=small*times;
4897        return {
4898          q:{en:`${n1} has ${big} ${it.en} and ${n2} has ${small}. One friend says "${n1} has ${big-small} more." Another says "${n1} has ${times} times as many." Which comparison is which kind, and are both correct? Explain.`,
4899             es:`${n1} tiene ${big} ${it.es} y ${n2} tiene ${small}. Un amigo dice "${n1} tiene ${big-small} más." Otro dice "${n1} tiene ${times} veces esa cantidad." ¿Qué tipo de comparación es cada una y son correctas las dos? Explica.`},
4900          a:{en:`Both true: +${big-small} is additive, ×${times} is multiplicative`,
4901             es:`Las dos: +${big-small} es aditiva, ×${times} es multiplicativa`}
4902        };
4903      }
4904      if(k===2){
4905        const small=ri(3,7), times=ri(3,6), big=small*times, wrong=small+times;
4906        return {
4907          q:{en:`${n2} has ${small} ${it.en}. ${n1} has ${times} times as many. ${n2} adds and says ${n1} has ${wrong}. What mistake did ${n2} make, and what is the correct number?`,
4908             es:`${n2} tiene ${small} ${it.es}. ${n1} tiene ${times} veces esa cantidad. ${n2} suma y dice que ${n1} tiene ${wrong}. ¿Qué error cometió ${n2} y cuál es el número correcto?`},
4909          a:{en:`Added instead of multiplied — ${times}×${small}=${big}`,
4910             es:`Sumó en vez de multiplicar — ${times}×${small}=${big}`}
4911        };
4912      }
4913      if(k===3){
4914        const c=ri(2,4), bT=ri(2,3), aT=ri(2,3);
4915        const bVal=c*bT, aVal=bVal*aT;
4916        return {
4917          q:{en:`A classmate has ${c} ${it.en}. ${n2} has ${bT} times as many as the classmate, and ${n1} has ${aT} times as many as ${n2}. How many ${it.en} does ${n1} have? Show each step.`,
4918             es:`Un compañero tiene ${c} ${it.es}. ${n2} tiene ${bT} veces esa cantidad y ${n1} tiene ${aT} veces la cantidad de ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n1}? Muestra cada paso.`},
4919          a:{en:`${bT}×${c}=${bVal}, then ${aT}×${bVal}=${aVal}`, es:`${bT}×${c}=${bVal}, luego ${aT}×${bVal}=${aVal}`}
4920        };
4921      }
4922      if(k===4){
4923        const small=ri(4,9), times=ri(4,8), big=small*times;
4924        return {
4925          q:{en:`${n1} has ${big} ${it.en}. That is ${times} times as many as ${n2}. Write an equation using n for ${n2}'s ${it.en}, then solve it.`,
4926             es:`${n1} tiene ${big} ${it.es}. Eso es ${times} veces la cantidad de ${n2}. Escribe una ecuación usando n para ${losLasEs(it)} ${it.es} de ${n2} y resuélvela.`},
4927          a:{en:`${times}×n=${big}; n=${small}`, es:`${times}×n=${big}; n=${small}`}
4928        };
4929      }
4930      const small=ri(3,6), tA=ri(2,3), tB=tA+ri(1,2);
4931      return {
4932        q:{en:`${n2} has ${small} ${it.en}. ${n1} wants at least ${tB} times as many but only collected ${tA*small}. Did ${n1} reach the goal? How many more ${it.en} are needed? Justify with an equation.`,
4933           es:`${n2} tiene ${small} ${it.es}. ${n1} quiere al menos ${tB} veces esa cantidad pero solo juntó ${tA*small}. ¿Alcanzó la meta? ¿${cuantosEs(it)} más necesita? Justifica con una ecuación.`},
4934        a:{en:`Goal ${tB}×${small}=${tB*small}; has ${tA*small} → needs ${tB*small-tA*small} more`,
4935           es:`Meta ${tB}×${small}=${tB*small}; tiene ${tA*small} → faltan ${tB*small-tA*small}`}
4936      };
4937    }
4938
4939    /* ---- On level · DOK 2 : forward, backward, how-many-times ---- */
4940    const k=ri(1,5);
4941    if(k===1){
4942      const small=ri(3,9), times=ri(3,8);
4943      return {
4944        q:{en:`${n2} collected ${small} ${it.en}. ${n1} collected ${times} times as many. How many ${it.en} did ${n1} collect?`,
4945           es:`${n2} juntó ${small} ${it.es}. ${n1} juntó ${times} veces esa cantidad. ¿${cuantosEs(it)} ${it.es} juntó ${n1}?`},
4946        a:{en:`${times} × ${small} = ${times*small}`, es:`${times} × ${small} = ${times*small}`}
4947      };
4948    }
4949    if(k===2){
4950      const small=ri(3,9), times=ri(3,8), big=small*times;
4951      return {
4952        q:{en:`${n1} has ${big} ${it.en}. That is ${times} times as many as ${n2} has. How many ${it.en} does ${n2} have?`,
4953           es:`${n1} tiene ${big} ${it.es}. Eso es ${times} veces la cantidad de ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n2}?`},
4954        a:{en:`${big} ÷ ${times} = ${small}`, es:`${big} ÷ ${times} = ${small}`}
4955      };
4956    }
4957    if(k===3){
4958      const small=ri(3,8), times=ri(3,7), big=small*times;
4959      return {
4960        q:{en:`${n1} has ${big} ${it.en} and ${n2} has ${small}. How many times as many ${it.en} does ${n1} have as ${n2}?`,
4961           es:`${n1} tiene ${big} ${it.es} y ${n2} tiene ${small}. ¿Cuántas veces la cantidad de ${n2} tiene ${n1}?`},
4962        a:{en:`${big} ÷ ${small} = ${times} times as many`, es:`${big} ÷ ${small} = ${times} veces esa cantidad`}
4963      };
4964    }
4965    if(k===4){
4966      const bin = pick(THEME.bins), small=ri(4,9), times=ri(3,7);
4967      return {
4968        q:{en:`${n1}'s small ${bin.one.en} holds ${small} ${it.en}. ${n1}'s large one holds ${times} times as many. How many ${it.en} fit in the large one?`,
4969           es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} ${gEs(bin)==="m"?"pequeño":"pequeña"} de ${n1} guarda ${small} ${it.es}. ${gEs(bin)==="m"?"El grande":"La grande"} guarda ${times} veces esa cantidad. ¿${cuantosEs(it)} ${it.es} caben en ${gEs(bin)==="m"?"el grande":"la grande"}?`},
4970        a:{en:`${times} × ${small} = ${times*small}`, es:`${times} × ${small} = ${times*small}`}
4971      };
4972    }
4973    const small=ri(3,8), times=ri(3,6), big=small*times;
4974    return {
4975      q:{en:`This week ${n1} saved ${big} ${it.en} — ${times} times as many as last week. How many ${it.en} did ${n1} save last week? Write the equation you used.`,
4976         es:`Esta semana ${n1} guardó ${big} ${it.es} — ${times} veces la cantidad de la semana pasada. ¿${cuantosEs(it)} ${it.es} guardó la semana pasada? Escribe la ecuación que usaste.`},
4977      a:{en:`${times}×n=${big}; n=${small}`, es:`${times}×n=${big}; n=${small}`}
4978    };
4979  }
4980},
4981{
4982  code:"4.OA.A.3", grade:4, dok:3,
4983  title:{en:"Multi-step problems & remainders",
4984         es:"Problemas de varios pasos y residuos"},
4985  text:{en:"Solve multistep word problems posed with whole numbers and having whole-number answers using the four operations, including problems in which remainders must be interpreted. Represent these problems using equations with a letter standing for the unknown quantity. Assess the reasonableness of answers using mental computation and estimation strategies including rounding.",
4986        es:"Resuelve problemas verbales de varios pasos con números enteros y respuestas enteras usando las cuatro operaciones, incluyendo problemas donde hay que interpretar el residuo. Representa estos problemas con ecuaciones usando una letra para la cantidad desconocida. Evalúa si las respuestas son razonables usando cálculo mental y estimación, incluyendo el redondeo."},
4987  build(n1,n2,lvl){
4988    const it = pickItem(), bin = pick(THEME.bins);
4989    let kind = ri(1,5);   // feeds Challenge (5 templates); On-level reassigns
4990
4991    /* ---- Support · DOK 1 : two clean steps, no remainder ---- */
4992    if(lvl===1){
4993      const k=ri(1,4);
4994      if(k===1){
4995        const packs=ri(3,6), per=ri(4,8), gave=ri(3,10);
4996        return {
4997          q:{en:`${n1} bought ${packs} packs of ${it.en} with ${per} in each pack, then gave ${gave} to ${n2}. How many ${it.en} are left?`,
4998             es:`${n1} compró ${packs} paquetes de ${it.es} con ${per} en cada uno y luego le dio ${gave} a ${n2}. ¿${cuantosEs(it)} ${it.es} quedan?`},
4999          a:{en:`${packs}×${per}=${packs*per}, −${gave} = ${packs*per-gave}`, es:`${packs}×${per}=${packs*per}, −${gave} = ${packs*per-gave}`}
5000        };
5001      }
5002      if(k===2){
5003        const per=ri(4,8), boxes=ri(3,7), tot=per*boxes;
5004        return {
5005          q:{en:`${n1} packed ${tot} ${it.en} into ${bin.en} with ${per} in each one. How many ${bin.en} did ${n1} fill?`,
5006             es:`${n1} guardó ${tot} ${it.es} en ${bin.es} con ${per} en cada ${unoEs(bin)}. ¿${cuantosEs(bin)} ${bin.es} llenó ${n1}?`},
5007          a:{en:`${tot}÷${per} = ${boxes}`, es:`${tot}÷${per} = ${boxes}`}
5008        };
5009      }
5010      if(k===3){
5011        const rows=ri(3,7), cols=ri(4,9), extra=ri(3,12);
5012        return {
5013          q:{en:`${n1} set out ${it.en} in ${rows} rows of ${cols}, then added ${extra} more. How many ${it.en} are there now?`,
5014             es:`${n1} acomodó ${it.es} en ${rows} filas de ${cols} y luego agregó ${extra} más. ¿${cuantosEs(it)} ${it.es} hay ahora?`},
5015          a:{en:`${rows}×${cols}=${rows*cols}, +${extra} = ${rows*cols+extra}`, es:`${rows}×${cols}=${rows*cols}, +${extra} = ${rows*cols+extra}`}
5016        };
5017      }
5018      const start=ri(40,90), used=ri(10,25), got=ri(8,20);
5019      return {
5020        q:{en:`${n1} started with ${start} ${it.en}, used ${used}, then got ${got} more from ${n2}. How many ${it.en} does ${n1} have now?`,
5021           es:`${n1} empezó con ${start} ${it.es}, usó ${used} y luego recibió ${got} más de ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n1} ahora?`},
5022        a:{en:`${start}−${used}=${start-used}, +${got} = ${start-used+got}`, es:`${start}−${used}=${start-used}, +${got} = ${start-used+got}`}
5023      };
5024    }
5025
5026    /* ---- Challenge · DOK 3 : interpret the remainder + explain ---- */
5027    if(lvl===3){
5028      if(kind===1){
5029        const per=ri(6,10), boxes=ri(6,12), extra=ri(1,per-1), tot=per*boxes+extra;
5030        return {
5031          q:{en:`${n1} has ${tot} ${it.en} and each ${bin.one.en} holds ${per}. ${n2} says ${boxes} ${bin.en} are enough. Is ${n2} right? Explain what happens to the leftover ${it.en}.`,
5032             es:`${n1} tiene ${tot} ${it.es} y cada ${bin.one.es} guarda ${per}. ${n2} dice que ${boxes} ${bin.es} son suficientes. ¿Tiene razón? Explica qué pasa con los ${it.es} que sobran.`},
5033          a:{en:`No — ${boxes+1} needed; ${extra} left over`, es:`No — se necesitan ${boxes+1}; sobran ${extra}`}
5034        };
5035      }
5036      if(kind===2){
5037        const per=ri(5,9), students=ri(20,29), need=per*students, have=ri(Math.floor(need*0.4), need-12);
5038        return {
5039          q:{en:`Every student needs ${per} ${it.en}. There are ${students} students and ${THEME.place.en} has ${have} ${it.en}. Packs come with ${per*2} ${it.en}. How many packs must ${n1} buy? Explain why you rounded the way you did.`,
5040             es:`Cada estudiante necesita ${per} ${it.es}. Hay ${students} estudiantes y ${THEME.place.es} tiene ${have} ${it.es}. Los paquetes traen ${per*2} ${it.es}. ¿Cuántos paquetes debe comprar ${n1}? Explica por qué redondeaste así.`},
5041          a:{en:`${need}−${have}=${need-have} short → ${Math.ceil((need-have)/(per*2))} packs`,
5042             es:`${need}−${have}=${need-have} faltan → ${Math.ceil((need-have)/(per*2))} paquetes`}
5043        };
5044      }
5045      if(kind===3){
5046        const teams=ri(4,7), per=ri(5,9), tot=teams*per+ri(1,per-1);
5047        return {
5048          q:{en:`${n1} and ${n2} split ${tot} ${it.en} evenly among ${teams} groups. How many does each group get, and what should they do with the extras? Explain your choice.`,
5049             es:`${n1} y ${n2} repartieron ${tot} ${it.es} entre ${teams} grupos por igual. ¿${cuantosEs(it)} recibe cada grupo y qué deben hacer con ${losLasEs(it)} que sobran? Explica tu decisión.`},
5050          a:{en:`${Math.floor(tot/teams)} each, ${tot%teams} left over`, es:`${Math.floor(tot/teams)} cada ${unoEs(it)}, sobran ${tot%teams}`}
5051        };
5052      }
5053      if(kind===4){
5054        const packs=ri(6,12), per=ri(6,12), gave=ri(10,30);
5055        const tot=packs*per, wrongAns=tot-gave + (ri(0,1)? per : -per);
5056        return {
5057          q:{en:`${n1} bought ${packs} packs of ${it.en} with ${per} in each, then gave away ${gave}. ${n2} used a calculator and got ${wrongAns}. Without a calculator, explain how you can tell whether ${n2}'s answer is reasonable.`,
5058             es:`${n1} compró ${packs} paquetes de ${it.es} con ${per} en cada uno y luego regaló ${gave}. ${n2} usó una calculadora y obtuvo ${wrongAns}. Sin calculadora, explica cómo puedes saber si la respuesta de ${n2} es razonable.`},
5059          a:{en:`Estimate: ${packs}×${per}≈${Math.round(packs*per/10)*10}; exact ${tot}−${gave}=${tot-gave}, so ${wrongAns} is off by ${Math.abs(wrongAns-(tot-gave))}`,
5060             es:`Estima: ${packs}×${per}≈${Math.round(packs*per/10)*10}; exacto ${tot}−${gave}=${tot-gave}, así que ${wrongAns} se aleja por ${Math.abs(wrongAns-(tot-gave))}`}
5061        };
5062      }
5063      const per=ri(6,10), have=ri(3,6), tot=per*ri(7,12)+ri(1,per
5063-1);
5064      const full=Math.floor(tot/per), left=tot%per;
5065      return {
5066        q:{en:`${aAn(bin.one.en)} ${bin.one.en} holds ${per} ${it.en}, and ${n1} has ${have} empty ${bin.en}. ${n1} needs to pack ${tot} ${it.en}. Are ${have} ${bin.en} enough? If not, how many more are needed? Justify with an equation.`,
5067           es:`${unUnaEs(bin)==="un"?"Un":"Una"} ${bin.one.es} guarda ${per} ${it.es} y ${n1} tiene ${have} ${bin.es} ${gEs(bin)==="m"?"vacíos":"vacías"}. ${n1} necesita empacar ${tot} ${it.es}. ¿Alcanzan? Si no, ¿${cuantosLc(bin)} más se necesitan? Justifica con una ecuación.`},
5068        a:{en:`${tot}÷${per} → ${full}${left?` R${left} → ${full+1} needed`:" needed"}; ${have>= (left?full+1:full) ? "yes, enough" : (left?full+1:full)-have+" more needed"}`,
5069           es:`${tot}÷${per} → ${full}${left?` R${left} → se necesitan ${full+1}`:" necesarias"}; ${have>=(left?full+1:full) ? "sí alcanzan" : "faltan "+((left?full+1:full)-have)}`}
5070      };
5071    }
5072
5073    /* ---- On level · DOK 2 ---- */
5074    kind = ri(1,5);   // more variety at the tier teachers use most
5075    if(kind===1){
5076      const per=ri(6,12), boxes=ri(5,12), extra=ri(1,per-1), tot=per*boxes+extra;
5077      return {
5078        q:{en:`${n1} has ${tot} ${it.en} to pack. Each ${bin.one.en} holds exactly ${per} ${it.en}. How many ${bin.en} can ${n1} fill completely, and how many ${it.en} will be left over?`,
5079           es:`${n1} tiene ${tot} ${it.es} para empacar. Cada ${bin.one.es} guarda exactamente ${per} ${it.es}. ¿${cuantosEs(bin)} ${bin.es} puede llenar ${n1} por completo y cuántos ${it.es} sobran?`},
5080        a:{en:`${boxes} full, ${extra} left over`, es:`${boxes} llenas, sobran ${extra}`}
5081      };
5082    }
5083    if(kind===2){
5084      const packs=ri(5,12), per=ri(6,12), gave=ri(9,30), tot=packs*per;
5085      return {
5086        q:{en:`${n1} bought ${packs} packs of ${it.en} with ${per} in each pack. ${n1} gave ${gave} ${it.en} to ${n2}. How many ${it.en} does ${n1} have now?`,
5087           es:`${n1} compró ${packs} paquetes de ${it.es} con ${per} en cada paquete. ${n1} le dio ${gave} ${it.es} a ${n2}. ¿${cuantosEs(it)} ${it.es} tiene ${n1} ahora?`},
5088        a:{en:`${tot-gave} ${it.en}`, es:`${tot-gave} ${it.es}`}
5089      };
5090    }
5091    if(kind===4){
5092      const packsB=ri(2,5), packsA=packsB+ri(2,5), per=ri(6,12);   // A must exceed B
5093      return {
5094        q:{en:`${n1} has ${packsA} packs of ${it.en} and ${n2} has ${packsB} packs. Each pack holds ${per}. How many more ${it.en} does ${n1} have?`,
5095           es:`${n1} tiene ${packsA} paquetes de ${it.es} y ${n2} tiene ${packsB} paquetes. Cada paquete trae ${per}. ¿${cuantosEs(it)} ${it.es} más tiene ${n1}?`},
5096        a:{en:`(${packsA}−${packsB})×${per} = ${(packsA-packsB)*per}`, es:`(${packsA}−${packsB})×${per} = ${(packsA-packsB)*per}`}
5097      };
5098    }
5099    if(kind===5){
5100      const bought=ri(80,160), gave=ri(15,35), used=ri(10,30);
5101      return {
5102        q:{en:`${n1} bought ${bought} ${it.en}, gave ${gave} to ${n2}, then used ${used}. How many ${it.en} are left?`,
5103           es:`${n1} compró ${bought} ${it.es}, le dio ${gave} a ${n2} y luego usó ${used}. ¿${cuantosEs(it)} ${it.es} quedan?`},
5104        a:{en:`${bought}−${gave}−${used} = ${bought-gave-used}`, es:`${bought}−${gave}−${used} = ${bought-gave-used}`}
5105      };
5106    }
5107    const per=ri(4,9), students=ri(18,29), need=per*students;
5108    const have=ri(Math.floor(need*0.35), need-8);
5109    return {
5110      q:{en:`Every student needs ${per} ${it.en}. There are ${students} students in ${n1}'s ${THEME.group.en}, and ${THEME.place.en} has ${have} ${it.en}. How many more ${it.en} are needed?`,
5111         es:`Cada estudiante necesita ${per} ${it.es}. Hay ${students} estudiantes en ${elLaEs(THEME.group)} ${THEME.group.es} de ${n1} y ${THEME.place.es} tiene ${have} ${it.es}. ¿${cuantosEs(it)} ${it.es} más se necesitan?`},
5112      a:{en:`${need} needed − ${have} = ${need-have} more`, es:`${need} necesarios − ${have} = ${need-have} más`}
5113    };
5114  }
5115},
5116{
5117  code:"4.OA.B.4", grade:4, dok:2,
5118  title:{en:"Factors, multiples & prime numbers",
5119         es:"Factores, múltiplos y números primos"},
5120  text:{en:"Find all factor pairs for a whole number in the range 1–100. Recognize that a whole number is a multiple of each of its factors. Determine whether a given whole number in the range 1–100 is a multiple of a given one-digit number. Determine whether a given whole number in the range 1–100 is prime or composite.",
5121        es:"Halla todos los pares de factores de un número entero del 1 al 100. Reconoce que un número entero es múltiplo de cada uno de sus factores. Determina si un número entero del 1 al 100 es múltiplo de un número de un dígito. Determina si un número entero del 1 al 100 es primo o compuesto."},
5122  build(n1,n2,lvl){
5123    const it = pickItem(), bin = pick(THEME.bins);
5124    const factorsOf = n => { const f=[]; for(let i=1;i<=n;i++) if(n%i===0) f.push(i); return f; };
5125
5126    /* ---- Support · DOK 1 : small numbers, factor pairs ---- */
5127    if(lvl===1){
5128      const k=ri(1,4);
5129      if(k===1){
5130        const a=ri(2,5), b=ri(2,6), tot=a*b;
5131        return {
5132          q:{en:`${n1} arranged ${tot} ${it.en} in ${a} equal rows. How many in each row? What factor pair does this show?`,
5133             es:`${n1} acomodó ${tot} ${it.es} en ${a} filas iguales. ¿${cuantosEs(it)} hay en cada fila? ¿Qué par de factores muestra?`},
5134          a:{en:`${b} per row — ${a} × ${b} = ${tot}`, es:`${b} por fila — ${a} × ${b} = ${tot}`}
5135        };
5136      }
5137      if(k===2){
5138        const tot=pick([12,16,18,20]);
5139        return {
5140          q:{en:`${n1} has ${tot} ${it.en}. Is ${tot} a multiple of 4? Show why with equal groups.`,
5141             es:`${n1} tiene ${tot} ${it.es}. ¿Es ${tot} múltiplo de 4? Muestra por qué con grupos iguales.`},
5142          a:{en:`${tot%4===0 ? "Yes — 4 × "+(tot/4)+" = "+tot : "No — 4 does not divide "+tot+" evenly"}`,
5143             es:`${tot%4===0 ? "Sí — 4 × "+(tot/4)+" = "+tot : "No — 4 no divide "+tot+" en partes iguales"}`}
5144        };
5145      }
5146      if(k===3){
5147        const tot=pick([6,8,10,12]);
5148        return {
5149          q:{en:`${n1} wants to put ${tot} ${it.en} in equal rows. List two ways. (Two factor pairs.)`,
5150             es:`${n1} quiere poner ${tot} ${it.es} en filas iguales. Escribe dos maneras. (Dos pares de factores.)`},
5151          a:{en:`e.g. 1 × ${tot} and 2 × ${tot/2}`, es:`p. ej. 1 × ${tot} y 2 × ${tot/2}`}
5152        };
5153      }
5154      const p2=pick([2,3,5,7]);
5155      return {
5156        q:{en:`${n1} has ${p2} ${it.en} and can only make 1 row of ${p2} or ${p2} rows of 1. Is ${p2} prime or composite?`,
5157           es:`${n1} tiene ${p2} ${it.es} y solo puede hacer 1 fila de ${p2} o ${p2} filas de 1. ¿Es ${p2} primo o compuesto?`},
5158        a:{en:`Prime — only factors are 1 and ${p2}`, es:`Primo — sus únicos factores son 1 y ${p2}`}
5159      };
5160    }
5161
5162    /* ---- Challenge · DOK 3 : all factor pairs, prime reasoning ---- */
5163    if(lvl===3){
5164      const k=ri(1,4);
5165      if(k===1){
5166        const tot=pick([24,36,48,60]);
5167        const fp=[]; for(let i=1;i*i<=tot;i++) if(tot%i===0) fp.push(i+"×"+(tot/i));
5168        return {
5169          q:{en:`${n1} must arrange ${tot} ${it.en} in equal rows. List ALL the factor pairs of ${tot}. How do you know you found them all?`,
5170             es:`${n1} debe acomodar ${tot} ${it.es} en filas iguales. Escribe TODOS los pares de factores de ${tot}. ¿Cómo sabes que los hallaste todos?`},
5171          a:{en:fp.join(", ")+" — stop when the factors meet in the middle",
5172             es:fp.join(", ")+" — para cuando los factores se encuentran"}
5173        };
5174      }
5175      if(k===2){
5176        const comp=pick([21,27,33,39,49,51]);
5177        return {
5178          q:{en:`${n2} says ${comp} ${it.en} cannot be put in equal rows because ${comp} is prime. Is ${n2} right? Find a factor pair or explain why none exists.`,
5179             es:`${n2} dice que ${comp} ${it.es} no se pueden poner en filas iguales porque ${comp} es primo. ¿Tiene razón? Halla un par de factores o explica por qué no existe.`},
5180          a:{en:`No — ${comp} is composite: ${factorsOf(comp).filter(x=>x!==1&&x!==comp)[0]} × ${comp/factorsOf(comp).filter(x=>x!==1&&x!==comp)[0]} = ${comp}`,
5181             es:`No — ${comp} es compuesto: ${factorsOf(comp).filter(x=>x!==1&&x!==comp)[0]} × ${comp/factorsOf(comp).filter(x=>x!==1&&x!==comp)[0]} = ${comp}`}
5182        };
5183      }
5184      if(k===3){
5185        const base=pick([3,4,6]), mult=ri(4,9), tot=base*mult;
5186        return {
5187          q:{en:`${n1} packs ${it.en} in groups of ${base}. Is ${tot} a multiple of ${base}? Is ${tot+1}? Explain how you can tell without dividing twice.`,
5188             es:`${n1} empaca ${it.es} en grupos de ${base}. ¿Es ${tot} múltiplo de ${base}? ¿Y ${tot+1}? Explica cómo lo sabes sin dividir dos veces.`},
5189          a:{en:`${tot} yes (${base}×${mult}); ${tot+1} no — it is 1 past a multiple`,
5190             es:`${tot} sí (${base}×${mult}); ${tot+1} no — está 1 más allá de un múltiplo`}
5191        };
5192      }
5193      const tot=pick([18,24,30,40]);
5194      return {
5195        q:{en:`${n1} wants ${bin.en} that each hold the same number of ${it.en}, with ${tot} ${it.en} total and more than 2 ${bin.en}. Give two ways that work and one that does not.`,
5196           es:`${n1} quiere ${bin.es} que guarden la misma cantidad de ${it.es}, con ${tot} ${it.es} en total y más de 2 ${bin.es}. Da dos maneras que funcionen y una que no.`},
5197        a:{en:`works: any factor of ${tot} above 2 (e.g. ${factorsOf(tot).filter(x=>x>2&&x<tot)[0]}, ${factorsOf(tot).filter(x=>x>2&&x<tot)[1]}); fails: a non-factor like ${factorsOf(tot).includes(7)?11:7}`,
5198           es:`funcionan: cualquier factor de ${tot} mayor que 2 (p. ej. ${factorsOf(tot).filter(x=>x>2&&x<tot)[0]}, ${factorsOf(tot).filter(x=>x>2&&x<tot)[1]}); no funciona: ${factorsOf(tot).includes(7)?11:7}`}
5199      };
5200    }
5201
5202    /* ---- On level · DOK 2 ---- */
5203    const k=ri(1,4);
5204    if(k===1){
5205      const tot=pick([12,18,20,24,28,32]);
5206      const fp=[]; for(let i=1;i*i<=tot;i++) if(tot%i===0) fp.push(i+"×"+(tot/i));
5207      return {
5208        q:{en:`${n1} arranges ${tot} ${it.en} in equal rows. List all the factor pairs of ${tot}.`,
5209           es:`${n1} acomoda ${tot} ${it.es} en filas iguales. Escribe todos los pares de factores de ${tot}.`},
5210        a:{en:fp.join(", "), es:fp.join(", ")}
5211      };
5212    }
5213    if(k===2){
5214      const base=ri(3,9), mult=ri(4,10), tot=base*mult;
5215      return {
5216        q:{en:`${n1} packs ${it.en} in groups of ${base}. Is ${tot} a multiple of ${base}? Show how you know.`,
5217           es:`${n1} empaca ${it.es} en grupos de ${base}. ¿Es ${tot} múltiplo de ${base}? Muestra cómo lo sabes.`},
5218        a:{en:`Yes — ${base} × ${mult} = ${tot}`, es:`Sí — ${base} × ${mult} = ${tot}`}
5219      };
5220    }
5221    if(k===3){
5222      const n=pick([13,17,19,23,29,31,37]);
5223      return {
5224        q:{en:`${n1} has ${n} ${it.en} and cannot make equal rows except 1 row of ${n}. Is ${n} prime or composite? Explain.`,
5225           es:`${n1} tiene ${n} ${it.es} y no puede hacer filas iguales excepto 1 fila de ${n}. ¿Es ${n} primo o compuesto? Explica.`},
5226        a:{en:`Prime — its only factors are 1 and ${n}`, es:`Primo — sus únicos factores son 1 y ${n}`}
5227      };
5228    }
5229    const n=pick([15,21,25,27,33,35]);
5230    const f=[]; for(let i=2;i<n;i++) if(n%i===0) f.push(i);
5231    return {
5232      q:{en:`${n1} says ${n} ${it.en} can be split into equal groups in more than one way. Is ${n} prime or composite? Name a factor other than 1 and ${n}.`,
5233         es:`${n1} dice que ${n} ${it.es} se pueden repartir en grupos iguales de más de una manera. ¿Es ${n} primo o compuesto? Nombra un factor distinto de 1 y ${n}.`},
5234      a:{en:`Composite — e.g. ${f[0]} (${f[0]} × ${n/f[0]} = ${n})`,
5235         es:`Compuesto — p. ej. ${f[0]} (${f[0]} × ${n/f[0]} = ${n})`}
5236    };
5237  }
5238},
5239{
5240  code:"4.NBT.A.3", grade:4, dok:2,
5241  title:{en:"Round multi-digit numbers to any place",
5242         es:"Redondear números de varios dígitos"},
5243  text:{en:"Use place value understanding to round multi-digit whole numbers to any place.",
5244        es:"Usa la comprensión del valor posicional para redondear números enteros de varios dígitos a cualquier posición."},
5245  build(n1,n2,lvl){
5246    const it = pickItem();
5247    const g = THEME.group;
5248
5249    /* ---- Support · DOK 1 : nearest ten / hundred with scaffolds ---- */
5250    if(lvl===1){
5251      const k=ri(1,4);
5252      if(k===1){
5253        const n=ri(3,9)*10+ri(1,9);
5254        return {
5255          q:{en:`${n1} counted ${n} ${it.en}. Round to the nearest ten. (Hint: which two tens is ${n} between?)`,
5256             es:`${n1} contó ${n} ${it.es}. Redondea a la decena más cercana. (Pista: ¿entre qué dos decenas está ${n}?)`},
5257          a:{en:`${rnd(n,10)}`, es:`${rnd(n,10)}`}
5258        };
5259      }
5260      if(k===2){
5261        const n=ri(2,8)*100+ri(11,89);
5262        return {
5263          q:{en:`${n1}'s ${g.en} collected ${n} ${it.en}. Round to the nearest hundred. (Hint: look at the tens digit.)`,
5264             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} juntó ${n} ${it.es}. Redondea a la centena más cercana. (Pista: mira el dígito de las decenas.)`},
5265          a:{en:`${rnd(n,100)}`, es:`${rnd(n,100)}`}
5266        };
5267      }
5268      if(k===3){
5269        const n=ri(4,9)*10+5;
5270        return {
5271          q:{en:`${n1} has ${n} ${it.en}. ${n} ends in 5 — which ten does it round to? Explain the rule.`,
5272             es:`${n1} tiene ${n} ${it.es}. ${n} termina en 5 — ¿a qué decena se redondea? Explica la regla.`},
5273          a:{en:`${rnd(n,10)} — a 5 rounds up`, es:`${rnd(n,10)} — el 5 redondea hacia arriba`}
5274        };
5275      }
5276      const n=ri(120,880);
5277      return {
5278        q:{en:`About how many ${it.en} does ${n1} have if the exact count is ${n}? Round to the nearest ten.`,
5279           es:`¿Como ${cuantosLc(it)} ${it.es} tiene ${n1} si el conteo exacto es ${n}? Redondea a la decena.`},
5280        a:{en:`${rnd(n,10)}`, es:`${rnd(n,10)}`}
5281      };
5282    }
5283
5284    /* ---- Challenge · DOK 3 : boundaries, place choice, error analysis ---- */
5285    if(lvl===3){
5286      const k=ri(1,5);
5287      if(k===1){
5288        const target=ri(3,8)*100;
5289        return {
5290          q:{en:`${n1} says a mystery number of ${it.en} rounds to ${target} at the nearest hundred. What are the smallest and largest whole numbers it could be? Explain.`,
5291             es:`${n1} dice que un número misterioso de ${it.es} se redondea a ${target} en la centena más cercana. ¿Cuáles son el menor y el mayor número entero posible? Explica.`},
5292          a:{en:`${target-50} to ${target+49}`, es:`de ${target-50} a ${target+49}`}
5293        };
5294      }
5295      if(k===2){
5296        const n=ri(2,8)*1000+ri(3,7)*100+ri(10,99);
5297        const wrong=rnd(n,1000);
5298        return {
5299          q:{en:`${n2} rounded ${n} ${it.en} to the nearest hundred and wrote ${wrong}. What place did ${n2} actually round to? Give the correct nearest-hundred answer.`,
5300             es:`${n2} redondeó ${n} ${it.es} a la centena más cercana y escribió ${wrong}. ¿A qué posición redondeó en realidad? Da la respuesta correcta a la centena.`},
5301          a:{en:`Rounded to thousands — nearest hundred is ${rnd(n,100)}`,
5302             es:`Redondeó al millar — la centena más cercana es ${rnd(n,100)}`}
5303        };
5304      }
5305      if(k===3){
5306        const n=ri(1,8)*1000+ri(100,899);
5307        return {
5308          q:{en:`${n1} counted ${n} ${it.en} at the fair. Round it to the nearest ten, hundred, and thousand. Why are the three answers different sizes of "about"?`,
5309             es:`${n1} contó ${n} ${it.es} en la feria. Redondéalo a la decena, la centena y el millar. ¿Por qué los tres resultados son distintos niveles de "aproximado"?`},
5310          a:{en:`${rnd(n,10)} / ${rnd(n,100)} / ${rnd(n,1000)} — bigger place, rougher estimate`,
5311             es:`${rnd(n,10)} / ${rnd(n,100)} / ${rnd(n,1000)} — a mayor posición, estimación más gruesa`}
5312        };
5313      }
5314      if(k===4){
5315        const a=ri(240,480), b=ri(240,480);
5316        return {
5317          q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. Estimate the total by rounding each to the nearest hundred, then find the exact total. How far off is the estimate?`,
5318             es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. Estima el total redondeando cada uno a la centena y luego halla el total exacto. ¿Por cuánto difiere la estimación?`},
5319          a:{en:`≈${rnd(a,100)+rnd(b,100)}; exact ${a+b}; off by ${Math.abs(rnd(a,100)+rnd(b,100)-(a+b))}`,
5320             es:`≈${rnd(a,100)+rnd(b,100)}; exacto ${a+b}; difiere por ${Math.abs(rnd(a,100)+rnd(b,100)-(a+b))}`}
5321        };
5322      }
5323      const n=ri(2,9)*100+50;
5324      return {
5325        q:{en:`${n2} says ${n} ${it.en} rounds DOWN to ${n-50} because "5 is in the middle." Is ${n2} right? State the rule and the correct nearest hundred.`,
5326           es:`${n2} dice que ${n} ${it.es} se redondea HACIA ABAJO a ${n-50} porque "el 5 está en medio." ¿Tiene razón? Di la regla y la centena correcta.`},
5327        a:{en:`No — 5 rounds up: ${rnd(n,100)}`, es:`No — el 5 redondea hacia arriba: ${rnd(n,100)}`}
5328      };
5329    }
5330
5331    /* ---- On level · DOK 2 : any place, 3-4 digits ---- */
5332    const k=ri(1,5);
5333    if(k===1){
5334      const n=ri(1,9)*1000+ri(100,999);
5335      return {
5336        q:{en:`${n1} counted ${n} ${it.en} at the ${g.en} fair. Round to the nearest thousand.`,
5337           es:`${n1} contó ${n} ${it.es} en la feria ${elLaEs(g)==="el"?"del":"de la"} ${g.es}. Redondea al millar más cercano.`},
5338        a:{en:`${rnd(n,1000)}`, es:`${rnd(n,1000)}`}
5339      };
5340    }
5341    if(k===2){
5342      const n=ri(2,9)*100+ri(11,99);
5343      return {
5344        q:{en:`${n1}'s ${g.en} collected ${n} ${it.en}. Round to the nearest hundred.`,
5345           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} juntó ${n} ${it.es}. Redondea a la centena más cercana.`},
5346        a:{en:`${rnd(n,100)}`, es:`${rnd(n,100)}`}
5347      };
5348    }
5349    if(k===3){
5350      const n=ri(1,8)*1000+ri(110,980);
5351      return {
5352        q:{en:`${n1}'s scanner shows ${n} ${it.en} in the warehouse. Round it to the nearest hundred AND the nearest thousand.`,
5353           es:`El escáner de ${n1} muestra ${n} ${it.es} en la bodega. Redondéalo a la centena Y al millar más cercanos.`},
5354        a:{en:`${rnd(n,100)} / ${rnd(n,1000)}`, es:`${rnd(n,100)} / ${rnd(n,1000)}`}
5355      };
5356    }
5357    if(k===4){
5358      const a=ri(140,460), b=ri(140,460);
5359      return {
5360        q:{en:`${n1} counted ${a} ${it.en} and ${n2} counted ${b}. About how many do they have together? Round each to the nearest hun
5360dred first.`,
5361           es:`${n1} contó ${a} ${it.es} y ${n2} contó ${b}. ¿Como ${cuantosLc(it)} tienen juntos? Redondea cada número a la centena primero.`},
5362        a:{en:`${rnd(a,100)} + ${rnd(b,100)} = about ${rnd(a,100)+rnd(b,100)}`,
5363           es:`${rnd(a,100)} + ${rnd(b,100)} = como ${rnd(a,100)+rnd(b,100)}`}
5364      };
5365    }
5366    const n=ri(3,9)*10+ri(1,9), n2v=ri(3,9)*10+ri(1,9);
5367    return {
5368      q:{en:`${n1} has ${n} ${it.en} and ${n2} has ${n2v}. Whose count rounds to the higher ten? Show both rounded numbers.`,
5369         es:`${n1} tiene ${n} ${it.es} y ${n2} tiene ${n2v}. ¿El conteo de quién se redondea a la decena más alta? Muestra los dos números redondeados.`},
5370      a:{en:`${rnd(n,10)} vs ${rnd(n2v,10)} — ${rnd(n,10)===rnd(n2v,10)?"same ten":(rnd(n,10)>rnd(n2v,10)?n1:n2)}`,
5371         es:`${rnd(n,10)} vs ${rnd(n2v,10)} — ${rnd(n,10)===rnd(n2v,10)?"la misma decena":(rnd(n,10)>rnd(n2v,10)?n1:n2)}`}
5372    };
5373  }
5374},
5375{
5376  code:"4.NBT.B.5", grade:4, dok:2,
5377  title:{en:"Multiply multi-digit numbers",
5378         es:"Multiplicar números de varios dígitos"},
5379  text:{en:"Multiply a whole number of up to four digits by a one-digit whole number, and multiply two two-digit numbers, using strategies based on place value and the properties of operations.",
5380        es:"Multiplica un número entero de hasta cuatro dígitos por un número de un dígito, y multiplica dos números de dos dígitos, usando estrategias basadas en el valor posicional y las propiedades de las operaciones."},
5381  build(n1,n2,lvl){
5382    const it = pickItem(), bin = pick(THEME.bins);
5383
5384    /* ---- Support · DOK 1 : 2-digit × 1-digit ---- */
5385    if(lvl===1){
5386      const k=ri(1,4);
5387      if(k===1){
5388        const a=ri(11,24), b=ri(2,5);
5389        return {
5390          q:{en:`${n1} filled ${b} ${bin.en} with ${a} ${it.en} each. How many ${it.en} in all?`,
5391             es:`${n1} llenó ${b} ${bin.es} con ${a} ${it.es} cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
5392          a:{en:`${b} × ${a} = ${a*b}`, es:`${b} × ${a} = ${a*b}`}
5393        };
5394      }
5395      if(k===2){
5396        const a=ri(12,30), b=ri(3,6);
5397        return {
5398          q:{en:`${n1} counts ${a} ${it.en} each day for ${b} days. How many ${it.en} is that?`,
5399             es:`${n1} cuenta ${a} ${it.es} cada día durante ${b} días. ¿${cuantosEs(it)} ${it.es} son?`},
5400          a:{en:`${b} × ${a} = ${a*b}`, es:`${b} × ${a} = ${a*b}`}
5401        };
5402      }
5403      if(k===3){
5404        const t=ri(2,6)*10, b=ri(3,7);
5405        return {
5406          q:{en:`${n1} has ${b} boxes with ${t} ${it.en} in each. How many ${it.en}? (Multiply the tens.)`,
5407             es:`${n1} tiene ${b} cajas con ${t} ${it.es} en cada una. ¿${cuantosEs(it)} ${it.es} hay? (Multiplica las decenas.)`},
5408          a:{en:`${b} × ${t} = ${b*t}`, es:`${b} × ${t} = ${b*t}`}
5409        };
5410      }
5411      const rows=ri(12,20), per=ri(3,6);
5412      return {
5413        q:{en:`${n1} set out ${rows} rows of ${per} ${it.en}. How many ${it.en} are there?`,
5414           es:`${n1} acomodó ${rows} filas de ${per} ${it.es}. ¿${cuantosEs(it)} ${it.es} hay?`},
5415        a:{en:`${rows} × ${per} = ${rows*per}`, es:`${rows} × ${per} = ${rows*per}`}
5416      };
5417    }
5418
5419    /* ---- Challenge · DOK 3 : partial products, estimation ---- */
5420    if(lvl===3){
5421      const k=ri(1,4);
5422      if(k===1){
5423        const a=ri(23,58), b=ri(23,48);
5424        const wrong=(Math.floor(a/10)*Math.floor(b/10)*100)+((a%10)*(b%10));
5425        if(wrong===a*b) return this.build(n1,n2,lvl);
5426        return {
5427          q:{en:`${n2} multiplied ${a} × ${b} for the ${it.en} count and got ${wrong} by multiplying tens by tens and ones by ones only. Which partial products are missing? Give the correct answer.`,
5428             es:`${n2} multiplicó ${a} × ${b} para el conteo de ${it.es} y obtuvo ${wrong}, multiplicando solo decenas por decenas y unidades por unidades. ¿Qué productos parciales faltan? Da la respuesta correcta.`},
5429          a:{en:`The two cross products — ${a} × ${b} = ${a*b}`,
5430             es:`Los dos productos cruzados — ${a} × ${b} = ${a*b}`}
5431        };
5432      }
5433      if(k===2){
5434        const a=ri(1200,3800), b=ri(3,7);
5435        const claim=a*b+(ri(0,1)?ri(400,900):-ri(400,900));
5436        return {
5437          q:{en:`${n1} counted ${a} ${it.en} in each of ${b} rooms. ${n2} says the total is ${claim}. Round to estimate, then say whether ${n2} is reasonable and give the exact total.`,
5438             es:`${n1} contó ${a} ${it.es} en cada uno de ${b} salones. ${n2} dice que el total es ${claim}. Redondea para estimar, di si es razonable y da el total exacto.`},
5439          a:{en:`≈${rnd(a,1000)*b}; exact ${a*b} — not reasonable`,
5440             es:`≈${rnd(a,1000)*b}; exacto ${a*b} — no es razonable`}
5441        };
5442      }
5443      if(k===3){
5444        const a=ri(24,48), b=ri(14,28);
5445        return {
5446          q:{en:`${n1} needs ${a} ${bin.en} of ${it.en} with ${b} in each. Break ${b} into tens and ones to find the total. Show both partial products.`,
5447             es:`${n1} necesita ${a} ${bin.es} de ${it.es} con ${b} en cada ${unoEs(bin)}. Separa ${b} en decenas y unidades para hallar el total. Muestra los dos productos parciales.`},
5448          a:{en:`${a}×${Math.floor(b/10)*10}=${a*Math.floor(b/10)*10}, ${a}×${b%10}=${a*(b%10)}; total ${a*b}`,
5449             es:`${a}×${Math.floor(b/10)*10}=${a*Math.floor(b/10)*10}, ${a}×${b%10}=${a*(b%10)}; total ${a*b}`}
5450        };
5451      }
5452      const aA=ri(18,34), bA=ri(12,25), aB=ri(20,40), bB=ri(10,22);
5453      if(aA*bA===aB*bB) return this.build(n1,n2,lvl);
5454      return {
5455        q:{en:`Plan A: ${aA} ${bin.en} of ${bA} ${it.en}. Plan B: ${aB} ${bin.en} of ${bB}. ${n1} wants more ${it.en}. Which plan, and by how many?`,
5456           es:`Plan A: ${aA} ${bin.es} de ${bA} ${it.es}. Plan B: ${aB} ${bin.es} de ${bB}. ${n1} quiere más ${it.es}. ¿Qué plan y por ${cuantosLc(it)}?`},
5457        a:{en:`A=${aA*bA}, B=${aB*bB} → ${aA*bA>aB*bB?"A":"B"} by ${Math.abs(aA*bA-aB*bB)}`,
5458           es:`A=${aA*bA}, B=${aB*bB} → ${aA*bA>aB*bB?"A":"B"} por ${Math.abs(aA*bA-aB*bB)}`}
5459      };
5460    }
5461
5462    /* ---- On level · DOK 2 ---- */
5463    const k=ri(1,4);
5464    if(k===1){
5465      const a=ri(112,2400), b=ri(3,8);
5466      return {
5467        q:{en:`${n1}'s school collected ${a} ${it.en} each year for ${b} years. How many ${it.en} in all?`,
5468           es:`La escuela de ${n1} juntó ${a} ${it.es} cada año durante ${b} años. ¿${cuantosEs(it)} ${it.es} hay en total?`},
5469        a:{en:`${b} × ${a} = ${a*b}`, es:`${b} × ${a} = ${a*b}`}
5470      };
5471    }
5472    if(k===2){
5473      const a=ri(14,48), b=ri(13,36);
5474      return {
5475        q:{en:`${n1} packed ${a} ${bin.en} with ${b} ${it.en} in each one. How many ${it.en} did ${n1} pack?`,
5476           es:`${n1} empacó ${a} ${bin.es} con ${b} ${it.es} en cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} empacó?`},
5477        a:{en:`${a} × ${b} = ${a*b}`, es:`${a} × ${b} = ${a*b}`}
5478      };
5479    }
5480    if(k===3){
5481      const rows=ri(15,32), cols=ri(12,28);
5482      return {
5483        q:{en:`${n1} and ${n2} arranged ${it.en} in ${rows} rows of ${cols}. How many ${it.en} are in the array?`,
5484           es:`${n1} y ${n2} acomodaron ${it.es} en ${rows} filas de ${cols}. ¿${cuantosEs(it)} ${it.es} hay en el arreglo?`},
5485        a:{en:`${rows} × ${cols} = ${rows*cols}`, es:`${rows} × ${cols} = ${rows*cols}`}
5486      };
5487    }
5488    const a=ri(16,40), b=ri(15,32), extra=ri(20,80);
5489    return {
5490      q:{en:`${n1} has ${a} ${bin.en} holding ${b} ${it.en} each, plus ${extra} loose ${it.en}. How many in all?`,
5491         es:`${n1} tiene ${a} ${bin.es} con ${b} ${it.es} cada ${unoEs(bin)}, más ${extra} ${it.es} sueltos. ¿${cuantosEs(it)} hay en total?`},
5492      a:{en:`${a}×${b}=${a*b}, +${extra} = ${a*b+extra}`, es:`${a}×${b}=${a*b}, +${extra} = ${a*b+extra}`}
5493    };
5494  }
5495},
5496{
5497  code:"4.NBT.B.6", grade:4, dok:3,
5498  title:{en:"Divide with one-digit divisors",
5499         es:"Dividir con divisores de un dígito"},
5500  text:{en:"Find whole-number quotients and remainders with up to four-digit dividends and one-digit divisors, using strategies based on place value, the properties of operations, and/or the relationship between multiplication and division.",
5501        es:"Halla cocientes y residuos con dividendos de hasta cuatro dígitos y divisores de un dígito, usando estrategias basadas en el valor posicional, las propiedades de las operaciones y/o la relación entre la multiplicación y la división."},
5502  build(n1,n2,lvl){
5503    const it = pickItem(), bin = pick(THEME.bins);
5504
5505    /* ---- Support · DOK 1 : clean quotients ---- */
5506    if(lvl===1){
5507      const k=ri(1,4);
5508      if(k===1){
5509        const per=ri(11,24), g=ri(2,5), tot=per*g;
5510        return {
5511          q:{en:`${n1} shared ${tot} ${it.en} equally among ${g} ${bin.en}. How many in each?`,
5512             es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${g} ${bin.es}. ¿${cuantosEs(it)} hay en cada ${unoEs(bin)}?`},
5513          a:{en:`${tot} ÷ ${g} = ${per}`, es:`${tot} ÷ ${g} = ${per}`}
5514        };
5515      }
5516      if(k===2){
5517        const per=ri(4,9), g=ri(11,25), tot=per*g;
5518        return {
5519          q:{en:`${n1} has ${tot} ${it.en} and puts ${per} in each ${bin.one.en}. How many ${bin.en} does ${n1} fill?`,
5520             es:`${n1} tiene ${tot} ${it.es} y pone ${per} en cada ${bin.one.es}. ¿${cuantosEs(bin)} ${bin.es} llena?`},
5521          a:{en:`${tot} ÷ ${per} = ${g}`, es:`${tot} ÷ ${per} = ${g}`}
5522        };
5523      }
5524      if(k===3){
5525        const per=ri(20,45), d=ri(3,6), tot=per*d;
5526        return {
5527          q:{en:`${n1} counted ${tot} ${it.en} over ${d} days, the same each day. How many per day?`,
5528             es:`${n1} contó ${tot} ${it.es} en ${d} días, la misma cantidad cada día. ¿${cuantosEs(it)} por día?`},
5529          a:{en:`${tot} ÷ ${d} = ${per}`, es:`${tot} ÷ ${d} = ${per}`}
5530        };
5531      }
5532      const per=ri(15,40), g=ri(3,6), tot=per*g;
5533      return {
5534        q:{en:`${n1} and ${n2} split ${tot} ${it.en} into ${g} equal piles. How many in each pile?`,
5535           es:`${n1} y ${n2} dividieron ${tot} ${it.es} en ${g} montones iguales. ¿${cuantosEs(it)} hay en cada montón?`},
5536        a:{en:`${tot} ÷ ${g} = ${per}`, es:`${tot} ÷ ${g} = ${per}`}
5537      };
5538    }
5539
5540    /* ---- Challenge · DOK 3 : remainders in context ---- */
5541    if(lvl===3){
5542      const k=ri(1,4);
5543      if(k===1){
5544        const d=ri(3,8), q2=ri(40,120), rem=ri(1,d-1), tot=d*q2+rem;
5545        return {
5546          q:{en:`${n1} packs ${tot} ${it.en} into ${bin.en} that hold ${d} each. How many ${bin.en} are completely full, and what happens to the rest? Explain your choice.`,
5547             es:`${n1} empaca ${tot} ${it.es} en ${bin.es} de ${d} cada ${unoEs(bin)}. ¿${cuantosEs(bin)} quedan llenas y qué pasa con el resto? Explica tu decisión.`},
5548          a:{en:`${tot} ÷ ${d} = ${q2} R${rem} — ${q2} full, ${rem} left over`,
5549             es:`${tot} ÷ ${d} = ${q2} R${rem} — ${q2} llenas, sobran ${rem}`}
5550        };
5551      }
5552      if(k===2){
5553        const d=ri(4,9), q2=ri(30,90), rem=ri(1,d-1), tot=d*q2+rem;
5554        return {
5555          q:{en:`${n1} needs ${bin.en} holding ${d} ${it.en} each to carry ${tot} ${it.en} — every one must go. How many ${bin.en} are needed? Explain why the remainder changes the answer.`,
5556             es:`${n1} necesita ${bin.es} de ${d} ${it.es} cada ${unoEs(bin)} para llevar ${tot} ${it.es} — todos deben ir. ¿${cuantosEs(bin)} se necesitan? Explica por qué el residuo cambia la respuesta.`},
5557          a:{en:`${tot} ÷ ${d} = ${q2} R${rem} → ${q2+1} needed`,
5558             es:`${tot} ÷ ${d} = ${q2} R${rem} → se necesitan ${q2+1}`}
5559        };
5560      }
5561      if(k===3){
5562        const d=ri(3,8), q2=ri(50,150), tot=d*q2;
5563        return {
5564          q:{en:`${n2} says ${tot} ${it.en} split among ${d} groups gives ${q2+ri(3,9)} each. Multiply to check, then give the correct number and explain how multiplication proves it.`,
5565             es:`${n2} dice que ${tot} ${it.es} repartidos en ${d} grupos dan ${q2+ri(3,9)} en cada uno. Multiplica para comprobar, da el número correcto y explica cómo lo demuestra la multiplicación.`},
5566          a:{en:`${d} × ${q2} = ${tot}, so ${q2} each`, es:`${d} × ${q2} = ${tot}, entonces ${q2} en cada grupo`}
5567        };
5568      }
5569      const d=ri(4,8), q2=ri(60,180), tot=d*q2, take=ri(40,120);
5570      return {
5571        q:{en:`${n1} started with ${tot+take} ${it.en}, gave away ${take}, then split the rest into ${d} equal groups. How many per group? Show both steps.`,
5572           es:`${n1} empezó con ${tot+take} ${it.es}, regaló ${take} y dividió el resto en ${d} grupos iguales. ¿${cuantosEs(it)} por grupo? Muestra los dos pasos.`},
5573        a:{en:`${tot+take}−${take}=${tot}, ÷${d} = ${q2}`, es:`${tot+take}−${take}=${tot}, ÷${d} = ${q2}`}
5574      };
5575    }
5576
5577    /* ---- On level · DOK 2 : 3-4 digit ÷ 1 digit ---- */
5578    const k=ri(1,4);
5579    if(k===1){
5580      const d=ri(3,9), q2=ri(60,400), tot=d*q2;
5581      return {
5582        q:{en:`${n1}'s school shared ${tot} ${it.en} equally among ${d} classrooms. How many ${it.en} did each classroom get?`,
5583           es:`La escuela de ${n1} repartió ${tot} ${it.es} entre ${d} salones por igual. ¿${cuantosEs(it)} ${it.es} recibió cada salón?`},
5584        a:{en:`${tot} ÷ ${d} = ${q2}`, es:`${tot} ÷ ${d} = ${q2}`}
5585      };
5586    }
5587    if(k===2){
5588      const d=ri(3,8), q2=ri(40,200), rem=ri(1,d-1), tot=d*q2+rem;
5589      return {
5590        q:{en:`${n1} packed ${tot} ${it.en} into ${bin.en} of ${d}. How many full ${bin.en}, and how many ${it.en} are left over?`,
5591           es:`${n1} empacó ${tot} ${it.es} en ${bin.es} de ${d}. ¿${cuantosEs(bin)} ${bin.es} llenas y ${cuantosLc(it)} ${it.es} sobran?`},
5592        a:{en:`${tot} ÷ ${d} = ${q2} R${rem}`, es:`${tot} ÷ ${d} = ${q2} R${rem}`}
5593      };
5594    }
5595    if(k===3){
5596      const per=ri(20,90), g=ri(4,9), tot=per*g;
5597      return {
5598        q:{en:`${n1} has ${tot} ${it.en} and wants ${g} equal groups. How many ${it.en} in each group?`,
5599           es:`${n1} tiene ${tot} ${it.es} y quiere ${g} grupos iguales. ¿${cuantosEs(it)} ${it.es} hay en cada grupo?`},
5600        a:{en:`${tot} ÷ ${g} = ${per}`, es:`${tot} ÷ ${g} = ${per}`}
5601      };
5602    }
5603    const d=ri(4,9), q2=ri(80,300), tot=d*q2;
5604    return {
5605      q:{en:`Over ${d} weeks ${n1} and ${n2} collected ${tot} ${it.en}, the same amount each week. How many ${it.en} per week?`,
5606         es:`En ${d} semanas ${n1} y ${n2} juntaron ${tot} ${it.es}, la misma cantidad cada semana. ¿${cuantosEs(it)} ${it.es} por semana?`},
5607      a:{en:`${tot} ÷ ${d} = ${q2}`, es:`${tot} ÷ ${d} = ${q2}`}
5608    };
5609  }
5610},
5611{
5612  code:"4.NF.A.2", grade:4, dok:3,
5613  title:{en:"Compare fractions with different denominators",
5614         es:"Comparar fracciones con denominadores distintos"},
5615  text:{en:"Compare two fractions with different numerators and different denominators, e.g., by creating common denominators or numerators, or by comparing to a benchmark fraction such as 1/2. Recognize that comparisons are valid only when the two fractions refer to the same whole. Record the results of comparisons with symbols >, =, or <, and justify the conclusions.",
5616        es:"Compara dos fracciones con numeradores y denominadores distintos, por ejemplo, creando denominadores o numeradores comunes, o comparando con una fracción de referencia como 1/2. Reconoce que las comparaciones son válidas solo cuando las fracciones se refieren al mismo todo. Registra los resultados con los símbolos >, =, o <."},
5617  build(n1,n2,lvl){
5618    const it = pickItem(), bin = pick(THEME.bins);
5619    const pairs=[[2,4],[2,6],[2,8],[3,6],[4,8],[2,3],[3,4],[2,5],[4,6],[3,8],[5,10]];
5620
5621    /* ---- Support · DOK 1 : one denominator doubles the other ---- */
5622    if(lvl===1){
5623      const k=ri(1,4);
5624      if(k===1){
5625        const d=pick([4,6,8]);
5626        return {
5627          q:{en:`${n1} filled ${frR(1,2)} of a ${bin.one.en} with ${it.en}. ${n2} filled ${frR(1,d)}. Rewrite ${frR(1,2)} as ${frR(d/2,d)} and compare.`,
5628             es:`${n1} llenó ${frR(1,2)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ${n2} llenó ${frR(1,d)}. Escribe ${frR(1,2)} como ${frR(d/2,d)} y compara.`},
5629          a:{en:`${frR(d/2,d)} > ${frR(1,d)} — ${n1} filled more`,
5630             es:`${frR(d/2,d)} > ${frR(1,d)} — ${n1} llenó más`}
5631        };
5632      }
5633      if(k===2){
5634        const d=pick([4,6,8]), a=ri(1,d/2-1), b=ri(d/2+1,d-1);
5635        return {
5636          q:{en:`${n1} used ${frR(a,d)} of a pack of ${it.en} and ${n2} used ${frR(b,d)}. Who used more? Use > or <.`,
5637             es:`${n1} usó ${frR(a,d)} de un paquete de ${it.es} y ${n2} usó ${frR(b,d)}. ¿Quién usó más? Usa > o <.`},
5638          a:{en:`${frR(b,d)} > ${frR(a,d)} — ${n2}`, es:`${frR(b,d)} > ${frR(a,d)} — ${n2}`}
5639        };
5640      }
5641      if(k===3){
5642        const d=pick([6,8,10]);
5643        return {
5644          q:{en:`${n1} filled ${frR(d/2,d)} of a ${bin.one.en}. Is that more or less than half? Explain.`,
5645             es:`${n1} llenó ${frR(d/2,d)} de ${unUnaEs(bin)} ${bin.one.es}. ¿Es más o menos que la mitad? Explica.`},
5646          a:{en:`Exactly half — ${frR(d/2,d)} = ${frR(1,2)}`, es:`Exactamente la mitad — ${frR(d/2,d)} = ${frR(1,2)}`}
5647        };
5648      }
5649      const d=pick([4,6,8]), a=ri(d/2+1,d-1);
5650      return {
5651        q:{en:`${n1} used ${frR(a,d)} of the ${it.en}. Is that more than ${frR(1,2)}? Explain using ${frR(d/2,d)}.`,
5652           es:`${n1} usó ${frR(a,d)} de ${losLasEs(it)} ${it.es}. ¿Es más que ${frR(1,2)}? Explica usando ${frR(d/2,d)}.`},
5653        a:{en:`Yes — ${frR(a,d)} > ${frR(d/2,d)} = ${frR(1,2)}`, es:`Sí — ${frR(a,d)} > ${frR(d/2,d)} = ${frR(1,2)}`}
5654      };
5655    }
5656
5657    /* ---- Challenge · DOK 3 : benchmarks, same whole, justify ---- */
5658    if(lvl===3){
5659      const k=ri(1,4);
5660      if(k===1){
5661        const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
5662        const a=ri(1,dA-1), b=ri(1,dB-1);
5663        const aL=a*L/dA, bL=b*L/dB;
5664        if(aL===bL) return this.build(n1,n2,lvl);
5665        return {
5666          q:{en:`${n1} filled ${frR(a,dA)} of a ${bin.one.en} with ${it.en}; ${n2} filled ${frR(b,dB)} of an identical one. Who filled more? Prove it with a common denominator and write the comparison.`,
5667             es:`${n1} llenó ${frR(a,dA)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}; ${n2} llenó ${frR(b,dB)} de ${unUnaEs(bin)==="un"?"uno idéntico":"una idéntica"}. ¿Quién llenó más? Compruébalo con un denominador común.`},
5668          a:{en:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)} — ${aL>bL?n1:n2}`,
5669             es:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)} — ${aL>bL?n1:n2}`}
5670        };
5671      }
5672      if(k===2){
5673        const a=2, dA=5, b=3, dB=8;
5674        return {
5675          q:{en:`${n2} says ${frR(3,8)} of the ${it.en} is more than ${frR(2,5)} because 8 is bigger than 5. Use ${frR(1,2)} as a benchmark to check. Who is right?`,
5676             es:`${n2} dice que ${frR(3,8)} de ${losLasEs(it)} ${it.es} es más que ${frR(2,5)} porque 8 es mayor que 5. Usa ${frR(1,2)} como referencia. ¿Quién tiene razón?`},
5677          a:{en:`Both are below ${frR(1,2)}; ${frR(2,5)}=16/40 > ${frR(3,8)}=15/40 — ${n2} is wrong`,
5678             es:`Las dos son menores que ${frR(1,2)}; ${frR(2,5)}=16/40 > ${frR(3,8)}=15/40 — ${n2} se equivoca`}
5679        };
5680      }
5681      if(k===3){
5682        const d=pick([3,4,6,8]), a=ri(1,d-1);
5683        return {
5684          q:{en:`${n1} filled ${frR(a,d)} of a SMALL ${bin.one.en} and ${n2} filled ${frR(a,d)} of a LARGE one. ${n2} says the fractions are equal so the amounts are equal. What is wrong with that reasoning?`,
5685             es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} PEQUEÑA y ${n2} llenó ${frR(a,d)} de una GRANDE. ${n2} dice que como las fracciones son iguales, las cantidades también. ¿Qué está mal en ese razonamiento?`},
5686          a:{en:`Equal fractions of DIFFERENT wholes are different amounts`,
5687             es:`Fracciones iguales de todos DIFERENTES son cantidades diferentes`}
5688        };
5689      }
5690      const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
5691      const a=ri(1,dA-1);
5692      return {
5693        q:{en:`${n1} used ${frR(a,dA)} of the ${it.en}. Name a fraction in ${dB}ths that is LESS than ${frR(a,dA)}, and explain how you know.`,
5694           es:`${n1} usó ${frR(a,dA)} de ${losLasEs(it)} ${it.es}. Nombra una fracción en ${dB}avos que sea MENOR que ${frR(a,dA)} y explica cómo lo sabes.`},
5695        a:{en:`${frR(a,dA)} = ${frR(a*L/dA,L)}; any ${dB}ths below that, e.g. ${frR(Math.max(1,Math.floor(a*dB/dA)-1),dB)}`,
5696           es:`${frR(a,dA)} = ${frR(a*L/dA,L)}; cualquier ${dB}avo menor, p. ej. ${frR(Math.max(1,Math.floor(a*dB/dA)-1),dB)}`}
5697      };
5698    }
5699
5700    /* ---- On level · DOK 2 ---- */
5701    const k=ri(1,4);
5702    if(k===1){
5703      const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
5704      const a=ri(1,dA-1), b=ri(1,dB-1);
5705      const aL=a*L/dA, bL=b*L/dB;
5706      if(aL===bL) return this.build(n1,n2,lvl);
5707      return {
5708        q:{en:`${n1} used ${frR(a,dA)} of the ${it.en} and ${n2} used ${frR(b,dB)}. Compare with > or < using a common denominator.`,
5709           es:`${n1} usó ${frR(a,dA)} de ${losLasEs(it)} ${it.es} y ${n2} usó ${frR(b,dB)}. Compara con > o < usando un denominador común.`},
5710        a:{en:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)}`, es:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)}`}
5711      };
5712    }
5713    if(k===2){
5714      const d=pick([3,5,6,8]), a=d>4?ri(Math.floor(d/2)+1,d-1):ri(2,d-1);
5715      return {
5716        q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en}. Is that more or less than ${frR(1,2)}? Explain.`,
5717           es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ¿Es más o menos que ${frR(1,2)}? Explica.`},
5718        a:{en:`${a/d>0.5?"More":(a/d===0.5?"Exactly half":"Less")} than ${frR(1,2)}`,
5719           es:`${a/d>0.5?"Más":(a/d===0.5?"Exactamente la mitad":"Menos")} que ${frR(1,2)}`}
5720      };
5721    }
5722    if(k===3){
5723      const d=pick([4,6,8,10]);
5724      return {
5725        q:{en:`${n1} says ${frR(1,2)} of the ${it.en} is the same as ${frR(d/2,d)}. Is ${n1} right? Show why.`,
5726           es:`${n1} dice que ${frR(1,2)} de ${losLasEs(it)} ${it.es} es lo mismo que ${frR(d/2,d)}. ¿Tiene razón? Muestra por qué.`},
5727        a:{en:`Yes — ${frR(1,2)} = ${frR(d/2,d)}`, es:`Sí — ${frR(1,2)} = ${frR(d/2,d)}`}
5728      };
5729    }
5730    const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
5731    const a=ri(1,dA-1), b=ri(1,dB-1);
5732    const aL=a*L/dA, bL=b*L/dB;
5733    if(aL===bL) return this.build(n1,n2,lvl);
5734    return {
5735      q:{en:`${n1} walked ${frR(a,dA)} km and ${n2} walked ${frR(b,dB)} km to the ${it.en} sale. Who walked farther? Write the comparison.`,
5736         es:`${n1} caminó ${frR(a,dA)} km y ${n2} caminó ${frR(b,dB)} km a la venta de ${it.es}. ¿Quién caminó más? Escribe la comparación.`},
5737      a:{en:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)} — ${aL>bL?n1:n2}`,
5738         es:`${frR(aL,L)} ${aL>bL?">":"<"} ${frR(bL,L)} — ${aL>bL?n1:n2}`}
5739    };
5740  }
5741},
5742{
5743  code:"4.NF.B.3.d", grade:4, dok:2,
5744  title:{en:"Add & subtract fractions — like denominators",
5745         es:"Sumar y restar fracciones — mismo denominador"},
5746  text:{en:"Solve word problems involving addition and subtraction of fractions referring to the same whole and having like denominators, e.g., by using visual fraction models and equations to represent the problem.",
5747        es:"Resuelve problemas verbales de suma y resta de fracciones que se refieren al mismo todo y tienen el mismo denominador, por ejemplo, usando modelos visuales de fracciones y ecuaciones para representar el problema."},
5748  build(n1,n2,lvl){
5749    const it = pickItem(), bin = pick(THEME.bins);
5750
5751    /* ---- Support · DOK 1 : sums within 1, small denominators ---- */
5752    if(lvl===1){
5753      const k=ri(1,4);
5754      if(k===1){
5755        const d=pick([4,6]), a=ri(1,2), b=ri(1,d-a-1);
5756        return {
5757          q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en}. ${n2} filled ${frR(b,d)} more. What fraction is filled now? (Add the tops; the bottom stays.)`,
5758             es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ${n2} llenó ${frR(b,d)} más. ¿Qué fracción está llena ahora? (Suma los de arriba; el de abajo no cambia.)`},
5759          a:{en:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`, es:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`}
5760        };
5761      }
5762      if(k===2){
5763        const d=pick([4,6,8]), a=ri(3,d-1), b=ri(1,a-1);
5764        return {
5765          q:{en:`A tray of ${it.en} was ${frR(a,d)} full. ${n1} used ${frR(b,d)} of it. What fraction is left?`,
5766             es:`Una bandeja de ${it.es} estaba llena hasta ${frR(a,d)}. ${n1} usó ${frR(b,d)}. ¿Qué fracción queda?`},
5767          a:{en:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`, es:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`}
5768        };
5769      }
5770      if(k===3){
5771        const d=pick([3,4]), a=1, b=1;
5772        return {
5773          q:{en:`${n1} packed ${frR(a,d)} of the ${it.en} in the morning and ${frR(b,d)} in the afternoon. What fraction did ${n1} pack in all?`,
5774             es:`${n1} empacó ${frR(a,d)} de ${losLasEs(it)} ${it.es} por la mañana y ${frR(b,d)} por la tarde. ¿Qué fracción empacó en total?`},
5775          a:{en:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`, es:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`}
5776        };
5777      }
5778      const d=pick([4,6]), whole=d, used=ri(1,d-1);
5779      return {
5780        q:{en:`${n1}'s ${bin.one.en} of ${it.en}
5780 was completely full (${frR(whole,d)}). ${n1} gave away ${frR(used,d)}. What fraction is left?`,
5781           es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${it.es} de ${n1} estaba ${gEs(bin)==="m"?"lleno":"llena"} (${frR(whole,d)}). ${n1} regaló ${frR(used,d)}. ¿Qué fracción queda?`},
5782        a:{en:`${frR(whole,d)} − ${frR(used,d)} = ${frR(whole-used,d)}`, es:`${frR(whole,d)} − ${frR(used,d)} = ${frR(whole-used,d)}`}
5783      };
5784    }
5785
5786    /* ---- Challenge · DOK 3 : the classic error, past one whole, missing part ---- */
5787    if(lvl===3){
5788      const k=ri(1,5);
5789      if(k===1){
5790        const d=pick([6,8]), a=ri(2,3), b=ri(2,3);
5791        return {
5792          q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en} and ${n2} filled ${frR(b,d)}. ${n2} says the total is ${frR(a+b,2*d)}. What mistake did ${n2} make? Give the correct total.`,
5793             es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y ${n2} llenó ${frR(b,d)}. ${n2} dice que el total es ${frR(a+b,2*d)}. ¿Qué error cometió? Da el total correcto.`},
5794          a:{en:`Added the denominators — correct: ${frR(a,d)}+${frR(b,d)}=${frR(a+b,d)}`,
5795             es:`Sumó los denominadores — correcto: ${frR(a,d)}+${frR(b,d)}=${frR(a+b,d)}`}
5796        };
5797      }
5798      if(k===2){
5799        const d=pick([4,6]), a=ri(2,d-1), b=ri(d-a+1,d-1);
5800        return {
5801          q:{en:`${n1} collected ${frR(a,d)} of a ${bin.one.en} of ${it.en} and ${n2} collected ${frR(b,d)}. Together is that more than 1 whole ${bin.one.en}? How much more or less? Show your thinking.`,
5802             es:`${n1} juntó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} y ${n2} juntó ${frR(b,d)}. ¿Juntos es más que 1 ${bin.one.es} entero? ¿Cuánto más o menos? Muestra tu razonamiento.`},
5803          a:{en:`${frR(a,d)}+${frR(b,d)}=${frR(a+b,d)} = ${mx(a+b,d)} — ${a+b>d?"more than 1 by "+frR(a+b-d,d):a+b===d?"exactly 1":"less than 1 by "+frR(d-a-b,d)}`,
5804             es:`${frR(a,d)}+${frR(b,d)}=${frR(a+b,d)} = ${mx(a+b,d)} — ${a+b>d?"más que 1 por "+frR(a+b-d,d):a+b===d?"exactamente 1":"menos que 1 por "+frR(d-a-b,d)}`}
5805        };
5806      }
5807      if(k===3){
5808        const d=pick([6,8]), tot=ri(4,d-1), a=ri(1,tot-1);
5809        return {
5810          q:{en:`${n1} and ${n2} together filled ${frR(tot,d)} of a ${bin.one.en} with ${it.en}. ${n1} filled ${frR(a,d)}. Write an equation with n for ${n2}'s fraction, then solve.`,
5811             es:`${n1} y ${n2} juntos llenaron ${frR(tot,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ${n1} llenó ${frR(a,d)}. Escribe una ecuación con n para la fracción de ${n2} y resuélvela.`},
5812          a:{en:`${frR(a,d)} + n = ${frR(tot,d)}; n = ${frR(tot-a,d)}`,
5813             es:`${frR(a,d)} + n = ${frR(tot,d)}; n = ${frR(tot-a,d)}`}
5814        };
5815      }
5816      if(k===4){
5817        const d=pick([6,8]), goal=d, a=ri(2,d-3), b=ri(1,d-a-2);
5818        return {
5819          q:{en:`${n1} needs a full ${bin.one.en} of ${it.en}. So far ${n1} has ${frR(a,d)} and ${n2} added ${frR(b,d)}. What fraction is still missing? Justify with an equation.`,
5820             es:`${n1} necesita ${unUnaEs(bin)} ${bin.one.es} ${gEs(bin)==="m"?"lleno":"llena"} de ${it.es}. Hasta ahora tiene ${frR(a,d)} y ${n2} agregó ${frR(b,d)}. ¿Qué fracción falta? Justifica con una ecuación.`},
5821          a:{en:`${frR(a,d)}+${frR(b,d)}+n=${frR(goal,d)}; n=${frR(goal-a-b,d)}`,
5822             es:`${frR(a,d)}+${frR(b,d)}+n=${frR(goal,d)}; n=${frR(goal-a-b,d)}`}
5823        };
5824      }
5825      const d=pick([6,8]), a=ri(3,d-1), used=ri(1,2), added=ri(1,2);
5826      return {
5827        q:{en:`A ${bin.one.en} of ${it.en} started at ${frR(a,d)} full. ${n1} used ${frR(used,d)}, then ${n2} added ${frR(added,d)}. What fraction is it now? Show both steps.`,
5828           es:`${unUnaEs(bin)==="un"?"Un":"Una"} ${bin.one.es} de ${it.es} empezó con ${frR(a,d)}. ${n1} usó ${frR(used,d)} y luego ${n2} agregó ${frR(added,d)}. ¿Qué fracción hay ahora? Muestra los dos pasos.`},
5829        a:{en:`${frR(a,d)}−${frR(used,d)}=${frR(a-used,d)}, +${frR(added,d)} = ${frR(a-used+added,d)}`,
5830           es:`${frR(a,d)}−${frR(used,d)}=${frR(a-used,d)}, +${frR(added,d)} = ${frR(a-used+added,d)}`}
5831      };
5832    }
5833
5834    /* ---- On level · DOK 2 ---- */
5835    const k=ri(1,5);
5836    if(k===1){
5837      const d=pick([6,8,10]), a=ri(1,4), b=ri(1,d-a-1);
5838      return {
5839        q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en} and ${n2} filled ${frR(b,d)}. What fraction of the ${bin.one.en} is filled?`,
5840           es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y ${n2} llenó ${frR(b,d)}. ¿Qué fracción está llena?`},
5841        a:{en:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`, es:`${frR(a,d)} + ${frR(b,d)} = ${frR(a+b,d)}`}
5842      };
5843    }
5844    if(k===2){
5845      const d=pick([6,8,10]), a=ri(4,d-1), b=ri(1,a-1);
5846      return {
5847        q:{en:`A ${bin.one.en} was ${frR(a,d)} full of ${it.en}. ${n1} took out ${frR(b,d)} for the class. What fraction is left?`,
5848           es:`${unUnaEs(bin)==="un"?"Un":"Una"} ${bin.one.es} estaba ${gEs(bin)==="m"?"lleno":"llena"} de ${it.es} hasta ${frR(a,d)}. ${n1} sacó ${frR(b,d)} para la clase. ¿Qué fracción queda?`},
5849        a:{en:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`, es:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`}
5850      };
5851    }
5852    if(k===3){
5853      const d=pick([6,8]), tot=ri(4,d-1), a=ri(1,tot-1);
5854      return {
5855        q:{en:`Together ${n1} and ${n2} sorted ${frR(tot,d)} of the ${it.en}. ${n1} sorted ${frR(a,d)}. What fraction did ${n2} sort?`,
5856           es:`Entre ${n1} y ${n2} ordenaron ${frR(tot,d)} de ${losLasEs(it)} ${it.es}. ${n1} ordenó ${frR(a,d)}. ¿Qué fracción ordenó ${n2}?`},
5857        a:{en:`${frR(tot,d)} − ${frR(a,d)} = ${frR(tot-a,d)}`, es:`${frR(tot,d)} − ${frR(a,d)} = ${frR(tot-a,d)}`}
5858      };
5859    }
5860    if(k===4){
5861      const d=pick([6,8,10]), a=ri(2,d-2), b=ri(1,a-1);
5862      return {
5863        q:{en:`${n1} packed ${frR(a,d)} of the ${it.en} and ${n2} packed ${frR(b,d)}. How much more did ${n1} pack than ${n2}?`,
5864           es:`${n1} empacó ${frR(a,d)} de ${losLasEs(it)} ${it.es} y ${n2} empacó ${frR(b,d)}. ¿Cuánto más empacó ${n1} que ${n2}?`},
5865        a:{en:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`, es:`${frR(a,d)} − ${frR(b,d)} = ${frR(a-b,d)}`}
5866      };
5867    }
5868    const d=pick([8,10]), a=ri(1,3), b=ri(1,3), c=ri(1,d-a-b-1);
5869    return {
5870      q:{en:`${n1} filled ${frR(a,d)} of a ${bin.one.en} with ${it.en} before lunch, ${frR(b,d)} after lunch, and ${n2} added ${frR(c,d)}. What fraction is filled in all?`,
5871         es:`${n1} llenó ${frR(a,d)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} antes del almuerzo, ${frR(b,d)} después, y ${n2} agregó ${frR(c,d)}. ¿Qué fracción está llena en total?`},
5872      a:{en:`${frR(a,d)}+${frR(b,d)}+${frR(c,d)} = ${frR(a+b+c,d)}`, es:`${frR(a,d)}+${frR(b,d)}+${frR(c,d)} = ${frR(a+b+c,d)}`}
5873    };
5874  }
5875},
5876{
5877  code:"4.NF.B.4.c", grade:4, dok:2,
5878  title:{en:"Multiply a fraction by a whole number",
5879         es:"Multiplicar una fracción por un número entero"},
5880  text:{en:"Solve word problems involving multiplication of a fraction by a whole number, e.g., by using visual fraction models and equations to represent the problem.",
5881        es:"Resuelve problemas verbales de multiplicación de una fracción por un número entero, por ejemplo, usando modelos visuales de fracciones y ecuaciones para representar el problema."},
5882  build(n1,n2,lvl){
5883    const it = pickItem(), bin = pick(THEME.bins);
5884
5885    /* ---- Support · DOK 1 : unit fractions, repeated addition link ---- */
5886    if(lvl===1){
5887      const k=ri(1,4);
5888      if(k===1){
5889        const d=pick([2,3,4]), n=ri(2,3);
5890        return {
5891          q:{en:`Each of ${n} friends gets ${frR(1,d)} of a ${bin.one.en} of ${it.en} from ${n1}. How much is that in all? (Hint: ${Array(n).fill(frR(1,d)).join(" + ")}.)`,
5892             es:`Cada uno de ${n} amigos recibe ${frR(1,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} de parte de ${n1}. ¿Cuánto es en total? (Pista: ${Array(n).fill(frR(1,d)).join(" + ")}.)`},
5893          a:{en:`${n} × ${frR(1,d)} = ${mx(n,d)}`, es:`${n} × ${frR(1,d)} = ${mx(n,d)}`}
5894        };
5895      }
5896      if(k===2){
5897        const d=pick([3,4]), n=2;
5898        return {
5899          q:{en:`${n1} fills ${frR(1,d)} of a bag with ${it.en}, and ${n2} fills another ${frR(1,d)}. Add the two fractions. How much of the bag is filled?`,
5900             es:`${n1} llena ${frR(1,d)} de una bolsa con ${it.es} y ${n2} llena otro ${frR(1,d)}. Suma las dos fracciones. ¿Cuánto de la bolsa está lleno?`},
5901          a:{en:`2 × ${frR(1,d)} = ${frR(2,d)}`, es:`2 × ${frR(1,d)} = ${frR(2,d)}`}
5902        };
5903      }
5904      if(k===3){
5905        const d=4, n=ri(2,3);
5906        return {
5907          q:{en:`Each mini-bag holds ${frR(1,4)} kg of ${it.en}. ${n1} packs ${n} mini-bags. What is the total mass? Count by fourths.`,
5908             es:`Cada bolsita guarda ${frR(1,4)} kg de ${it.es}. ${n1} empaca ${n} bolsitas. ¿Cuál es la masa total? Cuenta de cuarto en cuarto.`},
5909          a:{en:`${n} × ${frR(1,4)} = ${mx(n,4)} kg`, es:`${n} × ${frR(1,4)} = ${mx(n,4)} kg`}
5910        };
5911      }
5912      const d=pick([2,3]), n=d;
5913      return {
5914        q:{en:`${n1} pours ${frR(1,d)} of a jug for each of ${n} friends. Does that use the whole jug? Show the multiplication.`,
5915           es:`${n1} sirve ${frR(1,d)} de una jarra a cada uno de ${n} amigos. ¿Usa toda la jarra? Muestra la multiplicación.`},
5916        a:{en:`${n} × ${frR(1,d)} = ${frR(n,d)} = 1 whole — yes`, es:`${n} × ${frR(1,d)} = ${frR(n,d)} = 1 entero — sí`}
5917      };
5918    }
5919
5920    /* ---- Challenge · DOK 3 ---- */
5921    if(lvl===3){
5922      const k=ri(1,5);
5923      if(k===1){
5924        const a=ri(2,3), d=pick([4,8]), n=ri(3,5);
5925        return {
5926          q:{en:`Each pack holds ${frR(a,d)} kg of ${it.en}. ${n2} says ${n} packs hold ${frR(n*a,n*d)} kg, multiplying top AND bottom by ${n}. What went wrong? Give the correct total.`,
5927             es:`Cada paquete guarda ${frR(a,d)} kg de ${it.es}. ${n2} dice que ${n} paquetes guardan ${frR(n*a,n*d)} kg, multiplicando arriba Y abajo por ${n}. ¿Qué salió mal? Da el total correcto.`},
5928          a:{en:`Only the numerator scales — ${n}×${frR(a,d)} = ${mx(n*a,d)} kg`,
5929             es:`Solo se multiplica el numerador — ${n}×${frR(a,d)} = ${mx(n*a,d)} kg`}
5930        };
5931      }
5932      if(k===2){
5933        const a=ri(2,3), d=4, n=ri(4,6), cap=ri(3,5);
5934        const tot=n*a/d;
5935        return {
5936          q:{en:`${n1} packs ${n} bags of ${it.en}, each with a mass of ${frR(a,d)} kg, into a box that holds ${cap} kg. Will they fit? Show the total and compare.`,
5937             es:`${n1} empaca ${n} bolsas de ${it.es}, cada una con una masa de ${frR(a,d)} kg, en una caja que aguanta ${cap} kg. ¿Caben? Muestra el total y compara.`},
5938          a:{en:`${n}×${frR(a,d)} = ${mx(n*a,d)} kg — ${tot<=cap?"yes, fits":"no, too heavy"}`,
5939             es:`${n}×${frR(a,d)} = ${mx(n*a,d)} kg — ${tot<=cap?"sí caben":"no, pesa demasiado"}`}
5940        };
5941      }
5942      if(k===3){
5943        const d=pick([3,4]), n=ri(2,4)*d, each=1;
5944        return {
5945          q:{en:`${n1} gives ${frR(each,d)} of a ${bin.one.en} of ${it.en} to each classmate and uses exactly ${n/d} whole ${bin.en}. Write an equation with n for how many classmates there are, then solve.`,
5946             es:`${n1} da ${frR(each,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} a cada compañero y usa exactamente ${n/d} ${bin.es} enteras. Escribe una ecuación con n para cuántos compañeros hay y resuélvela.`},
5947          a:{en:`n × ${frR(each,d)} = ${n/d}; n = ${n}`, es:`n × ${frR(each,d)} = ${n/d}; n = ${n}`}
5948        };
5949      }
5950      if(k===4){
5951        const a=ri(2,3), d=pick([4,8]), n=ri(3,6);
5952        const asWhole=Math.floor(n*a/d), rem=(n*a)%d;
5953        return {
5954          q:{en:`${n1} runs ${frR(a,d)} km each morning for ${n} days. ${n2} estimates "less than ${asWhole+1} km total." Multiply to check whether ${n2} is right, and give the exact distance.`,
5955             es:`${n1} corre ${frR(a,d)} km cada mañana durante ${n} días. ${n2} estima "menos de ${asWhole+1} km en total." Multiplica para comprobar si tiene razón y da la distancia exacta.`},
5956          a:{en:`${n}×${frR(a,d)} = ${mx(n*a,d)} km — ${n*a/d < asWhole+1 ? "right" : "not right"}`,
5957             es:`${n}×${frR(a,d)} = ${mx(n*a,d)} km — ${n*a/d < asWhole+1 ? "tiene razón" : "no tiene razón"}`}
5958        };
5959      }
5960      const dA=4, aA=3, nA=ri(2,4), dB=2, aB=1, nB=ri(3,6);
5961      const tA=nA*aA/dA, tB=nB*aB/dB;
5962      if(tA===tB) return this.build(n1,n2,lvl);
5963      return {
5964        q:{en:`${n1} packs ${nA} bags at ${frR(aA,dA)} kg of ${it.en} each; ${n2} packs ${nB} bags at ${frR(aB,dB)} kg each. Who packed more mass? Prove it with both products.`,
5965           es:`${n1} empaca ${nA} bolsas de ${frR(aA,dA)} kg de ${it.es} cada una; ${n2} empaca ${nB} bolsas de ${frR(aB,dB)} kg. ¿Quién empacó más masa? Compruébalo con los dos productos.`},
5966        a:{en:`${mx(nA*aA,dA)} vs ${mx(nB*aB,dB)} kg — ${tA>tB?n1:n2}`,
5967           es:`${mx(nA*aA,dA)} vs ${mx(nB*aB,dB)} kg — ${tA>tB?n1:n2}`}
5968      };
5969    }
5970
5971    /* ---- On level · DOK 2 ---- */
5972    const k=ri(1,5);
5973    if(k===1){
5974      const a=ri(1,3), d=pick([4,8]), n=ri(3,6);
5975      return {
5976        q:{en:`Each bag of ${it.en} has a mass of ${frR(a,d)} kg. ${n1} carries ${n} bags. What is the total mass?`,
5977           es:`Cada bolsa de ${it.es} tiene una masa de ${frR(a,d)} kg. ${n1} lleva ${n} bolsas. ¿Cuál es la masa total?`},
5978        a:{en:`${n} × ${frR(a,d)} = ${mx(n*a,d)} kg`, es:`${n} × ${frR(a,d)} = ${mx(n*a,d)} kg`}
5979      };
5980    }
5981    if(k===2){
5982      const d=pick([3,4]), n=ri(3,6);
5983      return {
5984        q:{en:`${n1} gives each of ${n} classmates ${frR(1,d)} of a ${bin.one.en} of ${it.en}. How many whole ${bin.en} is that in all?`,
5985           es:`${n1} da a cada uno de ${n} compañeros ${frR(1,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es}. ¿Cuántas ${bin.es} enteras es en total?`},
5986        a:{en:`${n} × ${frR(1,d)} = ${mx(n,d)}`, es:`${n} × ${frR(1,d)} = ${mx(n,d)}`}
5987      };
5988    }
5989    if(k===3){
5990      const a=ri(2,3), d=4, n=ri(3,5);
5991      return {
5992        q:{en:`${n1} walks ${frR(a,d)} km to the ${it.en} stand every day for ${n} days. How far does ${n1} walk in all?`,
5993           es:`${n1} camina ${frR(a,d)} km al puesto de ${it.es} cada día durante ${n} días. ¿Cuánto camina en total?`},
5994        a:{en:`${n} × ${frR(a,d)} = ${mx(n*a,d)} km`, es:`${n} × ${frR(a,d)} = ${mx(n*a,d)} km`}
5995      };
5996    }
5997    if(k===4){
5998      const d=pick([2,4]), n=ri(4,8);
5999      return {
6000        q:{en:`A recipe for the ${it.en} sale uses ${frR(1,d)} cup of honey per batch. ${n1} makes ${n} batches. How many cups of honey are needed?`,
6001           es:`Una receta para la venta de ${it.es} usa ${frR(1,d)} taza de miel por tanda. ${n1} hace ${n} tandas. ¿Cuántas tazas de miel se necesitan?`},
6002        a:{en:`${n} × ${frR(1,d)} = ${mx(n,d)} cups`, es:`${n} × ${frR(1,d)} = ${mx(n,d)} tazas`}
6003      };
6004    }
6005    const a=ri(2,3), d=pick([4,8]), n=ri(3,6), tot=mx(n*a,d);
6006    return {
6007      q:{en:`${n1} fills ${n} jars, each with ${frR(a,d)} liter of juice, for the ${it.en} stand. How many liters is that altogether?`,
6008         es:`${n1} llena ${n} frascos, cada uno con ${frR(a,d)} litro de jugo, para el puesto de ${it.es}. ¿Cuántos litros son en total?`},
6009      a:{en:`${n} × ${frR(a,d)} = ${tot} liters`, es:`${n} × ${frR(a,d)} = ${tot} litros`}
6010    };
6011  }
6012},
6013{
6014  code:"4.NF.C.7", grade:4, dok:2,
6015  title:{en:"Compare decimals to hundredths",
6016         es:"Comparar decimales hasta centésimos"},
6017  text:{en:"Compare two decimals to hundredths by reasoning about their size. Recognize that comparisons are valid only when the two decimals refer to the same whole. Record the results of comparisons with the symbols >, =, or <, and justify the conclusions, e.g., by using a visual model.",
6018        es:"Compara dos decimales hasta centésimos razonando sobre su tamaño. Reconoce que las comparaciones son válidas solo cuando los dos decimales se refieren al mismo todo. Registra los resultados con los símbolos >, =, o <, y justifica las conclusiones, por ejemplo, usando un modelo visual."},
6019  build(n1,n2,lvl){
6020    const it = pickItem();
6021    const d2s = v => v.toFixed(2).replace(/0$/,"").replace(/\.$/,"");
6022
6023    /* ---- Support · DOK 1 : tenths, friendly ---- */
6024    if(lvl===1){
6025      const k=ri(1,4);
6026      if(k===1){
6027        const a=ri(2,8)/10, b=ri(2,8)/10;
6028        if(a===b) return this.build(n1,n2,lvl);
6029        return {
6030          q:{en:`${n1} jumped ${a} meters in the ${it.en} field day and ${n2} jumped ${b} meters. Who jumped farther? Write the comparison with > or <.`,
6031             es:`${n1} saltó ${a} metros en el día de campo de ${it.es} y ${n2} saltó ${b} metros. ¿Quién saltó más lejos? Escribe la comparación con > o <.`},
6032          a:{en:`${Math.max(a,b)} > ${Math.min(a,b)} — ${a>b?n1:n2}`, es:`${Math.max(a,b)} > ${Math.min(a,b)} — ${a>b?n1:n2}`}
6033        };
6034      }
6035      if(k===2){
6036        const a=ri(2,7)/10;
6037        return {
6038          q:{en:`${n1} says 0.${a*10}0 of the ${it.en} jar is full and ${n2} says ${a} is full. Are they saying the same amount? Explain with tenths and hundredths.`,
6039             es:`${n1} dice que 0.${a*10}0 del frasco de ${it.es} está lleno y ${n2} dice que ${a} está lleno. ¿Dicen la misma cantidad? Explica con décimos y centésimos.`},
6040          a:{en:`Yes — 0.${a*10}0 = ${a}`, es:`Sí — 0.${a*10}0 = ${a}`}
6041        };
6042      }
6043      if(k===3){
6044        const w=ri(1,3), a=w+ri(2,8)/10, b=w+ri(2,8)/10;
6045        if(a===b) return this.build(n1,n2,lvl);
6046        return {
6047          q:{en:`${n1}'s bag of ${it.en} has a mass of ${d2s(a)} kg and ${n2}'s has ${d2s(b)} kg. Whose bag is heavier? Use > or <.`,
6048             es:`La bolsa de ${it.es} de ${n1} tiene una masa de ${d2s(a)} kg y la de ${n2} tiene ${d2s(b)} kg. ¿Cuál bolsa pesa más? Usa > o <.`},
6049          a:{en:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`, es:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`}
6050        };
6051      }
6052      const t=ri(3,8), a=t/10, b=(t*10+ri(1,9))/100;
6053      return {
6054        q:{en:`Two ribbons for the ${it.en} display measure ${a} m and ${d2s(b)} m. ${n1} lines up the tenths digit first. Which ribbon is longer?`,
6055           es:`Dos cintas para la exhibición de ${it.es} miden ${a} m y ${d2s(b)} m. ${n1} alinea primero el dígito de los décimos. ¿Cuál cinta es más larga?`},
6056        a:{en:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))}`, es:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))}`}
6057      };
6058    }
6059
6060    /* ---- Challenge · DOK 3 : the longer-looks-bigger trap ---- */
6061    if(lvl===3){
6062      const k=ri(1,5);
6063      if(k===1){
6064        const a=ri(51,79)/100, bT=Math.floor(a*10)/10 + 0.1;
6065        const b=Math.round(bT*10)/10;
6066        return {
6067          q:{en:`${n2} says ${d2s(a)} > ${b} because ${Math.round(a*100)} is bigger than ${Math.round(b*10)}. Use place value to show why that reasoning fails, and write the true comparison.`,
6068             es:`${n2} dice que ${d2s(a)} > ${b} porque ${Math.round(a*100)} es más grande que ${Math.round(b*10)}. Usa el valor posicional para mostrar por qué falla ese razonamiento y escribe la comparación verdadera.`},
6069          a:{en:`${b} = ${Math.round(b*100)} hundredths — ${d2s(a)} < ${b}`,
6070             es:`${b} = ${Math.round(b*100)} centésimos — ${d2s(a)} < ${b}`}
6071        };
6072      }
6073      if(k===2){
6074        const a=(ri(11,14)*10+ri(1,9))/10, b=a-ri(3,9)/100;
6075        return {
6076          q:{en:`In the ${it.en} relay, ${n1} finished in ${d2s(b)} seconds and ${n2} in ${d2s(a)} seconds. ${n2} claims the bigger number wins. Who actually won, and why does smaller win here?`,
6077             es:`En el relevo de ${it.es}, ${n1} terminó en ${d2s(b)} segundos y ${n2} en ${d2s(a)} segundos. ${n2} dice que gana el número mayor. ¿Quién ganó en realidad y por qué aquí gana el menor?`},
6078          a:{en:`${n1} — less time is faster: ${d2s(b)} < ${d2s(a)}`,
6079             es:`${n1} — menos tiempo es más rápido: ${d2s(b)} < ${d2s(a)}`}
6080        };
6081      }
6082      if(k===3){
6083        const t=ri(3,7);
6084        return {
6085          q:{en:`${n1} filled 0.${t} of a small ${it.en} jar and ${n2} filled 0.${t} of a LARGE one. ${n2} says they filled equal amounts. What makes this comparison invali
6085d? Explain.`,
6086             es:`${n1} llenó 0.${t} de un frasco PEQUEÑO de ${it.es} y ${n2} llenó 0.${t} de uno GRANDE. ${n2} dice que llenaron cantidades iguales. ¿Por qué no es válida esta comparación? Explica.`},
6087          a:{en:`Decimals compare only with the SAME whole — the jars differ`,
6088             es:`Los decimales se comparan solo con el MISMO todo — los frascos son diferentes`}
6089        };
6090      }
6091      if(k===4){
6092        const a=ri(4,8)/10, b=(a*100-ri(2,8))/100;
6093        return {
6094          q:{en:`Name a decimal between ${d2s(b)} and ${a} for the mass of ${n1}'s ${it.one.en} in kg. Explain how you know it fits between them.`,
6095             es:`Nombra un decimal entre ${d2s(b)} y ${a} para la masa ${elLaEs(it)==="el"?"del":"de la"} ${it.one.es} de ${n1} en kg. Explica cómo sabes que queda entre los dos.`},
6096          a:{en:`e.g. ${d2s((a+b)/2)} — any value between ${d2s(b)} and ${a}`,
6097             es:`p. ej. ${d2s((a+b)/2)} — cualquier valor entre ${d2s(b)} y ${a}`}
6098        };
6099      }
6100      const a=ri(3,7)/10;
6101      return {
6102        q:{en:`${n1} wrote ${a} and ${n2} wrote ${d2s(a+0.00)}0. ${n2} insists the one with more digits is bigger. Prove with a model or place value whether they are equal.`,
6103           es:`${n1} escribió ${a} y ${n2} escribió ${d2s(a)}0. ${n2} insiste en que el de más dígitos es mayor. Demuestra con un modelo o el valor posicional si son iguales.`},
6104        a:{en:`${a} = ${d2s(a)}0 — trailing zeros add nothing`, es:`${a} = ${d2s(a)}0 — los ceros a la derecha no agregan nada`}
6105      };
6106    }
6107
6108    /* ---- On level · DOK 2 : hundredths ---- */
6109    const k=ri(1,5);
6110    if(k===1){
6111      const a=ri(20,90)/100, b=ri(20,90)/100;
6112      if(a===b) return this.build(n1,n2,lvl);
6113      return {
6114        q:{en:`${n1}'s ${it.one.en} has a mass of ${d2s(a)} kg and ${n2}'s has ${d2s(b)} kg. Compare with > or < and say whose is heavier.`,
6115           es:`${elLaEs(it)==="el"?"El":"La"} ${it.one.es} de ${n1} tiene una masa de ${d2s(a)} kg y ${elLaEs(it)} de ${n2} tiene ${d2s(b)} kg. Compara con > o < y di cuál pesa más.`},
6116        a:{en:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`, es:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`}
6117      };
6118    }
6119    if(k===2){
6120      const t=ri(3,8), a=t/10, b=(t*10-ri(2,8))/100;
6121      return {
6122        q:{en:`${n1} compares two paths at the ${it.en} fair: ${a} km and ${d2s(b)} km. Which is longer? Justify using tenths and hundredths.`,
6123           es:`${n1} compara dos senderos en la feria de ${it.es}: ${a} km y ${d2s(b)} km. ¿Cuál es más largo? Justifica usando décimos y centésimos.`},
6124        a:{en:`${a} = ${t*10} hundredths > ${Math.round(b*100)} — ${a} km is longer`,
6125           es:`${a} = ${t*10} centésimos > ${Math.round(b*100)} — ${a} km es más largo`}
6126      };
6127    }
6128    if(k===3){
6129      const a=(ri(10,13)*10+ri(1,9))/10, b=a+ri(2,9)/100;
6130      return {
6131        q:{en:`${n1} ran the ${it.en} dash in ${d2s(a)} seconds; ${n2} ran it in ${d2s(b)} seconds. Who was faster? Remember what a smaller time means.`,
6132           es:`${n1} corrió la carrera de ${it.es} en ${d2s(a)} segundos; ${n2} en ${d2s(b)} segundos. ¿Quién fue más rápido? Recuerda qué significa un tiempo menor.`},
6133        a:{en:`${d2s(a)} < ${d2s(b)} — ${n1} was faster`, es:`${d2s(a)} < ${d2s(b)} — ${n1} fue más rápido`}
6134      };
6135    }
6136    if(k===4){
6137      const a=ri(3,8)/10;
6138      return {
6139        q:{en:`${n1} poured ${a} liter of juice at the ${it.en} stand and ${n2} poured ${d2s(a)}0 liter. Compare the amounts with =, >, or <.`,
6140           es:`${n1} sirvió ${a} litro de jugo en el puesto de ${it.es} y ${n2} sirvió ${d2s(a)}0 litro. Compara las cantidades con =, > o <.`},
6141        a:{en:`${a} = ${d2s(a)}0`, es:`${a} = ${d2s(a)}0`}
6142      };
6143    }
6144    const a=ri(25,85)/100, b=ri(25,85)/100;
6145    if(Math.abs(a-b)<0.03) return this.build(n1,n2,lvl);
6146    return {
6147      q:{en:`${n1}'s vine grew ${d2s(a)} m and ${n2}'s grew ${d2s(b)} m by the ${it.en} contest. Write the comparison with a symbol and name the winner.`,
6148         es:`La planta de ${n1} creció ${d2s(a)} m y la de ${n2} creció ${d2s(b)} m para el concurso de ${it.es}. Escribe la comparación con un símbolo y nombra al ganador.`},
6149      a:{en:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`, es:`${d2s(Math.max(a,b))} > ${d2s(Math.min(a,b))} — ${a>b?n1:n2}`}
6150    };
6151  }
6152},
6153{
6154  code:"4.MD.A.3", grade:4, dok:2,
6155  title:{en:"Area & perimeter formulas",
6156         es:"Fórmulas de área y perímetro"},
6157  text:{en:"Apply the area and perimeter formulas for rectangles in real world and mathematical problems.",
6158        es:"Aplica las fórmulas de área y perímetro de rectángulos en problemas del mundo real y matemáticos."},
6159  build(n1,n2,lvl){
6160    const it = pickItem();
6161    const u = ITEMLOCK ? {en:"cm",es:"cm"} : pick([{en:"cm",es:"cm"},{en:"inches",es:"pulgadas"}]);
6162    const sq = {en:"square "+u.en, es:u.es+" cuadrados"};
6163
6164    /* ---- Support · DOK 1 : formula given ---- */
6165    if(lvl===1){
6166      const k=ri(1,4);
6167      if(k===1){
6168        const L=ri(5,10), W=ri(3,6);
6169        return {
6170          q:{en:`${n1}'s ${it.en} mat is ${L} ${u.en} by ${W} ${u.en}. Use A = l × w to find the area.`,
6171             es:`El tapete de ${it.es} de ${n1} mide ${L} por ${W} ${u.es}. Usa A = l × a para hallar el área.`},
6172          a:{en:`${L} × ${W} = ${L*W} ${sq.en}`, es:`${L} × ${W} = ${L*W} ${sq.es}`}
6173        };
6174      }
6175      if(k===2){
6176        const L=ri(5,10), W=ri(3,6);
6177        return {
6178          q:{en:`${n1}'s ${it.en} board is ${L} ${u.en} by ${W} ${u.en}. Use P = 2(l + w) to find the perimeter.`,
6179             es:`El tablero de ${it.es} de ${n1} mide ${L} por ${W} ${u.es}. Usa P = 2(l + a) para hallar el perímetro.`},
6180          a:{en:`2 × (${L} + ${W}) = ${2*(L+W)} ${u.en}`, es:`2 × (${L} + ${W}) = ${2*(L+W)} ${u.es}`}
6181        };
6182      }
6183      if(k===3){
6184        const s=ri(4,9);
6185        return {
6186          q:{en:`${n1}'s square ${it.en} card has ${s} ${u.en} sides. Find the area AND the perimeter.`,
6187             es:`La tarjeta cuadrada de ${it.es} de ${n1} tiene lados de ${s} ${u.es}. Halla el área Y el perímetro.`},
6188          a:{en:`area ${s*s} ${sq.en}; perimeter ${4*s} ${u.en}`, es:`área ${s*s} ${sq.es}; perímetro ${4*s} ${u.es}`}
6189        };
6190      }
6191      const L=ri(6,12), W=ri(2,4);
6192      return {
6193        q:{en:`${n1} is taping the edge of a ${L} by ${W} ${u.en} ${it.en} poster. How much tape is needed?`,
6194           es:`${n1} pega cinta en el borde de un cartel de ${it.es} de ${L} por ${W} ${u.es}. ¿Cuánta cinta necesita?`},
6195        a:{en:`2 × (${L} + ${W}) = ${2*(L+W)} ${u.en}`, es:`2 × (${L} + ${W}) = ${2*(L+W)} ${u.es}`}
6196      };
6197    }
6198
6199    /* ---- Challenge · DOK 3 : missing side, same area different perimeter ---- */
6200    if(lvl===3){
6201      const k=ri(1,4);
6202      if(k===1){
6203        const L=ri(6,14), W=ri(4,9), A=L*W;
6204        return {
6205          q:{en:`${n1}'s ${it.en} rug covers ${A} ${sq.en} and is ${L} ${u.en} long. Write an equation with n for the width, solve it, then find the perimeter.`,
6206             es:`El tapete de ${it.es} de ${n1} cubre ${A} ${sq.es} y mide ${L} ${u.es} de largo. Escribe una ecuación con n para el ancho, resuélvela y halla el perímetro.`},
6207          a:{en:`${L} × n = ${A}; n = ${W}; perimeter ${2*(L+W)} ${u.en}`,
6208             es:`${L} × n = ${A}; n = ${W}; perímetro ${2*(L+W)} ${u.es}`}
6209        };
6210      }
6211      if(k===2){
6212        const A=pick([24,36,48]);
6213        return {
6214          q:{en:`${n1} and ${n2} each make an ${it.en} banner with an area of ${A} ${sq.en}, but different perimeters. Give two rectangles that work and show why their perimeters differ.`,
6215             es:`${n1} y ${n2} hacen cada uno un cartel de ${it.es} con área de ${A} ${sq.es}, pero perímetros distintos. Da dos rectángulos que funcionen y muestra por qué difieren los perímetros.`},
6216          a:{en:`e.g. ${A/2}×2 (P=${2*(A/2+2)}) and ${A/4}×4 (P=${2*(A/4+4)}) — same area, different perimeter`,
6217             es:`p. ej. ${A/2}×2 (P=${2*(A/2+2)}) y ${A/4}×4 (P=${2*(A/4+4)}) — misma área, distinto perímetro`}
6218        };
6219      }
6220      if(k===3){
6221        const L=ri(7,14), W=ri(4,8);
6222        return {
6223          q:{en:`${n2} says the area of ${n1}'s ${L} by ${W} ${u.en} ${it.en} board is ${2*(L+W)} ${sq.en}. What did ${n2} calculate instead? Give the correct area.`,
6224             es:`${n2} dice que el área del tablero de ${it.es} de ${n1}, de ${L} por ${W} ${u.es}, es ${2*(L+W)} ${sq.es}. ¿Qué calculó en realidad? Da el área correcta.`},
6225          a:{en:`Calculated the perimeter — area is ${L}×${W} = ${L*W} ${sq.en}`,
6226             es:`Calculó el perímetro — el área es ${L}×${W} = ${L*W} ${sq.es}`}
6227        };
6228      }
6229      const P=pick([24,28,32,36]), W=ri(2,5), L=P/2-W;
6230      if(L<=W) return this.build(n1,n2,lvl);
6231      return {
6232        q:{en:`${n1} has ${P} ${u.en} of border for a rectangular ${it.en} sign that is ${W} ${u.en} wide. How long is it, and what area does it cover?`,
6233           es:`${n1} tiene ${P} ${u.es} de borde para un letrero rectangular de ${it.es} de ${W} ${u.es} de ancho. ¿Cuánto mide de largo y qué área cubre?`},
6234        a:{en:`${P}÷2−${W} = ${L} ${u.en}; area ${L*W} ${sq.en}`,
6235           es:`${P}÷2−${W} = ${L} ${u.es}; área ${L*W} ${sq.es}`}
6236      };
6237    }
6238
6239    /* ---- On level · DOK 2 ---- */
6240    const k=ri(1,4);
6241    if(k===1){
6242      const L=ri(8,20), W=ri(4,12);
6243      return {
6244        q:{en:`${n1}'s rectangular ${it.en} table is ${L} ${u.en} by ${W} ${u.en}. Find the area and the perimeter.`,
6245           es:`La mesa rectangular de ${it.es} de ${n1} mide ${L} por ${W} ${u.es}. Halla el área y el perímetro.`},
6246        a:{en:`area ${L*W} ${sq.en}; perimeter ${2*(L+W)} ${u.en}`, es:`área ${L*W} ${sq.es}; perímetro ${2*(L+W)} ${u.es}`}
6247      };
6248    }
6249    if(k===2){
6250      const L=ri(6,15), W=ri(4,10), A=L*W;
6251      return {
6252        q:{en:`A ${it.en} poster of ${n1}'s covers ${A} ${sq.en} and is ${W} ${u.en} wide. How long is it?`,
6253           es:`Un cartel de ${it.es} de ${n1} cubre ${A} ${sq.es} y mide ${W} ${u.es} de ancho. ¿Cuánto mide de largo?`},
6254        a:{en:`${A} ÷ ${W} = ${L} ${u.en}`, es:`${A} ÷ ${W} = ${L} ${u.es}`}
6255      };
6256    }
6257    if(k===3){
6258      const L=ri(8,16), W=ri(5,12), P=2*(L+W);
6259      return {
6260        q:{en:`${n1}'s ${it.en} garden has a perimeter of ${P} ${u.en} and is ${L} ${u.en} long. How wide is it? What is the area?`,
6261           es:`El jardín de ${it.es} de ${n1} tiene un perímetro de ${P} ${u.es} y mide ${L} ${u.es} de largo. ¿Cuánto mide de ancho? ¿Cuál es el área?`},
6262        a:{en:`${P}÷2−${L} = ${W} ${u.en}; area ${L*W} ${sq.en}`, es:`${P}÷2−${L} = ${W} ${u.es}; área ${L*W} ${sq.es}`}
6263      };
6264    }
6265    const L1=ri(6,14), W1=ri(4,9), L2=ri(6,14), W2=ri(4,9);
6266    if(L1*W1===L2*W2) return this.build(n1,n2,lvl);
6267    return {
6268      q:{en:`${n1}'s ${it.en} mat is ${L1} by ${W1} ${u.en}; ${n2}'s is ${L2} by ${W2} ${u.en}. Whose mat covers more area, and by how much?`,
6269         es:`El tapete de ${it.es} de ${n1} mide ${L1} por ${W1} ${u.es}; el de ${n2} mide ${L2} por ${W2} ${u.es}. ¿Cuál cubre más área y por cuánto?`},
6270      a:{en:`${L1*W1} vs ${L2*W2} — ${L1*W1>L2*W2?n1:n2} by ${Math.abs(L1*W1-L2*W2)} ${sq.en}`,
6271         es:`${L1*W1} vs ${L2*W2} — ${L1*W1>L2*W2?n1:n2} por ${Math.abs(L1*W1-L2*W2)} ${sq.es}`}
6272    };
6273  }
6274},
6275{
6276  code:"4.MD.A.2", grade:4, dok:3,
6277  title:{en:"Measurement word problems — time, money & distance",
6278         es:"Problemas de medición — tiempo, dinero y distancia"},
6279  text:{en:"Use the four operations to solve word problems involving distances, intervals of time, liquid volumes, masses of objects, and money, including problems involving simple fractions or decimals, and problems that require expressing measurements given in a larger unit in terms of a smaller unit. Represent measurement quantities using diagrams such as number line diagrams that feature a measurement scale.",
6280        es:"Usa las cuatro operaciones para resolver problemas verbales de distancias, intervalos de tiempo, volúmenes líquidos, masas de objetos y dinero, incluyendo problemas con fracciones simples o decimales, y problemas que requieren expresar medidas dadas en una unidad mayor en términos de una unidad menor. Representa cantidades de medición usando diagramas como rectas numéricas con escala."},
6281  build(n1,n2,lvl){
6282    const it = pickItem();
6283    let it2 = pick(THEME.items);
6284    while(it2.en===it.en) it2 = pick(THEME.items);
6285
6286    /* ---- Support · DOK 1 ---- */
6287    if(lvl===1){
6288      const k=ri(1,4);
6289      if(k===1){
6290        const h=ri(1,11), dur=pick([30,60]);
6291        return {
6292          q:{en:`${n1}'s ${it.en} project started at ${clk(h,0)} and took ${dur} minutes. What time did it end?`,
6293             es:`El proyecto de ${it.es} de ${n1} empezó a las ${clk(h,0)} y duró ${dur} minutos. ¿A qué hora terminó?`},
6294          a:{en:addMin(h,0,dur), es:addMin(h,0,dur)}
6295        };
6296      }
6297      if(k===2){
6298        const x=priceOf(it), y=priceOf(it2);
6299        return {
6300          q:{en:`${n1} bought one ${it.one.en} for ${money(x)} and one ${it2.one.en} for ${money(y)}. How much did ${n1} spend?`,
6301             es:`${n1} compró ${unUnaEs(it)} ${it.one.es} por ${dinero(x)} y ${unUnaEs(it2)} ${it2.one.es} por ${dinero(y)}. ¿Cuánto gastó?`},
6302          a:{en:money(x+y), es:dinero(x+y)}
6303        };
6304      }
6305      if(k===3){
6306        const a=ri(2,6), b=ri(2,5);
6307        return {
6308          q:{en:`${n1} walked ${a} kilometers to the ${it.en} fair and ${b} kilometers back home. How far did ${n1} walk in all?`,
6309             es:`${n1} caminó ${a} kilómetros a la feria de ${it.es} y ${b} kilómetros de regreso. ¿Cuánto caminó en total?`},
6310          a:{en:`${a} + ${b} = ${a+b} km`, es:`${a} + ${b} = ${a+b} km`}
6311        };
6312      }
6313      const h=ri(1,10), m=pick([15,30]);
6314      return {
6315        q:{en:`${n1} started sorting ${it.en} at ${clk(h,m)} and finished ${30} minutes later. What time did ${n1} finish?`,
6316           es:`${n1} empezó a ordenar ${it.es} a las ${clk(h,m)} y terminó ${30} minutos después. ¿A qué hora terminó?`},
6317        a:{en:addMin(h,m,30), es:addMin(h,m,30)}
6318      };
6319    }
6320
6321    /* ---- Challenge · DOK 3 ---- */
6322    if(lvl===3){
6323      const k=ri(1,5);
6324      if(k===1){
6325        const x=priceOf(it), qty=ri(3,6);
6326        const budget=Math.round((x*qty+ri(200,800)/100)*100)/100;
6327        return {
6328          q:{en:`${n1} has ${money(budget)} and buys ${qty} ${it.en} at ${money(x)} each. ${n2} says the change is ${money(budget-x)}. What did ${n2} forget? Give the correct change.`,
6329             es:`${n1} tiene ${dinero(budget)} y compra ${qty} ${it.es} a ${dinero(x)} cada ${unoEs(it)}. ${n2} dice que el cambio es ${dinero(budget-x)}. ¿Qué olvidó ${n2}? Da el cambio correcto.`},
6330          a:{en:`Forgot to multiply by ${qty} — ${money(budget)}−${money(x*qty)}=${money(budget-x*qty)}`,
6331             es:`Olvidó multiplicar por ${qty} — ${dinero(budget)}−${dinero(x*qty)}=${dinero(budget-x*qty)}`}
6332        };
6333      }
6334      if(k===2){
6335        const h=ri(1,9), m=pick([15,30,45]), dur=pick([50,70,80,95]);
6336        const deadlineMin = (h*60+m) + dur + (ri(0,1)? 10 : -10);
6337        const dh=Math.floor(deadlineMin/60), dm=deadlineMin%60;
6338        const makes = (h*60+m+dur) <= deadlineMin;
6339        return {
6340          q:{en:`${n1}'s ${it.en} practice starts at ${clk(h,m)} and lasts ${dur} minutes. ${n1} must be home by ${clk(dh,dm)}. Will ${n1} make it? Show the end time and explain.`,
6341             es:`La práctica de ${it.es} de ${n1} empieza a las ${clk(h,m)} y dura ${dur} minutos. ${n1} debe estar en casa a las ${clk(dh,dm)}. ¿Llegará a tiempo? Muestra la hora final y explica.`},
6342          a:{en:`Ends ${addMin(h,m,dur)} — ${makes?"yes, makes it":"no, too late"}`,
6343             es:`Termina ${addMin(h,m,dur)} — ${makes?"sí llega":"no, llega tarde"}`}
6344        };
6345      }
6346      if(k===3){
6347        const leg=ri(3,8), days=ri(3,5);
6348        return {
6349          q:{en:`${n1} bikes ${leg} km to ${it.en} practice and ${leg} km back, ${days} days this week. How many kilometers in all? Show the steps you used.`,
6350             es:`${n1} va en bici ${leg} km a la práctica de ${it.es} y ${leg} km de regreso, ${days} días esta semana. ¿Cuántos kilómetros en total? Muestra tus pasos.`},
6351          a:{en:`${leg}×2=${leg*2} per day, ×${days} = ${leg*2*days} km`,
6352             es:`${leg}×2=${leg*2} por día, ×${days} = ${leg*2*days} km`}
6353        };
6354      }
6355      if(k===4){
6356        const w=pick([[1,2],[3,4],[1,4]]), n=w[0], d=w[1], count=d*ri(2,4);
6357        return {
6358          q:{en:`Each bag of ${it.en} has a mass of ${frR(n,d)} kg. ${n1} packs ${count} bags. What is the total mass in kg? Explain how you multiplied the fraction.`,
6359             es:`Cada bolsa de ${it.es} tiene una masa de ${frR(n,d)} kg. ${n1} empaca ${count} bolsas. ¿Cuál es la masa total en kg? Explica cómo multiplicaste la fracción.`},
6360          a:{en:`${count} × ${frR(n,d)} = ${mx(count*n,d)} kg`, es:`${count} × ${frR(n,d)} = ${mx(count*n,d)} kg`}
6361        };
6362      }
6363      const h=ri(2,10), endM=pick([0,15,30]), dur=pick([45,70,90]);
6364      const startTotal=h*60+endM;
6365      return {
6366        q:{en:`${n1} finished the ${it.en} tournament at ${clk(h,endM)}. It lasted ${dur} minutes. Write an equation with n for the start time in minutes, then give the start time on the clock.`,
6367           es:`${n1} terminó el torneo de ${it.es} a las ${clk(h,endM)}. Duró ${dur} minutos. Escribe una ecuación con n para la hora de inicio en minutos y da la hora en el reloj.`},
6368        a:{en:`n + ${dur} = end; start ${addMin(h,endM,-dur)}`, es:`n + ${dur} = final; empezó ${addMin(h,endM,-dur)}`}
6369      };
6370    }
6371
6372    /* ---- On level · DOK 2 ---- */
6373    const k=ri(1,5);
6374    if(k===1){
6375      const h=ri(1,10), m=pick([10,15,20,25]), dur=pick([35,45,50,55]);
6376      return {
6377        q:{en:`${n1}'s ${it.en} club meeting started at ${clk(h,m)} and lasted ${dur} minutes. What time did it end?`,
6378           es:`La reunión del club de ${it.es} de ${n1} empezó a las ${clk(h,m)} y duró ${dur} minutos. ¿A qué hora terminó?`},
6379        a:{en:addMin(h,m,dur), es:addMin(h,m,dur)}
6380      };
6381    }
6382    if(k===2){
6383      const x=priceOf(it), qty=ri(3,7);
6384      const budget=Math.round((x*qty+ri(150,700)/100)*100)/100;
6385      return {
6386        q:{en:`${n1} has ${money(budget)}
6386 and buys ${qty} ${it.en} at ${money(x)} each. How much money is left?`,
6387           es:`${n1} tiene ${dinero(budget)} y compra ${qty} ${it.es} a ${dinero(x)} cada ${unoEs(it)}. ¿Cuánto dinero le queda?`},
6388        a:{en:`${money(budget)} − ${money(x*qty)} = ${money(budget-x*qty)}`,
6389           es:`${dinero(budget)} − ${dinero(x*qty)} = ${dinero(budget-x*qty)}`}
6390      };
6391    }
6392    if(k===3){
6393      const a=ri(4,9), b=ri(3,8), c=ri(2,7);
6394      return {
6395        q:{en:`On a trip to the ${it.en} festival, ${n1} rode ${a} km, walked ${b} km, and rode ${c} km more. How many kilometers was the trip?`,
6396           es:`En un viaje al festival de ${it.es}, ${n1} recorrió ${a} km, caminó ${b} km y recorrió ${c} km más. ¿Cuántos kilómetros fue el viaje?`},
6397        a:{en:`${a}+${b}+${c} = ${a+b+c} km`, es:`${a}+${b}+${c} = ${a+b+c} km`}
6398      };
6399    }
6400    if(k===4){
6401      const h1=ri(1,9), dur=pick([40,65,75,85]);
6402      const m1=pick([5,10,20]);
6403      return {
6404        q:{en:`${n1} started the ${it.en} drive at ${clk(h1,m1)} and arrived at ${addMin(h1,m1,dur)}. How many minutes did the drive take?`,
6405           es:`${n1} empezó el viaje de ${it.es} a las ${clk(h1,m1)} y llegó a las ${addMin(h1,m1,dur)}. ¿Cuántos minutos duró el viaje?`},
6406        a:{en:`${dur} minutes`, es:`${dur} minutos`}
6407      };
6408    }
6409    const each=ri(2,4), n=ri(3,6), gave=ri(2,each*n-2);   // >=2 so "liters" stays plural
6410    return {
6411      q:{en:`${n1} filled ${n} jugs with ${each} liters of water each for the ${it.en} stand, then used ${gave} liters. How many liters are left?`,
6412         es:`${n1} llenó ${n} jarras con ${each} litros de agua cada una para el puesto de ${it.es} y luego usó ${gave} litros. ¿Cuántos litros quedan?`},
6413      a:{en:`${n}×${each}=${n*each}, −${gave} = ${n*each-gave} liters`,
6414         es:`${n}×${each}=${n*each}, −${gave} = ${n*each-gave} litros`}
6415    };
6416  }
6417},
6418{
6419  code:"5.OA.A.2", grade:5, dok:3,
6420  title:{en:"Write & interpret numerical expressions",
6421         es:"Escribir e interpretar expresiones numéricas"},
6422  text:{en:"Write simple expressions that record calculations with numbers, and interpret numerical expressions without evaluating them.",
6423        es:"Escribe expresiones simples que registren cálculos con números, e interpreta expresiones numéricas sin evaluarlas."},
6424  build(n1,n2,lvl){
6425    const it = pickItem(), bin = pick(THEME.bins);
6426
6427    /* ---- Support · DOK 1 : write the expression ---- */
6428    if(lvl===1){
6429      const k=ri(1,4);
6430      if(k===1){
6431        const a=ri(4,12), b=ri(3,9);
6432        return {
6433          q:{en:`${n1} had ${a} ${it.en} and got ${b} more. Write an expression for how many ${it.en} ${n1} has. (Do not solve it.)`,
6434             es:`${n1} tenía ${a} ${it.es} y recibió ${b} más. Escribe una expresión para ${cuantosLc(it)} ${it.es} tiene. (No la resuelvas.)`},
6435          a:{en:`${a} + ${b}`, es:`${a} + ${b}`}
6436        };
6437      }
6438      if(k===2){
6439        const groups=ri(3,7), per=ri(4,9);
6440        return {
6441          q:{en:`${n1} filled ${groups} ${bin.en} with ${per} ${it.en} each. Write an expression for the total.`,
6442             es:`${n1} llenó ${groups} ${bin.es} con ${per} ${it.es} cada ${unoEs(bin)}. Escribe una expresión para el total.`},
6443          a:{en:`${groups} × ${per}`, es:`${groups} × ${per}`}
6444        };
6445      }
6446      if(k===3){
6447        const a=ri(15,40), b=ri(5,12);
6448        return {
6449          q:{en:`${n1} had ${a} ${it.en} and gave ${b} to ${n2}. Write an expression for how many are left.`,
6450             es:`${n1} tenía ${a} ${it.es} y le dio ${b} a ${n2}. Escribe una expresión para ${losLasEs(it)} que quedan.`},
6451          a:{en:`${a} − ${b}`, es:`${a} − ${b}`}
6452        };
6453      }
6454      const tot=ri(4,9)*ri(3,6), share=ri(3,6);
6455      return {
6456        q:{en:`${n1} shared ${tot} ${it.en} equally among ${share} friends. Write an expression for how many each friend gets.`,
6457           es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${share} amigos. Escribe una expresión para ${cuantosLc(it)} recibe cada amigo.`},
6458        a:{en:`${tot} ÷ ${share}`, es:`${tot} ÷ ${share}`}
6459      };
6460    }
6461
6462    /* ---- Challenge · DOK 3 : interpret WITHOUT evaluating ---- */
6463    if(lvl===3){
6464      const k=ri(1,5);
6465      if(k===1){
6466        const a=ri(20,60), f=ri(2,5);
6467        return {
6468          q:{en:`${n1} has ${a} ${it.en}. Without calculating, explain how ${f} × (${a} + ${ri(5,15)}) compares to ${a} + ${ri(5,15)}. What does the ${f} do to the amount?`,
6469             es:`${n1} tiene ${a} ${it.es}. Sin calcular, explica cómo se compara ${f} × (${a} + ${ri(5,15)}) con ${a} + ${ri(5,15)}. ¿Qué le hace el ${f} a la cantidad?`},
6470          a:{en:`${f} times as large — the whole sum is multiplied, not just part`,
6471             es:`${f} veces más grande — se multiplica toda la suma, no solo una parte`}
6472        };
6473      }
6474      if(k===2){
6475        const a=ri(12,30), b=ri(5,15), c=ri(2,6);
6476        return {
6477          q:{en:`${n1} wrote (${a} + ${b}) × ${c} and ${n2} wrote ${a} + ${b} × ${c} for the same ${it.en} problem. Without solving, explain why these give different answers and which one means "add first, then multiply."`,
6478             es:`${n1} escribió (${a} + ${b}) × ${c} y ${n2} escribió ${a} + ${b} × ${c} para el mismo problema de ${it.es}. Sin resolver, explica por qué dan resultados distintos y cuál significa "suma primero, luego multiplica."`},
6479          a:{en:`Parentheses group the addition — ${n1}'s adds first`,
6480             es:`Los paréntesis agrupan la suma — la de ${n1} suma primero`}
6481        };
6482      }
6483      if(k===3){
6484        const groups=ri(4,9), per=ri(6,14), extra=ri(5,20);
6485        return {
6486          q:{en:`${n1} filled ${groups} ${bin.en} with ${per} ${it.en} each, then found ${extra} more. Write one expression for the total, then write a second expression for twice that many — without multiplying anything out.`,
6487             es:`${n1} llenó ${groups} ${bin.es} con ${per} ${it.es} cada ${unoEs(bin)} y luego encontró ${extra} más. Escribe una expresión para el total y otra para el doble — sin multiplicar nada.`},
6488          a:{en:`(${groups} × ${per}) + ${extra}; then 2 × ((${groups} × ${per}) + ${extra})`,
6489             es:`(${groups} × ${per}) + ${extra}; luego 2 × ((${groups} × ${per}) + ${extra})`}
6490        };
6491      }
6492      if(k===4){
6493        const a=ri(30,80), b=ri(10,25);
6494        return {
6495          q:{en:`${n2} says ${a} − ${b} and ${b} − ${a} mean the same thing for the ${it.en} count. Without calculating, explain why order matters in subtraction but not in addition.`,
6496             es:`${n2} dice que ${a} − ${b} y ${b} − ${a} significan lo mismo para el conteo de ${it.es}. Sin calcular, explica por qué el orden importa en la resta pero no en la suma.`},
6497          a:{en:`Subtraction is not commutative — one takes from ${a}, the other from ${b}`,
6498             es:`La resta no es conmutativa — una quita de ${a}, la otra de ${b}`}
6499        };
6500      }
6501      const a=ri(15,40), b=ri(4,9);
6502      return {
6503        q:{en:`Look at ${b} × (${a} + 3) for ${n1}'s ${it.en}. Without evaluating, describe in words what the expression tells you to do, and say how the answer compares to ${b} × ${a}.`,
6504           es:`Mira ${b} × (${a} + 3) para ${losLasEs(it)} ${it.es} de ${n1}. Sin resolver, describe en palabras qué indica hacer la expresión y di cómo se compara con ${b} × ${a}.`},
6505        a:{en:`Add 3 first, then take ${b} groups — it is ${b}×3 = ${b*3} more than ${b} × ${a}`,
6506           es:`Suma 3 primero, luego toma ${b} grupos — es ${b}×3 = ${b*3} más que ${b} × ${a}`}
6507      };
6508    }
6509
6510    /* ---- On level · DOK 2 : two-step expressions with grouping ---- */
6511    const k=ri(1,5);
6512    if(k===1){
6513      const groups=ri(4,9), per=ri(6,14), extra=ri(5,20);
6514      return {
6515        q:{en:`${n1} filled ${groups} ${bin.en} with ${per} ${it.en} each, then added ${extra} more. Write an expression for the total number of ${it.en}.`,
6516           es:`${n1} llenó ${groups} ${bin.es} con ${per} ${it.es} cada ${unoEs(bin)} y luego agregó ${extra} más. Escribe una expresión para el total de ${it.es}.`},
6517        a:{en:`(${groups} × ${per}) + ${extra}`, es:`(${groups} × ${per}) + ${extra}`}
6518      };
6519    }
6520    if(k===2){
6521      const a=ri(20,50), b=ri(8,18), c=ri(2,5);
6522      return {
6523        q:{en:`${n1} had ${a} ${it.en}, gave ${b} to ${n2}, then split what was left into ${c} equal piles. Write an expression for the size of one pile.`,
6524           es:`${n1} tenía ${a} ${it.es}, le dio ${b} a ${n2} y dividió el resto en ${c} montones iguales. Escribe una expresión para el tamaño de un montón.`},
6525        a:{en:`(${a} − ${b}) ÷ ${c}`, es:`(${a} − ${b}) ÷ ${c}`}
6526      };
6527    }
6528    if(k===3){
6529      const a=ri(10,30), b=ri(5,15), c=ri(2,6);
6530      return {
6531        q:{en:`Read this expression about ${n1}'s ${it.en}: (${a} + ${b}) × ${c}. Describe in words what it says to do, in order. Do not calculate.`,
6532           es:`Lee esta expresión sobre ${losLasEs(it)} ${it.es} de ${n1}: (${a} + ${b}) × ${c}. Describe en palabras qué indica hacer, en orden. No calcules.`},
6533        a:{en:`Add ${a} and ${b} first, then multiply that sum by ${c}`,
6534           es:`Suma ${a} y ${b} primero, luego multiplica esa suma por ${c}`}
6535      };
6536    }
6537    if(k===4){
6538      const per=ri(8,20), groups=ri(3,7);
6539      return {
6540        q:{en:`${n1} has ${per} ${it.en} and ${n2} has ${groups} times as many. Write an expression for how many ${n2} has, and one for how many they have together.`,
6541           es:`${n1} tiene ${per} ${it.es} y ${n2} tiene ${groups} veces esa cantidad. Escribe una expresión para ${losLasEs(it)} de ${n2} y otra para el total de los dos.`},
6542        a:{en:`${groups} × ${per}; and ${per} + (${groups} × ${per})`,
6543           es:`${groups} × ${per}; y ${per} + (${groups} × ${per})`}
6544      };
6545    }
6546    const a=ri(25,60), b=ri(6,15);
6547    return {
6548      q:{en:`${n1} wrote 3 × (${a} − ${b}) for the ${it.en} problem. Without solving, explain what happens first and what the 3 is multiplying.`,
6549         es:`${n1} escribió 3 × (${a} − ${b}) para el problema de ${it.es}. Sin resolver, explica qué pasa primero y qué está multiplicando el 3.`},
6550      a:{en:`Subtract inside the parentheses first; the 3 multiplies that difference`,
6551         es:`Primero la resta dentro del paréntesis; el 3 multiplica esa diferencia`}
6552    };
6553  }
6554},
6555{
6556  code:"5.NBT.A.3", grade:5, dok:2,
6557  title:{en:"Read, write & compare decimals to thousandths",
6558         es:"Leer, escribir y comparar decimales hasta milésimos"},
6559  text:{en:"Read, write, and compare decimals to thousandths. Read and write decimals to thousandths using base-ten numerals, number names, and expanded form. Compare two decimals to thousandths based on meanings of the digits in each place, using >, =, and < symbols to record the results of comparisons.",
6560        es:"Lee, escribe y compara decimales hasta milésimos. Lee y escribe decimales usando numerales de base diez, nombres de números y forma desarrollada. Compara dos decimales hasta milésimos según el significado de los dígitos en cada posición, usando los símbolos >, = y <."},
6561  build(n1,n2,lvl){
6562    const it = pickItem();
6563    const d3 = v => v.toFixed(3).replace(/0+$/,"").replace(/\.$/,".0");
6564
6565    /* ---- Support · DOK 1 : tenths and hundredths ---- */
6566    if(lvl===1){
6567      const k=ri(1,4);
6568      if(k===1){
6569        const a=ri(20,90)/100, b=ri(20,90)/100;
6570        if(a===b) return this.build(n1,n2,lvl);
6571        return {
6572          q:{en:`${n1}'s ${it.one.en} has a mass of ${a.toFixed(2)} kg and ${n2}'s has ${b.toFixed(2)} kg. Which is heavier? Use > or <.`,
6573             es:`${elLaEs(it)==="el"?"El":"La"} ${it.one.es} de ${n1} tiene una masa de ${a.toFixed(2)} kg y ${elLaEs(it)} de ${n2} tiene ${b.toFixed(2)} kg. ¿Cuál pesa más? Usa > o <.`},
6574          a:{en:`${Math.max(a,b).toFixed(2)} > ${Math.min(a,b).toFixed(2)} — ${a>b?n1:n2}`,
6575             es:`${Math.max(a,b).toFixed(2)} > ${Math.min(a,b).toFixed(2)} — ${a>b?n1:n2}`}
6576        };
6577      }
6578      if(k===2){
6579        const t=ri(2,8);
6580        return {
6581          q:{en:`${n1} measured ${(t/10).toFixed(1)} liters of juice for the ${it.en} stand. Write that as hundredths and as thousandths.`,
6582             es:`${n1} midió ${(t/10).toFixed(1)} litros de jugo para el puesto de ${it.es}. Escríbelo en centésimos y en milésimos.`},
6583          a:{en:`${(t/10).toFixed(2)} and ${(t/10).toFixed(3)}`, es:`${(t/10).toFixed(2)} y ${(t/10).toFixed(3)}`}
6584        };
6585      }
6586      if(k===3){
6587        const w=ri(1,4), h=ri(10,99);
6588        return {
6589          q:{en:`${n1}'s bag of ${it.en} weighs ${(w + h/100).toFixed(2)} kg. Write the value of the digit in the hundredths place.`,
6590             es:`La bolsa de ${it.es} de ${n1} pesa ${(w + h/100).toFixed(2)} kg. Escribe el valor del dígito en el lugar de los centésimos.`},
6591          a:{en:`${h%10} hundredths = ${(h%10/100).toFixed(2)}`, es:`${h%10} centésimos = ${(h%10/100).toFixed(2)}`}
6592        };
6593      }
6594      const a=ri(3,8)/10;
6595      return {
6596        q:{en:`${n1} says ${a.toFixed(1)} and ${a.toFixed(2)} of a ${it.one.en} are the same amount. Is ${n1} right? Explain.`,
6597           es:`${n1} dice que ${a.toFixed(1)} y ${a.toFixed(2)} de ${unUnaEs(it)} ${it.one.es} son la misma cantidad. ¿Tiene razón? Explica.`},
6598        a:{en:`Yes — ${a.toFixed(1)} = ${a.toFixed(2)}`, es:`Sí — ${a.toFixed(1)} = ${a.toFixed(2)}`}
6599      };
6600    }
6601
6602    /* ---- Challenge · DOK 3 : the digit-count trap, ordering ---- */
6603    if(lvl===3){
6604      const k=ri(1,4);
6605      if(k===1){
6606        const big=ri(4,8)/10, small=(big*100 - ri(2,9))/1000;
6607        return {
6608          q:{en:`${n2} says ${small.toFixed(3)} kg is more than ${big.toFixed(1)} kg because it has more digits. Compare the ${it.en} masses using place value and explain why ${n2} is wrong.`,
6609             es:`${n2} dice que ${small.toFixed(3)} kg es más que ${big.toFixed(1)} kg porque tiene más dígitos. Compara las masas de ${it.es} usando el valor posicional y explica por qué se equivoca.`},
6610          a:{en:`${big.toFixed(3)} > ${small.toFixed(3)} — more digits does not mean larger`,
6611             es:`${big.toFixed(3)} > ${small.toFixed(3)} — más dígitos no significa mayor`}
6612        };
6613      }
6614      if(k===2){
6615        const a=ri(200,900)/1000, b=ri(2,9)/10, c=ri(20,90)/100;
6616        const arr=[[a,"A"],[b,"B"],[c,"C"]].sort((x,y)=>x[0]-y[0]);
6617        return {
6618          q:{en:`${n1} recorded three ${it.en} masses: A = ${a.toFixed(3)} kg, B = ${b.toFixed(1)} kg, C = ${c.toFixed(2)} kg. Put them in order from least to greatest. Show how you lined up the places.`,
6619             es:`${n1} anotó tres masas de ${it.es}: A = ${a.toFixed(3)} kg, B = ${b.toFixed(1)} kg, C = ${c.toFixed(2)} kg. Ponlas en orden de menor a mayor. Muestra cómo alineaste las posiciones.`},
6620          a:{en:arr.map(x=>x[1]+" ("+x[0].toFixed(3)+")").join(" < "),
6621             es:arr.map(x=>x[1]+" ("+x[0].toFixed(3)+")").join(" < ")}
6622        };
6623      }
6624      if(k===3){
6625        const lo=ri(30,60)/100, hi=lo+ri(2,8)/100;
6626        return {
6627          q:{en:`Name a decimal between ${lo.toFixed(2)} and ${hi.toFixed(2)} for the mass of ${n1}'s ${it.one.en}. Explain how you know it fits between them.`,
6628             es:`Nombra un decimal entre ${lo.toFixed(2)} y ${hi.toFixed(2)} para la masa ${elLaEs(it)==="el"?"del":"de la"} ${it.one.es} de ${n1}. Explica cómo sabes que queda entre los dos.`},
6629          a:{en:`e.g. ${((lo+hi)/2).toFixed(3)} — any value between them`,
6630             es:`p. ej. ${((lo+hi)/2).toFixed(3)} — cualquier valor entre los dos`}
6631        };
6632      }
6633      const w=ri(1,5), t=ri(1,9), h=ri(0,9), th=ri(1,9);
6634      const val = w + t/10 + h/100 + th/1000;
6635      return {
6636        q:{en:`${n1} wrote the ${it.en} weight as ${val.toFixed(3)} kg. Write it in expanded form and say the value of the thousandths digit.`,
6637           es:`${n1} escribió el peso de ${it.es} como ${val.toFixed(3)} kg. Escríbelo en forma desarrollada y di el valor del dígito de los milésimos.`},
6638        a:{en:`${w} + ${(t/10).toFixed(1)} + ${(h/100).toFixed(2)} + ${(th/1000).toFixed(3)}; thousandths = ${th}`,
6639           es:`${w} + ${(t/10).toFixed(1)} + ${(h/100).toFixed(2)} + ${(th/1000).toFixed(3)}; milésimos = ${th}`}
6640      };
6641    }
6642
6643    /* ---- On level · DOK 2 : thousandths ---- */
6644    const k=ri(1,4);
6645    if(k===1){
6646      const a=ri(200,900)/1000, b=ri(200,900)/1000;
6647      if(a===b) return this.build(n1,n2,lvl);
6648      return {
6649        q:{en:`${n1}'s ${it.one.en} weighs ${a.toFixed(3)} kg and ${n2}'s weighs ${b.toFixed(3)} kg. Compare with > or < and say whose is heavier.`,
6650           es:`${elLaEs(it)==="el"?"El":"La"} ${it.one.es} de ${n1} pesa ${a.toFixed(3)} kg y ${elLaEs(it)} de ${n2} pesa ${b.toFixed(3)} kg. Compara con > o < y di cuál pesa más.`},
6651        a:{en:`${Math.max(a,b).toFixed(3)} > ${Math.min(a,b).toFixed(3)} — ${a>b?n1:n2}`,
6652           es:`${Math.max(a,b).toFixed(3)} > ${Math.min(a,b).toFixed(3)} — ${a>b?n1:n2}`}
6653      };
6654    }
6655    if(k===2){
6656      const t=ri(2,9)/10, h=(t*100 - ri(1,9))/100;
6657      return {
6658        q:{en:`Two ${it.en} measure ${t.toFixed(1)} m and ${h.toFixed(2)} m. Which is longer? Justify using tenths and hundredths for ${n1}.`,
6659           es:`Dos ${it.es} miden ${t.toFixed(1)} m y ${h.toFixed(2)} m. ¿Cuál es más largo? Justifica usando décimos y centésimos para ${n1}.`},
6660        a:{en:`${t.toFixed(2)} > ${h.toFixed(2)} — the ${t.toFixed(1)} m one`,
6661           es:`${t.toFixed(2)} > ${h.toFixed(2)} — el de ${t.toFixed(1)} m`}
6662      };
6663    }
6664    if(k===3){
6665      const w=ri(1,6), t=ri(1,9), h=ri(0,9), th=ri(1,9);
6666      const val = w + t/10 + h/100 + th/1000;
6667      return {
6668        q:{en:`${n1} recorded ${val.toFixed(3)} kg of ${it.en}. Write this decimal in words.`,
6669           es:`${n1} anotó ${val.toFixed(3)} kg de ${it.es}. Escribe este decimal en palabras.`},
6670        a:{en:`${w} and ${Math.round((val-w)*1000)} thousandths`,
6671           es:`${w} y ${Math.round((val-w)*1000)} milésimos`}
6672      };
6673    }
6674    const a=ri(3,8)/10;
6675    return {
6676      q:{en:`${n1} measured ${a.toFixed(1)} kg of ${it.en} and ${n2} measured ${a.toFixed(3)} kg. Compare the two amounts with =, >, or <.`,
6677         es:`${n1} midió ${a.toFixed(1)} kg de ${it.es} y ${n2} midió ${a.toFixed(3)} kg. Compara las dos cantidades con =, > o <.`},
6678      a:{en:`${a.toFixed(1)} = ${a.toFixed(3)}`, es:`${a.toFixed(1)} = ${a.toFixed(3)}`}
6679    };
6680  }
6681},
6682{
6683  code:"5.NBT.A.4", grade:5, dok:2,
6684  title:{en:"Round decimals",
6685         es:"Redondear decimales"},
6686  text:{en:"Use place value understanding to round decimals to any place.",
6687        es:"Usa la comprensión del valor posicional para redondear decimales a cualquier posición."},
6688  build(n1,n2,lvl){
6689    const it = pickItem();
6690    const rd = (v,p) => (Math.round(v*p)/p);
6691
6692    /* ---- Support · DOK 1 : round to whole or tenth ---- */
6693    if(lvl===1){
6694      const k=ri(1,4);
6695      if(k===1){
6696        const v = ri(10,90)/10 + ri(1,9)/100;
6697        return {
6698          q:{en:`${n1}'s bag of ${it.en} weighs ${v.toFixed(2)} kg. Round to the nearest tenth. (Look at the hundredths digit.)`,
6699             es:`La bolsa de ${it.es} de ${n1} pesa ${v.toFixed(2)} kg. Redondea al décimo más cercano. (Mira el dígito de los centésimos.)`},
6700          a:{en:`${rd(v,10).toFixed(1)}`, es:`${rd(v,10).toFixed(1)}`}
6701        };
6702      }
6703      if(k===2){
6704        const v = ri(2,9) + ri(1,9)/10;
6705        return {
6706          q:{en:`${n1} measured ${v.toFixed(1)} liters of juice. Round to the nearest whole liter.`,
6707             es:`${n1} midió ${v.toFixed(1)} litros de jugo. Redondea al litro entero más cercano.`},
6708          a:{en:`${Math.round(v)}`, es:`${Math.round(v)}`}
6709        };
6710      }
6711      if(k===3){
6712        const v = ri(1,8) + 0.5;
6713        return {
6714          q:{en:`${n1} has ${v.toFixed(1)} kg of ${it.en}. It ends in 5. Which whole number does it round to? Say the rule.`,
6715             es:`${n1} tiene ${v.toFixed(1)} kg de ${it.es}. Termina en 5. ¿A qué número entero se redondea? Di la regla.`},
6716          a:{en:`${Math.round(v)} — a 5 rounds up`, es:`${Math.round(v)} — el 5 redondea hacia arriba`}
6717        };
6718      }
6719      const v = ri(100,900)/100;
6720      return {
6721        q:{en:`About how many kg of ${it.en} does ${n1} have if the exact mass is ${v.toFixed(2)} kg? Round to the nearest whole number.`,
6722           es:`¿Como cuántos kg de ${it.es} tiene ${n1} si la masa exacta es ${v.toFixed(2)} kg? Redondea al entero más cercano.`},
6723        a:{en:`${Math.round(v)}`, es:`${Math.round(v)}`}
6724      };
6725    }
6726
6727    /* ---- Challenge · DOK 3 ---- */
6728    if(lvl===3){
6729      const k=ri(1,4);
6730      if(k===1){
6731        const target=ri(2,8);
6732        return {
6733          q:{en:`${n1} says a ${it.en} mass rounds to ${target} kg at the nearest whole number. What are the smallest and largest decimals (to hundredths) it could be? Explain.`,
6734             es:`${n1} dice que una masa de ${it.es} se redondea a ${target} kg al entero más cercano. ¿Cuál es el decimal menor y el mayor (en centésimos) que podría ser? Explica.`},
6735          a:{en:`${(target-0.5).toFixed(2)} to ${(target+0.49).toFixed(2)}`,
6736             es:`de ${(target-0.5).toFixed(2)} a ${(target+0.49).toFixed(2)}`}
6737        };
6738      }
6739      if(k===2){
6740        const v = ri(2,8) + ri(40,49)/100 + ri(1,9)/1000;
6741        return {
6742          q:{en:`${n2} rounded ${v.toFixed(3)} kg of ${it.en} to the nearest tenth and got ${Math.round(v)}. What place did ${n2} actually round to? Give the correct nearest tenth.`,
6743             es:`${n2} redondeó ${v.toFixed(3)} kg de ${it.es} al décimo más cercano y obtuvo ${Math.round(v)}. ¿A qué posición redondeó en realidad? Da el décimo correcto.`},
6744          a:{en:`Rounded to whole numbers — nearest tenth is ${rd(v,10).toFixed(1)}`,
6745             es:`Redondeó al entero — el décimo más cercano es ${rd(v,10).toFixed(1)}`}
6746        };
6747      }
6748      if(k===3){
6749        const v = ri(1,9) + ri(100,999)/1000;
6750        return {
6751          q:{en:`${n1} weighed ${it.en} at ${v.toFixed(3)} kg. Round it to the nearest tenth, hundredth, and whole number. Why do the three answers differ?`,
6752             es:`${n1} pesó ${it.es} en ${v.toFixed(3)} kg. Redondéalo al décimo, al centésimo y al entero. ¿Por qué difieren las tres respuestas?`},
6753          a:{en:`${rd(v,10).toFixed(1)} / ${rd(v,100).toFixed(2)} / ${Math.round(v)} — bigger place, rougher estimate`,
6754             es:`${rd(v,10).toFixed(1)} / ${rd(v,100).toFixed(2)} / ${Math.round(v)} — a mayor posición, estimación más gruesa`}
6755        };
6756      }
6757      const a = ri(150,450)/100, b = ri(150,450)/100;
6758      return {
6759        q:{en:`${n1} measured ${a.toFixed(2)} kg of ${it.en} and ${n2} measured ${b.toFixed(2)} kg. Estimate the total by rounding each to the nearest whole number, then find the exact total. How far off is the estimate?`,
6760           es:`${n1} midió ${a.toFixed(2)} kg de ${it.es} y ${n2} midió ${b.toFixed(2)} kg. Estima el total redondeando cada uno al entero, luego halla el total exacto. ¿Por cuánto difiere?`},
6761        a:{en:`≈${Math.round(a)+Math.round(b)}; exact ${(a+b).toFixed(2)}; off by ${Math.abs(Math.round(a)+Math.round(b)-(a+b)).toFixed(2)}`,
6762           es:`≈${Math.round(a)+Math.round(b)}; exacto ${(a+b).toFixed(2)}; difiere por ${Math.abs(Math.round(a)+Math.round(b)-(a+b)).toFixed(2)}`}
6763      };
6764    }
6765
6766    /* ---- On level · DOK 2 : any place ---- */
6767    const k=ri(1,4);
6768    if(k===1){
6769      const v = ri(1,9) + ri(100,999)/1000;
6770      return {
6771        q:{en:`${n1} weighed ${v.toFixed(3)} kg of ${it.en}. Round to the nearest hundredth.`,
6772           es:`${n1} pesó ${v.toFixed(3)} kg de ${it.es}. Redondea al centésimo más cercano.`},
6773        a:{en:`${rd(v,100).toFixed(2)}`, es:`${rd(v,100).toFixed(2)}`}
6774      };
6775    }
6776    if(k===2){
6777      const v = ri(1,9) + ri(10,99)/100;
6778      return {
6779        q:{en:`${n1}'s ${it.en} order weighed ${v.toFixed(2)} kg. Round to the nearest tenth.`,
6780           es:`El pedido de ${it.es} de ${n1} pesó ${v.toFixed(2)} kg. Redondea al décimo más cercano.`},
6781        a:{en:`${rd(v,10).toFixed(1)}`, es:`${rd(v,10).toFixed(1)}`}
6782      };
6783    }
6784    if(k===3){
6785      const v = ri(1,9) + ri(100,999)/1000;
6786      return {
6787        q:{en:`${n1} and ${n2} measured ${v.toFixed(3)} kg of ${it.en}. Round it to the nearest tenth AND the nearest whole number.`,
6788           es:`${n1} y ${n2} midieron ${v.toFixed(3)} kg de ${it.es}. Redondéalo al décimo Y al entero más cercano.`},
6789        a:{en:`${rd(v,10).toFixed(1)} / ${Math.round(v)}`, es:`${rd(v,10).toFixed(1)} / ${Math.round(v)}`}
6790      };
6791    }
6792    const a = ri(120,480)/100, b = ri(120,480)/100;
6793    return {
6794      q:{en:`${n1} used ${a.toFixed(2)} kg and ${n2} used ${b.toFixed(2)} kg of ${it.en}. About how much did they use together? Round each to the nearest whole number first.`,
6795         es:`${n1} usó ${a.toFixed(2)} kg y ${n2} usó ${b.toFixed(2)} kg de ${it.es}. ¿Como cuánto usaron juntos? Redondea cada uno al entero primero.`},
6796      a:{en:`${Math.round(a)} + ${Math.round(b)} = about ${Math.round(a)+Math.round(b)} kg`,
6797         es:`${Math.round(a)} + ${Math.round(b)} = como ${Math.round(a)+Math.round(b)} kg`}
6798    };
6799  }
6800},
6801{
6802  code:"5.NBT.B.5", grade:5, dok:2,
6803  title:{en:"Multiply multi-digit whole numbers",
6804         es:"Multiplicar números de varios dígitos"},
6805  text:{en:"Fluently multiply multi-digit whole numbers using the standard algorithm.",
6806        es:"Multiplica con fluidez números enteros de varios dígitos usando el algoritmo estándar."},
6807  build(n1,n2,lvl){
6808    const it = pickItem(), bin = pick(THEME.bins);
6809    const g = THEME.group;
6810
6811    /* ---- Support · DOK 1 : 2-digit x 1-digit, friendly ---- */
6812    if(lvl===1){
6813      const k=ri(1,4);
6814      if(k===1){
6815        const boxes=ri(3,8), per=ri(11,24);
6816        return {
6817          q:{en:`${n1} packed ${boxes} ${bin.en} with ${per} ${it.en} in each one. How many ${it.en} in all?`,
6818             es:`${n1} empacó ${boxes} ${bin.es} con ${per} ${it.es} en cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} hay en total?`},
6819          a:{en:`${boxes} × ${per} = ${boxes*per}`, es:`${boxes} × ${per} = ${boxes*per}`}
6820        };
6821      }
6822      if(k===2){
6823        const rows=ri(12,25), per=ri(3,6);
6824        return {
6825          q:{en:`${n1} set out ${rows} rows of ${it.en} with ${per} in each row. How many ${it.en} are there?`,
6826             es:`${n1} acomodó ${rows} filas de ${it.es} con ${per} en cada fila. ¿${cuantosEs(it)} ${it.es} hay?`},
6827          a:{en:`${rows} × ${per} = ${rows*per}`, es:`${rows} × ${per} = ${rows*per}`}
6828        };
6829      }
6830      if(k===3){
6831        const days=ri(4,9), each=ri(15,30);
6832        return {
6833          q:{en:`${n1} counts ${each} ${it.en} every day for ${days} days. How many ${it.en} is that altogether?`,
6834             es:`${n1} cuenta ${each} ${it.es} cada día durante ${days} días. ¿${cuantosEs(it)} ${it.es} son en total?`},
6835          a:{en:`${days} × ${each} = ${days*each}`, es:`${days} × ${each} = ${days*each}`}
6836        };
6837      }
6838      const tens=ri(2,6)*10, per=ri(4,9);
6839      return {
6840        q:{en:`${n1}'s ${g.en} has ${tens} ${bin.en}, and each holds ${per} ${it.en}. How many ${it.en} in all? (Multiply by the tens first.)`,
6841           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} tiene ${tens} ${bin.es} y cada ${unoEs(bin)} guarda ${per} ${it.es}. ¿${cuantosEs(it)} ${it.es} hay en total? (Multiplica primero por las decenas.)`},
6842        a:{en:`${tens} × ${per} = ${tens*per}`, es:`${tens} × ${per} = ${tens*per}`}
6843      };
6844    }
6845
6846    /* ---- Challenge · DOK 3 : partial products, error analysis, estimation ---- */
6847    if(lvl===3){
6848      const k=ri(1,5);
6849      if(k===1){
6850        const a=ri(23,58), b=ri(23,48);
6851        const wrong = (Math.floor(a/10)*Math.floor(b/10)*100) + ((a%10)*(b%10));
6852        if(wrong===a*b) return this.build(n1,n2,lvl);
6853        return {
6854          q:{en:`${n2} multiplied ${a} × ${b} for the ${it.en} count and got ${wrong} by multiplying the tens together and the ones together. Which partial products did ${n2} skip? Give the correct total.`,
6855             es:`${n2} multiplicó ${a} × ${b} para el conteo de ${it.es} y obtuvo ${wrong} multiplicando las decenas entre sí y las unidades entre sí. ¿Qué productos parciales omitió? Da el total correcto.`},
6856          a:{en:`Missed the two cross products — ${a} × ${b} = ${a*b}`,
6857             es:`Omitió los dos productos cruzados — ${a} × ${b} = ${a*b}`}
6858        };
6859      }
6860      if(k===2){
6861        const a=ri(24,68), b=ri(18,42);
6862        const claim = a*b + (ri(0,1)? ri(150,400) : -ri(150,400));
6863        return {
6864          q:{en:`${n1}'s ${g.en} needs ${a} ${bin.en} of ${it.en} with ${b} in each. ${n2} says that is ${claim} ${it.en}. Round both factors to estimate, then say whether ${n2} is reasonable and give the exact product.`,
6865             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} necesita ${a} ${bin.es} de ${it.es} con ${b} en cada ${unoEs(bin)}. ${n2} dice que son ${claim} ${it.es}. Redondea los dos factores para estimar, di si es razonable y da el producto exacto.`},
6866          a:{en:`≈${rnd(a,10)}×${rnd(b,10)}=${rnd(a,10)*rnd(b,10)}; exact ${a*b} — not reasonable`,
6867             es:`≈${rnd(a,10)}×${rnd(b,10)}=${rnd(a,10)*rnd(b,10)}; exacto ${a*b} — no es razonable`}
6868        };
6869      }
6870      if(k===3){
6871        const cases=ri(12,26), boxes=ri(8,15), each=ri(6,12);
6872        return {
6873          q:{en:`${n1} orders ${cases} cases of ${it.en}. Each case has ${boxes} ${bin.en} and each ${bin.one.en} holds ${each}. How many ${it.en} did ${n1} order? Show both multiplications.`,
6874             es:`${n1} pide ${cases} cajas grandes de ${it.es}. Cada una tiene ${boxes} ${bin.es} y cada ${bin.one.es} guarda ${each}. ¿${cuantosEs(it)} ${it.es} pidió? Muestra las dos multiplicaciones.`},
6875          a:{en:`${boxes}×${each}=${boxes*each} per case, ×${cases}
6875 = ${cases*boxes*each}`,
6876             es:`${boxes}×${each}=${boxes*each} por caja, ×${cases} = ${cases*boxes*each}`}
6877        };
6878      }
6879      if(k===4){
6880        const a=ri(26,64), b=ri(14,38), total=a*b;
6881        return {
6882          q:{en:`${n1} counted ${total} ${it.en} arranged in ${a} equal rows. ${n2} claims each row has ${b+ri(2,6)}. Use multiplication to check ${n2}'s claim and give the true number per row.`,
6883             es:`${n1} contó ${total} ${it.es} en ${a} filas iguales. ${n2} dice que cada fila tiene ${b+ri(2,6)}. Usa la multiplicación para comprobarlo y da el número real por fila.`},
6884          a:{en:`${a} × ${b} = ${total}, so ${b} per row`, es:`${a} × ${b} = ${total}, entonces ${b} por fila`}
6885        };
6886      }
6887      const aA=ri(18,34), bA=ri(12,25), aB=ri(20,40), bB=ri(10,22);
6888      const tA=aA*bA, tB=aB*bB;
6889      if(tA===tB) return this.build(n1,n2,lvl);
6890      return {
6891        q:{en:`Plan A: ${aA} ${bin.en} of ${bA} ${it.en}. Plan B: ${aB} ${bin.en} of ${bB}. ${n1} wants the plan with more ${it.en}. Which one, and by how many? Show both products.`,
6892           es:`Plan A: ${aA} ${bin.es} de ${bA} ${it.es}. Plan B: ${aB} ${bin.es} de ${bB}. ${n1} quiere el plan con más ${it.es}. ¿Cuál y por ${cuantosLc(it)}? Muestra los dos productos.`},
6893        a:{en:`A=${tA}, B=${tB} → ${tA>tB?"A":"B"} by ${Math.abs(tA-tB)}`,
6894           es:`A=${tA}, B=${tB} → ${tA>tB?"A":"B"} por ${Math.abs(tA-tB)}`}
6895      };
6896    }
6897
6898    /* ---- On level · DOK 2 : 2-digit x 2-digit, 3-digit x 1-digit ---- */
6899    const k=ri(1,5);
6900    if(k===1){
6901      const a=ri(14,48), b=ri(13,36);
6902      return {
6903        q:{en:`${n1} packed ${a} ${bin.en} with ${b} ${it.en} in each one. How many ${it.en} did ${n1} pack?`,
6904           es:`${n1} empacó ${a} ${bin.es} con ${b} ${it.es} en cada ${unoEs(bin)}. ¿${cuantosEs(it)} ${it.es} empacó?`},
6905        a:{en:`${a} × ${b} = ${a*b}`, es:`${a} × ${b} = ${a*b}`}
6906      };
6907    }
6908    if(k===2){
6909      const a=ri(112,485), b=ri(3,8);
6910      return {
6911        q:{en:`${n1}'s ${g.en} collected ${a} ${it.en} each week for ${b} weeks. How many ${it.en} is that in all?`,
6912           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} juntó ${a} ${it.es} por semana durante ${b} semanas. ¿${cuantosEs(it)} ${it.es} son en total?`},
6913        a:{en:`${a} × ${b} = ${a*b}`, es:`${a} × ${b} = ${a*b}`}
6914      };
6915    }
6916    if(k===3){
6917      const rows=ri(15,32), cols=ri(12,28);
6918      return {
6919        q:{en:`${n1} and ${n2} arranged ${it.en} in ${rows} rows with ${cols} in each row. How many ${it.en} are in the array?`,
6920           es:`${n1} y ${n2} acomodaron ${it.es} en ${rows} filas con ${cols} en cada fila. ¿${cuantosEs(it)} ${it.es} hay en el arreglo?`},
6921        a:{en:`${rows} × ${cols} = ${rows*cols}`, es:`${rows} × ${cols} = ${rows*cols}`}
6922      };
6923    }
6924    if(k===4){
6925      const days=ri(12,30), each=ri(14,45);
6926      return {
6927        q:{en:`${n1} sorts ${each} ${it.en} every school day. Over ${days} days, how many ${it.en} does ${n1} sort?`,
6928           es:`${n1} ordena ${each} ${it.es} cada día de escuela. En ${days} días, ¿${cuantosEs(it)} ${it.es} ordena?`},
6929        a:{en:`${days} × ${each} = ${days*each}`, es:`${days} × ${each} = ${days*each}`}
6930      };
6931    }
6932    const a=ri(16,40), b=ri(15,32), extra=ri(20,80);
6933    return {
6934      q:{en:`${n1} has ${a} ${bin.en} holding ${b} ${it.en} each, plus ${extra} loose ${it.en}. How many ${it.en} in all?`,
6935         es:`${n1} tiene ${a} ${bin.es} con ${b} ${it.es} cada ${unoEs(bin)}, más ${extra} ${it.es} sueltos. ¿${cuantosEs(it)} ${it.es} hay en total?`},
6936      a:{en:`${a}×${b}=${a*b}, +${extra} = ${a*b+extra}`, es:`${a}×${b}=${a*b}, +${extra} = ${a*b+extra}`}
6937    };
6938  }
6939},
6940{
6941  code:"5.NBT.B.6", grade:5, dok:3,
6942  title:{en:"Divide with four-digit dividends",
6943         es:"Dividir con dividendos de cuatro dígitos"},
6944  text:{en:"Find whole-number quotients of whole numbers with up to four-digit dividends and two-digit divisors, using strategies based on place value, the properties of operations, and/or the relationship between multiplication and division.",
6945        es:"Halla cocientes de números enteros con dividendos de hasta cuatro dígitos y divisores de dos dígitos, usando estrategias basadas en el valor posicional, las propiedades de las operaciones y/o la relación entre la multiplicación y la división."},
6946  build(n1,n2,lvl){
6947    const it = pickItem(), bin = pick(THEME.bins);
6948    const g = THEME.group;
6949
6950    /* ---- Support · DOK 1 : clean quotients, 1-digit divisor ---- */
6951    if(lvl===1){
6952      const k=ri(1,4);
6953      if(k===1){
6954        const per=ri(12,30), groups=ri(3,8), tot=per*groups;
6955        return {
6956          q:{en:`${n1} shared ${tot} ${it.en} equally among ${groups} ${bin.en}. How many ${it.en} went in each one?`,
6957             es:`${n1} repartió ${tot} ${it.es} en partes iguales entre ${bin.es} (${groups}). ¿${cuantosEs(it)} ${it.es} van en cada ${unoEs(bin)}?`},
6958          a:{en:`${tot} ÷ ${groups} = ${per}`, es:`${tot} ÷ ${groups} = ${per}`}
6959        };
6960      }
6961      if(k===2){
6962        const per=ri(6,12), groups=ri(11,25), tot=per*groups;
6963        return {
6964          q:{en:`${n1}'s ${g.en} has ${tot} ${it.en} to put ${per} in each ${bin.one.en}. How many ${bin.en} does ${n1} need?`,
6965             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} tiene ${tot} ${it.es} para poner ${per} en cada ${bin.one.es}. ¿${cuantosEs(bin)} ${bin.es} necesita?`},
6966          a:{en:`${tot} ÷ ${per} = ${groups}`, es:`${tot} ÷ ${per} = ${groups}`}
6967        };
6968      }
6969      if(k===3){
6970        const days=ri(4,9), per=ri(20,45), tot=days*per;
6971        return {
6972          q:{en:`${n1} counted ${tot} ${it.en} over ${days} days, the same number each day. How many ${it.en} per day?`,
6973             es:`${n1} contó ${tot} ${it.es} en ${days} días, la misma cantidad cada día. ¿${cuantosEs(it)} ${it.es} por día?`},
6974          a:{en:`${tot} ÷ ${days} = ${per}`, es:`${tot} ÷ ${days} = ${per}`}
6975        };
6976      }
6977      const per=ri(15,40), groups=ri(4,8), tot=per*groups;
6978      return {
6979        q:{en:`${tot} ${it.en} are split evenly into ${groups} equal groups by ${n1}. How many are in each group?`,
6980           es:`${n1} divide ${tot} ${it.es} en ${groups} grupos iguales. ¿${cuantosEs(it)} hay en cada grupo?`},
6981        a:{en:`${tot} ÷ ${groups} = ${per}`, es:`${tot} ÷ ${groups} = ${per}`}
6982      };
6983    }
6984
6985    /* ---- Challenge · DOK 3 : remainders in context, checking, judgment ---- */
6986    if(lvl===3){
6987      const k=ri(1,5);
6988      if(k===1){
6989        const per=ri(14,28), full=ri(20,45), extra=ri(1,per-1), tot=per*full+extra;
6990        return {
6991          q:{en:`${n1} packs ${it.en} ${per} to a ${bin.one.en} and has ${tot} ${it.en}. How many ${bin.en} are completely full, and what should ${n1} do with the rest? Explain your choice.`,
6992             es:`${n1} empaca ${it.es} de ${per} en ${per} por ${bin.one.es} y tiene ${tot} ${it.es}. ¿${cuantosEs(bin)} ${bin.es} quedan llenas por completo y qué debe hacer con el resto? Explica tu decisión.`},
6993          a:{en:`${tot} ÷ ${per} = ${full} R${extra} — ${full} full, ${extra} left over`,
6994             es:`${tot} ÷ ${per} = ${full} R${extra} — ${full} llenas, sobran ${extra}`}
6995        };
6996      }
6997      if(k===2){
6998        const per=ri(15,32), full=ri(18,40), extra=ri(1,per-1), tot=per*full+extra;
6999        return {
7000          q:{en:`${n1} needs ${bin.en} that hold ${per} ${it.en} each to carry ${tot} ${it.en} — every ${it.one.en} must go. How many ${bin.en} are needed? Explain why the remainder changes your answer.`,
7001             es:`${n1} necesita ${bin.es} de ${per} ${it.es} cada ${unoEs(bin)} para llevar ${tot} ${it.es} — ${losLasEs(it)} ${it.es} deben ir todos. ¿${cuantosEs(bin)} se necesitan? Explica por qué el residuo cambia la respuesta.`},
7002          a:{en:`${tot} ÷ ${per} = ${full} R${extra} → ${full+1} needed (round up)`,
7003             es:`${tot} ÷ ${per} = ${full} R${extra} → se necesitan ${full+1} (redondear hacia arriba)`}
7004        };
7005      }
7006      if(k===3){
7007        const divisor=ri(12,28), quot=ri(30,80), tot=divisor*quot;
7008        return {
7009          q:{en:`${n2} says ${tot} ${it.en} split among ${divisor} ${bin.en} gives ${quot+ri(3,9)} each. Multiply to check ${n2}'s answer, then give the correct number and explain how multiplication proves it.`,
7010             es:`${n2} dice que ${tot} ${it.es} repartidos entre ${divisor} ${bin.es} dan ${quot+ri(3,9)} en cada ${unoEs(bin)}. Multiplica para comprobarlo, da el número correcto y explica cómo lo demuestra la multiplicación.`},
7011          a:{en:`${divisor} × ${quot} = ${tot}, so ${quot} each`, es:`${divisor} × ${quot} = ${tot}, entonces ${quot} en cada ${unoEs(bin)}`}
7012        };
7013      }
7014      if(k===4){
7015        const divisor=ri(15,35), quot=ri(40,90), tot=divisor*quot;
7016        return {
7017          q:{en:`${n1}'s ${g.en} divided ${tot} ${it.en} into equal groups of ${divisor}. Write an equation with n for the number of groups, solve it, and estimate first to show your answer is sensible.`,
7018             es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} dividió ${tot} ${it.es} en grupos iguales de ${divisor}. Escribe una ecuación con n para el número de grupos, resuélvela y estima primero para mostrar que tu respuesta tiene sentido.`},
7019          a:{en:`${divisor} × n = ${tot}; n = ${quot} (≈${rnd(tot,100)}÷${rnd(divisor,10)})`,
7020             es:`${divisor} × n = ${tot}; n = ${quot} (≈${rnd(tot,100)}÷${rnd(divisor,10)})`}
7021        };
7022      }
7023      const per=ri(16,30), groups=ri(25,60), tot=per*groups, take=ri(40,120);
7024      return {
7025        q:{en:`${n1} started with ${tot+take} ${it.en}, gave away ${take}, then split the rest evenly into ${groups} ${bin.en}. How many ${it.en} per ${bin.one.en}? Show both steps.`,
7026           es:`${n1} empezó con ${tot+take} ${it.es}, regaló ${take} y repartió el resto en ${groups} ${bin.es} iguales. ¿${cuantosEs(it)} ${it.es} por ${bin.one.es}? Muestra los dos pasos.`},
7027        a:{en:`${tot+take}−${take}=${tot}, ÷${groups} = ${per}`, es:`${tot+take}−${take}=${tot}, ÷${groups} = ${per}`}
7028      };
7029    }
7030
7031    /* ---- On level · DOK 2 : 4-digit ÷ 2-digit ---- */
7032    const k=ri(1,5);
7033    if(k===1){
7034      const divisor=ri(12,32), quot=ri(30,95), tot=divisor*quot;
7035      return {
7036        q:{en:`${n1}'s ${g.en} shared ${tot} ${it.en} equally among ${divisor} ${bin.en}. How many ${it.en} in each ${bin.one.en}?`,
7037           es:`${elLaEs(g)==="el"?"El":"La"} ${g.es} de ${n1} repartió ${tot} ${it.es} entre ${divisor} ${bin.es} por igual. ¿${cuantosEs(it)} ${it.es} hay en cada ${bin.one.es}?`},
7038        a:{en:`${tot} ÷ ${divisor} = ${quot}`, es:`${tot} ÷ ${divisor} = ${quot}`}
7039      };
7040    }
7041    if(k===2){
7042      const per=ri(15,40), groups=ri(24,60), tot=per*groups;
7043      return {
7044        q:{en:`${n1} has ${tot} ${it.en} and puts ${per} in each ${bin.one.en}. How many ${bin.en} does ${n1} fill?`,
7045           es:`${n1} tiene ${tot} ${it.es} y pone ${per} en cada ${bin.one.es}. ¿${cuantosEs(bin)} ${bin.es} llena?`},
7046        a:{en:`${tot} ÷ ${per} = ${groups}`, es:`${tot} ÷ ${per} = ${groups}`}
7047      };
7048    }
7049    if(k===3){
7050      const divisor=ri(14,28), quot=ri(35,85), tot=divisor*quot, extra=ri(1,divisor-1);
7051      return {
7052        q:{en:`${n1} counted ${tot+extra} ${it.en} and packed them ${divisor} to a ${bin.one.en}. How many full ${bin.en}, and how many ${it.en} are left over?`,
7053           es:`${n1} contó ${tot+extra} ${it.es} y los empacó de ${divisor} en ${divisor} por ${bin.one.es}. ¿${cuantosEs(bin)} ${bin.es} llenas y ${cuantosLc(it)} ${it.es} sobran?`},
7054        a:{en:`${tot+extra} ÷ ${divisor} = ${quot} R${extra}`, es:`${tot+extra} ÷ ${divisor} = ${quot} R${extra}`}
7055      };
7056    }
7057    if(k===4){
7058      const weeks=ri(12,26), per=ri(45,120), tot=weeks*per;
7059      return {
7060        q:{en:`Over ${weeks} weeks ${n1}'s ${g.en} collected ${tot} ${it.en}, the same amount each week. How many ${it.en} per week?`,
7061           es:`En ${weeks} semanas ${elLaEs(g)==="el"?"el":"la"} ${g.es} de ${n1} juntó ${tot} ${it.es}, la misma cantidad cada semana. ¿${cuantosEs(it)} ${it.es} por semana?`},
7062        a:{en:`${tot} ÷ ${weeks} = ${per}`, es:`${tot} ÷ ${weeks} = ${per}`}
7063      };
7064    }
7065    const divisor=ri(16,35), quot=ri(28,70), tot=divisor*quot;
7066    return {
7067      q:{en:`${n1} and ${n2} split ${tot} ${it.en} into ${divisor} equal piles for the ${g.en}. How many ${it.en} are in each pile?`,
7068         es:`${n1} y ${n2} dividieron ${tot} ${it.es} en ${divisor} montones iguales para ${elLaEs(g)==="el"?"el":"la"} ${g.es}. ¿${cuantosEs(it)} ${it.es} hay en cada montón?`},
7069      a:{en:`${tot} ÷ ${divisor} = ${quot}`, es:`${tot} ÷ ${divisor} = ${quot}`}
7070    };
7071  }
7072},
7073{
7074  code:"5.NF.A.2", grade:5, dok:3,
7075  title:{en:"Add & subtract fractions — unlike denominators",
7076         es:"Sumar y restar fracciones — denominadores distintos"},
7077  text:{en:"Solve word problems involving addition and subtraction of fractions referring to the same whole, including cases of unlike denominators, e.g., by using visual fraction models or equations to represent the problem. Use benchmark fractions and number sense of fractions to estimate mentally and assess the reasonableness of answers.",
7078        es:"Resuelve problemas verbales de suma y resta de fracciones que se refieren al mismo todo, incluyendo casos con denominadores distintos, por ejemplo, usando modelos visuales o ecuaciones. Usa fracciones de referencia y el sentido numérico para estimar mentalmente y evaluar si las respuestas son razonables."},
7079  build(n1,n2,lvl){
7080    const it = pickItem(), bin = pick(THEME.bins);
7081    const pairs=[[2,4],[2,6],[2,8],[3,6],[4,8],[2,3],[3,4],[2,5],[4,6],[3,8]];
7082
7083    /* ---- Support · DOK 1 : one denominator doubles the other ---- */
7084    if(lvl===1){
7085      const k=ri(1,4);
7086      if(k===1){
7087        const d=pick([4,6,8]);
7088        return {
7089          q:{en:`${n1} filled 1/2 of a ${bin.one.en} with ${it.en}. ${n2} filled ${frR(1,d)} more. Rewrite 1/2 as ${frR(d/2,d)}, then add.`,
7090             es:`${n1} llenó 1/2 de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}. ${n2} llenó ${frR(1,d)} más. Escribe 1/2 como ${frR(d/2,d)} y luego suma.`},
7091          a:{en:`${frR(d/2,d)} + ${frR(1,d)} = ${frR(d/2+1,d)}`, es:`${frR(d/2,d)} + ${frR(1,d)} = ${frR(d/2+1,d)}`}
7092        };
7093      }
7094      if(k===2){
7095        const dSm=pick([2,3]), dBig=dSm*2, a=1, b=1;
7096        return {
7097          q:{en:`A tray of ${it.en}
7097 was ${frR(a,dSm)} full. ${n1} used ${frR(b,dBig)}. Rewrite ${frR(a,dSm)} as ${frR(a*2,dBig)}, then subtract to find what is left.`,
7098             es:`Una bandeja de ${it.es} estaba llena hasta ${frR(a,dSm)}. ${n1} usó ${frR(b,dBig)}. Escribe ${frR(a,dSm)} como ${frR(a*2,dBig)} y resta para hallar lo que queda.`},
7099          a:{en:`${frR(a*2,dBig)} − ${frR(b,dBig)} = ${frR(a*2-b,dBig)}`, es:`${frR(a*2,dBig)} − ${frR(b,dBig)} = ${frR(a*2-b,dBig)}`}
7100        };
7101      }
7102      if(k===3){
7103        const d=pick([6,8]);
7104        return {
7105          q:{en:`${n1} sorted ${frR(1,2)} of the ${it.en} and ${n2} sorted ${frR(2,d)}. Use ${d}ths for both fractions, then add.`,
7106             es:`${n1} ordenó ${frR(1,2)} de ${losLasEs(it)} ${it.es} y ${n2} ordenó ${frR(2,d)}. Usa ${d>=8?"octavos":"sextos"} para las dos fracciones y luego suma.`},
7107          a:{en:`${frR(d/2,d)} + ${frR(2,d)} = ${fr(d/2+2,d)}`, es:`${frR(d/2,d)} + ${frR(2,d)} = ${fr(d/2+2,d)}`}
7108        };
7109      }
7110      const d=4;
7111      return {
7112        q:{en:`${n1} filled ${frR(1,4)} of a ${bin.one.en} with ${it.en}, then ${frR(1,2)} more. How full is it now? (Think: how many fourths is one half?)`,
7113           es:`${n1} llenó ${frR(1,4)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y luego ${frR(1,2)} más. ¿Qué tan ${gEs(bin)==="m"?"lleno":"llena"} está ahora? (Piensa: ¿cuántos cuartos son un medio?)`},
7114        a:{en:`${frR(1,4)} + ${frR(2,4)} = ${frR(3,4)}`, es:`${frR(1,4)} + ${frR(2,4)} = ${frR(3,4)}`}
7115      };
7116    }
7117
7118    /* ---- Challenge · DOK 3 : benchmarks & reasonableness (the standard's own example) ---- */
7119    if(lvl===3){
7120      const k=ri(1,5);
7121      if(k===1){
7122        return {
7123          q:{en:`${n1} filled 1/2 of a ${bin.one.en} with ${it.en} and ${n2} filled 1/3. ${n2} says together they filled 2/5. Use benchmarks to explain why 2/5 cannot be right, then give the correct sum.`,
7124             es:`${n1} llenó 1/2 de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y ${n2} llenó 1/3. ${n2} dice que juntos llenaron 2/5. Usa fracciones de referencia para explicar por qué 2/5 no puede ser correcto y da la suma correcta.`},
7125          a:{en:`2/5 < 1/2, but the sum must be MORE than 1/2 — correct: 3/6+2/6 = 5/6`,
7126             es:`2/5 < 1/2, pero la suma debe ser MÁS que 1/2 — correcto: 3/6+2/6 = 5/6`}
7127        };
7128      }
7129      if(k===2){
7130        const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
7131        const a=ri(1,dA-1), b=ri(1,dB-1);
7132        const sumN=a*L/dA + b*L/dB;
7133        return {
7134          q:{en:`${n1} packed ${frR(a,dA)} of the ${it.en} and ${n2} packed ${frR(b,dB)}. Estimate first: is the total more or less than 1? Then find the exact total.`,
7135             es:`${n1} empacó ${frR(a,dA)} de ${losLasEs(it)} ${it.es} y ${n2} empacó ${frR(b,dB)}. Estima primero: ¿el total es más o menos que 1? Luego halla el total exacto.`},
7136          a:{en:`${fr(a*L/dA,L)} + ${fr(b*L/dB,L)} = ${mx(sumN,L)} (${sumN>L?"more":sumN===L?"exactly 1":"less"} than 1)`,
7137             es:`${fr(a*L/dA,L)} + ${fr(b*L/dB,L)} = ${mx(sumN,L)} (${sumN>L?"más":sumN===L?"exactamente 1":"menos"} que 1)`}
7138        };
7139      }
7140      if(k===3){
7141        const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
7142        const goalN=L, a=ri(1,dA-1);
7143        const need=goalN - a*L/dA;
7144        if(need<=0) return this.build(n1,n2,lvl);
7145        return {
7146          q:{en:`${n1} wants a completely full ${bin.one.en} of ${it.en} and has filled ${frR(a,dA)} so far. Write an equation with n for the missing fraction, then solve it in ${L}ths.`,
7147             es:`${n1} quiere ${unUnaEs(bin)} ${bin.one.es} completamente ${gEs(bin)==="m"?"lleno":"llena"} de ${it.es} y ha llenado ${frR(a,dA)}. Escribe una ecuación con n para la fracción que falta y resuélvela en ${L}avos.`},
7148          a:{en:`${frR(a*L/dA,L)} + n = ${frR(L,L)}; n = ${frR(need,L)}`,
7149             es:`${frR(a*L/dA,L)} + n = ${frR(L,L)}; n = ${frR(need,L)}`}
7150        };
7151      }
7152      if(k===4){
7153        const a=ri(1,2), dA=pick([3,4]), b=1, dB=pick([6,8]);
7154        const L=(dA*dB)/gcd(dA,dB), diff=a*L/dA - b*L/dB;
7155        if(diff<=0) return this.build(n1,n2,lvl);
7156        return {
7157          q:{en:`${n1} says ${frR(a,dA)} of a ${bin.one.en} of ${it.en} minus ${frR(b,dB)} leaves less than ${frR(1,dB)}. Check the claim with a common denominator and say whether ${n1} is right.`,
7158             es:`${n1} dice que ${frR(a,dA)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} menos ${frR(b,dB)} deja menos que ${frR(1,dB)}. Comprueba con un denominador común y di si ${n1} tiene razón.`},
7159          a:{en:`${fr(a*L/dA,L)}−${fr(b*L/dB,L)}=${fr(diff,L)} — ${diff < L/dB ? "right" : "not right"}`,
7160             es:`${fr(a*L/dA,L)}−${fr(b*L/dB,L)}=${fr(diff,L)} — ${diff < L/dB ? "tiene razón" : "no tiene razón"}`}
7161        };
7162      }
7163      const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
7164      const a=ri(1,dA-1), b=ri(1,dB-1);
7165      const aL=a*L/dA, bL=b*L/dB;
7166      if(aL===bL) return this.build(n1,n2,lvl);
7167      return {
7168        q:{en:`${n1} filled ${frR(a,dA)} of one ${bin.one.en} with ${it.en}; ${n2} filled ${frR(b,dB)} of an identical one. Who filled more, and by what fraction? Prove it with a common denominator.`,
7169           es:`${n1} llenó ${frR(a,dA)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es}; ${n2} llenó ${frR(b,dB)} de ${unUnaEs(bin)==="un"?"uno idéntico":"una idéntica"}. ¿Quién llenó más y por qué fracción? Compruébalo con un denominador común.`},
7170        a:{en:`${fr(aL,L)} vs ${fr(bL,L)} → ${aL>bL?n1:n2} by ${fr(Math.abs(aL-bL),L)}`,
7171           es:`${fr(aL,L)} vs ${fr(bL,L)} → ${aL>bL?n1:n2} por ${fr(Math.abs(aL-bL),L)}`}
7172      };
7173    }
7174
7175    /* ---- On level · DOK 2 ---- */
7176    const k=ri(1,5);
7177    if(k===1){
7178      const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
7179      const a=ri(1,dA-1), b=ri(1,dB-1);
7180      return {
7181        q:{en:`${n1} filled ${frR(a,dA)} of a ${bin.one.en} with ${it.en} and ${n2} filled ${frR(b,dB)}. What fraction is filled altogether?`,
7182           es:`${n1} llenó ${frR(a,dA)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} y ${n2} llenó ${frR(b,dB)}. ¿Qué fracción está llena en total?`},
7183        a:{en:`${fr(a*L/dA,L)} + ${fr(b*L/dB,L)} = ${mx(a*L/dA+b*L/dB,L)}`,
7184           es:`${fr(a*L/dA,L)} + ${fr(b*L/dB,L)} = ${mx(a*L/dA+b*L/dB,L)}`}
7185      };
7186    }
7187    if(k===2){
7188      const dB=pick([4,6,8]), a=1, dA=2, b=ri(1,dB/2-0);
7189      const L=dB, diff=L/2 - b;
7190      if(diff<=0) return this.build(n1,n2,lvl);
7191      return {
7192        q:{en:`A ${bin.one.en} of ${it.en} was ${frR(a,dA)} full. ${n1} removed ${frR(b,dB)}. What fraction remains?`,
7193           es:`${unUnaEs(bin)==="un"?"Un":"Una"} ${bin.one.es} de ${it.es} estaba a ${frR(a,dA)}. ${n1} sacó ${frR(b,dB)}. ¿Qué fracción queda?`},
7194        a:{en:`${frR(L/2,L)} − ${frR(b,L)} = ${fr(diff,L)}`, es:`${frR(L/2,L)} − ${frR(b,L)} = ${fr(diff,L)}`}
7195      };
7196    }
7197    if(k===3){
7198      const [dA,dB]=pick(pairs), L=(dA*dB)/gcd(dA,dB);
7199      const totN=ri(Math.floor(L/2),L-1), aL=ri(1,totN-1);
7200      return {
7201        q:{en:`Together ${n1} and ${n2} sorted ${fr(totN,L)} of the ${it.en}. ${n1} sorted ${fr(aL,L)}. What fraction did ${n2} sort?`,
7202           es:`Entre ${n1} y ${n2} ordenaron ${fr(totN,L)} de ${losLasEs(it)} ${it.es}. ${n1} ordenó ${fr(aL,L)}. ¿Qué fracción ordenó ${n2}?`},
7203        a:{en:`${fr(totN,L)} − ${fr(aL,L)} = ${fr(totN-aL,L)}`, es:`${fr(totN,L)} − ${fr(aL,L)} = ${fr(totN-aL,L)}`}
7204      };
7205    }
7206    if(k===4){
7207      const dA=pick([3,4,5]), dB=2, a=ri(1,dA-1), L=dA*2;
7208      const aL=a*2, bL=dA;
7209      if(aL===bL) return this.build(n1,n2,lvl);
7210      return {
7211        q:{en:`${n1} packed ${frR(a,dA)} of the ${it.en} and ${n2} packed ${frR(1,2)}. Who packed more? By what fraction?`,
7212           es:`${n1} empacó ${frR(a,dA)} de ${losLasEs(it)} ${it.es} y ${n2} empacó ${frR(1,2)}. ¿Quién empacó más? ¿Por qué fracción?`},
7213        a:{en:`${fr(aL,L)} vs ${fr(bL,L)} → ${aL>bL?n1:n2} by ${fr(Math.abs(aL-bL),L)}`,
7214           es:`${fr(aL,L)} vs ${fr(bL,L)} → ${aL>bL?n1:n2} por ${fr(Math.abs(aL-bL),L)}`}
7215      };
7216    }
7217    const dA=pick([3,4]), dB=pick([6,8]), L=(dA*dB)/gcd(dA,dB);
7218    const a=1, b=ri(1,2), c=ri(1,2);
7219    const sumN=a*L/dA + b*L/dB + c*L/dB;
7220    return {
7221      q:{en:`${n1} filled ${frR(a,dA)} of a ${bin.one.en} with ${it.en} in the morning and ${frR(b,dB)} at noon; ${n2} added ${frR(c,dB)}. What fraction is filled now?`,
7222         es:`${n1} llenó ${frR(a,dA)} de ${unUnaEs(bin)} ${bin.one.es} con ${it.es} por la mañana y ${frR(b,dB)} al mediodía; ${n2} agregó ${frR(c,dB)}. ¿Qué fracción está llena ahora?`},
7223      a:{en:`${fr(a*L/dA,L)}+${fr(b*L/dB,L)}+${fr(c*L/dB,L)} = ${mx(sumN,L)}`,
7224         es:`${fr(a*L/dA,L)}+${fr(b*L/dB,L)}+${fr(c*L/dB,L)} = ${mx(sumN,L)}`}
7225    };
7226  }
7227},
7228{
7229  code:"5.NF.B.3", grade:5, dok:3,
7230  title:{en:"Fractions as division & remainders as fractions",
7231         es:"Fracciones como división y residuos como fracciones"},
7232  text:{en:"Interpret a fraction as division of the numerator by the denominator (a/b = a ÷ b). Solve word problems involving division of whole numbers leading to answers in the form of fractions or mixed numbers, e.g., by using visual fraction models or equations to represent the problem.",
7233        es:"Interpreta una fracción como la división del numerador entre el denominador (a/b = a ÷ b). Resuelve problemas de división de números enteros cuyas respuestas son fracciones o números mixtos, por ejemplo, usando modelos visuales o ecuaciones."},
7234  build(n1,n2,lvl){
7235    const it = pickItem();
7236
7237    /* ---- Support · DOK 1 : small sharing, simple fractions ---- */
7238    if(lvl===1){
7239      const k=ri(1,4);
7240      if(k===1){
7241        const people=ri(2,4), things=ri(1,people-1);
7242        return {
7243          q:{en:`${n1} shares ${things} trays of ${it.en} equally among ${people} friends. How much does each friend get? Write it as a fraction.`,
7244             es:`${n1} reparte ${things} bandejas de ${it.es} en partes iguales entre ${people}
7244 amigos. ¿Cuánto recibe cada uno? Escríbelo como fracción.`},
7245          a:{en:`${things} ÷ ${people} = ${fr(things,people)}`, es:`${things} ÷ ${people} = ${fr(things,people)}`}
7246        };
7247      }
7248      if(k===2){
7249        const people=ri(2,4);
7250        return {
7251          q:{en:`${n1} and ${n2} split 1 pan of ${it.en} among ${people} people. What fraction does each person get?`,
7252             es:`${n1} y ${n2} reparten 1 bandeja de ${it.es} entre ${people} personas. ¿Qué fracción recibe cada persona?`},
7253          a:{en:`1 ÷ ${people} = ${frR(1,people)}`, es:`1 ÷ ${people} = ${frR(1,people)}`}
7254        };
7255      }
7256      if(k===3){
7257        const d=ri(2,5), n=d*ri(2,3);
7258        return {
7259          q:{en:`${n1} shares ${n} liters of juice equally among ${d} groups. Write ${n} ÷ ${d} as a fraction, then simplify.`,
7260             es:`${n1} reparte ${n} litros de jugo entre ${d} grupos por igual. Escribe ${n} ÷ ${d} como fracción y simplifica.`},
7261          a:{en:`${frR(n,d)} = ${n/d}`, es:`${frR(n,d)} = ${n/d}`}
7262        };
7263      }
7264      const people=ri(3,5), things=ri(1,2);
7265      return {
7266        q:{en:`${things} pan${things===1?"":"s"} of ${it.en} shared by ${n1} among ${people} people. Write the division as a fraction.`,
7267           es:`${things} bandeja${things===1?"":"s"} de ${it.es} que ${n1} reparte entre ${people} personas. Escribe la división como fracción.`},
7268        a:{en:`${things} ÷ ${people} = ${fr(things,people)}`, es:`${things} ÷ ${people} = ${fr(things,people)}`}
7269      };
7270    }
7271
7272    /* ---- Challenge · DOK 3 : remainder as a fraction, interpret ---- */
7273    if(lvl===3){
7274      const k=ri(1,4);
7275      if(k===1){
7276        const people=ri(3,6), whole=ri(1,3), rem=ri(1,people-1);
7277        const total=whole*people+rem;
7278        return {
7279          q:{en:`${n1} shares ${total} trays of ${it.en} equally among ${people} friends. How much does each get? Give the answer as a mixed number and explain what the fraction part means.`,
7280             es:`${n1} reparte ${total} bandejas de ${it.es} en partes iguales entre ${people} amigos. ¿Cuánto recibe cada uno? Da la respuesta como número mixto y explica qué significa la fracción.`},
7281          a:{en:`${total} ÷ ${people} = ${mx(total,people)} — the fraction is the leftover shared out`,
7282             es:`${total} ÷ ${people} = ${mx(total,people)} — la fracción es lo que sobra repartido`}
7283        };
7284      }
7285      if(k===2){
7286        const people=ri(4,8), whole=ri(2,4), rem=ri(1,people-1);
7287        const total=whole*people+rem;
7288        return {
7289          q:{en:`${n2} divides ${total} by ${people} for the ${it.en} problem and writes ${whole} R${rem}. ${n1} writes ${mx(total,people)}. Are both right? Explain when each form is more useful.`,
7290             es:`${n2} divide ${total} entre ${people} en el problema de ${it.es} y escribe ${whole} R${rem}. ${n1} escribe ${mx(total,people)}. ¿Están bien las dos? Explica cuándo es más útil cada forma.`},
7291          a:{en:`Both correct — R${rem} for whole objects, ${mx(total,people)} when the leftover can be shared`,
7292             es:`Las dos — R${rem} para objetos enteros, ${mx(total,people)} cuando lo que sobra se puede repartir`}
7293        };
7294      }
7295      if(k===3){
7296        const people=ri(3,6), total=ri(people+1, people*2-1);
7297        return {
7298          q:{en:`${n1} says ${total} pans of ${it.en} shared by ${people} people gives less than 2 pans each. Use division to check, then give the exact amount.`,
7299             es:`${n1} dice que ${total} bandejas de ${it.es} repartidas entre ${people} personas dan menos de 2 bandejas cada una. Usa la división para comprobarlo y da la cantidad exacta.`},
7300          a:{en:`${total} ÷ ${people} = ${mx(total,people)} — ${total/people < 2 ? "right" : "not right"}`,
7301             es:`${total} ÷ ${people} = ${mx(total,people)} — ${total/people < 2 ? "tiene razón" : "no tiene razón"}`}
7302        };
7303      }
7304      const people=ri(4,7), each=ri(2,4), total=people*each+ri(1,people-1);
7305      return {
7306        q:{en:`${n1} needs to give ${people} groups an equal share of ${total} liters of juice for the ${it.en} stand. Write an equation with n for each share, then solve as a mixed number.`,
7307           es:`${n1} debe dar a ${people} grupos una parte igual de ${total} litros de jugo para el puesto de ${it.es}. Escribe una ecuación con n para cada parte y resuélvela como número mixto.`},
7308        a:{en:`${people} × n = ${total};
7308 n = ${mx(total,people)}`, es:`${people} × n = ${total}; n = ${mx(total,people)}`}
7309      };
7310    }
7311
7312    /* ---- On level · DOK 2 ---- */
7313    const k=ri(1,4);
7314    if(k===1){
7315      const people=ri(3,6), total=ri(people+1, people*3);
7316      return {
7317        q:{en:`${n1} shares ${total} trays of ${it.en} equally among ${people} friends. How much does each friend get?`,
7318           es:`${n1} reparte ${total} bandejas de ${it.es} en partes iguales entre ${people} amigos. ¿Cuánto recibe cada amigo?`},
7319        a:{en:`${total} ÷ ${people} = ${mx(total,people)}`, es:`${total} ÷ ${people} = ${mx(total,people)}`}
7320      };
7321    }
7322    if(k===2){
7323      const people=ri(2,6), things=ri(1,people-1);
7324      return {
7325        q:{en:`${n1} and ${n2} divide ${things} pan${things===1?"":"s"} of ${it.en} among ${people} people. Write the answer as a fraction.`,
7326           es:`${n1} y ${n2} dividen ${things} bandeja${things===1?"":"s"} de ${it.es} entre ${people} personas. Escribe la respuesta como fracción.`},
7327        a:{en:`${things} ÷ ${people} = ${fr(things,people)}`, es:`${things} ÷ ${people} = ${fr(things,people)}`}
7328      };
7329    }
7330    if(k===3){
7331      const d=ri(3,8), n=ri(d+1, d*3);
7332      return {
7333        q:{en:`Write ${n} ÷ ${d} as a fraction for ${n1}'s ${it.en} problem, then write it as a mixed number.`,
7334           es:`Escribe ${n} ÷ ${d} como fracción para el problema de ${it.es} de ${n1}, luego como número mixto.`},
7335        a:{en:`${frR(n,d)} = ${mx(n,d)}`, es:`${frR(n,d)} = ${mx(n,d)}`}
7336      };
7337    }
7338    const people=ri(4,8), total=ri(people+2, people*2+3);
7339    return {
7340      q:{en:`${n1} pours ${total} liters of juice equally into ${people} jugs for the ${it.en} stand. How many liters in each jug?`,
7341         es:`${n1} sirve ${total} litros de jugo por igual en ${people} jarras para el puesto de ${it.es}. ¿Cuántos litros hay en cada jarra?`},
7342      a:{en:`${total} ÷ ${people} = ${mx(total,people)} liters`, es:`${total} ÷ ${people} = ${mx(total,people)} litros`}
7343    };
7344  }
7345},
7346{
7347  code:"5.NF.B.5", grade:5, dok:3,
7348  title:{en:"Multiplication as scaling",
7349         es:"La multiplicación como cambio de escala"},
7350  text:{en:"Interpret multiplication as scaling (resizing), by comparing the size of a product to the size of one factor on the basis of the size of the other factor, without performing the indicated multiplication.",
7351        es:"Interpreta la multiplicación como un cambio de escala, comparando el tamaño de un producto con el tamaño de un factor según el tamaño del otro factor, sin realizar la multiplicación indicada."},
7352  build(n1,n2,lvl){
7353    const it = pickItem();
7354
7355    /* ---- Support · DOK 1 : bigger or smaller ---- */
7356    if(lvl===1){
7357      const k=ri(1,4);
7358      if(k===1){
7359        const a=ri(10,40), f=ri(2,4);
7360        return {
7361          q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${f} times as many. Without multiplying, is ${n2}'s number bigger or smaller than ${a}?`,
7362             es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${f} veces esa cantidad. Sin multiplicar, ¿el número de ${n2} es mayor o menor que ${a}?`},
7363          a:{en:`Bigger — multiplying by ${f} (more than 1) makes it larger`,
7364             es:`Mayor — multiplicar por ${f} (más que 1) lo hace más grande`}
7365        };
7366      }
7367      if(k===2){
7368        const a=ri(12,40), d=pick([2,4]);
7369        return {
7370          q:{en:`${n1} has ${a} kg of ${it.en}. ${n2} has ${frR(1,d)} as much. Without multiplying, is ${n2}'s amount bigger or smaller?`,
7371             es:`${n1} tiene ${a} kg de ${it.es}. ${n2} tiene ${frR(1,d)} de esa cantidad. Sin multiplicar, ¿la cantidad de ${n2} es mayor o menor?`},
7372          a:{en:`Smaller — ${frR(1,d)} is less than 1`, es:`Menor — ${frR(1,d)} es menos que 1`}
7373        };
7374      }
7375      if(k===3){
7376        const a=ri(15,45);
7377        return {
7378          q:{en:`${n1} has ${a} ${it.en}. ${n2} has 1 times as many. Without multiplying, how do the two amounts compare?`,
7379             es:`${n1} tiene ${a} ${it.es}. ${n2} tiene 1 vez esa cantidad. Sin multiplicar, ¿cómo se comparan?`},
7380          a:{en:`The same — multiplying by 1 does not change size`,
7381             es:`Iguales — multiplicar por 1 no cambia el tamaño`}
7382        };
7383      }
7384      const a=ri(20,60), f=ri(3,6);
7385      return {
7386        q:{en:`${n1}'s recipe uses ${a} ${it.en}. ${n2} makes ${f} times the recipe. Will ${n2} need more or fewer ${it.en}? Explain without computing.`,
7387           es:`La receta de ${n1} usa ${a} ${it.es}. ${n2} hace ${f} veces la receta. ¿Necesitará más o menos ${it.es}? Explica sin calcular.`},
7388        a:{en:`More — scaling by ${f} enlarges it`, es:`Más — escalar por ${f} lo agranda`}
7389      };
7390    }
7391
7392    /* ---- Challenge · DOK 3 : compare without computing ---- */
7393    if(lvl===3){
7394      const k=ri(1,4);
7395      if(k===1){
7396        const a=ri(20,60), n=ri(3,7), d=n+ri(1,3);
7397        return {
7398          q:{en:`${n1} has ${a} kg of ${it.en}. ${n2} has ${frR(n,d)} times as much. Without multiplying, is ${n2}'s amount more or less than ${a} kg? Explain using the size of ${frR(n,d)}.`,
7399             es:`${n1} tiene ${a} kg de ${it.es}. ${n2} tiene ${frR(n,d)} de esa cantidad. Sin multiplicar, ¿es más o menos que ${a} kg? Explica usando el tamaño de ${frR(n,d)}.`},
7400          a:{en:`Less — ${frR(n,d)} < 1, so the product is smaller than ${a}`,
7401             es:`Menos — ${frR(n,d)} < 1, así que el producto es menor que ${a}`}
7402        };
7403      }
7404      if(k===2){
7405        const a=ri(20,50), n=ri(5,9), d=ri(2,4);
7406        return {
7407          q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${frR(n,d)} times as many. Without multiplying, will ${n2} have more or fewer? How do you know from the fraction alone?`,
7408             es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${frR(n,d)} de esa cantidad. Sin multiplicar, ¿tendrá más o menos? ¿Cómo lo sabes solo por la fracción?`},
7409          a:{en:`More — ${frR(n,d)} > 1 because ${n} > ${d}`,
7410             es:`Más — ${frR(n,d)} > 1 porque ${n} > ${d}`}
7411        };
7412      }
7413      if(k===3){
7414        const a=ri(20,60), d=pick([2,3,4]);
7415        return {
7416          q:{en:`${n2} says multiplying always makes numbers bigger, so ${a} × ${frR(1,d)} of a ${it.en} order must be more than ${a}. Explain why ${n2} is wrong without doing the multiplication.`,
7417             es:`${n2} dice que multiplicar siempre agranda, así que ${a} × ${frR(1,d)} de un pedido de ${it.es} debe ser más que ${a}. Explica por qué se equivoca sin multiplicar.`},
7418          a:{en:`Multiplying by a number less than 1 shrinks it — the product is less than ${a}`,
7419             es:`Multiplicar por un número menor que 1 lo reduce — el producto es menor que ${a}`}
7420        };
7421      }
7422      const a=ri(24,60), n=ri(3,5), d=n;
7423      return {
7424        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${frR(n,d)} times as many. Without multiplying, what is ${n2}'s amount? Explain what a fraction equal to 1 does.`,
7425           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${frR(n,d)} de esa cantidad. Sin multiplicar, ¿cuánto tiene ${n2}? Explica qué hace una fracción igual a 1.`},
7426        a:{en:`Same, ${a} — ${frR(n,d)} = 1 leaves the size unchanged`,
7427           es:`Lo mismo, ${a} — ${frR(n,d)}
7427 = 1 no cambia el tamaño`}
7428      };
7429    }
7430
7431    /* ---- On level · DOK 2 ---- */
7432    const k=ri(1,4);
7433    if(k===1){
7434      const a=ri(20,80), f=ri(2,6);
7435      return {
7436        q:{en:`${n1} has ${a} ${it.en}. ${n2} has ${f} times as many. Without multiplying, tell whether ${n2}'s amount is greater or less than ${a}, and explain why.`,
7437           es:`${n1} tiene ${a} ${it.es}. ${n2} tiene ${f} veces esa cantidad. Sin multiplicar, di si es mayor o menor que ${a} y explica por qué.`},
7438        a:{en:`Greater — the factor ${f} is more than 1`, es:`Mayor — el factor ${f} es más que 1`}
7439      };
7440    }
7441    if(k===2){
7442      const a=ri(20,80), d=pick([2,3,5]);
7443      return {
7444        q:{en:`${n1} measured ${a} kg of ${it.en}. ${n2} measured ${frR(1,d)} times as much. Is ${n2}'s amount greater or less? Explain without computing.`,
7445           es:`${n1} midió ${a} kg de ${it.es}. ${n2} midió ${frR(1,d)} de esa cantidad. ¿Es mayor o menor? Explica sin calcular.`},
7446        a:{en:`Less — ${frR(1,d)} is less than 1`, es:`Menor — ${frR(1,d)} es menos que 1`}
7447      };
7448    }
7449    if(k===3){
7450      const a=ri(20,60), n=ri(5,9), d=ri(2,4);
7451      const bigger = n/d > 1;
7452      return {
7453        q:{en:`${n1} has ${a} ${it.en} and ${n2} has ${frR(n,d)} times as many. Without multiplying, is ${n2}'s number bigger or smaller? How can you tell from ${frR(n,d)}?`,
7454           es:`${n1} tiene ${a} ${it.es} y ${n2} tiene ${frR(n,d)} de esa cantidad. Sin multiplicar, ¿es mayor o menor? ¿Cómo lo sabes por ${frR(n,d)}?`},
7455        a:{en:`${bigger?"Bigger":"Smaller"} — ${frR(n,d)} is ${bigger?"more":"less"} than 1`,
7456           es:`${bigger?"Mayor":"Menor"} — ${frR(n,d)} es ${bigger?"más":"menos"} que 1`}
7457      };
7458    }
7459    const a=ri(30,90), f=ri(2,5);
7460    return {
7461      q:{en:`${n1}'s ${it.en} order is ${a} kg. ${n2} orders ${f} times as much, and a friend orders ${frR(1,2)} as much as ${n1}. Order the three amounts from smallest to largest without multiplying.`,
7462         es:`El pedido de ${it.es} de ${n1} es ${a} kg. ${n2} pide ${f} veces esa cantidad y un amigo pide ${frR(1,2)} de la de ${n1}. Ordena las tres cantidades de menor a mayor sin multiplicar.`},
7463      a:{en:`friend (${frR(1,2)}×) < ${n1} (${a}) < ${n2} (${f}×)`,
7464         es:`amigo (${frR(1,2)}×) < ${n1} (${a}) < ${n2} (${f}×)`}
7465    };
7466  }
7467},
7468{
7469  code:"5.NF.B.6", grade:5, dok:2,
7470  title:{en:"Multiply fractions & mixed numbers — word problems",
7471         es:"Multiplicar fracciones y números mixtos — problemas"},
7472  text:{en:"Solve real world problems involving multiplication of fractions and mixed numbers, e.g., by using visual fraction models or equations to represent the problem.",
7473        es:"Resuelve problemas del mundo real de multiplicación de fracciones y números mixtos, por ejemplo, usando modelos visuales de fracciones o ecuaciones para representar el problema."},
7474  build(n1,n2,lvl){
7475    const it = pickItem(), bin = pick(THEME.bins);
7476
7477    /* ---- Support · DOK 1 : unit × unit, halves ---- */
7478    if(lvl===1){
7479      const k=ri(1,4);
7480      if(k===1){
7481        const d=pick([2,3,4]);
7482        return {
7483          q:{en:`${n1}'s ${bin.one.en} is 1/2 full of ${it.en}. ${n1} gives ${frR(1,d)} of what's there to ${n2}. What fraction of the whole ${bin.one.en} is that? (Hint: 1/${d} of 1/2.)`,
7484             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${n1} está a la mitad de ${it.es}. ${n1} le da ${frR(1,d)} de lo que hay a ${n2}. ¿Qué fracción de todo ${elLaEs(bin)} ${bin.one.es} es? (Pista: 1/${d} de 1/2.)`},
7485          a:{en:`${frR(1,d)} × 1/2 = ${fr(1,2*d)}`, es:`${frR(1,d)} × 1/2 = ${fr(1,2*d)}`}
7486        };
7487      }
7488      if(k===2){
7489        const dA=2, dB=pick([3,4]);
7490        return {
7491          q:{en:`A recipe for the ${it.en} sale needs ${frR(1,dB)} cup of sugar. ${n1} makes only 1/2 of the recipe. How much sugar is needed? Multiply the fractions.`,
7492             es:`Una receta para la venta de ${it.es} necesita ${frR(1,dB)} taza de azúcar. ${n1} hace solo la mitad de la receta. ¿Cuánta azúcar se necesita? Multiplica las fracciones.`},
7493          a:{en:`1/2 × ${frR(1,dB)} = ${fr(1,2*dB)}`, es:`1/2 × ${frR(1,dB)} = ${fr(1,2*dB)}`}
7494        };
7495      }
7496      if(k===3){
7497        const n=ri(2,3), d=pick([3,4]);
7498        return {
7499          q:{en:`${n1} walks ${frR(1,d)} km each lap around the ${it.en} field and does ${n} laps. Add ${Array(n).fill(frR(1,d)).join(" + ")} or multiply. How far is that?`,
7500             es:`${n1} camina ${frR(1,d)} km por vuelta alrededor del campo de ${it.es} y da ${n} vueltas. Suma ${Array(n).fill(frR(1,d)).join(" + ")} o multiplica. ¿Cuánto es?`},
7501          a:{en:`${n} × ${frR(1,d)} = ${mx(n,d)} km`, es:`${n} × ${frR(1,d)} = ${mx(n,d)} km`}
7502        };
7503      }
7504      return {
7505        q:{en:`${n2} has 1/2 of a tray of ${it.en} and shares 1/2 of it with ${n1}. What fraction of the whole tray does ${n1} get? Draw it if it helps.`,
7506           es:`${n2} tiene 1/2 bandeja de ${it.es} y comparte la mitad con ${n1}. ¿Qué fracción de toda la bandeja recibe ${n1}? Dibújalo si te ayuda.`},
7507        a:{en:`1/2 × 1/2 = 1/4`, es:`1/2 × 1/2 = 1/4`}
7508      };
7509    }
7510
7511    /* ---- Challenge · DOK 3 ---- */
7512    if(lvl===3){
7513      const k=ri(1,5);
7514      if(k===1){
7515        const dA=pick([2,3]), dB=pick([3,4]);
7516        return {
7517          q:{en:`${n2} computes ${frR(1,dA)} × ${frR(1,dB)} for the ${it.en} recipe and gets ${frR(2,dA+dB)} by adding tops and bottoms. Name the error and give the correct product.`,
7518             es:`${n2} calcula ${frR(1,dA)} × ${frR(1,dB)} para la receta de ${it.es} y obtiene ${frR(2,dA+dB)} sumando arriba y abajo. Nombra el error y da el producto correcto.`},
7519          a:{en:`Added instead of multiplied — ${frR(1,dA)}×${frR(1,dB)} = ${fr(1,dA*dB)}`,
7520             es:`Sumó en vez de multiplicar — ${frR(1,dA)}×${frR(1,dB)} = ${fr(1,dA*dB)}`}
7521        };
7522      }
7523      if(k===2){
7524        const a=1, dA=2, b=ri(2,3), dB=pick([3,4]);
7525        return {
7526          q:{en:`${n1} multiplies ${frR(a,dA)} × ${frR(b,dB)} for the ${it.en} project and the product is SMALLER than both factors. ${n2} says that must be a mistake. Is it? Explain why multiplying fractions can shrink.`,
7527             es:`${n1} multiplica ${frR(a,dA)} × ${frR(b,dB)} para el proyecto de ${it.es} y el producto es MENOR que los dos factores. ${n2} dice que debe ser un error. ¿Lo es? Explica por qué multiplicar fracciones puede reducir.`},
7528          a:{en:`No error — taking ${frR(a,dA)} OF ${frR(b,dB)} gives ${fr(a*b,dA*dB)}, a part of a part`,
7529             es:`No es error — tomar ${frR(a,dA)} DE ${frR(b,dB)} da ${fr(a*b,dA*dB)}, una parte de una parte`}
7530        };
7531      }
7532      if(k===3){
7533        const W=1, wd=2, n=ri(2,4), whole=n, half=n/2;
7534        return {
7535          q:{en:`Each bag of ${it.en} has a mass of 1 ${frR(W,wd)} kg. ${n1} lifts ${n} bags at once. What is the total mass? Show how you multiplied the mixed number.`,
7536             es:`Cada bolsa de ${it.es} tiene una masa de 1 ${frR(W,wd)} kg. ${n1} carga ${n} bolsas a la vez. ¿Cuál es la masa total? Muestra cómo multiplicaste el número mixto.`},
7537          a:{en:`${n} × 1 ${frR(W,wd)} = ${n} + ${mx(n*W,wd)} = ${mx(n*wd*1+n*W, wd)} kg`,
7538             es:`${n} × 1 ${frR(W,wd)} = ${n} + ${mx(n*W,wd)} = ${mx(n*wd*1+n*W, wd)} kg`}
7539        };
7540      }
7541      if(k===4){
7542        const b=ri(2,3), dB=4, target=fr(b,dB*2);
7543        return {
7544          q:{en:`${n1} needs exactly ${target} of a ${bin.one.en} of ${it.en} and plans to take 1/2 of what ${n2} has. Write an equation with n for the fraction ${n2} must have, then solve.`,
7545             es:`${n1} necesita exactamente ${target} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} y planea tomar la mitad de lo que tiene ${n2}. Escribe una ecuación con n para la fracción que debe tener ${n2} y resuélvela.`},
7546          a:{en:`1/2 × n = ${target}; n = ${frR(b,dB)}`, es:`1/2 × n = ${target}; n = ${frR(b,dB)}`}
7547        };
7548      }
7549      const dA=2, dB=pick([3,4]), bA=dB===3?2:ri(2,3);
7550      const p1=fr(1*bA,2*dB), whole=1;
7551      return {
7552        q:{en:`${n1} uses 1/2 of ${frR(bA,dB)} of a jug for the ${it.en} stand; ${n2} uses ${frR(1,dB)} of a full jug. Who uses more? Prove it by computing both amounts.`,
7553           es:`${n1} usa la mitad de ${frR(bA,dB)} de una jarra para el puesto de ${it.es}; ${n2} usa ${frR(1,dB)} de una jarra llena. ¿Quién usa más? Compruébalo calculando las dos cantidades.`},
7554        a:{en:`${p1} vs ${fr(1,dB)} — ${bA/(2*dB) > 1/dB ? n1 : n2} uses more`,
7555           es:`${p1} vs ${fr(1,dB)} — ${bA/(2*dB) > 1/dB ? n1 : n2} usa más`}
7556      };
7557    }
7558
7559    /* ---- On level · DOK 2 ---- */
7560    const k=ri(1,5);
7561    if(k===1){
7562      const a=ri(1,2), dA=pick([2,3]), b=ri(1,3), dB=pick([3,4]);
7563      return {
7564        q:{en:`${n1} has ${frR(b,dB)} of a ${bin.one.en} of ${it.en} and gives ${frR(a,dA)} of it to ${n2}. What fraction of the whole ${bin.one.en} does ${n2} get?`,
7565           es:`${n1} tiene ${frR(b,dB)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} y le da ${frR(a,dA)} de eso a ${n2}. ¿Qué fracción de todo ${elLaEs(bin)} ${bin.one.es} recibe ${n2}?`},
7566        a:{en:`${frR(a,dA)} × ${frR(b,dB)} = ${fr(a*b,dA*dB)}`, es:`${frR(a,dA)} × ${frR(b,dB)} = ${fr(a*b,dA*dB)}`}
7567      };
7568    }
7569    if(k===2){
7570      const n=ri(2,4), W=1, wd=pick([2,4]), num=ri(1,wd-1);
7571      return {
7572        q:{en:`${n1} fills ${n} pitchers with 1 ${frR(num,wd)} liters of juice each for the ${it.en} sale. How many liters is that in all?`,
7573           es:`${n1} llena ${n} jarras con 1 ${frR(num,wd)} litros de jugo cada una para la venta de ${it.es}. ¿Cuántos litros son en total?`},
7574        a:{en:`${n} × 1 ${frR(num,wd)}
7574 = ${mx(n*(wd+num),wd)} liters`, es:`${n} × 1 ${frR(num,wd)} = ${mx(n*(wd+num),wd)} litros`}
7575      };
7576    }
7577    if(k===3){
7578      const dA=2, b=ri(2,3), dB=pick([3,4]);
7579      return {
7580        q:{en:`A board for the ${it.en} shelf is ${frR(b,dB)} m long. ${n2} needs a piece 1/2 that length. How long is the piece?`,
7581           es:`Una tabla para el estante de ${it.es} mide ${frR(b,dB)} m. ${n2} necesita un pedazo de la mitad de ese largo. ¿Cuánto mide el pedazo?`},
7582        a:{en:`1/2 × ${frR(b,dB)} = ${fr(b,2*dB)} m`, es:`1/2 × ${frR(b,dB)} = ${fr(b,2*dB)} m`}
7583      };
7584    }
7585    if(k===4){
7586      const a=ri(1,3), d=4, hrs=ri(2,3);
7587      return {
7588        q:{en:`${n1} reads about ${it.en} for ${frR(a,d)} hour each night. After ${hrs} nights, how many hours has ${n1} read?`,
7589           es:`${n1} lee sobre ${it.es} durante ${frR(a,d)} de hora cada noche. Después de ${hrs} noches, ¿cuántas horas ha leído?`},
7590        a:{en:`${hrs} × ${frR(a,d)} = ${mx(hrs*a,d)} hour${hrs*a===d?"":"s"}`, es:`${hrs} × ${frR(a,d)} = ${mx(hrs*a,d)} hora${hrs*a===d?"":"s"}`}
7591      };
7592    }
7593    const L=1, ld=2, w=ri(1,3), wd=4;
7594    return {
7595      q:{en:`${n1}'s garden bed by the ${it.en} stand is 1 ${frR(L,ld)} m long and ${frR(w,wd)} m wide. What is its area? Multiply length by width.`,
7596         es:`El cantero de ${n1} junto al puesto de ${it.es} mide 1 ${frR(L,ld)} m de largo y ${frR(w,wd)} m de ancho. ¿Cuál es su área? Multiplica largo por ancho.`},
7597      a:{en:`1 ${frR(L,ld)} × ${frR(w,wd)} = ${fr((ld+L)*w, ld*wd)} sq m`, es:`1 ${frR(L,ld)} × ${frR(w,wd)} = ${fr((ld+L)*w, ld*wd)} m cuadrados`}
7598    };
7599  }
7600},
7601{
7602  code:"5.NF.B.7.c", grade:5, dok:3,
7603  title:{en:"Divide with unit fractions",
7604         es:"Dividir con fracciones unitarias"},
7605  text:{en:"Solve real world problems involving division of unit fractions by non-zero whole numbers and division of whole numbers by unit fractions, e.g., by using visual fraction models and equations to represent the problem.",
7606        es:"Resuelve problemas del mundo real de división de fracciones unitarias entre números enteros distintos de cero y de números enteros entre fracciones unitarias, por ejemplo, usando modelos visuales de fracciones y ecuaciones."},
7607  build(n1,n2,lvl){
7608    const it = pickItem(), bin = pick(THEME.bins);
7609
7610    /* ---- Support · DOK 1 : whole ÷ unit fraction, small numbers ---- */
7611    if(lvl===1){
7612      const k=ri(1,4);
7613      if(k===1){
7614        const w=ri(2,4), d=pick([2,3,4]);
7615        return {
7616          q:{en:`${n1} has ${w} liters of juice for the ${it.en} stand and pours ${frR(1,d)} liter into each cup. How many cups can ${n1} fill? (Hint: how many ${frR(1,d)}s are in 1?)`,
7617             es:`${n1} tiene ${w} litros de jugo para el puesto de ${it.es} y sirve ${frR(1,d)} de litro en cada vaso. ¿Cuántos vasos puede llenar? (Pista: ¿cuántos ${frR(1,d)} hay en 1?)`},
7618          a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} cups`, es:`${w} ÷ ${frR(1,d)} = ${w*d} vasos`}
7619        };
7620      }
7621      if(k===2){
7622        const w=ri(2,5), d=pick([2,3]);
7623        return {
7624          q:{en:`${n1} cuts ${w} meters of ribbon for the ${it.en} display into pieces ${frR(1,d)} meter long. How many pieces does ${n1} get?`,
7625             es:`${n1} corta ${w} metros de cinta para la exhibición de ${it.es} en pedazos de ${frR(1,d)} de metro. ¿Cuántos pedazos obtiene?`},
7626          a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} pieces`, es:`${w} ÷ ${frR(1,d)} = ${w*d} pedazos`}
7627        };
7628      }
7629      if(k===3){
7630        const d=pick([2,3,4]), n=ri(2,3);
7631        return {
7632          q:{en:`${n1} has ${frR(1,d)} of a ${bin.one.en} of ${it.en} and shares it equally with ${n-1===1?"1 friend":(n-1)+" friends"} (${n} people total). What fraction of the whole ${bin.one.en} does each person get?`,
7633             es:`${n1} tiene ${frR(1,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} y lo comparte por igual entre ${n} personas. ¿Qué fracción de todo ${elLaEs(bin)} ${bin.one.es} recibe cada persona?`},
7634          a:{en:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`, es:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`}
7635        };
7636      }
7637      const w=ri(2,4), d=2;
7638      return {
7639        q:{en:`${n1} splits ${w} trays of ${it.en} into half-tray servings. How many servings is that? Draw the halves if it helps.`,
7640           es:`${n1} divide ${w} bandejas de ${it.es} en porciones de media bandeja. ¿Cuántas porciones son? Dibuja las mitades si te ayuda.`},
7641        a:{en:`${w} ÷ ${frR(1,2)} = ${w*2} servings`, es:`${w} ÷ ${frR(1,2)} = ${w*2} porciones`}
7642      };
7643    }
7644
7645    /* ---- Challenge · DOK 3 : the "why did it get bigger" reasoning ---- */
7646    if(lvl===3){
7647      const k=ri(1,5);
7648      if(k===1){
7649        const w=ri(3,6), d=pick([3,4,5]);
7650        return {
7651          q:{en:`${n1} divides ${w} liters of juice into ${frR(1,d)}-liter cups and gets ${w*d} cups — MORE than ${w}. ${n2} says dividing should always make a smaller number. Explain why ${n2} is wrong here.`,
7652             es:`${n1} divide ${w} litros de jugo en vasos de ${frR(1,d)} de litro y obtiene ${w*d} vasos — MÁS que ${w}. ${n2} dice que dividir siempre da un número menor. Explica por qué ${n2} se equivoca aquí.`},
7653          a:{en:`Dividing by a number less than 1 asks "how many small parts fit" — ${w} ÷ ${frR(1,d)} = ${w*d}`,
7654             es:`Dividir entre un número menor que 1 pregunta "cuántas partes pequeñas caben" — ${w} ÷ ${frR(1,d)} = ${w*d}`}
7655        };
7656      }
7657      if(k===2){
7658        const d=pick([2,3,4]), n=ri(3,5);
7659        return {
7660          q:{en:`${n1} has ${frR(1,d)} of a ${bin.one.en} of ${it.en} to split among ${n} classmates. ${n2} says each gets ${frR(n,d)}. What did ${n2} do wrong? Give the correct fraction and explain what happens to the pieces.`,
7661             es:`${n1} tiene ${frR(1,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} para repartir entre ${n} compañeros. ${n2} dice que cada uno recibe ${frR(n,d)}. ¿Qué hizo mal? Da la fracción correcta y explica qué pasa con los pedazos.`},
7662          a:{en:`Multiplied instead of divided — ${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}, pieces get smaller`,
7663             es:`Multiplicó en vez de dividir — ${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}, los pedazos se hacen más pequeños`}
7664        };
7665      }
7666      if(k===3){
7667        const w=ri(3,7), d=pick([3,4]), need=w*d;
7668        return {
7669          q:{en:`${n1} needs ${need} servings of ${it.en}, each ${frR(1,d)} of a ${bin.one.en}. Write an equation with n for how many whole ${bin.en} ${n1} needs, then solve and check by multiplying.`,
7670             es:`${n1} necesita ${need} porciones de ${it.es}, cada una de ${frR(1,d)} de ${bin.one.es}. Escribe una ecuación con n para ${cuantosLc(bin)} ${bin.es} enteras necesita, resuélvela y comprueba multiplicando.`},
7671          a:{en:`n ÷ ${frR(1,d)} = ${need}; n = ${w} (check: ${w} × ${d} = ${need})`,
7672             es:`n ÷ ${frR(1,d)} = ${need}; n = ${w} (comprueba: ${w} × ${d} = ${need})`}
7673        };
7674      }
7675      if(k===4){
7676        const w=ri(2,4), d=pick([3,4]), n=ri(2,3);
7677        return {
7678          q:{en:`${n1} compares two ${it.en} problems without a calculator: ${w} ÷ ${frR(1,d)} and ${frR(1,d)} ÷ ${n}. Which gives the larger answer, and why? Explain what each one is really asking.`,
7679             es:`${n1} compara dos problemas de ${it.es} sin calculadora: ${w} ÷ ${frR(1,d)} y ${frR(1,d)} ÷ ${n}. ¿Cuál da el resultado mayor y por qué? Explica qué pregunta cada uno.`},
7680          a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} (how many small parts fit); ${frR(1,d)} ÷ ${n} = ${fr(1,d*n)} (splitting a part) — the first is larger`,
7681             es:`${w} ÷ ${frR(1,d)} = ${w*d} (cuántas partes caben); ${frR(1,d)} ÷ ${n} = ${fr(1,d*n)} (partir un pedazo) — el primero es mayor`}
7682        };
7683      }
7684      const w=ri(4,6), d=pick([2,4]), used=ri(2,w-2);   // >=2 so "liters" stays plural
7685      return {
7686        q:{en:`${n1} started with ${w} liters of water for the ${it.en} stand, used ${used} liters, then poured the rest into ${frR(1,d)}-liter bottles. How many bottles? Show both steps.`,
7687           es:`${n1} empezó con ${w} litros de agua para el puesto de ${it.es}, usó ${used} litros y sirvió el resto en botellas de ${frR(1,d)} de litro. ¿Cuántas botellas? Muestra los dos pasos.`},
7688        a:{en:`${w}−${used}=${w-used}, ÷${frR(1,d)} = ${(w-used)*d} bottles`,
7689           es:`${w}−${used}=${w-used}, ÷${frR(1,d)} = ${(w-used)*d} botellas`}
7690      };
7691    }
7692
7693    /* ---- On level · DOK 2 : both directions ---- */
7694    const k=ri(1,5);
7695    if(k===1){
7696      const w=ri(3,8), d=pick([2,3,4,5]);
7697      return {
7698        q:{en:`${n1} has ${w} liters of juice for the ${it.en} stand and fills cups holding ${frR(1,d)} liter each. How many cups can ${n1} fill?`,
7699           es:`${n1} tiene ${w} litros de jugo para el puesto de ${it.es} y llena vasos de ${frR(1,d)} de litro. ¿Cuántos vasos puede llenar?`},
7700        a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} cups`, es:`${w} ÷ ${frR(1,d)} = ${w*d} vasos`}
7701      };
7702    }
7703    if(k===2){
7704      const d=pick([2,3,4]), n=ri(2,5);
7705      return {
7706        q:{en:`${n1} has ${frR(1,d)} of a ${bin.one.en} of ${it.en} and splits it equally among ${n} people. What fraction of the whole ${bin.one.en} does each person get?`,
7707           es:`${n1} tiene ${frR(1,d)} de ${unUnaEs(bin)} ${bin.one.es} de ${it.es} y lo divide por igual entre ${n} personas. ¿Qué fracción de todo ${elLaEs(bin)} ${bin.one.es}
7707 recibe cada una?`},
7708        a:{en:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`, es:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`}
7709      };
7710    }
7711    if(k===3){
7712      const w=ri(2,6), d=pick([3,4,6]);
7713      return {
7714        q:{en:`${n1} cuts ${w} meters of string for the ${it.en} display into ${frR(1,d)}-meter pieces. How many pieces does ${n1} get?`,
7715           es:`${n1} corta ${w} metros de cordel para la exhibición de ${it.es} en pedazos de ${frR(1,d)} de metro. ¿Cuántos pedazos obtiene?`},
7716        a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} pieces`, es:`${w} ÷ ${frR(1,d)} = ${w*d} pedazos`}
7717      };
7718    }
7719    if(k===4){
7720      const d=pick([2,3]), n=ri(3,6);
7721      return {
7722        q:{en:`${n1} and ${n2} share ${frR(1,d)} of a pan of ${it.en} with ${n-2} other classmates (${n} people in all). How much of the whole pan does each person get?`,
7723           es:`${n1} y ${n2} comparten ${frR(1,d)} de una bandeja de ${it.es} con otros compañeros (${n} personas en total). ¿Cuánto de toda la bandeja recibe cada persona?`},
7724        a:{en:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`, es:`${frR(1,d)} ÷ ${n} = ${fr(1,d*n)}`}
7725      };
7726    }
7727    const w=ri(3,7), d=pick([2,4]);
7728    return {
7729      q:{en:`${n1} divides ${w} pans of ${it.en} into servings of ${frR(1,d)} pan each. How many servings, and is that more or fewer than ${w}? Explain in one sentence.`,
7730         es:`${n1} divide ${w} bandejas de ${it.es} en porciones de ${frR(1,d)} de bandeja. ¿Cuántas porciones y son más o menos que ${w}? Explica en una oración.`},
7731      a:{en:`${w} ÷ ${frR(1,d)} = ${w*d} servings — more, because each serving is less than one pan`,
7732         es:`${w} ÷ ${frR(1,d)} = ${w*d} porciones — más, porque cada porción es menos de una bandeja`}
7733    };
7734  }
7735},
7736{
7737  code:"5.MD.A.1", grade:5, dok:2,
7738  title:{en:"Convert measurement units",
7739         es:"Convertir unidades de medida"},
7740  text:{en:"Convert among different-sized standard measurement units within a given measurement system (e.g., convert 5 cm to 0.05 m), and use these conversions in solving multi-step, real world problems.",
7741        es:"Convierte entre unidades de medida estándar de distinto tamaño dentro de un mismo sistema (por ejemplo, convierte 5 cm a 0.05 m), y usa estas conversiones para resolver problemas de varios pasos del mundo real."},
7742  build(n1,n2,lvl){
7743    const it = pickItem();
7744
7745    /* ---- Support · DOK 1 : one conversion, friendly numbers ---- */
7746    if(lvl===1){
7747      const k=ri(1,4);
7748      if(k===1){
7749        const m=ri(2,9);
7750        return {
7751          q:{en:`${n1}'s ribbon for the ${it.en} display is ${m} meters long. How many centimeters is that? (1 m = 100 cm)`,
7752             es:`La cinta de ${n1} para la exhibición de ${it.es} mide ${m} metros. ¿Cuántos centímetros son? (1 m = 100 cm)`},
7753          a:{en:`${m} × 100 = ${m*100} cm`, es:`${m} × 100 = ${m*100} cm`}
7754        };
7755      }
7756      if(k===2){
7757        const kg=ri(2,9);
7758        return {
7759          q:{en:`${n1} has ${kg} kilograms of ${it.en}. How many grams is that? (1 kg = 1,000 g)`,
7760             es:`${n1} tiene ${kg} kilogramos de ${it.es}. ¿Cuántos gramos son? (1 kg = 1,000 g)`},
7761          a:{en:`${kg} × 1,000 = ${kg*1000} g`, es:`${kg} × 1,000 = ${kg*1000} g`}
7762        };
7763      }
7764      if(k===3){
7765        const cm=ri(2,9)*100;
7766        return {
7767          q:{en:`${n1} measured ${cm} centimeters of string for the ${it.en} project. How many meters is that?`,
7768             es:`${n1} midió ${cm} centímetros de cordel para el proyecto de ${it.es}. ¿Cuántos metros son?`},
7769          a:{en:`${cm} ÷ 100 = ${cm/100} m`, es:`${cm} ÷ 100 = ${cm/100} m`}
7770        };
7771      }
7772      const L=ri(2,9);
7773      return {
7774        q:{en:`${n1} poured ${L} liters of juice at the ${it.en} stand. How many milliliters is that? (1 L = 1,000 mL)`,
7775           es:`${n1} sirvió ${L} litros de jugo en el puesto de ${it.es}. ¿Cuántos mililitros son? (1 L = 1,000 mL)`},
7776        a:{en:`${L} × 1,000 = ${L*1000} mL`, es:`${L} × 1,000 = ${L*1000} mL`}
7777      };
7778    }
7779
7780    /* ---- Challenge · DOK 3 : multi-step with conversion ---- */
7781    if(lvl===3){
7782      const k=ri(1,4);
7783      if(k===1){
7784        const m=ri(3,8), cm=ri(20,80), pieces=ri(4,9);
7785        const totalCm = m*100 + cm;
7786        return {
7787          q:{en:`${n1} has ${m} m ${cm} cm of ribbon for the ${it.en} display and cuts it into ${pieces} equal pieces. How long is each piece in centimeters? Convert first, then divide.`,
7788             es:`${n1} tiene ${m} m ${cm} cm de cinta para la exhibición de ${it.es} y la corta en ${pieces} pedazos iguales. ¿Cuánto mide cada pedazo en centímetros? Convierte primero y luego divide.`},
7789          a:{en:`${totalCm} cm ÷ ${pieces} = ${(totalCm/pieces).toFixed(1)} cm`,
7790             es:`${totalCm} cm ÷ ${pieces} = ${(totalCm/pieces).toFixed(1)} cm`}
7791        };
7792      }
7793      if(k===2){
7794        const kg=ri(2,6), g=ri(100,900), used=ri(300,900);
7795        const totalG = kg*1000 + g;
7796        return {
7797          q:{en:`${n1} started with ${kg} kg ${g} g of ${it.en} and used ${used} g. How many grams are left? Then write the answer in kilograms and grams.`,
7798             es:`${n1} empezó con ${kg} kg ${g} g de ${it.es} y usó ${used} g. ¿Cuántos gramos quedan? Luego escribe la respuesta en kilogramos y gramos.`},
7799          a:{en:`${totalG}−${used} = ${totalG-used} g = ${Math.floor((totalG-used)/1000)} kg ${(totalG-used)%1000} g`,
7800             es:`${totalG}−${used} = ${totalG-used} g = ${Math.floor((totalG-used)/1000)} kg ${(totalG-used)%1000} g`}
7801        };
7802      }
7803      if(k===3){
7804        const cm=ri(20,90);
7805        return {
7806          q:{en:`${n2} says ${cm} cm of ${it.en} ribbon is ${cm*100} m because there are 100 cm in a meter. Explain ${n2}'s mistake and give the correct length in meters.`,
7807             es:`${n2} dice que ${cm} cm de cinta de ${it.es} son ${cm*100} m porque hay 100 cm en un metro. Explica el error y da la longitud correcta en metros.`},
7808          a:{en:`Multiplied instead of dividing — ${cm} ÷ 100 = ${(cm/100).toFixed(2)} m`,
7809             es:`Multiplicó en vez de dividir — ${cm} ÷ 100 = ${(cm/100).toFixed(2)} m`}
7810        };
7811      }
7812      const L=ri(3,8), mL=ri(100,900), cups=ri(4,8);
7813      const totalML = L*1000 + mL;
7814      return {
7815        q:{en:`${n1} has ${L} L ${mL} mL of juice for the ${it.en} stand and fills ${cups} equal cups. How many milliliters in each cup? Show the conversion step.`,
7816           es:`${n1} tiene ${L} L ${mL} mL de jugo para el puesto de ${it.es} y llena ${cups} vasos iguales. ¿Cuántos mililitros hay en cada vaso? Muestra el paso de conversión.`},
7817        a:{en:`${totalML} mL ÷ ${cups} = ${(totalML/cups).toFixed(1)} mL`,
7818           es:`${totalML} mL ÷ ${cups} = ${(totalML/cups).toFixed(1)} mL`}
7819      };
7820    }
7821
7822    /* ---- On level · DOK 2 ---- */
7823    const k=ri(1,4);
7824    if(k===1){
7825      const m=ri(2,9), cm=ri(10,90);
7826      return {
7827        q:{en:`${n1}'s ${it.en} table is ${m} m ${cm} cm long. What is that length in centimeters?`,
7828           es:`La mesa de ${it.es} de ${n1} mide ${m} m ${cm} cm. ¿Cuál es esa longitud en centímetros?`},
7829        a:{en:`${m}×100 + ${cm} = ${m*100+cm} cm`, es:`${m}×100 + ${cm} = ${m*100+cm} cm`}
7830      };
7831    }
7832    if(k===2){
7833      const kg=ri(2,8), g=ri(100,900);
7834      return {
7835        q:{en:`${n1} weighed ${kg} kg ${g} g of ${it.en}. How many grams is that in all?`,
7836           es:`${n1} pesó ${kg} kg ${g} g de ${it.es}. ¿Cuántos gramos son en total?`},
7837        a:{en:`${kg}×1,000 + ${g} = ${kg*1000+g} g`, es:`${kg}×1,000 + ${g} = ${kg*1000+g} g`}
7838      };
7839    }
7840    if(k===3){
7841      const mL=ri(2,9)*500;
7842      return {
7843        q:{en:`${n1} and ${n2} poured ${mL} mL of juice for the ${it.en} stand. How many liters is that?`,
7844           es:`${n1} y ${n2} sirvieron ${mL} mL de jugo para el puesto de ${it.es}. ¿Cuántos litros son?`},
7845        a:{en:`${mL} ÷ 1,000 = ${mL/1000} L`, es:`${mL} ÷ 1,000 = ${mL/1000} L`}
7846      };
7847    }
7848    const m=ri(3,9), pieces=ri(4,8);
7849    const totalCm=m*100;
7850    return {
7851      q:{en:`${n1} cuts ${m} meters of ribbon for the ${it.en} display into ${pieces} equal pieces. How many centimeters long is each piece?`,
7852         es:`${n1} corta ${m} metros de cinta para la exhibición de ${it.es} en ${pieces} pedazos iguales. ¿Cuántos centímetros mide cada pedazo?`},
7853      a:{en:`${totalCm} ÷ ${pieces} = ${(totalCm/pieces).toFixed(1)} cm`,
7854         es:`${totalCm} ÷ ${pieces} = ${(totalCm/pieces).toFixed(1)} cm`}
7855    };
7856  }
7857},
7858{
7859  code:"5.MD.C.5.b", grade:5, dok:2,
7860  title:{en:"Volume of rectangular prisms",
7861         es:"Volumen de prismas rectangulares"},
7862  text:{en:"Apply the formulas V = l × w × h and V = b × h for rectangular prisms to find volumes of right rectangular prisms with whole-number edge lengths in the context of solving real world and mathematical problems.",
7863        es:"Aplica las fórmulas V = l × a × h y V = b × h para hallar volúmenes de prismas rectangulares rectos con longitudes de arista de números enteros en el contexto de problemas del mundo real y matemáticos."},
7864  build(n1,n2,lvl){
7865    const it = pickItem(), bin = pick(THEME.bins);
7866    const u = ITEMLOCK ? {en:"cm",es:"cm"} : pick([{en:"cm",es:"cm"},{en:"inches",es:"pulgadas"}]);
7867    const cu = {en:"cubic "+u.en, es:u.es+" cúbicos"};
7868
7869    /* ---- Support · DOK 1 : small edges, formula given ---- */
7870    if(lvl===1){
7871      const k=ri(1,4);
7872      if(k===1){
7873        const l=ri(3,6), w=ri(2,4), h=ri(2,4);
7874        return {
7875          q:{en:`${n1}'s ${bin.one.en} for ${it.en} is ${l} ${u.en} long, ${w} ${u.en} wide, and ${h} ${u.en} tall. Use V = l × w × h to find the volume.`,
7876             es:`${elLaEs(bin)==="el"?"El":"La"} ${bin.one.es} de ${it.es} de ${n1} mide ${l} ${u.es} de largo, ${w} ${u.es} de ancho y ${h} ${u.es} de alto. Usa V = l × a × h para hallar el volumen.`},
7877          a:{en:`${l} × ${w} × ${h} = ${l*w*h} ${cu.en}`, es:`${l} × ${w} × ${h} = ${l*w*h} ${cu.es}`}
7878        };
7879      }
7880      if(k===2){
7881        const s=ri(2,5);
7882        return {
7883          q:{en:`${n1} packs ${it.en} in a cube-shaped box with every edge ${s} ${u.en}. What is its volume?`,
7884             es:`${n1} empaca ${it.es} en una caja cúbica con todas las aristas de ${s} ${u.es}. ¿Cuál es su volumen?`},
7885          a:{en:`${s} × ${s} × ${s} = ${s*s*s} ${cu.en}`, es:`${s} × ${s} × ${s} = ${s*s*s} ${cu.es}`}
7886        };
7887      }
7888      if(k===3){
7889        const b=ri(6,15), h=ri(2,5);
7890        return {
7891          q:{en:`The base of ${n1}'s ${it.en} box covers ${b} square ${u.en} and the box is ${h} ${u.en} tall. Use V = b × h to find the volume.`,
7892             es:`La base de la caja de ${it.es} de ${n1} cubre ${b} ${u.es} cuadrados y la caja mide ${h} ${u.es} de alto. Usa V = b × h para hallar el volumen.`},
7893          a:{en:`${b} × ${h} = ${b*h} ${cu.en}`, es:`${b} × ${h} = ${b*h} ${cu.es}`}
7894        };
7895      }
7896      const l=ri(4,7), w=ri(2,3), h=2;
7897      return {
7898        q:{en:`${n1} stacks ${it.en} in a box ${l} by ${w} by ${h} ${u.en}. How many unit cubes would fill it?`,
7899           es:`${n1} apila ${it.es} en una caja de ${l} por ${w} por ${h} ${u.es}. ¿Cuántos cubos unitarios la llenarían?`},
7900        a:{en:`${l} × ${w} × ${h} = ${l*w*h}`, es:`${l} × ${w} × ${h} = ${l*w*h}`}
7901      };
7902    }
7903
7904    /* ---- Challenge · DOK 3 : missing edge, same volume different shape ---- */
7905    if(lvl===3){
7906      const k=ri(1,5);
7907      if(k===1){
7908        const l=ri(4,9), w=ri(3,6), h=ri(2,6), V=l*w*h;
7909        return {
7910          q:{en:`${n1}'s ${it.en} crate holds ${V} ${cu.en}. Its base is ${l} ${u.en} by ${w} ${u.en}. Write an equation with n for the height, then solve it.`,
7911             es:`La caja de ${it.es} de ${n1} tiene ${V} ${cu.es}. Su base mide ${l} por ${w} ${u.es}. Escribe una ecuación con n para la altura y resuélvela.`},
7912          a:{en:`${l} × ${w} × n = ${V}; n = ${h} ${u.en}`, es:`${l} × ${w} × n = ${V}; n = ${h} ${u.es}`}
7913        };
7914      }
7915      if(k===2){
7916        const V=pick([24,36,48,60]);
7917        return {
7918          q:{en:`${n1} and ${n2} each build an ${it.en} box holding exactly ${V} ${cu.en}, but the boxes are different shapes. Give two different sets of whole-number dimensions that both work, and show why.`,
7919             es:`${n1} y ${n2} construyen cada uno una caja de ${it.es} de exactamente ${V} ${cu.es}, pero con formas diferentes. Da dos conjuntos distintos de medidas enteras que funcionen y muestra por qué.`},
7920          a:{en:`any l×w×h = ${V} — e.g. ${V/4}×2×2 and ${V/6}×3×2`,
7921             es:`cualquier l×a×h = ${V} — p. ej. ${V/4}×2×2 y ${V/6}×3×2`}
7922        };
7923      }
7924      if(k===3){
7925        const l=ri(4,8), w=ri(3,6), h=ri(2,5);
7926        const wrong = l+w+h;
7927        return {
7928          q:{en:`${n2} says the volume of ${n1}'s ${l} × ${w} × ${h} ${u.en} ${it.en} box is ${wrong} ${cu.en}, adding the edges. What did ${n2} confuse volume with? Give the correct volume.`,
7929             es:`${n2} dice que el volumen de la caja de ${it.es} de ${n1}, de ${l} × ${w} × ${h} ${u.es}, es ${wrong} ${cu.es}, sumando las aristas. ¿Con qué confundió el volumen? Da el volumen correcto.`},
7930          a:{en:`Added instead of multiplying — ${l}×${w}×${h} = ${l*w*h} ${cu.en}`,
7931             es:`Sumó en vez de multiplicar — ${l}×${w}×${h} = ${l*w*h} ${cu.es}`}
7932        };
7933      }
7934      if(k===4){
7935        const l=ri(4,8), w=ri(3,6), h=ri(2,5), V=l*w*h;
7936        const cap=ri(2,4);
7937        return {
7938          q:{en:`${n1}'s ${it.en} box is ${l} × ${w} × ${h} ${u.en}. ${n2}'s box has the same base but is ${cap} times as tall. How much more does ${n2}'s hold? Explain what happens to volume when only the height changes.`,
7939             es:`La caja de ${it.es} de ${n1} mide ${l} × ${w} × ${h} ${u.es}. La de ${n2} tiene la misma base pero es ${cap} veces más alta. ¿Cuánto más guarda la de ${n2}? Explica qué le pasa al volumen cuando solo cambia la altura.`},
7940          a:{en:`${V} vs ${V*cap} → ${V*cap-V} ${cu.en} more;
7940 volume scales by ${cap}`,
7941             es:`${V} vs ${V*cap} → ${V*cap-V} ${cu.es} más; el volumen se multiplica por ${cap}`}
7942        };
7943      }
7944      const l1=ri(4,8), w1=ri(3,6), h1=ri(2,5), l2=ri(4,8), w2=ri(3,6), h2=ri(2,5);
7945      const V1=l1*w1*h1, V2=l2*w2*h2;
7946      if(V1===V2) return this.build(n1,n2,lvl);
7947      return {
7948        q:{en:`${n1}'s ${it.en} bin is ${l1} × ${w1} × ${h1} ${u.en}; ${n2}'s is ${l2} × ${w2} × ${h2} ${u.en}. Whose holds more, and by how many ${cu.en}? Show both volumes.`,
7949           es:`La caja de ${it.es} de ${n1} mide ${l1} × ${w1} × ${h1} ${u.es}; la de ${n2} mide ${l2} × ${w2} × ${h2} ${u.es}. ¿Cuál guarda más y por cuántos ${cu.es}? Muestra los dos volúmenes.`},
7950        a:{en:`${V1} vs ${V2} → ${V1>V2?n1:n2} by ${Math.abs(V1-V2)} ${cu.en}`,
7951           es:`${V1} vs ${V2} → ${V1>V2?n1:n2} por ${Math.abs(V1-V2)} ${cu.es}`}
7952      };
7953    }
7954
7955    /* ---- On level · DOK 2 ---- */
7956    const k=ri(1,5);
7957    if(k===1){
7958      const l=ri(5,12), w=ri(3,8), h=ri(2,7);
7959      return {
7960        q:{en:`${n1}'s ${it.en} crate measures ${l} ${u.en} by ${w} ${u.en} by ${h} ${u.en}. What is its volume?`,
7961           es:`La caja de ${it.es} de ${n1} mide ${l} por ${w} por ${h} ${u.es}. ¿Cuál es su volumen?`},
7962        a:{en:`${l} × ${w} × ${h} = ${l*w*h} ${cu.en}`, es:`${l} × ${w} × ${h} = ${l*w*h} ${cu.es}`}
7963      };
7964    }
7965    if(k===2){
7966      const b=ri(12,40), h=ri(3,8);
7967      return {
7968        q:{en:`The base of ${n1}'s ${it.en} box covers ${b} square ${u.en} and it stands ${h} ${u.en} tall. Use V = b × h to find the volume.`,
7969           es:`La base de la caja de ${it.es} de ${n1} cubre ${b} ${u.es} cuadrados y mide ${h} ${u.es} de alto. Usa V = b × h para hallar el volumen.`},
7970        a:{en:`${b} × ${h} = ${b*h} ${cu.en}`, es:`${b} × ${h} = ${b*h} ${cu.es}`}
7971      };
7972    }
7973    if(k===3){
7974      const l=ri(5,10), w=ri(3,7), h=ri(2,6), V=l*w*h;
7975      return {
7976        q:{en:`A ${it.en} bin holds ${V} ${cu.en} and its base is ${l} ${u.en} by ${w} ${u.en}. How tall is ${n1}'s bin?`,
7977           es:`Una caja de ${it.es} tiene ${V} ${cu.es} y su base mide ${l} por ${w} ${u.es}. ¿Qué altura tiene la caja de ${n1}?`},
7978        a:{en:`${V} ÷ (${l} × ${w}) = ${h} ${u.en}`, es:`${V} ÷ (${l} × ${w}) = ${h} ${u.es}`}
7979      };
7980    }
7981    if(k===4){
7982      const s=ri(3,7);
7983      return {
7984        q:{en:`${n1} stores ${it.en} in a cube-shaped bin with edges of ${s} ${u.en}. What is the volume, and how many 1-${u.en} cubes would fill it?`,
7985           es:`${n1} guarda ${it.es} en una caja cúbica con aristas de ${s} ${u.es}. ¿Cuál es el volumen y cuántos cubos de 1 ${u.es} la llenarían?`},
7986        a:{en:`${s}×${s}×${s} = ${s*s*s} ${cu.en}; ${s*s*s} cubes`, es:`${s}×${s}×${s} = ${s*s*s} ${cu.es}; ${s*s*s} cubos`}
7987      };
7988    }
7989    const l=ri(4,9), w=ri(3,6), h=ri(2,5), n=ri(2,4);
7990    return {
7991      q:{en:`${n1} stacks ${n} identical ${it.en} boxes, each ${l} × ${w} × ${h} ${u.en}. What is the total volume of the stack?`,
7992         es:`${n1} apila ${n} cajas idénticas de ${it.es}, cada una de ${l} × ${w} × ${h} ${u.es}. ¿Cuál es el volumen total de la pila?`},
7993      a:{en:`${l}×${w}×${h}=${l*w*h}, ×${n} = ${l*w*h*n} ${cu.en}`,
7994         es:`${l}×${w}×${h}=${l*w*h}, ×${n} = ${l*w*h*n} ${cu.es}`}
7995    };
7996  }
7997},
7998{
7999  code:"5.NBT.B.7", grade:5, dok:2,
8000  title:{en:"Add, subtract & multiply decimals to hundredths",
8001         es:"Sumar, restar y multiplicar decimales hasta centésimas"},
8002  text:{en:"Add, subtract, multiply, and divide decimals to hundredths, using concrete models or drawings and strategies based on place value, properties of operations, and/or the relationship between addition and subtraction; relate the strategy to a written method and explain the reasoning used.",
8003        es:"Suma, resta, multiplica y divide decimales hasta las centésimas, usando modelos concretos o dibujos y estrategias basadas en el valor posicional, las propiedades de las operaciones y/o la relación entre la suma y la resta; relaciona la estrategia con un método escrito y explica el razonamiento usado."},
8004  build(n1,n2,lvl){
8005    const it = pickItem();
8006    let it2 = pick(THEME.items);
8007    while(it2.en === it.en) it2 = pick(THEME.items);
8008    let kind = ri(1,5);   // feeds Challenge (5 templates); On-level reassigns
8009
8010    /* ---- Support · DOK 1 : tenths, one step ---- */
8011    if(lvl===1){
8012      const k=ri(1,4);
8013      if(k===1){
8014        const x=Math.round(priceOf(it)*10)/10, y=Math.round(priceOf(it2)*10)/10;
8015        return {
8016          q:{en:`${n1} spent ${money(x)} on ${it.en} and ${money(y)} on ${it2.en}. How much did ${n1} spend in all?`,
8017             es:`${n1} gastó ${dinero(x)} en ${it.es} y ${dinero(y)} en ${it2.es}. ¿Cuánto gastó ${n1} en total?`},
8018          a:{en:money(x+y), es:dinero(x+y)}
8019        };
8020      }
8021      if(k===2){
8022        const spend=Math.round(priceOf(it)*10)/10;
8023        const start=Math.round((spend+ri(15,60)/10)*10)/10;
8024        return {
8025          q:{en:`${n1} had ${money(start)} and spent ${money(spend)} on ${it.en}. How much is left?`,
8026             es:`${n1} tenía ${dinero(start)} y gastó ${dinero(spend)} en ${it.es}. ¿Cuánto le queda?`},
8027          a:{en:money(start-spend), es:dinero(start-spend)}
8028        };
8029      }
8030      if(k===3){
8031        const each=Math.round(priceOf(it)*10)/10, qty=ri(2,4);
8032        return {
8033          q:{en:`Each ${it.one.en} costs ${money(each)}. ${n1} buys ${qty}. How much does ${n1} spend?`,
8034             es:`Cada ${it.one.es} cuesta ${dinero(each)}. ${n1} compra ${qty}. ¿Cuánto gasta ${n1}?`},
8035          a:{en:money(each*qty), es:dinero(each*qty)}
8036        };
8037      }
8038      const x=Math.round(priceOf(it)*10)/10;
8039      const y=Math.round((x - ri(5,12)/10)*10)/10;
8040      const lo = y > 0.2 ? y : Math.round((x/2)*10)/10;
8041      return {
8042        q:{en:`${n1} spent ${money(x)} and ${n2} spent ${money(lo)}. How much more did ${n1} spend?`,
8043           es:`${n1} gastó ${dinero(x)} y ${n2} gastó ${dinero(lo)}. ¿Cuánto más gastó ${n1}?`},
8044        a:{en:money(x-lo), es:dinero(x-lo)}
8045      };
8046    }
8047
8048    /* ---- Challenge · DOK 3 : multi-step + explain ---- */
8049    if(lvl===3){
8050      if(kind===1){
8051        const each=priceOf(it), qty=ri(3,8);
8052        const budget=Math.round((each*qty+ri(150,900)/100)*100)/100;
8053        return {
8054          q:{en:`Each ${it.one.en} costs ${money(each)}. ${n1} buys ${qty} of them with ${money(budget)}. How much change does ${n1} get? Explain which operation you did first.`,
8055             es:`Cada ${it.one.es} cuesta ${dinero(each)}. ${n1} compra ${qty} con ${dinero(budget)}. ¿Cuánto cambio recibe? Explica qué operación hiciste primero.`},
8056          a:{en:`${money(each*qty)} spent → ${money(budget-each*qty)} change`,
8057             es:`${dinero(each*qty)} gastado → ${dinero(budget-each*qty)} de cambio`}
8058        };
8059      }
8060      if(kind===2){
8061        const x=ri(215,875)/100, y=ri(215,875)/100;
8062        return {
8063          q:{en:`${n1} spent ${money(x)} and ${n2} spent ${money(y)}. ${n2} says they spent about the same because both start with the same digit. Is ${n2} right? Explain using place value.`,
8064             es:`${n1} gastó ${dinero(x)} y ${n2} gastó ${dinero(y)}. ${n2} dice que gastaron casi lo mismo porque empiezan con el mismo dígito. ¿Tiene razón? Explica usando el valor posicional.`},
8065          a:{en:`Difference is ${money(Math.abs(x-y))}`, es:`La diferencia es ${dinero(Math.abs(x-y))}`}
8066        };
8067      }
8068      if(kind===3){
8069        const each=priceOf(it), qty=ri(3,7), extra=priceOf(it2);
8070        return {
8071          q:{en:`${n1} buys ${qty} ${it.en} at ${money(each)} each, plus one ${it2.one.en} for ${money(extra)}. What is the total? Explain why you multiplied before you added.`,
8072             es:`${n1} compra ${qty} ${it.es} a ${dinero(each)} cada ${unoEs(it)} más ${unUnaEs(it2)} ${it2.one.es} por ${dinero(extra)}. ¿Cuál es el total? Explica por qué multiplicaste antes de sumar.`},
8073          a:{en:`${money(each*qty)} + ${money(extra)} = ${money(each*qty+extra)}`,
8074             es:`${dinero(each*qty)} + ${dinero(extra)} = ${dinero(each*qty+extra)}`}
8075        };
8076      }
8077      if(kind===4){
8078        const each=priceOf(it), qty=ri(4,9);
8079        const claimed=Math.round((each*qty + (ri(0,1)? each/10 : -each/10))*100)/100;
8080        return {
8081          q:{en:`Each ${it.one.en} costs ${money(each)}. ${n2} says ${qty} of them cost ${money(claimed)}. ${n2} moved the decimal point when multiplying. Find ${n2}'s mistake and give the correct total.`,
8082             es:`Cada ${it.one.es} cuesta ${dinero(each)}. ${n2} dice que ${qty} cuestan ${dinero(claimed)}. ${n2} movió mal el punto decimal al multiplicar. Encuentra el error de ${n2} y da el total correcto.`},
8083          a:{en:`${money(each)}×${qty} = ${money(each*qty)}`, es:`${dinero(each)}×${qty} = ${dinero(each*qty)}`}
8084        };
8085      }
8086      const priceA=priceOf(it), priceB=Math.round((priceA + ri(20,120)/100)*100)/100, budget=Math.round((priceB*3 + ri(50,300)/100)*100)/100;
8087      return {
8088        q:{en:`${it.en} cost ${money(priceA)} at one stand and ${money(priceB)} at another. ${n1} needs 3 and has ${money(budget)}. Which stand should ${n1} choose, and how much is saved? Explain.`,
8089           es:`${losLasEs(it)==="los"?"Los":"Las"} ${it.es} cuestan ${dinero(priceA)} en un puesto y ${dinero(priceB)} en otro. ${n1} necesita 3 y tiene ${dinero(budget)}. ¿Qué puesto debe elegir y cuánto ahorra? Explica.`},
8090        a:{en:`Cheaper stand: 3×${money(priceA)}=${money(priceA*3)}; saves ${money((priceB-priceA)*3)}`,
8091           es:`El puesto más barato: 3×${dinero(priceA)}=${dinero(priceA*3)}; ahorra ${dinero((priceB-priceA)*3)}`}
8092      };
8093    }
8094
8095    /* ---- On level · DOK 2 ---- */
8096    kind = ri(1,5);   // more variety at the tier teachers use most
8097    if(kind===1){
8098      const x=priceOf(it), y=priceOf(it2);
8099      return {
8100        q:{en:`${n1} spent ${money(x)} on ${it.en} and ${money(y)} on ${it2.en}. How much did ${n1} spend in all?`,
8101           es:`${n1} gastó ${dinero(x)} en ${it.es} y ${dinero(y)} en ${it2.es}. ¿Cuánto gastó ${n1} en total?`},
8102        a:{en:money(x+y), es:dinero(x+y)}
8103      };
8104    }
8105    if(kind===2){
8106      const spend=priceOf(it);
8107      const start=Math.round((spend+ri(400,1600)/100)*100)/100;
8108      return {
8109        q:{en:`${n1} had ${money(start)} to spend and spent ${money(spend)} on ${it.en}. How much money does ${n1} have left?`,
8110           es:`${n1} tenía ${dinero(start)} para gastar y gastó ${dinero(spend)} en ${it.es}. ¿Cuánto dinero le queda a ${n1}?`},
8111        a:{en:money(start-spend), es:dinero(start-spend)}
8112      };
8113    }
8114    if(kind===4){
8115      const each=priceOf(it), qty=ri(2,5);
8116      const start=Math.round((each*qty + ri(200,900)/100)*100)/100;
8117      return {
8118        q:{en:`${n1} had ${money(start)} and bought ${qty} ${it.en} at ${money(each)} each. How much money is left?`,
8119           es:`${n1} tenía ${dinero(start)} y compró ${qty} ${it.es} a ${dinero(each)} cada ${unoEs(it)}. ¿Cuánto dinero le queda?`},
8120        a:{en:`${money(each*qty)} spent → ${money(start-each*qty)} left`,
8121           es:`${dinero(each*qty)} gastado → ${dinero(start-each*qty)} le queda`}
8122      };
8123    }
8124    if(kind===5){
8125      const mine=priceOf(it), theirs=priceOf(it2), tot=Math.round((mine+theirs)*100)/100;
8126      return {
8127        q:{en:`${n1} and ${n2} spent ${money(tot)} together. ${n1} spent ${money(mine)}. How much did ${n2} spend?`,
8128           es:`${n1} y ${n2} gastaron ${dinero(tot)} juntos. ${n1} gastó ${dinero(mine)}. ¿Cuánto gastó ${n2}?`},
8129        a:{en:money(tot-mine), es:dinero(tot-mine)}
8130      };
8131    }
8132    const each=priceOf(it), qty=ri(3,8);
8133    return {
8134      q:{en:`Each ${it.one.en} costs ${money(each)}. ${n1} and ${n2} need ${qty} of them. What is the total cost?`,
8135         es:`Cada ${it.one.es} cuesta ${dinero(each)}. ${n1} y ${n2} necesitan ${qty}. ¿Cuál es el costo total?`},
8136      a:{en:money(each*qty), es:dinero(each*qty)}
8137    };
8138  }
8139}
8140];
8141
8142/* ============================================================
8143   STATE
8144============================================================ */
8145let LANG = localStorage.getItem("mshLang") || "en";
8146let SHEET = null;
8147let VIEWLV = 2;   // level shown in the stage (2 = on level)
8148const FRIEND = "\u2063friend\u2063";   // placeholder, swapped per language at render
8149let SHOWALL = false;
8150let MODE = "ws";   // "ws" = worksheet, "et" = exit ticket  // true only while printing all three
8151
8152const $ = id => document.getElementById(id);
8153
8154/* ---------- roster ---------- */
8155let UNPICKED = new Set();   // names the teacher has toggled OFF
8156
8157function fullRoster(){
8158  const raw = $("roster").value.split(/[\n,]/).map(s=>s.trim()).filter(Boolean);
8159  return [...new Set(raw)];   // two kids typed the same? only one goes in the math
8160}
8161function readRoster(){
8162  // only the checked names go into the math
8163  const all = fullRoster();
8164  const picked = all.filter(n=>!UNPICKED.has(n));
8165  return picked.length ? picked : all;   // never generate from an empty set
8166}
8167function renderPicker(){
8168  const all = fullRoster();
8169  [...UNPICKED].forEach(n=>{ if(!all.includes(n)) UNPICKED.delete(n); });
8170  const box = $("namePick"), row = $("pickRow");
8171  if(all.length < 2){ box.innerHTML=""; row.style.display="none"; return; }
8172  box.innerHTML = all.map(n=>
8173    '<span class="namechip'+(UNPICKED.has(n)?' off':'')+'" data-n="'+esc(n)+'">'+esc(n)+'</span>').join("");
8174  box.querySelectorAll(".namechip").forEach(ch=>{
8175    ch.addEventListener("click", ()=>{
8176      const n = ch.dataset.n;
8177      if(UNPICKED.has(n)) UNPICKED.delete(n); else UNPICKED.add(n);
8178      renderPicker();
8179    });
8180  });
8181  row.style.display = "flex";
8182  const t = STR[LANG];
8183  const on = all.length - UNPICKED.size;
8184  $("pickCount").textContent = t.pickCount.replace("{n}", on).replace("{t}", all.length);
8185  $("pickAll").textContent = t.pickAll;
8186  $("pickNone").textContent = t.pickNone;
8187}
8188function loadSaved(){
8189  try{
8190    const r = localStorage.getItem("mshWPRoster");
8191    if(r) $("roster").value = JSON.parse(r).join("\n");
8192  }catch(e){}
8193  renderPicker();
8194}
8195
8196/* ---------- language ---------- */
8197function applyLang(){
8198  const t = STR[LANG];
8199  document.documentElement.lang = LANG;
8200  $("tagline").textContent = t.tagline;
8201  $("langBtn").textContent = t.langBtn;
8202  $("printBtn").textContent = t.print;
8203  $("lblRoster").textContent = t.lblRoster;
8204  $("lblStd").textContent = t.lblStd;
8205  $("lblCount").textContent = t.lblCount;
8206  $("hintRoster").textContent = t.hintRoster;
8207  $("genBtn").textContent = t.gen;
8208  $("saveBtn").textContent = t.save;
8209  $("clearBtn").textContent = t.clear;
8210  $("privacyBox").innerHTML = t.privacy;
8211  const lb = $("lockedBox");
8212  lb.innerHTML = "<h4>"+t.lockedH+"</h4><ul>"+t.locked.map(s=>"<li>"+s+"</li>").join("")+"</ul>";
8213  const es = $("emptyState");
8214  if(es) es.innerHTML = '<span class="big">'+t.emptyBig+'</span>'+t.emptyBody;
8215  $("lblTheme").textContent = t.lblTheme;
8216  $("lblMode").textContent = t.modeLabel;
8217  $("modeWs").innerHTML = "<b>"+t.modeWs+"</b><i>"+t.modeWsSub+"</i>";
8218  $("modeEt").innerHTML = "<b>"+t.modeEt+" \ud83d\udd12</b><i>"+t.modeEtSub+"</i>";
8219  buildStdOptions();
8220  updateStdHint();
8221  renderPicker();
8222  buildOverlays();
8223  if(SHEET) render();
8224}
8225
8226function buildStdOptions(){
8227  const sel = $("std"), keep = sel.value;
8228  sel.innerHTML = "";
8229  STANDARDS.forEach((s,i)=>{
8230    const o = document.createElement("option");
8231    o.value = i;
8232    o.textContent = (s.grade==="K" ? "K" : STR[LANG].gradeWord+" "+s.grade) + " · " + s.code;
8233    sel.appendChild(o);
8234  });
8235  if(keep) sel.value = keep;
8236
8237  const th = $("theme"), keepT = th.value;
8238  th.innerHTML = "";
8239  Object.keys(THEMES).forEach(k=>{
8240    const o = document.createElement("option");
8241    o.value = k; o.textContent = THEMES[k].label[LANG];
8242    th.appendChild(o);
8243  });
8244  if(keepT) th.value = keepT;
8245}
8246
8247function updateStdHint(){
8248  const s = STANDARDS[+$("std").value];
8249  if(!s) return;
8250  $("stdHint").innerHTML = esc(s.title[LANG]) + '<br>'
8251    + STR[LANG].setMarks.map((m,i)=>
8252        '<span class="pair"><span class="star">'+m+'</span>\u00a0'+esc(STR[LANG].lvlNames[i])+'</span>'
8253      ).join(' <span class="sep">/</span> ');
8254}
8255
8256function buildOverlays(){
8257  const t = STR[LANG];
8258  $("howBtn").textContent = t.howTitle;
8259  $("ovHowTitle").textContent = t.howTitle;
8260  $("ovHowBody").innerHTML = t.howBody.map(l=>'<p>'+l+'</p>').join("");
8261  document.querySelectorAll(".ov-close").forEach(b=>b.textContent = LANG==="es" ? "Cerrar" : "Close");
8262}
8263
8264/* ---------- generate ---------- */
8265// Templates re-roll themselves via `return this.build(...)` when a draw is
8266// unusable (equal fractions, impossible subtraction...). That recursion is
8267// normally 1-2 deep, but it is unbounded in principle. safeBuild caps the
8268// nesting: past MAXDEPTH we accept whatever the template hands back.
8269const MAXDEPTH = 12;
8270let BUILDDEPTH = 0;
8271function safeBuild(std, a, b, lv){
8272  if(BUILDDEPTH >= MAXDEPTH) return std.build(a,b,lv);   // stop descending
8273  BUILDDEPTH++;
8274  try { return std.build(a,b,lv); }
8275  finally { BUILDDEPTH--; }
8276}
8277
8278function generate(){
8279  const names = readRoster();
8280  if(!names.length){ alert(STR[LANG].need); $("roster").focus(); return; }
8281  THEME = THEMES[$("theme").value] || THEMES.school;
8282  const std = STANDARDS[+$("std").value];
8283  const n = Math.max(4, Math.min(16, parseInt($("count").value)||8));
8284
8285  // Deal names from a shuffled deck and only reshuffle once everyone has
8286  // appeared, so nobody shows up twice while a classmate is still waiting.
8287  const shuffled = () => {
8288    const d = names.slice();
8289    for(let i=d.length-1;i>0;i--){ const j=ri(0,i); [d[i],d[j]]=[d[j],d[i]]; }
8290    return d;
8291  };
8292  // Two independent decks. The star deck is what matters: every student
8293  // stars once before anyone stars twice. If n1 and n2 shared a deck it
8294  // would burn through the roster at double speed and repeat early.
8295  const dealer = () => {
8296    let deck = shuffled();
8297    return avoid => {
8298      if(!deck.length) deck = shuffled();
8299      let k = deck.findIndex(x => x !== avoid);
8300      if(k === -1) k = 0;                  // only one distinct name left
8301      return deck.splice(k,1)[0];
8302    };
8303  };
8304  const dealStar = dealer();   // who the problem is about
8305  const dealExtra = dealer();  // the classmate in the problem
8306
8307  // parallel casts: the same students appear in the same slot at every level
8308  const cast = [];
8309  for(let i=0;i<n;i++){
8310    const n1 = dealStar(null);
8311    let n2 = dealExtra(n1);
8312    // A one-student roster (or repeated names) must not produce
8313    // "Jacob says Jacob has more than Jacob" — use a stand-in instead.
8314    if(n2 === n1) n2 = FRIEND;
8315    cast.push([n1,n2]);
8316  }
8317
8318  if(MODE === "et"){
8319    // Four tickets to a page. Each ticket stars a different student and
8320    // ramps DOK 1 -> 2 -> 3 so you can see where a student stopped.
8321    const tickets = [];
8322    for(let i=0;i<4;i++){
8323      const [a,b] = cast[i % cast.length];
8324      ITEMLOCK = pick(THEME.items);          // one object for the whole ticket
8325      const seen = new Set();
8326      tickets.push({ star:a, probs:[1,2,3].map(lv => {
8327        let pr = safeBuild(std,a,b,lv);
8328        for(let t=0; t<14 && seen.has(pr.q.en); t++) pr = safeBuild(std,a,b,lv);
8329        seen.add(pr.q.en);
8330        return pr;
8331      })});
8332      ITEMLOCK = null;
8333    }
8334    SHEET = {std, tickets, cast, mode:"et"};
8335    render();
8336    return;
8337  }
8338
8339  // Small number ranges (especially Kindergarten) can repeat a problem
8340  // verbatim on the same sheet. Re-roll a few times before accepting one.
8341  const buildUnique = (a,b,lv,seen) => {
8342    let p = safeBuild(std,a,b,lv);
8343    for(let tries=0; tries<14 && seen.has(p.q.en); tries++) p = safeBuild(std,a,b,lv);
8344    seen.add(p.q.en);
8345    return p;
8346  };
8347
8348  const levels = [1,2,3];
8349  const sets = levels.map(lv => {
8350    const seen = new Set();
8351    return { lv, probs: cast.map(([a,b]) => buildUnique(a,b,lv,seen)) };
8352  });
8353
8354  VIEWLV = 2;
8355  SHEET = {std, sets, cast, mode:"ws"};
8356  render();
8357}
8358
8359/* ---------- render ---------- */
8360function friendly(str){
8361  const word = LANG==="es" ? "un amigo" : "a friend";
8362  let out = str.split(FRIEND).join(word);
8363  // capitalise it if it landed at the start of a sentence
8364  return out.replace(/(^|[.!?]\s+|¿)(a friend|un amigo)/g,
8365    (m,pre,w)=> pre + w.charAt(0).toUpperCase() + w.slice(1));
8366}
8367function esc(s){ return String(s).replace(/[&<>]/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;"}[c])); }
8368
8369function render(){
8370  const t = STR[LANG], stage = $("stage");
8371  const std = SHEET.std, sets = SHEET.sets;
8372  const year = new Date().getFullYear();
8373  const dokOf = lv => lv===3 ? "2\u20133" : lv;   // Challenge spans DOK 2-3
8374  let out = "";
8375
8376  /* =============== EXIT TICKETS =============== */
8377  if(SHEET.mode === "et"){
8378    out += '<div class="demoflag noprint">🔒 '+t.etLocked+'</div>';
8379    out += '<div class="demoflag noprint soft">📈 '+t.etRamp+'</div>';
8380
8381    out += '<section class="sheet ticketpage">'
8382        +  '<div class="cutrow noprint"><span>\u2702 '+t.etCut+'</span></div>'
8383        +  '<div class="tickets">';
8384
8385    SHEET.tickets.forEach((tk,ti)=>{
8386      out += '<div class="ticket">'
8387          +  '<div class="tk-head"><span class="tk-title">'+t.etHead+'</span>'
8388          +    '<span class="tk-code">'+std.code+'</span></div>'
8389          +  '<div class="tk-name"><span>'+t.name+'</span><span>'+t.date+'</span></div>';
8390      tk.probs.forEach((p,i)=>{
8391        out += '<div class="tk-prob"><b>'+(i+1)+'.</b> '+esc(friendly(p.q[LANG]))+'</div>'
8392            +  '<div class="tk-line"></div>';
8393      });
8394      out += '<div class="tk-foot">myschoolhero.com<span class="tk-stamp">'+t.sample+'</span></div>'
8395          +  '</div>';
8396    });
8397
8398    out += '</div></section>';
8399
8400    out += '<section class="sheet key">'
8401        +  '<div class="sheet-head"><h1 class="sheet-title">'+t.etKey+'</h1>'
8402        +  '<div class="sheet-meta"><span class="code">'+std.code+'</span>'
8403        +  '<span>'+esc(std.title[LANG])+'</span></div></div>';
8404    SHEET.tickets.forEach((tk,ti)=>{
8405      out += '<div class="keyblock"><b>'+t.etTicket+' '+(ti+1)+'</b><div class="keygrid">';
8406      tk.probs.forEach((p,i)=>{
8407        out += '<div class="keyrow"><b>'+(i+1)+'.</b><span>'+esc(friendly(p.a[LANG]))
8408            +  ' <em>('+t.dok+' '+(i+1)+')</em></span></div>';
8409      });
8410      out += '</div></div>';
8411    });
8412    out += '<div class="sheet-foot"><span>'+esc(std.text[LANG])
8413        +  '<br><small style="color:#8A8A8A">'+t.ccssCredit+'</small></span></div></section>';
8414
8415    stage.innerHTML = out;
8416    if(!SHOWALL) stage.scrollIntoView({behavior:"smooth", block:"start"});
8417    return;
8418  }
8419  /* =============== WORKSHEETS =============== */
8420
8421  {
8422    out += '<div class="demoflag noprint">✨ '+t.demoNote+'</div>';
8423    out += '<div class="lvltabs noprint"><span class="tablabel">'+t.pickLevel+'</span><div class="tabrow">';
8424    sets.forEach(set=>{
8425      out += '<button class="tab'+(set.lv===VIEWLV?' on':'')+'" data-lv="'+set.lv+'">'
8426          +  '<b><span class="setmark">'+t.setMarks[set.lv-1]+'</span>'+t.lvlNames[set.lv-1]+'</b><i>'+t.lvlSub[set.lv-1]+'</i></button>';
8427    });
8428    out += '</div><button class="btn btn-go printall" id="printAllBtn">'+t.printAll+'</button></div>';
8429  }
8430
8431  sets.filter(set=>
8431SHOWALL || set.lv===VIEWLV).forEach(set=>{
8432    // Students see a neutral letter only — no "Support"/"Challenge", no descriptor.
8433    const setTag = true
8434      ? '<span class="lvlpill">'+t.setWord+' '+t.setMarks[set.lv-1]+'</span>'
8435      : '';
8436    // The answer key is the teacher's copy, so it names the level plainly.
8437    const keyTag = true
8438      ? '<span class="lvlpill">'+t.setWord+' '+t.setMarks[set.lv-1]+'</span>'
8439        + '<span class="lvlsub">'+t.lvlNames[set.lv-1]+' \u00b7 '+t.lvlSub[set.lv-1]+'</span>'
8440      : '';
8441
8442    out += '<section class="sheet">'
8443      + '<div class="sheet-head">'
8444      +   '<h1 class="sheet-title">'+esc(std.title[LANG])+'</h1>'
8445      +   '<div class="sheet-meta"><span class="code">'+std.code+'</span>'
8446      +     setTag+'</div>'
8447      + '</div>'
8448      + '<div class="namebar"><span>'+t.name+'</span><span>'+t.date+'</span></div>';
8449
8450    set.probs.forEach((p,i)=>{
8451      // Support hints scaffold the first three problems, then fade so
8452      // students don't learn to skip straight to the hint.
8453      let qTxt = p.q[LANG];
8454      if(set.lv===1 && i>=3) qTxt = qTxt.replace(/\s*\((Hint|Pista):[^)]*\)/,"");
8455      out += '<div class="prob">'
8456          +  '<span class="prob-n">'+(i+1)+'</span>'
8457          +  '<button class="reroll noprint" data-i="'+i+'" title="'+t.rerollTip+'">\u21bb</button>'
8458          +  '<span class="prob-q">'+esc(friendly(qTxt))+'</span>'
8459          +  '<div class="work" data-label="'+t.show+'"></div>'
8460          +  '<div class="ansline">'+t.answer+' <i></i></div>'
8461          + '</div>';
8462    });
8463
8464    out += '<div class="sheet-foot"><span>'+t.footer+' '
8465        +  '<a href="https://myschoolhero.com" target="_blank" rel="noopener">myschoolhero.com</a></span>'
8466        +  '<span>© '+year+'</span></div></section>';
8467
8468    out += '<section class="sheet key">'
8469      + '<div class="sheet-head"><h1 class="sheet-title">'+t.keyTitle+'</h1>'
8470      + '<div class="sheet-meta"><span class="code">'+std.code+'</span>'
8471      + '<span>'+t.dok+' '+dokOf(set.lv)+'</span><span>'+esc(std.title[LANG])+'</span>'+keyTag+'</div></div>'
8472      + '<div class="keygrid">';
8473    set.probs.forEach((p,i)=>{
8474      out += '<div class="keyrow"><b>'+(i+1)+'.</b><span>'+esc(friendly(p.a[LANG]))+'</span></div>';
8475    });
8476    out += '</div><div class="sheet-foot"><span>'+esc(std.text[LANG])+'</span></div></section>';
8477  });
8478
8479  stage.innerHTML = out;
8480
8481  stage.querySelectorAll(".reroll").forEach(btn=>{
8482    btn.addEventListener("click", ()=>{
8483      const i = +btn.dataset.i;
8484      const [a,b] = SHEET.cast[i % SHEET.cast.length];
8485      SHEET.sets.forEach(set=>{
8486        const seen = new Set(set.probs.map(pr=>pr.q.en));
8487        let pr = safeBuild(SHEET.std, a, b, set.lv);
8488        for(let t2=0; t2<14 && seen.has(pr.q.en); t2++) pr = safeBuild(SHEET.std, a, b, set.lv);
8489        set.probs[i] = pr;
8490      });
8491      render();
8492    });
8493  });
8494
8495  stage.querySelectorAll(".tab").forEach(btn=>{
8496    btn.addEventListener("click", ()=>{ VIEWLV = +btn.dataset.lv; render(); });
8497  });
8498  const pa = $("printAllBtn");
8499  if(pa) pa.addEventListener("click", ()=>{
8500    SHOWALL = true;  render();
8501    window.print();
8502    SHOWALL = false; render();
8503  });
8504
8505  if(!SHOWALL) stage.scrollIntoView({behavior:"smooth", block:"start"});
8506}
8507
8508/* ============================================================
8509   WIRE UP
8510============================================================ */
8511document.querySelectorAll(".mode").forEach(btn=>{
8512  btn.addEventListener("click", ()=>{
8513    MODE = btn.dataset.mode;
8514    document.querySelectorAll(".mode").forEach(m=>m.classList.toggle("on", m===btn));
8515    document.body.classList.toggle("et-mode", MODE==="et");
8516    if(SHEET) generate();
8517  });
8518});
8519$("roster").addEventListener("input", renderPicker);
8520$("pickAll").addEventListener("click", ()=>{ UNPICKED.clear(); renderPicker(); });
8521$("pickNone").addEventListener("click", ()=>{
8522  const all = fullRoster();
8523  UNPICKED = new Set(all.slice(1));   // keep one so generation never empties
8524  renderPicker();
8525});
8526$("std").addEventListener("change", updateStdHint);
8527$("genBtn").addEventListener("click", generate);
8528$("printBtn").addEventListener("click", ()=>{
8529  if(!SHEET){ generate(); setTimeout(()=>window.print(),300); return; }
8530  window.print();
8531});
8532$("langBtn").addEventListener("click", ()=>{
8533  LANG = LANG==="en" ? "es" : "en";
8534  localStorage.setItem("mshLang", LANG);
8535  applyLang();
8536});
8537$("saveBtn").addEventListener("click", ()=>{
8538  const names = readRoster();
8539  localStorage.setItem("mshWPRoster", JSON.stringify(names));
8540  alert(STR[LANG].saved);
8541});
8542$("clearBtn").addEventListener("click", ()=>{
8543  $("roster").value = "";
8544  localStorage.removeItem("mshWPRoster");
8545  alert(STR[LANG].cleared);
8546});
8547
8548function openOv(id){ $(id).classList.add("open"); }
8549function closeOv(){ document.querySelectorAll(".ov").forEach(o=>o.classList.remove("open")); }
8550$("howBtn").addEventListener("click", ()=>openOv("ovHow"));
8551document.querySelectorAll(".ov-close").forEach(b=>b.addEventListener("click", closeOv));
8552document.querySelectorAll(".ov").forEach(o=>o.addEventListener("click", e=>{ if(e.target===o) closeOv(); }));
8553document.addEventListener("keydown", e=>{ if(e.key==="Escape") closeOv(); });
8554
8555loadSaved();
8556applyLang();
8557</script>
8557
8558
8559</body>
8560</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.