CSCI2720 · Stage practice A
Review route
This practice covers the seven instructional units from browser/server foundations to React components. Work through the review route first, then attempt the paper before opening the explanations and marking guide. The suggested 90 minutes and 100-mark allocation are a study arrangement for this stage practice.
1.1 Browsers, servers and web resources
Start with the resource and the responsible program. An HTTP request identifies an operation and a resource; its response supplies a status, headers and a representation. A visible page can combine an HTML document, stylesheets, scripts and images obtained by separate requests. Count requests only after stating assumptions about caching, redirects and additional dependencies. Their number does not determine a strictly sequential loading order.
Be able to separate a URL's scheme, host, port, path, query and fragment. Resolve a relative URL from the document's base URL rather than appending strings. The origin includes scheme, host and port. A fragment can select a location in the document; it is not part of the HTTP request target.
For a button interaction, name the state before the event, the handler's operation and the resulting DOM change. A changed screen alone does not establish a network request or a stored server value. A variable initialized for each new document starts again when a new instance loads unless the program uses a persistence mechanism.
Work through one address rather than memorising the field names. From https://study.example.test/unit3/page.html, the reference ../icons/book.svg?scale=2#key first uses the directory /unit3/, moves up one directory to /, and appends icons/book.svg. The path is therefore /icons/book.svg. Keep ?scale=2 as the query and #key as the fragment. The origin is https://study.example.test; the ordinary request target is /icons/book.svg?scale=2. This separation answers two different diagnostic questions: which resource is requested, and which fragment the client will interpret. The query text scale=2 does not, by itself, create a JavaScript number or prove that the server saved anything.
Readiness check: Given a document URL, a relative image URL and a click handler, can you derive the final resource URL and distinguish the request target from the fragment? Can you explain exactly which values survive another click and which survive a new document?
2.1 Semantic HTML documents
Read the source as a description of relationships. An element has a role; tags delimit its source; attributes provide values such as a destination, identifier or class. Distinguish the document title from a visible heading, navigation from a generic collection of text, and a data table from a visual arrangement. A class name alone supplies neither styling nor behaviour.
For a table, identify the caption, row and column headers, and each data cell's relationship to those headers. For an image, distinguish useful alternative text from an empty alternative for a decorative image. For literal source text, encode < and & appropriately rather than expecting the browser to display markup unchanged. A character reference becomes a character in the DOM; it does not cause a second parsing pass that constructs that character sequence as new elements.
Suppose a table cell contains 40, its row header is DOM, and its column header is Minutes. Read across both relationships: this records a 40-minute DOM session. Without the column header, 40 might instead mean pages or a score. The table gives the value its meaning; it does not turn the cell's DOM text, the string "40", into an application number. If code must add two session durations, read the text and perform the intended conversion explicitly. Choose headings and table headers to preserve these relationships when the visual layout changes, rather than choosing tags only because their default font looks convenient.
Readiness check: Can you choose elements because of their meaning, explain what a table cell means through its headers, and distinguish the literal text <em>focus</em> from an actual em element?
3.1 Responsive CSS and Bootstrap
First identify which declarations apply to the element. Under normal, unlayered rules from the same author origin, compare specificity before source order. A declaration on the element is distinct from an inherited value. Moving a rule between an external stylesheet and a style element does not, by itself, change its specificity or author origin. State these conditions when predicting a winner.
Draw the content, padding, border and margin boxes. With content-box, add horizontal padding and borders to the declared width to obtain the border-box width. With border-box, subtract those quantities from the declared width to obtain the content width. Margin remains outside either declared width. Do not add a transform to the normal-flow calculation as though it allocated new layout space.
For a responsive rule, test the actual viewport condition and retain the same underlying content. With Bootstrap's default grid, a row has 12 sizing units. Read the active breakpoint classes at each specified viewport width: a larger-tier class starts applying at its minimum and remains active until another applicable declaration changes the result. Static grid classes require the stylesheet; interactive collapse or dropdown behaviour additionally requires the relevant JavaScript.
For a concrete width calculation, take a card with declared width 180 CSS pixels, 8 pixels of padding on each side and a 2-pixel border on each side. Under content-box, the content is 180 and the border box is 180 + 2×8 + 2×2 = 200 CSS pixels. Under border-box, the whole border box is 180 and the content is 180 - 16 - 4 = 160. Draw the two sides before adding or subtracting; adding only one padding is a different geometry. First determine the box-sizing declaration that actually applies, then identify which width is given and which is required. Knowing a content width does not let you choose content-box in place of the actual rule; it tells you which quantity to convert. A viewport threshold uses the viewport's width in CSS pixels, not this card's width, and a grid fraction describes a fraction of its row rather than a physical length in pixels.
Readiness check: Can you justify a winning colour, calculate both box models, and explain the layout immediately below and above a stated breakpoint without treating HTML class order as CSS priority?
4.1 JavaScript, functions and collections
Trace expressions in evaluation order and retain the type of every intermediate value. Numeric addition and string concatenation are different operations. Convert intended numeric input deliberately. A nonempty string such as "0" is truthy even though numeric zero is falsy; strict equality does not convert a number into a string.
Separate function creation, argument passing, invocation and return. A callback can run synchronously. A closure retains access to the particular surrounding bindings associated with its creation. Different calls creating closures can produce separate retained state. A missing return produces undefined; an arrow with a block body needs an explicit return when it is meant to supply a result.
For arrays, keep a reference diagram as well as a list of values. Assignment can introduce an alias. A spread or slice copy creates a different outer array but can retain references to the same nested objects. Distinguish a returned value from a mutation: map and filter construct arrays, forEach discards callback return values, and splice mutates its receiver. A generator's next() returns both a value and a completion flag; a final return is not another yielded item.
To trace a closure, draw one state box for each factory call. A counter made with total 10 changes to 14 when its returned function adds 4, then to 13 when the next call adds −1. The second call starts from the retained 14, not the original 10. A different counter made with total 10 still has 10 until its own function runs. This is why closures can maintain separate event-handler state. Record the operator and type at each step too: adding numeric 2 to the string "6" produces "62", while adding it to the converted number 6 produces 8. Identical-looking input characters do not imply identical operations.
Readiness check: Can you predict a mixed string/number expression, trace independent closures, and show why a nested edit may appear through a shallow copy while a newly appended outer-array member does not?
4.2 DOM events and object state
Begin with the initial tree and identify the objects returned by each API. querySelectorAll records static membership, but its nodes remain mutable. A live collection follows changes in the document. Appending an existing node moves it; it does not create a second independent node.
For an event, separate the originating target from the listener's currentTarget. Follow the listeners in the stated propagation phase and registration order. A form's default submission is a separate behaviour from a click bubbling to an ancestor listener. An event handler changes the application state only through the operations it actually performs.
Choose updates by meaning: textContent supplies text, value reads or writes a control's current value, and classList changes class tokens. Explain method calls using their receiver rather than assuming that moving a function retains the same this. JSON is text representing suitable data; parsing it constructs values with new object identity and does not restore methods.
Imagine three matching list nodes. Record both a static selector result and a live collection. Change the first node's label from Draft to Ready, then append a fourth matching node. The static result still contains three node references, and its first node now says Ready; the live collection contains four. A static result fixes membership, not a photograph of each node's old properties. Choose a fixed result when an operation should act on the originally selected nodes; choose a live collection when the intention is to observe current matching membership. When modifying the tree while iterating a live collection, account for membership changing during the iteration instead of assuming that its indices still describe the original set.
Readiness check: Can you trace a nested click, give the current static and live collection lengths, and distinguish an object alias from an independently parsed JSON value?
5.1 Forms, validation and Fetch
List the successful named controls before constructing the submitted entries. A disabled control is omitted; a read-only named control can contribute its value. An unchecked checkbox does not contribute an entry. A visible label and an id do not substitute for a submitted name.
Distinguish a control's raw string value from the application's intended value and from the number obtained by explicit conversion. required does not express every application rule: spaces may satisfy a text control's nonempty requirement but fail a rule requiring visible characters. A custom validity message remains active until the program clears it. Interface constraints do not replace validation at the receiving boundary.
Trace asynchronous work in stages: obtaining a response, checking its status, reading its body and interpreting the resulting data. An HTTP error response can still fulfil the Fetch operation; invalid JSON can reject body reading after a successful status. Work before an await starts during the current call; continuation after it runs later. A dependent read should follow completion of the write on which it depends.
Separate a value trace from a validity trace. A number input can hold the raw string "6"; after checking the relevant input constraints, explicit numeric conversion gives 6, so adding two pages gives 8 rather than the concatenated text "62". Now suppose a custom error message is set. Editing the control to another acceptable number changes its value, but the custom message remains a separate piece of validity state until cleared. After a request, make the same separation again: an available response supplies a status, that status distinguishes HTTP success from HTTP error, and reading the body supplies data to interpret under the application's contract. Even an error response can carry useful diagnostic data. Do not erase the learner's input merely because a response became available.
Readiness check: Can you predict form entries and validity separately, identify the failed step in a request trace, and explain the lifetime promised by a response from an in-memory service?
6.1 Components, state and rendering
Describe a component as a view of its current props and state. Rendering computes the interface; an event handler requests a state update; the later commit changes the DOM. A state variable captured by a running handler remains that render's snapshot. Repeated replacement requests based on that snapshot differ from updater functions that receive the preceding pending value.
A controlled input needs both its current value and a handler that requests the next value. Use stable item IDs as keys when component state belongs to those items. Keys identify sibling instances; they are not ordinary props automatically available inside the child. If selection belongs to the parent, filtering can hide its selected item without changing the retained selection. Removing a state-owning child from the tree instead unmounts that instance.
Effects synchronise external facilities after a commit. A timer setup needs matching cleanup. With an appropriate empty dependency array, ordinary updates retain the running interval; unmounting cancels it. Keep timer creation out of rendering. State the Strict Mode and flushing assumptions when predicting an exact lifecycle trace.
React retains state for each mounted component identity. When it calls a component to render again, the function gets a new local binding for that render's value. A handler returned by an earlier call still refers to that call's binding. This differs from the closure counter above, which directly changes a retained let binding with +=: a state setter does not reassign the running handler's const count. It requests another state value and render. The distinction explains why both examples use closures yet have different update traces.
An Effect connects the committed component to something outside its rendered state, such as an interval or a registration set. Rendering calculates the view; setup establishes the external relationship after that view commits, and cleanup removes that relationship when required. Reordering items with the same stable keys preserves their state identities. Removing an item unmounts its identity and calls the corresponding cleanup. This is how an external registration can stop when the component stops existing rather than accumulating after each render.
Use three columns in a state trace: the render's captured value, the pending value while React processes queued operations, and the committed display. Suppose the captured count is 3. Two requests to replace it with count + 1 both carry the number 4, so processing them ends at 4. Two updater functions that each add one instead process 3 → 4 → 5. The handler's captured variable remains 3 while it is running; the second updater receives pending 4. The display changes when the update commits. Use an updater when the next value depends on the preceding queued value, and identify the state-owning component before reasoning about filtering, reordering or unmounting it.
Readiness check: Can you follow one queued update, identify the owner of state across filtering, and account for every timer setup and cleanup in the stated sequence?
How to use the paper
- Suggested time: 90 minutes. Total: 100 marks.
- First predict each output without running the code. Write intermediate values, object relationships or event stages where they explain the result.
- Each question states its starting conditions. Treat the examples as independent; changes in one do not carry into another.
- After attempting the paper, use the explanations to distinguish a wrong prediction from a missing justification. Award the separate reasoning marks when their conditions are met.
| Question | Focus | Marks |
|---|---|---|
| Q01 | URLs, resource requests and state | 7 |
| Q02 | Semantic HTML and literal text | 8 |
| Q03 | CSS, box sizes and responsive layout | 10 |
| Q04 | Values and independent closures | 10 |
| Q05 | Array identity and iteration | 8 |
| Q06 | DOM collections and event propagation | 10 |
| Q07 | Object receivers and JSON | 6 |
| Q08 | Form entries and validation | 9 |
| Q09 | Response status and failure stages | 8 |
| Q10 | Asynchronous execution order | 6 |
| Q11 | React state queues and rendering | 10 |
| Q12 | React identity and lifecycle | 8 |
| Total | 100 |
Q01 — Resolve a resource and explain the request (7 marks)
Run the following as an independent JavaScript program with the standard URL API. It constructs URLs; it does not request their resources.
const base = new URL("https://notes.example.test:8443/course/week3/index.html");
const target = new URL("../assets/timetable.svg?size=2#caption", base);
console.log(target.href);
console.log(target.origin);
console.log(target.pathname + target.search);
(a) Write the three printed lines exactly. (3 marks)
(b) Explain how ../ changes the directory and why the query appears in the third line while the fragment does not. (2 marks)
(c) On a separate HTML page, a reader changes only its fragment, then a handler changes a paragraph's textContent. Explain why neither observation alone establishes that a server saved new application data. (2 marks)
Q02 — Read a document's meaning (8 marks)
Consider the complete HTML document below after parsing, with its shown structure unchanged.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Session board</title>
</head>
<body>
<main>
<h1>Session board</h1>
<a href="#schedule">Jump to the schedule</a>
<table id="schedule">
<caption>Study sessions</caption>
<thead><tr><th scope="col">Topic</th><th scope="col">Minutes</th></tr></thead>
<tbody><tr><th scope="row">CSS</th><td>25</td></tr></tbody>
</table>
<p>Write <code><em>focus</em></code> to show the markup.</p>
</main>
</body>
</html>
(a) State the different roles of title, h1 and main in this document. (3 marks)
(b) Explain the meaning of the 25 cell using its row and column headers. Also explain what the caption names and what the link's fragment identifies. (3 marks)
(c) Write the text contained by the code element. Does parsing that text create an em descendant in that element? Explain. (2 marks)
Q03 — Derive a style and a responsive box (10 marks)
The stylesheet below applies to <main id="board"><article class="tile notice">Session</article></main>. All declarations shown are normal, unlayered author rules. There are no other relevant declarations. The article uses the initial content-box sizing below the media-query threshold, and its padding and borders have their shown sizes.
.tile {
width: 240px;
padding: 12px;
border: 3px solid black;
color: green;
}
#board .tile { color: blue; }
.tile.notice { color: red; }
@media (min-width: 768px) {
.tile { box-sizing: border-box; }
}
(a) Which colour applies to the article? Compare the competing selectors explicitly. (3 marks)
(b) At a viewport width of 600 CSS pixels, calculate the article's content width and border-box width. Explain which parts the declared width includes. (3 marks)
(c) At a viewport width of 800 CSS pixels, calculate those two widths again. (2 marks)
(d) In a separate layout using the default Bootstrap 5.3 stylesheet, a .row contains two sibling elements each with class="col-12 col-md-6". Describe their arrangement at 600 and 800 CSS pixels. No additional grid-sizing classes apply. (2 marks)
Q04 — Trace conversion and independent closures (10 marks)
Evaluate this as one independent JavaScript program.
console.log(JSON.stringify(["5" + 1, "5" - 1, 0 === "0"]));
function makeCounter(start) {
let value = start;
return delta => {
value += delta;
return value;
};
}
const first = makeCounter(2);
const second = makeCounter(2);
console.log(first(3));
console.log(second(1));
console.log(first(-1));
(a) Write the four printed lines exactly. (4 marks)
(b) Trace the retained value for first and second separately. Explain why a call through one returned function does not update the other's retained value. (4 marks)
(c) Explain why the first array contains both a string and a number, and why its last value is false. (2 marks)
Q05 — Separate an outer array from its elements (8 marks)
Evaluate this as one independent JavaScript program.
const sessions = [{ minutes: 20 }, { minutes: 35 }];
const alias = sessions;
const copy = sessions.slice();
copy[0].minutes = 25;
copy.push({ minutes: 10 });
const kept = sessions
.filter(item => item.minutes >= 25)
.map(item => item.minutes / 5);
console.log(JSON.stringify([
sessions.length, alias.length, copy.length, sessions[0].minutes,
]));
console.log(JSON.stringify(kept));
function* slots() {
yield "start";
yield "finish";
return "done";
}
const cursor = slots();
console.log(JSON.stringify([cursor.next(), cursor.next(), cursor.next()]));
(a) Write the three printed lines exactly. (3 marks)
(b) Explain why copy[0].minutes = 25 affects sessions[0], while pushing the extra object changes only copy's length. Explain how the filter/map pipeline obtains its result. (3 marks)
(c) Explain why the final generator result has done: true. What would one additional cursor.next() return? (2 marks)
Q06 — Follow nodes and a bubbling event (10 marks)
Open this complete standalone document with ordinary DOM click behaviour. Its script runs once after the shown elements have been parsed and invokes the final .click() exactly once. There are no other event listeners or DOM changes.
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Event trace</title></head>
<body>
<ul id="agenda"><li class="slot">A</li><li class="slot">B</li></ul>
<div id="panel">
<button id="choose" type="button"><span id="word">Select</span></button>
</div>
<script>
const snapshot = document.querySelectorAll(".slot");
const live = document.getElementsByClassName("slot");
document.querySelector(".slot").textContent = "Changed";
const item = document.createElement("li");
item.className = "slot";
item.textContent = "C";
document.querySelector("#agenda").appendChild(item);
console.log(`${snapshot.length},${live.length},${snapshot[0].textContent}`);
const panel = document.querySelector("#panel");
const button = document.querySelector("#choose");
button.addEventListener("click", event => {
console.log(`button:${event.target.id}:${event.currentTarget.id}`);
});
panel.addEventListener("click", event => {
console.log(`bubble:${event.target.id}:${event.currentTarget.id}`);
});
document.querySelector("#word").click();
</script>
</body>
</html>
(a) Write all three printed lines exactly. (3 marks)
(b) Explain the two collection lengths and the changed text. Then explain why the listener on choose runs before the listener on panel. (4 marks)
(c) In both event lines, identify which value describes the originating element and which describes the listener's element. Why do they not have to be the same element? (3 marks)
Q07 — Distinguish identity, data and a method receiver (6 marks)
Evaluate this as one independent JavaScript program.
const original = {
name: "Sketch",
meta: { count: 1 },
describe() { return this.name; },
};
const alias = original;
const roundTrip = JSON.parse(JSON.stringify(original));
alias.meta.count = 2;
console.log(JSON.stringify([
original === alias,
original === roundTrip,
roundTrip.meta.count,
typeof roundTrip.describe,
]));
console.log(original.describe());
(a) Write the two printed lines exactly. Explain the identity comparisons and the value retained inside roundTrip.meta. (3 marks)
(b) Explain why roundTrip.describe has its reported type and why calling original.describe() returns the shown text. (3 marks)
Q08 — Inspect entries and persistent validity state (9 marks)
Open the standalone document below. Its script runs once, without a user submitting the form. In particular, new FormData(form) is called without a submitter argument.
Here stepMismatch reports a violation of the control's step rule, and customError reports a nonempty custom validity message.
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Form trace</title></head>
<body>
<form id="plan">
<label for="title">Session title</label>
<input id="title" name="title" required value="CSS">
<label for="pages">Pages</label>
<input id="pages" name="pages" type="number" min="1" step="1" required value="3">
<label><input name="include" type="checkbox" value="yes" checked>Include notes</label>
<label><input name="skip" type="checkbox" value="yes">Skip notes</label>
<input name="hint" value="draft" disabled>
<select name="format"><option value="notes" selected>Notes</option></select>
<button name="action" value="save">Save</button>
</form>
<script>
const form = document.querySelector("#plan");
const pages = document.querySelector("#pages");
console.log(JSON.stringify([...new FormData(form)]));
pages.value = "1.5";
console.log(JSON.stringify([pages.validity.stepMismatch, form.checkValidity()]));
pages.setCustomValidity("Whole pages only");
pages.value = "4";
console.log(JSON.stringify([pages.validity.customError, form.checkValidity()]));
pages.setCustomValidity("");
console.log(JSON.stringify([pages.validity.customError, form.checkValidity()]));
</script>
</body>
</html>
(a) Write the first printed line exactly, preserving entry order and the string value of pages. Explain why skip, hint and action do not appear. (3 marks)
(b) Write the final three lines exactly. Explain the step mismatch, the custom error after assigning "4", and the final change in validity. (4 marks)
(c) If hint were an enabled, named, read-only text control instead of a disabled control, would it contribute an entry? Would that interface state make its value trustworthy to a receiving service? Explain both answers. (2 marks)
Q09 — Locate the failed asynchronous step (8 marks)
Run this with the standard Response and Promise APIs, then wait for the asynchronous function to finish. Every response is constructed in memory. The last rejected promise models a request failing before a usable response becomes available.
async function inspectResponses() {
const response = await Promise.resolve(new Response('{"message":"later"}', {
status: 503,
headers: { "Content-Type": "application/json" },
}));
console.log(`fulfilled:${response.status}:${response.ok}`);
console.log((await response.json()).message);
try {
await new Response("{broken", { status: 200 }).json();
} catch {
console.log("json-error");
}
try {
await Promise.reject(new TypeError("connection unavailable"));
} catch {
console.log("request-error");
}
}
inspectResponses();
(a) Write the four printed lines exactly. (4 marks)
(b) Explain, in order, why the 503 response is available, why its JSON can still be read, which operation fails for "{broken", and which earlier stage the final rejection represents. (4 marks)
Q10 — Separate the current task from its continuations (6 marks)
Treat the complete script below as the current task. Let its promise continuations finish. No other scheduled work is involved.
console.log("A");
Promise.resolve().then(() => console.log("B"));
async function study() {
console.log("C");
await Promise.resolve();
console.log("D");
}
study();
console.log("E");
(a) Write all five printed lines in order. (3 marks)
(b) Explain why C precedes E, why E precedes both promise continuations, and why B precedes D. (3 marks)
Q11 — Process the queue rather than count setter calls (10 marks)
Mount one fresh Counter using the current React component model, without StrictMode. Wait for the initial commit and record the button text. Click the button once, let that update commit and record its text. Click it a second time, let that update commit and record its text. There are no other updates.
import React, { useState } from "react";
export function Counter() {
const [count, setCount] = useState(1);
return (
<button type="button" onClick={() => {
setCount(count + 1);
setCount(value => value * 3);
setCount(count + 1);
}}>
{count}
</button>
);
}
(a) Write the three recorded button texts, one per line. (3 marks)
(b) For the first click, write the queue's intermediate values. Distinguish the handler's captured count from the value passed to the updater function. Explain why three setter calls do not produce three successive increments. (4 marks)
(c) Rewrite the first and third calls as updater functions, retaining addition by one, multiplication by three, then addition by one. What would a first click from a fresh count of 1 display with this repair? (3 marks)
Q12 — Retain item identity and balance lifecycle work (8 marks)
Mount one fresh SessionList without StrictMode, using items = [{ id: "a", title: "Plan" }, { id: "b", title: "Review" }]. Wait for the initial commit and Effects. The exported set is initially empty and only this list uses it. Carry out the following sequence, allowing each update and its Effects to finish before proceeding:
- Record the initial cards in DOM order using prefix
initial:, then comma-separatedid=valuepairs from each ID and its button'saria-pressedvalue. - Click the button for
a, then record the cards using prefixmarked:. - Re-render the same root with the same item objects in the order
[b, a], then record the cards using prefixreordered:. - Record the sorted IDs in
activeSessionsusing prefixactive:. - Unmount the root, let cleanup finish, then record the set's size using prefix
after-unmount:.
The set is an observation aid for Effect setup and cleanup; it does not control the visible pinned state.
import React, { useEffect, useState } from "react";
export const activeSessions = new Set();
function SessionCard({ item }) {
const [pinned, setPinned] = useState(false);
useEffect(() => {
activeSessions.add(item.id);
return () => activeSessions.delete(item.id);
}, [item.id]);
return (
<li data-id={item.id}>
<button type="button" aria-pressed={pinned}
onClick={() => setPinned(value => !value)}>
{item.title}
</button>
</li>
);
}
export function SessionList({ items }) {
return <ul>{items.map(item => <SessionCard key={item.id} item={item} />)}</ul>;
}
(a) Write the five observation lines exactly. (3 marks)
(b) Explain which component owns pinned and why reordering with these keys preserves the pin on a. What relationship would index keys preserve instead? (3 marks)
(c) Explain why the set contains two IDs after reordering and none after unmounting. (2 marks)
Diagnose the result
Use the per-part marking guide rather than only a total. For an incorrect answer, record the first step at which your model differs from the explanation. Revisit the corresponding review section, then predict a small changed input before rerunning the example.
- Wrong URL or request claim: revisit 1.1; distinguish address resolution, communication and state lifetime.
- Wrong element, escaped text or table relationship: revisit 2.1; draw the constructed document and label its relationships.
- Wrong colour, width or breakpoint: revisit 3.1; list matching rules and draw the boxes before calculating.
- Wrong primitive result, closure or shallow copy: revisit 4.1; record intermediate types and reference relationships.
- Wrong event or object result: revisit 4.2; trace the actual listener and object rather than only the visible label.
- Wrong form or promise result: revisit 5.1; separate entries, validity, response status, body parsing and continuation order.
- Wrong React result: revisit 6.1; write the pending state operations and keep item identity separate from position.