1// An opt-in, deterministic class simulation. These notes never enter the 2// public Google Form or Sheet; remove ?simulateNotes=200 to return to live notes. 3export function annotationSimulationRequest(search = window.location.search) { 4 const params = new URLSearchParams(search); 5 const count = Number(params.get("simulateNotes")); 6 return Number.isInteger(count) && count > 0 && count <= 500 && params.get("map") 7 ? { mapId: params.get("map"), count } 8 : null; 9} 10 11function seededRandom(seed) { 12 let state = seed >>> 0; 13 return () => { 14 state = (state + 0x6D2B79F5) >>> 0; 15 let value = Math.imul(state ^ (state >>> 15), 1 | state); 16 value ^= value + Math.imul(value ^ (value >>> 7), 61 | value); 17 return ((value ^ (value >>> 14)) >>> 0) / 4294967296; 18 }; 19} 20 21export function simulatedAnnotations(map, count = 60) { 22 const seed = [...map.id].reduce((value, character) => Math.imul(value ^ character.charCodeAt(0), 16777619), 2166136261); 23 const random = seededRandom(seed); 24 const [west, south, east, north] = map.bbox; 25 const marginX = (east - west) * .07; 26 const marginY = (north - south) * .07; 27 const aliases = ["Mina", "Leo", "Asha", "Ren", "Sofia", "Jun", "Nadia", "Eli", "Hana", "Mateo", "Iris", "Omar", "Clara", "Theo", "Amira", "Kai", "Lena", "Ravi", "Noor", "Emil"]; 28 const shuffledAliases = [...aliases]; 29 for (let index = shuffledAliases.length - 1; index > 0; index -= 1) { 30 const other = Math.floor(random() * (index + 1)); 31 [shuffledAliases[index], shuffledAliases[other]] = [shuffledAliases[other], shuffledAliases[index]]; 32 } 33 const observations = [ 34 "The border looks firmer here than I expected.", 35 "I keep comparing this edge with the present coastline.", 36 "The open space feels just as important as the place names.", 37 "This label is clear, but the area around it is hard to read.", 38 "The map makes distance feel different from the basemap.", 39 "I wonder what has been left outside this frame.", 40 "The line seems to join places that feel far apart now.", 41 "The colors make this region feel divided into pieces.", 42 "I noticed how quickly the map changes when I move across it.", 43 "This point looks ordinary until I compare it with the older layer.", 44 "The printed boundary does not feel like a natural edge.", 45 "Some names stand out; others seem almost hidden.", 46 "I am not sure where the map stops describing and starts proposing.", 47 "The scale makes this place feel connected to a much larger space.", 48 "I followed the road and lost track of where the border was.", 49 "The texture of the old map changes how I read the terrain.", 50 "There is a small detail here I would have missed at first.", 51 "The map's center feels less important than its edges.", 52 "I can see more than one version of this place at once.", 53 "The old route gives this landscape a different direction." 54 ]; 55 const reflections = [ 56 "I wonder whose route this map takes for granted.", 57 "The mismatch makes the overlay more interesting to me.", 58 "I would like to compare this with a neighboring layer.", 59 "It feels like a choice, not just a measurement.", 60 "I am not sure what the map cannot show here.", 61 "This detail is easy to miss until I slow down.", 62 "Maybe the blank area is part of the story.", 63 "I want to see how this changes at another scale.", 64 "The old surface makes this place feel less settled.", 65 "It would look different from the other side." 66 ]; 67 return Array.from({ length: count }, (_, index) => { 68 const number = String(index + 1).padStart(3, "0"); 69 return { 70 id: `class-simulation-${map.id.replace(/[^a-zA-Z0-9]/g, "-")}-${number}`, 71 simulated: true, 72 simulationCount: count, 73 timestamp: new Date(Date.UTC(2026, 8, 27, 0, index)).toISOString(), 74 timestampValue: Date.UTC(2026, 8, 27, 0, index), 75 text: `${observations[index % observations.length]} ${reflections[Math.floor(index / observations.length) % reflections.length]}`, 76 name: shuffledAliases[index % shuffledAliases.length], 77 tag: "class simulation", 78 tags: ["class simulation"], 79 context: { 80 mapId: map.id, title: map.title, city: map.city, year: map.year, 81 point: { lng: west + marginX + random() * (east - west - 2 * marginX), lat: south + marginY + random() * (north - south - 2 * marginY) }, 82 core: null, camera: null 83 } 84 }; 85 }); 86}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.