@plasius/learning 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ import { L as LearningCourseV1, C as CoursePracticeQuestion } from '../course-authoring-DImvrK5r.cjs';
2
+
3
+ declare const course: LearningCourseV1;
4
+ declare const practice: CoursePracticeQuestion[];
5
+
6
+ export { course, practice };
@@ -0,0 +1,6 @@
1
+ import { L as LearningCourseV1, C as CoursePracticeQuestion } from '../course-authoring-DImvrK5r.js';
2
+
3
+ declare const course: LearningCourseV1;
4
+ declare const practice: CoursePracticeQuestion[];
5
+
6
+ export { course, practice };
@@ -0,0 +1,199 @@
1
+ import {
2
+ webProjectFiles,
3
+ webReferences,
4
+ webStarterCss
5
+ } from "../chunk-UNPCTBNK.js";
6
+ import {
7
+ authorCourse
8
+ } from "../chunk-2UIOBMJZ.js";
9
+ import "../chunk-OXWMIHYI.js";
10
+
11
+ // src/courses/creature-care-dashboard.ts
12
+ var { course, practice } = authorCourse({
13
+ slug: "creature-care-dashboard",
14
+ title: "Creature Care Dashboard",
15
+ category: "web-app",
16
+ summary: "Create an accessible dashboard for a fictional creature. Connect labelled care actions to bounded state, model time without browser timers, distinguish rest from pause and show an honest activity history. Finish a responsive three-file application with readable status, safe reset and evidence for its edge cases.",
17
+ projectFiles: webProjectFiles,
18
+ starterProject: { files: [
19
+ { path: "index.html", source: `<main>
20
+ <h1>Creature Care Dashboard</h1><p>Care for a fictional creature in a simulated habitat.</p>
21
+ <section aria-labelledby="creature-heading"><h2 id="creature-heading" data-text="name"></h2>
22
+ <p data-text="modeText"></p><p data-text="clockText"></p>
23
+ <label for="food">Food</label><meter id="food" min="0" max="100" data-value="food" data-label="foodLabel"></meter><p data-text="foodLabel"></p>
24
+ <label for="energy">Energy</label><meter id="energy" min="0" max="100" data-value="energy" data-label="energyLabel"></meter><p data-text="energyLabel"></p>
25
+ <label for="joy">Joy</label><meter id="joy" min="0" max="100" data-value="joy" data-label="joyLabel"></meter><p data-text="joyLabel"></p>
26
+ <div class="actions"><button type="button" data-action="feed" data-disabled="feedDisabled">Feed</button><button type="button" data-action="play" data-disabled="playDisabled">Play</button><button type="button" data-action="rest" data-disabled="restDisabled">Rest</button><button type="button" data-action="wake" data-disabled="wakeDisabled">Wake</button></div>
27
+ </section>
28
+ <div class="actions"><button type="button" data-action="resume">Resume simulation</button><button type="button" data-action="pause">Pause simulation</button><button type="button" data-action="reset">Reset habitat</button></div>
29
+ <section aria-labelledby="history-heading"><h2 id="history-heading">Care history</h2><p data-text="historySummary"></p><ol><li data-repeat="history" data-text="text"></li></ol></section>
30
+ <p role="status" data-text="message"></p>
31
+ </main>` },
32
+ { path: "app.css", source: webStarterCss },
33
+ { path: "app.js", source: `function initialState() {
34
+ return { name: "Moss", draftName: "Moss", nameError: "", food: 60, energy: 70, joy: 50,
35
+ mode: "awake", paused: true, elapsed: 0, history: [], nextEventId: 1, message: "Resume when you are ready to care for Moss." };
36
+ }
37
+ function update(state, input) {
38
+ if (input.type === "reset") return initialState();
39
+ return JSON.parse(JSON.stringify(state));
40
+ }
41
+ function view(state) {
42
+ return { name: state.name, draftName: state.draftName, nameError: state.nameError, nameInvalid: state.nameError !== "",
43
+ food: state.food, energy: state.energy, joy: state.joy,
44
+ foodLabel: "Food " + Math.round(state.food) + " of 100", energyLabel: "Energy " + Math.round(state.energy) + " of 100",
45
+ joyLabel: "Joy " + Math.round(state.joy) + " of 100", modeText: state.mode + (state.paused ? ", paused" : ", running"),
46
+ clockText: Math.floor(state.elapsed) + " seconds simulated", feedDisabled: true, playDisabled: true, restDisabled: true,
47
+ wakeDisabled: true, resumeDisabled: false, pauseDisabled: true, history: [], historySummary: "No care actions yet.", message: state.message };
48
+ }
49
+ ` }
50
+ ] },
51
+ reference: [
52
+ ...webReferences,
53
+ { name: "initialState", signature: "initialState() \u2192 fresh habitat", description: "Start with name/draftName='Moss', nameError='', food=60, energy=70, joy=50, mode='awake', paused=true, elapsed=0, history=[], nextEventId=1 and useful message. Food, energy and joy always remain within 0\u2013100. The model is fictional game behaviour, not advice about real animals.", example: '{ food: 60, energy: 70, joy: 50, mode: "awake", paused: true }' },
54
+ { name: "care rules", signature: "feed/play/rest/wake", description: "Successful actions require !paused. Feed also requires awake and food<100; add 20 food capped at 100. Play requires awake, food>=10, energy>=15 and joy<100; subtract 10 food and 15 energy, add 20 joy capped at 100. Rest changes awake to asleep; wake changes asleep to awake. Refused/repeated ineligible actions change only message. Each successful care/mode action records exactly one history event; no action mutates input state.", example: 'if (next.paused || next.mode !== "awake" || next.energy < 15 || next.food < 10 || next.joy >= 100) return { ...next, message: "Play needs an awake, running creature with enough food and energy." };' },
55
+ { name: "tick", signature: '{ type: "tick", dt: seconds }', description: "The host supplies finite dt from 0 to 1 inclusive; invalid/negative/oversized values preserve state. When running, advance by min(dt,3600-elapsed); decrease food by 1/second and joy by 0.5/second, and change energy by -0.75/second awake or +3/second asleep. Clamp all needs to 0\u2013100. At elapsed=3600 pause and explain that reset starts another session. Ignore ticks while paused. No Date, setInterval or device-clock access is used.", example: "const seconds = Math.min(input.dt, 3600 - next.elapsed); next.food = Math.max(0, next.food - seconds);" },
56
+ { name: "pause and reset", signature: "resume/pause/reset", description: "resume clears paused only when elapsed<3600; pause sets it immediately without changing mode, needs or history. Repeating either action changes only feedback. Pause freezes both time and care actions; rest allows time to continue while energy recovers. reset creates a fresh paused habitat with empty history and original values, independently of course completion or account source saves.", example: 'if (input.type === "pause") return { ...next, paused: true, message: "Simulation paused." };' },
57
+ { name: "history", signature: "[{id,action,at}] newest first", description: "Append one event only after a successful feed/play/rest/wake transition, using id='care-'+nextEventId, action and at=elapsed; then increment nextEventId. Store newest first and keep the latest 20 entries. nextEventId is an integer 1\u20131000000; refuse a care action if no ID remains. Ticks, naming, pause and refused actions do not create entries. IDs are never reused when old entries leave the list.", example: 'next.history = [{ id: "care-" + next.nextEventId, action: input.type, at: next.elapsed }, ...next.history].slice(0, 20); next.nextEventId += 1;' },
58
+ { name: "name", signature: 'field{name:"name",value} then rename', description: "A string name field updates only draftName, at most 30 characters, and clears nameError. rename trims it and accepts 2\u201330 characters without control characters; success changes name, normalises draftName and clears errors, while failure keeps name and draft and sets useful error text. Naming is allowed while paused and makes no care-history entry. Use fictional names without personal information.", example: '<input id="name" name="name" type="text" maxlength="30" aria-describedby="name-error" data-value="draftName" data-invalid="nameInvalid">' },
59
+ { name: "view", signature: "view(state) \u2192 needs, permissions and readable history", description: "Return name/draftName/nameError/nameInvalid, numeric food/energy/joy plus rounded text labels, modeText and clockText, feedDisabled/playDisabled/restDisabled/wakeDisabled/resumeDisabled/pauseDisabled reflecting actual guards, history [{id,text}], historySummary and message. Read state without mutation. Include mode and paused in text; numeric meters need labels. Do not put every tick in a live region; announce explicit actions and failures instead.", example: 'const foodLabel = "Food " + Math.round(state.food) + " of 100";' }
60
+ ]
61
+ }, [
62
+ {
63
+ title: "Meet the creature in data",
64
+ concepts: ["State modelling", "Semantic meters", "Responsive styling"],
65
+ goals: ["Present the creature's initial needs truthfully with text and labelled meters.", "Make a readable three-file dashboard before implementing care actions."],
66
+ extension: "Try an alternative habitat theme in a separate save. Preserve the numeric meanings and readable labels while changing its visual character.",
67
+ activities: {
68
+ learn: ["The creature is a fictional model with food, energy and joy from 0\u2013100. JavaScript owns those values, HTML names their meaning and CSS arranges them. A meter needs an accessible name and nearby text so its meaning is not conveyed only by colour or length.", "The initial paused state gives people time to understand the page before the simulation begins."],
69
+ predict: ["Predict the three initial meter values and their rounded text labels from food 60, energy 70 and joy 50. Then predict whether simply calling view should change any need or elapsed time.", "Reading the dashboard is a projection of state, not an event that feeds or tires the creature."],
70
+ build: ["Review the semantic main/heading/section structure and complete truthful initial view data. Style the habitat and need indicators for 320px, large text and both themes, keeping meter values and readable labels connected to the same state.", "Keep all important status visible in words; a green bar by itself cannot explain whether it represents food, energy or joy."],
71
+ run: ["Inspect the paused habitat with keyboard navigation, zoom and a screen reader. Compare each meter's accessible label with its value and the visible text, then reset and confirm the same starting values.", "The care controls are intentionally unfinished while this first mission establishes an honest initial dashboard."],
72
+ assess: ["Check fresh initial state, bounded needs, truthful labels, one main landmark and nonmutating view. Confirm controls have meaningful names and the layout remains readable without depending on motion.", "This milestone does not require later time or care mechanics, but it does require an accurate representation of the initial model."],
73
+ inspect: ["If text and meters disagree, inspect whether both derive from the same field. If an indicator has no announced name, inspect its label association instead of adding another colour cue.", "A visually attractive indicator can still be ambiguous when read without its surrounding layout."],
74
+ fix: ["Repair the projection, label or responsive rule and repeat the initial-state checks at 320px. Preserve visible focus outlines and avoid fixed heights that clip text when zoomed.", "Let content determine the height of panels so readable text is not traded away for a rigid card shape."],
75
+ explain: ["Explain why a meter needs both a numeric model and a meaningful name. Choose the design that communicates the same state to people using different ways of reading the page.", "Accessible presentation describes the underlying model clearly rather than adding a separate inconsistent version of it."],
76
+ reward: ["Save Honest habitat. Your creature's state can now be understood through labelled values and a readable page. Next you will make its care actions change that model.", "Keep this paused baseline for comparing changes caused by each later action."]
77
+ },
78
+ questions: {
79
+ learn: { question: "What does a labelled meter communicate beyond a coloured bar?", choices: ["Which need the value represents", "A hidden timer", "A new care action"], correctChoice: 0, feedback: "A meaningful label explains the quantity being displayed even when colour or visual position is unavailable." },
80
+ predict: { question: "What should calling view do to energy=70?", choices: ["Reduce it automatically", "Leave it at 70", "Reset it to 100"], correctChoice: 1, feedback: "The display function reads state without advancing time or performing actions, so viewing the dashboard preserves energy." },
81
+ explain: { question: "Which display avoids relying only on colour?", choices: ["Three unnamed coloured blocks", "An unlabeled animation", "Named meters with readable values and status text"], correctChoice: 2, feedback: "Labels, values and status text communicate the model through more than a single visual signal." }
82
+ }
83
+ },
84
+ {
85
+ title: "Make care actions matter",
86
+ concepts: ["Guarded actions", "Clamping", "Detached updates"],
87
+ goals: ["Implement meaningful feed and play transitions with explicit prerequisites.", "Refuse unavailable actions without partial effects and keep control states truthful."],
88
+ extension: "Write a short explanation of why the creature cannot play in each refused case. Keep messages useful without changing the resource rules.",
89
+ activities: {
90
+ learn: ["Feed and play spend or replenish specific resources. Feed adds 20 food up to 100. Play spends 10 food and 15 energy to add 20 joy up to 100. Both need an awake running creature, and checking prerequisites before any change prevents a refused action from partially spending resources.", "A disabled button helps explain availability, but update must enforce the same guard even if an action arrives directly."],
91
+ predict: ["Predict feed at food 90 and play at food 10, energy 15, joy 90. Compare the exact-boundary play with energy 14 and explain which fields may change in the refused case.", "Clamping the gain and checking the costs are separate operations; a generous reward must not permit a negative resource balance."],
92
+ build: ["Implement resume and pause guards, then feed/play using detached next state and exact prerequisites. Derive feedDisabled and playDisabled from the same rules. Add useful success/refusal messages while keeping history for a later mission.", "At this milestone the host assesses resource behaviour; the later history lesson adds receipt tracking without changing these care rules."],
93
+ run: ["Resume, feed near the maximum and play until a resource prevents another turn. Pause and try care again. Compare enabled controls, messages and resource changes with the predictions.", "Use the same action sequence with keyboard and touch so both input paths exercise the same state transition."],
94
+ assess: ["Check gains, costs, upper and lower bounds, exact eligibility thresholds, paused/asleep guards, unknown actions and input immutability. Confirm refused actions change only feedback and never partially spend food or energy.", "Direct-action scenarios verify guards independently from whatever the current button appearance suggests."],
95
+ inspect: ["If a rejected play drains energy, inspect the order of mutation and guard checks. If a full food meter still accepts feeding, inspect the food<100 condition in both update and view.", "The interface and transition function must agree on availability; neither should have an unrelated copy of the rule."],
96
+ fix: ["Repair the earliest wrong resource transition and replay threshold cases on each side of eligibility. Verify that repeated requests cannot push values outside 0\u2013100 and that the current source preserves input objects.", "Clone nested state before changing it so previous states remain useful for comparison and later evidence."],
97
+ explain: ["Explain why resource costs are checked before applying any effect and why a disabled button is not the sole guard. Choose the result for a play request with insufficient energy.", "The transition function is responsible for correctness even when an event does not originate from the visible control."],
98
+ reward: ["Save Meaningful care. Feeding and play now have bounded, understandable consequences. Next you will make the fictional habitat evolve through supplied simulated time.", "Keep the exact-threshold case because small comparison mistakes often hide at resource boundaries."]
99
+ },
100
+ questions: {
101
+ learn: { question: "Where must care prerequisites be enforced?", choices: ["Only in CSS", "In update as well as truthful control state", "Only in the button label"], correctChoice: 1, feedback: "The model must reject invalid direct actions while the interface accurately explains which actions are currently available." },
102
+ predict: { question: "What is food after feeding from 90?", choices: ["110", "90", "100"], correctChoice: 2, feedback: "Feeding adds twenty but clamps the result to the documented maximum of one hundred." },
103
+ explain: { question: "What should play do with energy 14?", choices: ["Preserve needs and explain refusal", "Spend food anyway", "Set energy to -1"], correctChoice: 0, feedback: "Insufficient energy makes the whole action ineligible, so resources stay unchanged and feedback explains the refusal." }
104
+ }
105
+ },
106
+ {
107
+ title: "Let simulated time pass",
108
+ concepts: ["Time steps", "Rates", "Deterministic simulation"],
109
+ goals: ["Advance needs using bounded supplied time steps rather than browser timers.", "Clamp values and stop the session at its exact duration limit."],
110
+ extension: "Compare one one-second tick with two half-second ticks away from boundaries. Explain why the same elapsed time should produce the same resource changes.",
111
+ activities: {
112
+ learn: ["The host supplies tick actions with finite dt between 0 and 1 seconds. While running, food falls by 1 per second, joy by 0.5 and awake energy by 0.75. Multiply each rate by dt, clamp needs and cap total elapsed time at 3600 seconds.", "No browser timer or Date call is needed; supplied time makes the same action sequence repeatable in assessment."],
113
+ predict: ["Predict food, joy and energy after half a second awake from the initial needs. Then predict a tick of 2 seconds, a negative tick and a tick while paused.", "Invalid time inputs preserve the model; a large delayed frame is not permission to bypass the bounded tick contract."],
114
+ build: ["Implement tick validation and elapsed advancement, limiting the last step to the remaining session time. Apply awake decay rates and clamp needs. At 3600 pause and show a reset instruction, with resumeDisabled remaining true until reset.", "Use the same effective seconds for elapsed and every rate so the final partial step remains coherent."],
115
+ run: ["Resume and compare a recorded sequence of half-second and one-second ticks. Pause between ticks, then use the near-session-end scenario to check the final fractional step and automatic pause.", "The host controls simulation pace; changing real browser frame timing must not alter the meaning of one supplied tick."],
116
+ assess: ["Check finite dt boundaries, rejected oversized/negative inputs, paused preservation, decay rates, zero clamps, partitioned time and the exact 3600-second stop. Confirm ticks never create care-history records.", "The timer display may round elapsed time, but assessment checks the underlying numeric state."],
117
+ inspect: ["If decay depends on frame count, look for subtracting a fixed amount instead of rate times dt. If the last step overshoots, compare effective seconds used for elapsed and needs.", "A visible whole-second clock can hide fractional errors; inspect the underlying values when a prediction differs."],
118
+ fix: ["Repair time scaling or boundary handling and replay the same deterministic tick sequence. Verify that zero time has no effects and that repeated ticks after automatic pause leave the finished session unchanged.", "Stopping the clock is a state rule, not just hiding its visible number."],
119
+ explain: ["Explain why supplied dt supports repeatable tests and why elapsed time has a finite cap. Distinguish simulated time from how long someone leaves the browser tab open.", "The model advances only through accepted actions, making its behaviour independent of an uncontrolled device clock."],
120
+ reward: ["Save Measured time. The habitat now evolves predictably within fixed limits. Next you will combine time with rest and deliberate pause/recovery behaviour.", "Keep the fractional final-step case for later changes to energy recovery and status feedback."]
121
+ },
122
+ questions: {
123
+ learn: { question: "How much food is lost during an accepted half-second tick?", choices: ["One unit regardless of dt", "Two units", "Half a unit"], correctChoice: 2, feedback: "Food decays at one unit per second, so multiplying by half a second gives a loss of one half." },
124
+ predict: { question: "What should a tick with dt=2 do?", choices: ["Preserve state because it exceeds the allowed step", "Advance two seconds anyway", "Reset the habitat"], correctChoice: 0, feedback: "The input contract allows steps only up to one second, so an oversized tick is rejected without effects." },
125
+ explain: { question: "Why supply time as an input instead of reading Date?", choices: ["To hide elapsed time", "To make replay and assessment deterministic", "To make every action random"], correctChoice: 1, feedback: "Explicit time inputs let the same initial state and action sequence produce reproducible results across hosts." }
126
+ }
127
+ },
128
+ {
129
+ title: "Rest, pause and recover",
130
+ concepts: ["State machines", "Independent modes", "Fresh reset"],
131
+ goals: ["Distinguish sleeping recovery from pausing the whole simulation.", "Implement guarded mode changes and fresh reset without losing course progress."],
132
+ extension: "Sketch a state diagram for awake/asleep crossed with running/paused. Explain which transitions affect mode and which affect the simulation clock.",
133
+ activities: {
134
+ learn: ["Rest changes awake to asleep while the simulation keeps running. Asleep energy recovers by 3 per second; food and joy still decay. Pause freezes all time and care actions without changing awake/asleep mode. Reset starts a fresh paused habitat independently of earned course completion.", "Two independent state fields express these different ideas more clearly than one ambiguous status word."],
135
+ predict: ["Predict energy after two accepted one-second ticks asleep from 70. Compare that with the same ticks paused asleep, then predict wake while paused and resume afterwards.", "A paused creature cannot change care mode until resumed; resuming preserves whichever mode was already selected."],
136
+ build: ["Implement rest/wake guards, asleep energy recovery and truthful control permissions. Preserve needs and mode when pausing, preserve mode when resuming, and reset all preview state through a new initialState result.", "Refused repeated rest or wake changes only feedback; it must not manufacture a second successful transition."],
137
+ run: ["Resume, rest, advance time, pause, advance attempted time, resume and wake. Compare energy, food, joy and elapsed after each action. Reset and verify original values, empty history and paused mode.", "A visible status should say both asleep/awake and running/paused so a frozen clock is understandable."],
138
+ assess: ["Check sleep recovery clamping, continued food/joy decay, pause freezing, refused mode changes while paused, retained mode on resume and detached reset. Verify the session-end pause cannot be resumed without reset.", "The correct final meter value alone is insufficient if invalid intermediate transitions were accepted."],
139
+ inspect: ["If rest freezes food, inspect whether sleep was incorrectly treated as pause. If resume wakes the creature, inspect coupled assignments. If reset leaves old values, inspect shared nested objects or partial reset logic.", "Fresh initial state should be created each time rather than reusing a previously mutated object."],
140
+ fix: ["Separate the mode and pause rules, then replay the complete rest/pause/resume/wake sequence. Recheck awake decay from the previous mission so recovery changes do not replace its rates accidentally.", "Use a focused transition table to keep the two independent state dimensions understandable."],
141
+ explain: ["Explain why pause and rest cannot share one meaning and describe what reset affects. Choose the sequence that allows energy recovery while time advances.", "Course progress records learning evidence separately, so resetting the fictional habitat is safe for experimentation."],
142
+ reward: ["Save Restful recovery. Your creature can recover energy, pause safely and start again without confusing those operations. Next you will explain successful actions through a bounded history.", "Keep the transition table beside your code as a reference for clear controls and feedback."]
143
+ },
144
+ questions: {
145
+ learn: { question: "What is the difference between rest and pause?", choices: ["Rest changes mode; pause freezes the simulation", "Both delete the habitat", "Pause always wakes the creature"], correctChoice: 0, feedback: "Rest lets simulated time continue with different energy behaviour, while pause preserves the whole model without advancing it." },
146
+ predict: { question: "Energy starts at 70 asleep and running; after two one-second ticks it is what?", choices: ["70", "76", "68.5"], correctChoice: 1, feedback: "Sleeping energy gains three units per second, so two seconds add six before applying the upper bound." },
147
+ explain: { question: "What should reset do to earned course completion?", choices: ["Delete it", "Replace it with a meter value", "Leave it intact while resetting the preview habitat"], correctChoice: 2, feedback: "Simulation state and verified learning progress are separate records, allowing safe replay after completion." }
148
+ }
149
+ },
150
+ {
151
+ title: "Explain the care history",
152
+ concepts: ["Event records", "Bounded history", "Accessible feedback"],
153
+ goals: ["Record successful care transitions once using stable event identities.", "Make naming, history and feedback understandable without excessive announcements."],
154
+ extension: "Compare a newest-first history with a chronological explanation of the same actions. State which task each ordering helps without changing the stored event contract.",
155
+ activities: {
156
+ learn: ["History records what actually happened: one event after each successful feed, play, rest or wake. Give events increasing IDs, keep the newest 20 entries and never record refused actions as successes. A fictional name can personalise the view without changing care rules or creating history events.", "Ticks can arrive frequently, so history and live announcements should not be flooded with every numerical change."],
157
+ predict: ["Predict history after feed succeeds, play is refused, rest succeeds and time advances. Then predict its length and IDs after more than twenty successful actions, and what happens when the event counter is exhausted.", "Discarding the oldest display entry does not make its identity available for reuse."],
158
+ build: ["Add bounded event recording after successful care transitions and project readable id/text history. Add a labelled naming form with bounded draft input, trim validation, linked errors and aria-invalid. Announce explicit actions and failures through the status message, keeping per-tick need text outside live regions.", "Check event-ID availability before committing a care effect so an exhausted counter cannot leave an unrecorded success."],
159
+ run: ["Perform successful and refused care actions and compare each history entry with its resource transition. Rename with valid and invalid fictional text while paused. Read the page with a screen reader while simulated time runs.", "A useful announcement conveys a meaningful change; repeated tick chatter can hide the result of the user's actual action."],
160
+ assess: ["Check one event per success, none for refused/tick/name/pause actions, stable IDs, newest-first order, 20-entry bound and counter exhaustion. Check naming validation, retained failed draft, inert text and truthful history summaries.", "History is explanatory data, not the authority that awards course completion or replaces protected assessment."],
161
+ inspect: ["If history claims a refused play succeeded, inspect whether recording occurs before guards. If entries repeat after trimming, inspect ID reuse. If naming changes needs, inspect accidental state replacement.", "A display label should never become a command or an identity just because the learner typed it."],
162
+ fix: ["Repair event placement, bounds or naming feedback and replay a mixed success/refusal sequence. Verify that errors remain linked to their field and repeated render updates preserve input focus.", "Keep the original name until a valid rename commits; the editable draft and accepted name serve different purposes."],
163
+ explain: ["Explain why history contains successful transitions instead of every attempted click or tick. Describe how useful feedback differs from repeatedly announcing the same changing meter.", "The person needs a clear account of meaningful actions without losing the ability to read and operate the rest of the page."],
164
+ reward: ["Save Understandable care. The dashboard now explains successful actions and lets learners personalise a fictional creature accessibly. The final mission tests the complete model and interface together.", "Keep a history containing both resource and mode changes as a useful final demonstration."]
165
+ },
166
+ questions: {
167
+ learn: { question: "Which action should create a care-history event?", choices: ["Every tick", "A successful rest transition", "A refused play request"], correctChoice: 1, feedback: "History records committed care or mode changes, while ticks and refused requests do not claim an action succeeded." },
168
+ predict: { question: "After 21 successful care actions, how many entries should remain?", choices: ["21", "One", "20"], correctChoice: 2, feedback: "The history retains the newest twenty entries while keeping its allocation counter increasing so identities are not reused." },
169
+ explain: { question: "Why keep per-tick values outside a live region?", choices: ["To avoid overwhelming meaningful user-action feedback", "To hide all need values", "To prevent keyboard operation"], correctChoice: 0, feedback: "Frequent automatic announcements can interrupt reading and obscure the result of deliberate actions or useful errors." }
170
+ }
171
+ },
172
+ {
173
+ title: "A dashboard worth caring for",
174
+ concepts: ["Integrated simulation", "Accessible interaction", "Capstone"],
175
+ goals: ["Deliver a coherent dashboard with care, time, recovery and truthful history.", "Verify the exact source across normal, refused, boundary and accessible-use scenarios."],
176
+ extension: "Propose another fictional care action in a separate project save, defining its resource costs, timing, history event and accessible feedback before coding it.",
177
+ activities: {
178
+ learn: ["The complete dashboard joins model, controls, time, recovery and explanation. Its theme should make the fictional habitat inviting while labels, bounded rules and useful feedback make it understandable. The final assessment tests the current source, including mistakes and edge cases.", "A lively visual scene is useful only when the displayed state and actual action rules continue to agree."],
179
+ predict: ["Plan a demonstration that resumes, feeds, plays, rests, advances time, pauses, renames, resumes, wakes and resets. Predict needs, modes and history entries, including an intentionally refused action.", "Use supplied time steps so another person can replay the same demonstration and compare exact results."],
180
+ build: ["Finish the three-file application, review every button permission and label, and keep mode/time/history projections truthful. Add any final theme refinements while preserving readable text, focus and reduced motion preferences.", "Do not add automatic browser timers or external services to make the demonstration seem more complete; the host supplies the bounded simulation clock."],
181
+ run: ["Perform the sequence with keyboard and touch, at 320px and enlarged text, in both themes and reduced motion. Check the name form, meter labels, history and announcements with a screen reader. Save/reload the project source and replay.", "Keep controls large enough to operate and allow action groups to wrap without changing the meaning of their labels."],
182
+ assess: ["Run final checks for initial values, action guards, resource accounting, deterministic ticks, session expiry, sleep/pause separation, history bounds, naming, nonmutation and reset. Obtain evidence for the saved current source after the whole accessible journey is verified.", "Every earlier mission contributes rules to this final application; later polish does not replace their required behaviour."],
183
+ inspect: ["Compare a failure with its earliest divergent state: action eligibility, time rate, mode, history or view. If controls and rules disagree, inspect both the projection and transition rather than changing only the visible disabled state.", "A useful reproduction names the starting state and input sequence, not just a screenshot of the eventual mismatch."],
184
+ fix: ["Repair the responsible rule, repeat its boundary case and rerun the full demonstration. Save a named final version and obtain a fresh assessment after the last source change.", "Use the earlier exact-threshold and fractional-time examples to protect behaviour during final styling work."],
185
+ explain: ["Explain the difference between rest and pause, why the history is bounded, and how supplied time makes the model testable. Describe one accessibility decision using evidence from your demonstration.", "Be precise about the limits of this fictional simulation and avoid suggesting its numeric needs describe real creature care."],
186
+ reward: ["Save Caring dashboard and finish the final assessment. You have built an editable web application that connects interactive controls, deterministic time and understandable feedback. Replay a mission or extend another save while keeping earned completion.", "Resetting Moss is a fresh simulation start; your account-bound source and course evidence remain separate."]
187
+ },
188
+ questions: {
189
+ learn: { question: "What should final visual polish preserve?", choices: ["Only the background colour", "Only the newest control", "Truthful state, readable access and all established rules"], correctChoice: 2, feedback: "A coherent final interface improves presentation while preserving the working model and accessible interaction paths." },
190
+ predict: { question: "What makes another learner's replay comparable with yours?", choices: ["The same initial state and supplied action/time sequence", "An unknown browser frame rate", "Different random timer delays"], correctChoice: 0, feedback: "Explicit starting conditions and deterministic inputs let both runs be compared against the same expected transitions." },
191
+ explain: { question: "Which evidence supports an accessibility claim?", choices: ["A decorative icon alone", "A verified keyboard, label and announcement journey", "A promise to test later"], correctChoice: 1, feedback: "Accessibility claims need observed operation through the relevant controls and assistive presentation, not appearance alone." }
192
+ }
193
+ }
194
+ ]);
195
+ export {
196
+ course,
197
+ practice
198
+ };
199
+ //# sourceMappingURL=creature-care-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/courses/creature-care-dashboard.ts"],"sourcesContent":["import { authorCourse } from \"./course-authoring.js\";\nimport { webProjectFiles, webReferences, webStarterCss } from \"./web-course-authoring.js\";\n\nexport const { course, practice } = authorCourse({\n slug: \"creature-care-dashboard\", title: \"Creature Care Dashboard\", category: \"web-app\",\n summary: \"Create an accessible dashboard for a fictional creature. Connect labelled care actions to bounded state, model time without browser timers, distinguish rest from pause and show an honest activity history. Finish a responsive three-file application with readable status, safe reset and evidence for its edge cases.\",\n projectFiles: webProjectFiles,\n starterProject: { files: [\n { path: \"index.html\", source: `<main>\n <h1>Creature Care Dashboard</h1><p>Care for a fictional creature in a simulated habitat.</p>\n <section aria-labelledby=\"creature-heading\"><h2 id=\"creature-heading\" data-text=\"name\"></h2>\n <p data-text=\"modeText\"></p><p data-text=\"clockText\"></p>\n <label for=\"food\">Food</label><meter id=\"food\" min=\"0\" max=\"100\" data-value=\"food\" data-label=\"foodLabel\"></meter><p data-text=\"foodLabel\"></p>\n <label for=\"energy\">Energy</label><meter id=\"energy\" min=\"0\" max=\"100\" data-value=\"energy\" data-label=\"energyLabel\"></meter><p data-text=\"energyLabel\"></p>\n <label for=\"joy\">Joy</label><meter id=\"joy\" min=\"0\" max=\"100\" data-value=\"joy\" data-label=\"joyLabel\"></meter><p data-text=\"joyLabel\"></p>\n <div class=\"actions\"><button type=\"button\" data-action=\"feed\" data-disabled=\"feedDisabled\">Feed</button><button type=\"button\" data-action=\"play\" data-disabled=\"playDisabled\">Play</button><button type=\"button\" data-action=\"rest\" data-disabled=\"restDisabled\">Rest</button><button type=\"button\" data-action=\"wake\" data-disabled=\"wakeDisabled\">Wake</button></div>\n </section>\n <div class=\"actions\"><button type=\"button\" data-action=\"resume\">Resume simulation</button><button type=\"button\" data-action=\"pause\">Pause simulation</button><button type=\"button\" data-action=\"reset\">Reset habitat</button></div>\n <section aria-labelledby=\"history-heading\"><h2 id=\"history-heading\">Care history</h2><p data-text=\"historySummary\"></p><ol><li data-repeat=\"history\" data-text=\"text\"></li></ol></section>\n <p role=\"status\" data-text=\"message\"></p>\n</main>` },\n { path: \"app.css\", source: webStarterCss },\n { path: \"app.js\", source: `function initialState() {\n return { name: \"Moss\", draftName: \"Moss\", nameError: \"\", food: 60, energy: 70, joy: 50,\n mode: \"awake\", paused: true, elapsed: 0, history: [], nextEventId: 1, message: \"Resume when you are ready to care for Moss.\" };\n}\nfunction update(state, input) {\n if (input.type === \"reset\") return initialState();\n return JSON.parse(JSON.stringify(state));\n}\nfunction view(state) {\n return { name: state.name, draftName: state.draftName, nameError: state.nameError, nameInvalid: state.nameError !== \"\",\n food: state.food, energy: state.energy, joy: state.joy,\n foodLabel: \"Food \" + Math.round(state.food) + \" of 100\", energyLabel: \"Energy \" + Math.round(state.energy) + \" of 100\",\n joyLabel: \"Joy \" + Math.round(state.joy) + \" of 100\", modeText: state.mode + (state.paused ? \", paused\" : \", running\"),\n clockText: Math.floor(state.elapsed) + \" seconds simulated\", feedDisabled: true, playDisabled: true, restDisabled: true,\n wakeDisabled: true, resumeDisabled: false, pauseDisabled: true, history: [], historySummary: \"No care actions yet.\", message: state.message };\n}\n` },\n ] },\n reference: [...webReferences,\n { name: \"initialState\", signature: \"initialState() → fresh habitat\", description: \"Start with name/draftName='Moss', nameError='', food=60, energy=70, joy=50, mode='awake', paused=true, elapsed=0, history=[], nextEventId=1 and useful message. Food, energy and joy always remain within 0–100. The model is fictional game behaviour, not advice about real animals.\", example: '{ food: 60, energy: 70, joy: 50, mode: \"awake\", paused: true }' },\n { name: \"care rules\", signature: \"feed/play/rest/wake\", description: \"Successful actions require !paused. Feed also requires awake and food<100; add 20 food capped at 100. Play requires awake, food>=10, energy>=15 and joy<100; subtract 10 food and 15 energy, add 20 joy capped at 100. Rest changes awake to asleep; wake changes asleep to awake. Refused/repeated ineligible actions change only message. Each successful care/mode action records exactly one history event; no action mutates input state.\", example: 'if (next.paused || next.mode !== \"awake\" || next.energy < 15 || next.food < 10 || next.joy >= 100) return { ...next, message: \"Play needs an awake, running creature with enough food and energy.\" };' },\n { name: \"tick\", signature: '{ type: \"tick\", dt: seconds }', description: \"The host supplies finite dt from 0 to 1 inclusive; invalid/negative/oversized values preserve state. When running, advance by min(dt,3600-elapsed); decrease food by 1/second and joy by 0.5/second, and change energy by -0.75/second awake or +3/second asleep. Clamp all needs to 0–100. At elapsed=3600 pause and explain that reset starts another session. Ignore ticks while paused. No Date, setInterval or device-clock access is used.\", example: 'const seconds = Math.min(input.dt, 3600 - next.elapsed); next.food = Math.max(0, next.food - seconds);' },\n { name: \"pause and reset\", signature: \"resume/pause/reset\", description: \"resume clears paused only when elapsed<3600; pause sets it immediately without changing mode, needs or history. Repeating either action changes only feedback. Pause freezes both time and care actions; rest allows time to continue while energy recovers. reset creates a fresh paused habitat with empty history and original values, independently of course completion or account source saves.\", example: 'if (input.type === \"pause\") return { ...next, paused: true, message: \"Simulation paused.\" };' },\n { name: \"history\", signature: \"[{id,action,at}] newest first\", description: \"Append one event only after a successful feed/play/rest/wake transition, using id='care-'+nextEventId, action and at=elapsed; then increment nextEventId. Store newest first and keep the latest 20 entries. nextEventId is an integer 1–1000000; refuse a care action if no ID remains. Ticks, naming, pause and refused actions do not create entries. IDs are never reused when old entries leave the list.\", example: 'next.history = [{ id: \"care-\" + next.nextEventId, action: input.type, at: next.elapsed }, ...next.history].slice(0, 20); next.nextEventId += 1;' },\n { name: \"name\", signature: 'field{name:\"name\",value} then rename', description: \"A string name field updates only draftName, at most 30 characters, and clears nameError. rename trims it and accepts 2–30 characters without control characters; success changes name, normalises draftName and clears errors, while failure keeps name and draft and sets useful error text. Naming is allowed while paused and makes no care-history entry. Use fictional names without personal information.\", example: '<input id=\"name\" name=\"name\" type=\"text\" maxlength=\"30\" aria-describedby=\"name-error\" data-value=\"draftName\" data-invalid=\"nameInvalid\">' },\n { name: \"view\", signature: \"view(state) → needs, permissions and readable history\", description: \"Return name/draftName/nameError/nameInvalid, numeric food/energy/joy plus rounded text labels, modeText and clockText, feedDisabled/playDisabled/restDisabled/wakeDisabled/resumeDisabled/pauseDisabled reflecting actual guards, history [{id,text}], historySummary and message. Read state without mutation. Include mode and paused in text; numeric meters need labels. Do not put every tick in a live region; announce explicit actions and failures instead.\", example: 'const foodLabel = \"Food \" + Math.round(state.food) + \" of 100\";' },\n ],\n}, [\n {\n title: \"Meet the creature in data\", concepts: [\"State modelling\", \"Semantic meters\", \"Responsive styling\"],\n goals: [\"Present the creature's initial needs truthfully with text and labelled meters.\", \"Make a readable three-file dashboard before implementing care actions.\"],\n extension: \"Try an alternative habitat theme in a separate save. Preserve the numeric meanings and readable labels while changing its visual character.\",\n activities: {\n learn: [\"The creature is a fictional model with food, energy and joy from 0–100. JavaScript owns those values, HTML names their meaning and CSS arranges them. A meter needs an accessible name and nearby text so its meaning is not conveyed only by colour or length.\", \"The initial paused state gives people time to understand the page before the simulation begins.\"],\n predict: [\"Predict the three initial meter values and their rounded text labels from food 60, energy 70 and joy 50. Then predict whether simply calling view should change any need or elapsed time.\", \"Reading the dashboard is a projection of state, not an event that feeds or tires the creature.\"],\n build: [\"Review the semantic main/heading/section structure and complete truthful initial view data. Style the habitat and need indicators for 320px, large text and both themes, keeping meter values and readable labels connected to the same state.\", \"Keep all important status visible in words; a green bar by itself cannot explain whether it represents food, energy or joy.\"],\n run: [\"Inspect the paused habitat with keyboard navigation, zoom and a screen reader. Compare each meter's accessible label with its value and the visible text, then reset and confirm the same starting values.\", \"The care controls are intentionally unfinished while this first mission establishes an honest initial dashboard.\"],\n assess: [\"Check fresh initial state, bounded needs, truthful labels, one main landmark and nonmutating view. Confirm controls have meaningful names and the layout remains readable without depending on motion.\", \"This milestone does not require later time or care mechanics, but it does require an accurate representation of the initial model.\"],\n inspect: [\"If text and meters disagree, inspect whether both derive from the same field. If an indicator has no announced name, inspect its label association instead of adding another colour cue.\", \"A visually attractive indicator can still be ambiguous when read without its surrounding layout.\"],\n fix: [\"Repair the projection, label or responsive rule and repeat the initial-state checks at 320px. Preserve visible focus outlines and avoid fixed heights that clip text when zoomed.\", \"Let content determine the height of panels so readable text is not traded away for a rigid card shape.\"],\n explain: [\"Explain why a meter needs both a numeric model and a meaningful name. Choose the design that communicates the same state to people using different ways of reading the page.\", \"Accessible presentation describes the underlying model clearly rather than adding a separate inconsistent version of it.\"],\n reward: [\"Save Honest habitat. Your creature's state can now be understood through labelled values and a readable page. Next you will make its care actions change that model.\", \"Keep this paused baseline for comparing changes caused by each later action.\"],\n },\n questions: {\n learn: { question: \"What does a labelled meter communicate beyond a coloured bar?\", choices: [\"Which need the value represents\", \"A hidden timer\", \"A new care action\"], correctChoice: 0, feedback: \"A meaningful label explains the quantity being displayed even when colour or visual position is unavailable.\" },\n predict: { question: \"What should calling view do to energy=70?\", choices: [\"Reduce it automatically\", \"Leave it at 70\", \"Reset it to 100\"], correctChoice: 1, feedback: \"The display function reads state without advancing time or performing actions, so viewing the dashboard preserves energy.\" },\n explain: { question: \"Which display avoids relying only on colour?\", choices: [\"Three unnamed coloured blocks\", \"An unlabeled animation\", \"Named meters with readable values and status text\"], correctChoice: 2, feedback: \"Labels, values and status text communicate the model through more than a single visual signal.\" },\n },\n },\n {\n title: \"Make care actions matter\", concepts: [\"Guarded actions\", \"Clamping\", \"Detached updates\"],\n goals: [\"Implement meaningful feed and play transitions with explicit prerequisites.\", \"Refuse unavailable actions without partial effects and keep control states truthful.\"],\n extension: \"Write a short explanation of why the creature cannot play in each refused case. Keep messages useful without changing the resource rules.\",\n activities: {\n learn: [\"Feed and play spend or replenish specific resources. Feed adds 20 food up to 100. Play spends 10 food and 15 energy to add 20 joy up to 100. Both need an awake running creature, and checking prerequisites before any change prevents a refused action from partially spending resources.\", \"A disabled button helps explain availability, but update must enforce the same guard even if an action arrives directly.\"],\n predict: [\"Predict feed at food 90 and play at food 10, energy 15, joy 90. Compare the exact-boundary play with energy 14 and explain which fields may change in the refused case.\", \"Clamping the gain and checking the costs are separate operations; a generous reward must not permit a negative resource balance.\"],\n build: [\"Implement resume and pause guards, then feed/play using detached next state and exact prerequisites. Derive feedDisabled and playDisabled from the same rules. Add useful success/refusal messages while keeping history for a later mission.\", \"At this milestone the host assesses resource behaviour; the later history lesson adds receipt tracking without changing these care rules.\"],\n run: [\"Resume, feed near the maximum and play until a resource prevents another turn. Pause and try care again. Compare enabled controls, messages and resource changes with the predictions.\", \"Use the same action sequence with keyboard and touch so both input paths exercise the same state transition.\"],\n assess: [\"Check gains, costs, upper and lower bounds, exact eligibility thresholds, paused/asleep guards, unknown actions and input immutability. Confirm refused actions change only feedback and never partially spend food or energy.\", \"Direct-action scenarios verify guards independently from whatever the current button appearance suggests.\"],\n inspect: [\"If a rejected play drains energy, inspect the order of mutation and guard checks. If a full food meter still accepts feeding, inspect the food<100 condition in both update and view.\", \"The interface and transition function must agree on availability; neither should have an unrelated copy of the rule.\"],\n fix: [\"Repair the earliest wrong resource transition and replay threshold cases on each side of eligibility. Verify that repeated requests cannot push values outside 0–100 and that the current source preserves input objects.\", \"Clone nested state before changing it so previous states remain useful for comparison and later evidence.\"],\n explain: [\"Explain why resource costs are checked before applying any effect and why a disabled button is not the sole guard. Choose the result for a play request with insufficient energy.\", \"The transition function is responsible for correctness even when an event does not originate from the visible control.\"],\n reward: [\"Save Meaningful care. Feeding and play now have bounded, understandable consequences. Next you will make the fictional habitat evolve through supplied simulated time.\", \"Keep the exact-threshold case because small comparison mistakes often hide at resource boundaries.\"],\n },\n questions: {\n learn: { question: \"Where must care prerequisites be enforced?\", choices: [\"Only in CSS\", \"In update as well as truthful control state\", \"Only in the button label\"], correctChoice: 1, feedback: \"The model must reject invalid direct actions while the interface accurately explains which actions are currently available.\" },\n predict: { question: \"What is food after feeding from 90?\", choices: [\"110\", \"90\", \"100\"], correctChoice: 2, feedback: \"Feeding adds twenty but clamps the result to the documented maximum of one hundred.\" },\n explain: { question: \"What should play do with energy 14?\", choices: [\"Preserve needs and explain refusal\", \"Spend food anyway\", \"Set energy to -1\"], correctChoice: 0, feedback: \"Insufficient energy makes the whole action ineligible, so resources stay unchanged and feedback explains the refusal.\" },\n },\n },\n {\n title: \"Let simulated time pass\", concepts: [\"Time steps\", \"Rates\", \"Deterministic simulation\"],\n goals: [\"Advance needs using bounded supplied time steps rather than browser timers.\", \"Clamp values and stop the session at its exact duration limit.\"],\n extension: \"Compare one one-second tick with two half-second ticks away from boundaries. Explain why the same elapsed time should produce the same resource changes.\",\n activities: {\n learn: [\"The host supplies tick actions with finite dt between 0 and 1 seconds. While running, food falls by 1 per second, joy by 0.5 and awake energy by 0.75. Multiply each rate by dt, clamp needs and cap total elapsed time at 3600 seconds.\", \"No browser timer or Date call is needed; supplied time makes the same action sequence repeatable in assessment.\"],\n predict: [\"Predict food, joy and energy after half a second awake from the initial needs. Then predict a tick of 2 seconds, a negative tick and a tick while paused.\", \"Invalid time inputs preserve the model; a large delayed frame is not permission to bypass the bounded tick contract.\"],\n build: [\"Implement tick validation and elapsed advancement, limiting the last step to the remaining session time. Apply awake decay rates and clamp needs. At 3600 pause and show a reset instruction, with resumeDisabled remaining true until reset.\", \"Use the same effective seconds for elapsed and every rate so the final partial step remains coherent.\"],\n run: [\"Resume and compare a recorded sequence of half-second and one-second ticks. Pause between ticks, then use the near-session-end scenario to check the final fractional step and automatic pause.\", \"The host controls simulation pace; changing real browser frame timing must not alter the meaning of one supplied tick.\"],\n assess: [\"Check finite dt boundaries, rejected oversized/negative inputs, paused preservation, decay rates, zero clamps, partitioned time and the exact 3600-second stop. Confirm ticks never create care-history records.\", \"The timer display may round elapsed time, but assessment checks the underlying numeric state.\"],\n inspect: [\"If decay depends on frame count, look for subtracting a fixed amount instead of rate times dt. If the last step overshoots, compare effective seconds used for elapsed and needs.\", \"A visible whole-second clock can hide fractional errors; inspect the underlying values when a prediction differs.\"],\n fix: [\"Repair time scaling or boundary handling and replay the same deterministic tick sequence. Verify that zero time has no effects and that repeated ticks after automatic pause leave the finished session unchanged.\", \"Stopping the clock is a state rule, not just hiding its visible number.\"],\n explain: [\"Explain why supplied dt supports repeatable tests and why elapsed time has a finite cap. Distinguish simulated time from how long someone leaves the browser tab open.\", \"The model advances only through accepted actions, making its behaviour independent of an uncontrolled device clock.\"],\n reward: [\"Save Measured time. The habitat now evolves predictably within fixed limits. Next you will combine time with rest and deliberate pause/recovery behaviour.\", \"Keep the fractional final-step case for later changes to energy recovery and status feedback.\"],\n },\n questions: {\n learn: { question: \"How much food is lost during an accepted half-second tick?\", choices: [\"One unit regardless of dt\", \"Two units\", \"Half a unit\"], correctChoice: 2, feedback: \"Food decays at one unit per second, so multiplying by half a second gives a loss of one half.\" },\n predict: { question: \"What should a tick with dt=2 do?\", choices: [\"Preserve state because it exceeds the allowed step\", \"Advance two seconds anyway\", \"Reset the habitat\"], correctChoice: 0, feedback: \"The input contract allows steps only up to one second, so an oversized tick is rejected without effects.\" },\n explain: { question: \"Why supply time as an input instead of reading Date?\", choices: [\"To hide elapsed time\", \"To make replay and assessment deterministic\", \"To make every action random\"], correctChoice: 1, feedback: \"Explicit time inputs let the same initial state and action sequence produce reproducible results across hosts.\" },\n },\n },\n {\n title: \"Rest, pause and recover\", concepts: [\"State machines\", \"Independent modes\", \"Fresh reset\"],\n goals: [\"Distinguish sleeping recovery from pausing the whole simulation.\", \"Implement guarded mode changes and fresh reset without losing course progress.\"],\n extension: \"Sketch a state diagram for awake/asleep crossed with running/paused. Explain which transitions affect mode and which affect the simulation clock.\",\n activities: {\n learn: [\"Rest changes awake to asleep while the simulation keeps running. Asleep energy recovers by 3 per second; food and joy still decay. Pause freezes all time and care actions without changing awake/asleep mode. Reset starts a fresh paused habitat independently of earned course completion.\", \"Two independent state fields express these different ideas more clearly than one ambiguous status word.\"],\n predict: [\"Predict energy after two accepted one-second ticks asleep from 70. Compare that with the same ticks paused asleep, then predict wake while paused and resume afterwards.\", \"A paused creature cannot change care mode until resumed; resuming preserves whichever mode was already selected.\"],\n build: [\"Implement rest/wake guards, asleep energy recovery and truthful control permissions. Preserve needs and mode when pausing, preserve mode when resuming, and reset all preview state through a new initialState result.\", \"Refused repeated rest or wake changes only feedback; it must not manufacture a second successful transition.\"],\n run: [\"Resume, rest, advance time, pause, advance attempted time, resume and wake. Compare energy, food, joy and elapsed after each action. Reset and verify original values, empty history and paused mode.\", \"A visible status should say both asleep/awake and running/paused so a frozen clock is understandable.\"],\n assess: [\"Check sleep recovery clamping, continued food/joy decay, pause freezing, refused mode changes while paused, retained mode on resume and detached reset. Verify the session-end pause cannot be resumed without reset.\", \"The correct final meter value alone is insufficient if invalid intermediate transitions were accepted.\"],\n inspect: [\"If rest freezes food, inspect whether sleep was incorrectly treated as pause. If resume wakes the creature, inspect coupled assignments. If reset leaves old values, inspect shared nested objects or partial reset logic.\", \"Fresh initial state should be created each time rather than reusing a previously mutated object.\"],\n fix: [\"Separate the mode and pause rules, then replay the complete rest/pause/resume/wake sequence. Recheck awake decay from the previous mission so recovery changes do not replace its rates accidentally.\", \"Use a focused transition table to keep the two independent state dimensions understandable.\"],\n explain: [\"Explain why pause and rest cannot share one meaning and describe what reset affects. Choose the sequence that allows energy recovery while time advances.\", \"Course progress records learning evidence separately, so resetting the fictional habitat is safe for experimentation.\"],\n reward: [\"Save Restful recovery. Your creature can recover energy, pause safely and start again without confusing those operations. Next you will explain successful actions through a bounded history.\", \"Keep the transition table beside your code as a reference for clear controls and feedback.\"],\n },\n questions: {\n learn: { question: \"What is the difference between rest and pause?\", choices: [\"Rest changes mode; pause freezes the simulation\", \"Both delete the habitat\", \"Pause always wakes the creature\"], correctChoice: 0, feedback: \"Rest lets simulated time continue with different energy behaviour, while pause preserves the whole model without advancing it.\" },\n predict: { question: \"Energy starts at 70 asleep and running; after two one-second ticks it is what?\", choices: [\"70\", \"76\", \"68.5\"], correctChoice: 1, feedback: \"Sleeping energy gains three units per second, so two seconds add six before applying the upper bound.\" },\n explain: { question: \"What should reset do to earned course completion?\", choices: [\"Delete it\", \"Replace it with a meter value\", \"Leave it intact while resetting the preview habitat\"], correctChoice: 2, feedback: \"Simulation state and verified learning progress are separate records, allowing safe replay after completion.\" },\n },\n },\n {\n title: \"Explain the care history\", concepts: [\"Event records\", \"Bounded history\", \"Accessible feedback\"],\n goals: [\"Record successful care transitions once using stable event identities.\", \"Make naming, history and feedback understandable without excessive announcements.\"],\n extension: \"Compare a newest-first history with a chronological explanation of the same actions. State which task each ordering helps without changing the stored event contract.\",\n activities: {\n learn: [\"History records what actually happened: one event after each successful feed, play, rest or wake. Give events increasing IDs, keep the newest 20 entries and never record refused actions as successes. A fictional name can personalise the view without changing care rules or creating history events.\", \"Ticks can arrive frequently, so history and live announcements should not be flooded with every numerical change.\"],\n predict: [\"Predict history after feed succeeds, play is refused, rest succeeds and time advances. Then predict its length and IDs after more than twenty successful actions, and what happens when the event counter is exhausted.\", \"Discarding the oldest display entry does not make its identity available for reuse.\"],\n build: [\"Add bounded event recording after successful care transitions and project readable id/text history. Add a labelled naming form with bounded draft input, trim validation, linked errors and aria-invalid. Announce explicit actions and failures through the status message, keeping per-tick need text outside live regions.\", \"Check event-ID availability before committing a care effect so an exhausted counter cannot leave an unrecorded success.\"],\n run: [\"Perform successful and refused care actions and compare each history entry with its resource transition. Rename with valid and invalid fictional text while paused. Read the page with a screen reader while simulated time runs.\", \"A useful announcement conveys a meaningful change; repeated tick chatter can hide the result of the user's actual action.\"],\n assess: [\"Check one event per success, none for refused/tick/name/pause actions, stable IDs, newest-first order, 20-entry bound and counter exhaustion. Check naming validation, retained failed draft, inert text and truthful history summaries.\", \"History is explanatory data, not the authority that awards course completion or replaces protected assessment.\"],\n inspect: [\"If history claims a refused play succeeded, inspect whether recording occurs before guards. If entries repeat after trimming, inspect ID reuse. If naming changes needs, inspect accidental state replacement.\", \"A display label should never become a command or an identity just because the learner typed it.\"],\n fix: [\"Repair event placement, bounds or naming feedback and replay a mixed success/refusal sequence. Verify that errors remain linked to their field and repeated render updates preserve input focus.\", \"Keep the original name until a valid rename commits; the editable draft and accepted name serve different purposes.\"],\n explain: [\"Explain why history contains successful transitions instead of every attempted click or tick. Describe how useful feedback differs from repeatedly announcing the same changing meter.\", \"The person needs a clear account of meaningful actions without losing the ability to read and operate the rest of the page.\"],\n reward: [\"Save Understandable care. The dashboard now explains successful actions and lets learners personalise a fictional creature accessibly. The final mission tests the complete model and interface together.\", \"Keep a history containing both resource and mode changes as a useful final demonstration.\"],\n },\n questions: {\n learn: { question: \"Which action should create a care-history event?\", choices: [\"Every tick\", \"A successful rest transition\", \"A refused play request\"], correctChoice: 1, feedback: \"History records committed care or mode changes, while ticks and refused requests do not claim an action succeeded.\" },\n predict: { question: \"After 21 successful care actions, how many entries should remain?\", choices: [\"21\", \"One\", \"20\"], correctChoice: 2, feedback: \"The history retains the newest twenty entries while keeping its allocation counter increasing so identities are not reused.\" },\n explain: { question: \"Why keep per-tick values outside a live region?\", choices: [\"To avoid overwhelming meaningful user-action feedback\", \"To hide all need values\", \"To prevent keyboard operation\"], correctChoice: 0, feedback: \"Frequent automatic announcements can interrupt reading and obscure the result of deliberate actions or useful errors.\" },\n },\n },\n {\n title: \"A dashboard worth caring for\", concepts: [\"Integrated simulation\", \"Accessible interaction\", \"Capstone\"],\n goals: [\"Deliver a coherent dashboard with care, time, recovery and truthful history.\", \"Verify the exact source across normal, refused, boundary and accessible-use scenarios.\"],\n extension: \"Propose another fictional care action in a separate project save, defining its resource costs, timing, history event and accessible feedback before coding it.\",\n activities: {\n learn: [\"The complete dashboard joins model, controls, time, recovery and explanation. Its theme should make the fictional habitat inviting while labels, bounded rules and useful feedback make it understandable. The final assessment tests the current source, including mistakes and edge cases.\", \"A lively visual scene is useful only when the displayed state and actual action rules continue to agree.\"],\n predict: [\"Plan a demonstration that resumes, feeds, plays, rests, advances time, pauses, renames, resumes, wakes and resets. Predict needs, modes and history entries, including an intentionally refused action.\", \"Use supplied time steps so another person can replay the same demonstration and compare exact results.\"],\n build: [\"Finish the three-file application, review every button permission and label, and keep mode/time/history projections truthful. Add any final theme refinements while preserving readable text, focus and reduced motion preferences.\", \"Do not add automatic browser timers or external services to make the demonstration seem more complete; the host supplies the bounded simulation clock.\"],\n run: [\"Perform the sequence with keyboard and touch, at 320px and enlarged text, in both themes and reduced motion. Check the name form, meter labels, history and announcements with a screen reader. Save/reload the project source and replay.\", \"Keep controls large enough to operate and allow action groups to wrap without changing the meaning of their labels.\"],\n assess: [\"Run final checks for initial values, action guards, resource accounting, deterministic ticks, session expiry, sleep/pause separation, history bounds, naming, nonmutation and reset. Obtain evidence for the saved current source after the whole accessible journey is verified.\", \"Every earlier mission contributes rules to this final application; later polish does not replace their required behaviour.\"],\n inspect: [\"Compare a failure with its earliest divergent state: action eligibility, time rate, mode, history or view. If controls and rules disagree, inspect both the projection and transition rather than changing only the visible disabled state.\", \"A useful reproduction names the starting state and input sequence, not just a screenshot of the eventual mismatch.\"],\n fix: [\"Repair the responsible rule, repeat its boundary case and rerun the full demonstration. Save a named final version and obtain a fresh assessment after the last source change.\", \"Use the earlier exact-threshold and fractional-time examples to protect behaviour during final styling work.\"],\n explain: [\"Explain the difference between rest and pause, why the history is bounded, and how supplied time makes the model testable. Describe one accessibility decision using evidence from your demonstration.\", \"Be precise about the limits of this fictional simulation and avoid suggesting its numeric needs describe real creature care.\"],\n reward: [\"Save Caring dashboard and finish the final assessment. You have built an editable web application that connects interactive controls, deterministic time and understandable feedback. Replay a mission or extend another save while keeping earned completion.\", \"Resetting Moss is a fresh simulation start; your account-bound source and course evidence remain separate.\"],\n },\n questions: {\n learn: { question: \"What should final visual polish preserve?\", choices: [\"Only the background colour\", \"Only the newest control\", \"Truthful state, readable access and all established rules\"], correctChoice: 2, feedback: \"A coherent final interface improves presentation while preserving the working model and accessible interaction paths.\" },\n predict: { question: \"What makes another learner's replay comparable with yours?\", choices: [\"The same initial state and supplied action/time sequence\", \"An unknown browser frame rate\", \"Different random timer delays\"], correctChoice: 0, feedback: \"Explicit starting conditions and deterministic inputs let both runs be compared against the same expected transitions.\" },\n explain: { question: \"Which evidence supports an accessibility claim?\", choices: [\"A decorative icon alone\", \"A verified keyboard, label and announcement journey\", \"A promise to test later\"], correctChoice: 1, feedback: \"Accessibility claims need observed operation through the relevant controls and assistive presentation, not appearance alone.\" },\n },\n },\n]);\n"],"mappings":"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","names":[]}