From 5d09ad30d7f3c21e4d2a5de50d653219c890678b Mon Sep 17 00:00:00 2001 From: 33333-33333 Date: Thu, 14 May 2026 20:15:23 +0900 Subject: [PATCH 1/8] separation of script.js --- app-state.js | 50 ++ boot.js | 116 ++++ config.js | 110 ++++ script.js => engine.js | 1323 +--------------------------------------- index.html | 9 +- render.js | 897 +++++++++++++++++++++++++++ utils.js | 116 ++++ 7 files changed, 1314 insertions(+), 1307 deletions(-) create mode 100644 app-state.js create mode 100644 boot.js create mode 100644 config.js rename script.js => engine.js (71%) create mode 100644 render.js create mode 100644 utils.js diff --git a/app-state.js b/app-state.js new file mode 100644 index 0000000..2974c27 --- /dev/null +++ b/app-state.js @@ -0,0 +1,50 @@ +const elementIds = [ +"world", "toggleRun", "stepOnce", "resetWorld", +"speed", "agentCount", "worldSize", "viewMode", "year", "activeGroups", "urbanPopulation", +"ethnicities", "cities", "polities", "wars", "routes", "farmingKnowledge", "metallurgyKnowledge", +"deaths", "frameCost", "ethnicityList", "legend", "tooltip", "stateGraph", "historyRange", +"historyFilter", "historySort", "historyMetric", "toggleActiveStates", "togglePastStates", +"stateGraphInfo", "stateGraphTooltip" +]; +const els = Object.fromEntries(elementIds.map(id => [id === "world" ? "canvas" : id, document.getElementById(id)])); +els.sim = document.querySelector(".sim"); +const ctx = els.canvas.getContext("2d", { alpha: false }); +let sim; +let running = true; +let lastStatsAt = 0; +let lastGraphRenderAt = 0; +let lastRenderAt = 0; +let lastSimTickAt = 0; +let renderDirty = true; +let loopTimer = null; +let loopScheduled = false; +let hoverState = null; +let renderImage = null; +let renderImageSize = 0; +const LoopConfig = Object.freeze({ +simTickMs: 33, +renderMs: 66, +stepBudgetMs: 4.5, +idlePollMs: 180, +hiddenPollMs: 1000 +}); +const graphState = { +filter: "all", +sort: "oldest", +metric: "power", +showActive: true, +showPast: true, +hoverPolityId: null, +rows: [], +markers: [], +scale: null +}; +const legendByMode = { +terrain: () => terrainInfo.map(t => `${t.name}`).join(""), +ethnicity: () => "Agent and city colors show lineage. Land remains terrain-colored.", +pressure: () => "High local population pressure", +polities: () => "Color = city-centered state. Uncolored cities are independent.", +technology: () => "Farming knowledgeMetallurgy knowledge", +pheromone: () => "Pheromone strengthFormal trade routes", +resources: () => "Regenerating local resource stock" +}; diff --git a/boot.js b/boot.js new file mode 100644 index 0000000..7a24abc --- /dev/null +++ b/boot.js @@ -0,0 +1,116 @@ +function requestRender() { +renderDirty = true; +} +function drawFrame(forceStats = false) { +render(); +updateStats(forceStats); +renderTooltip(); +renderDirty = false; +lastRenderAt = performance.now(); +} +function scheduleLoop() { +if (loopScheduled) return; +loopScheduled = true; +const delay = document.hidden +? LoopConfig.hiddenPollMs +: running ? 0 : LoopConfig.idlePollMs; +if (delay > 0) { +loopTimer = setTimeout(() => { +loopTimer = null; +requestAnimationFrame(loop); +}, delay); +} else { +requestAnimationFrame(loop); +} +} +function loop(now = performance.now()) { +loopScheduled = false; +if (running && !document.hidden && now - lastSimTickAt >= LoopConfig.simTickMs) { +lastSimTickAt = now; +const steps = Number(els.speed.value); +const stepBudget = LoopConfig.stepBudgetMs * Math.max(1, steps); +const loopStart = performance.now(); +let completedSteps = 0; +for (let i = 0; i < steps; i++) { +sim.step(); +completedSteps++; +if (completedSteps > 0 && performance.now() - loopStart > stepBudget) break; +} +if (completedSteps > 0) requestRender(); +} +const shouldRender = !document.hidden && +(renderDirty || (running && now - lastRenderAt >= LoopConfig.renderMs)); +if (shouldRender) drawFrame(); +scheduleLoop(); +} +function reset() { +const size = Number(els.worldSize.value); +const count = Number(els.agentCount.value); +els.canvas.width = size; +els.canvas.height = size; +renderImage = null; +renderImageSize = 0; +sim = new Simulation(size, count); +setLegend(); +drawFrame(true); +renderStateGraph(); +} +function refreshStateGraph() { +renderStateGraph(); +clearStateGraphInfo(); +} +els.toggleRun.addEventListener("click", () => { +running = !running; +els.toggleRun.textContent = running ? "Pause" : "Run"; +lastSimTickAt = 0; +if (running && loopTimer) { +clearTimeout(loopTimer); +loopTimer = null; +loopScheduled = false; +scheduleLoop(); +} else if (running) { +scheduleLoop(); +} +}); +els.stepOnce.addEventListener("click", () => { +sim.step(); +requestRender(); +drawFrame(true); +renderStateGraph(); +}); +els.resetWorld.addEventListener("click", reset); +for (const control of [els.worldSize, els.agentCount]) control.addEventListener("change", reset); +els.viewMode.addEventListener("change", () => { +setLegend(); +requestRender(); +drawFrame(); +}); +els.canvas.addEventListener("mousemove", showTooltip); +els.canvas.addEventListener("mouseleave", hideTooltip); +for (const control of [els.historyFilter, els.historySort, els.historyMetric]) { +control?.addEventListener("change", refreshStateGraph); +} +els.toggleActiveStates?.addEventListener("click", () => { +graphState.showActive = !graphState.showActive; +els.toggleActiveStates.setAttribute("aria-pressed", String(graphState.showActive)); +refreshStateGraph(); +}); +els.togglePastStates?.addEventListener("click", () => { +graphState.showPast = !graphState.showPast; +els.togglePastStates.setAttribute("aria-pressed", String(graphState.showPast)); +refreshStateGraph(); +}); +els.stateGraph?.addEventListener("mousemove", updateStateGraphInfo); +els.stateGraph?.addEventListener("mouseleave", clearStateGraphInfo); +document.addEventListener("visibilitychange", () => { +lastSimTickAt = 0; +requestRender(); +if (!document.hidden && loopTimer) { +clearTimeout(loopTimer); +loopTimer = null; +loopScheduled = false; +scheduleLoop(); +} +}); +reset(); +loop(); diff --git a/config.js b/config.js new file mode 100644 index 0000000..2ec80df --- /dev/null +++ b/config.js @@ -0,0 +1,110 @@ +const Terrain = Object.freeze({ +PLAINS: 0, +FOREST: 1, +MOUNTAIN: 2, +WATER: 3, +DESERT: 4 +}); +const terrainInfo = [ +{ name: "Plains", color: [82, 102, 74], move: 1.0, fertility: 0.55, mineral: 0.05, regen: 0.025 }, +{ name: "Forest", color: [58, 91, 68], move: 1.3, fertility: 0.62, mineral: 0.08, regen: 0.038 }, +{ name: "Mountains", color: [104, 105, 101], move: 2.6, fertility: 0.18, mineral: 0.78, regen: 0.012 }, +{ name: "Water", color: [52, 78, 103], move: 7.0, fertility: 0.04, mineral: 0.02, regen: 0.004 }, +{ name: "Desert", color: [139, 123, 86], move: 1.55, fertility: 0.16, mineral: 0.16, regen: 0.014 } +]; +const WEEKS_PER_MONTH = 4; +const MONTHS_PER_YEAR = 12; +const WEEKS_PER_YEAR = MONTHS_PER_YEAR * WEEKS_PER_MONTH; +const SimConfig = Object.freeze({ +population: Object.freeze({ +maxAgentsFloor: 8000, +maxAgentsScale: 1.15, +softCapStart: 0.85, +hardCapScale: 1.35, +offspringCrowdingPenalty: 1.8, +minOffspringAcceptance: 0.035, +maxOffspringPerStep: 360, +carryingCapacityBase: 2.4, +carryingCapacityFertility: 7.8, +carryingCapacityMineral: 1.8, +carryingCapacityFarmland: 5.5, +pressurePenaltyBase: 0.2, +pressureReproductionPenalty: 0.16 +}), +city: Object.freeze({ +maxCities: 300 +}), +render: Object.freeze({ +graphThrottleMs: 1400, +statsThrottleMs: 900, +historyWindowYears: 2000, +historySamplePaddingYears: 240 +}), +technology: Object.freeze({ +cityDiffusion: 0.0022, +tradeDiffusion: 0.0032, +cityInnovation: 0.00045 +}), +polity: Object.freeze({ +minimumPerCapitaFood: 0.06, +logisticsDistance: 34 +}), +polityAccess: Object.freeze({ +enabled: true, +maxSearchDepth: 8, +indirectPenalty: 0.012, +perHopPenalty: 0.006, +noAccessPenalty: 0.045, +lowLoyaltyTransitPenalty: 0.012, +foreignTransitPenalty: 0.008 +}), +culture: Object.freeze({ +spreadRadius: 3, +cityWeight: 0.035, +routeWeight: 1.35, +minimumInfluence: 0.18 +}), +route: Object.freeze({ +maxRouteLength: 42, +pheromoneDecay: 0.996, +pheromoneDiffusion: 0.045, +maxPheromone: 18, +routePheromoneBuild: 0.18, +routePheromoneMaintain: 0.12, +routeUpkeepPerTile: 0.018, +routeWeakThreshold: 8, +routeUnsupportedDecay: 7, +routeMaintainedBoost: 10 +}), +disaster: Object.freeze({ +damageScale: 1.5, +majorLossRate: 0.05, +checkIntervalYears: 8, +baseChance: 0.76, +minRadius: 6, +maxRadius: 34, +rareLargeChance: 0.10, +largeRadiusMin: 28, +largeRadiusMax: 54, +minIntensity: 0.25, +maxIntensity: 0.95, +visualDurationYears: 18, +maxActiveVisuals: 12, +maxHistory: 160 +}), +frontierWave: Object.freeze({ +enabledAfterYears: 300, +intervalYears: 80, +chance: 0.45, +minAgents: 60, +maxAgents: 140, +maxPopulationRatio: 1.28, +edgeBand: 4, +mutation: 0.08, +minResources: 12, +maxResources: 28 +}) +}); +function years(value) { +return value * WEEKS_PER_YEAR; +} diff --git a/script.js b/engine.js similarity index 71% rename from script.js rename to engine.js index d843674..3d1c45e 100644 --- a/script.js +++ b/engine.js @@ -1,167 +1,3 @@ -const Terrain = Object.freeze({ -PLAINS: 0, -FOREST: 1, -MOUNTAIN: 2, -WATER: 3, -DESERT: 4, -FERTILE: 5, -MINERAL: 6 -}); -const terrainInfo = [ -{ name: "Plains", color: [82, 102, 74], move: 1.0, fertility: 0.55, mineral: 0.05, regen: 0.025 }, -{ name: "Forest", color: [58, 91, 68], move: 1.3, fertility: 0.62, mineral: 0.08, regen: 0.038 }, -{ name: "Mountains", color: [104, 105, 101], move: 2.6, fertility: 0.18, mineral: 0.78, regen: 0.012 }, -{ name: "Water", color: [52, 78, 103], move: 7.0, fertility: 0.04, mineral: 0.02, regen: 0.004 }, -{ name: "Desert", color: [139, 123, 86], move: 1.55, fertility: 0.16, mineral: 0.16, regen: 0.014 }, -{ name: "Fertile", color: [94, 122, 78], move: 0.9, fertility: 0.92, mineral: 0.04, regen: 0.055 }, -{ name: "Mineral", color: [118, 101, 94], move: 1.5, fertility: 0.38, mineral: 0.95, regen: 0.018 } -]; -const WEEKS_PER_MONTH = 4; -const MONTHS_PER_YEAR = 12; -const WEEKS_PER_YEAR = MONTHS_PER_YEAR * WEEKS_PER_MONTH; -const SimConfig = Object.freeze({ -population: Object.freeze({ -maxAgentsFloor: 8000, -maxAgentsScale: 1.15, -softCapStart: 0.85, -hardCapScale: 1.35, -offspringCrowdingPenalty: 1.8, -minOffspringAcceptance: 0.035, -maxOffspringPerStep: 360, -carryingCapacityBase: 2.4, -carryingCapacityFertility: 7.8, -carryingCapacityMineral: 1.8, -carryingCapacityFarmland: 5.5, -pressurePenaltyBase: 0.2, -pressureReproductionPenalty: 0.16 -}), -city: Object.freeze({ -maxCities: 300 -}), -render: Object.freeze({ -graphThrottleMs: 1400, -statsThrottleMs: 900, -historyWindowYears: 2000, -historySamplePaddingYears: 240 -}), -technology: Object.freeze({ -cityDiffusion: 0.0022, -tradeDiffusion: 0.0032, -cityInnovation: 0.00045 -}), -polity: Object.freeze({ -minimumPerCapitaFood: 0.06, -logisticsDistance: 34 -}), -polityAccess: Object.freeze({ -enabled: true, -maxSearchDepth: 8, -indirectPenalty: 0.012, -perHopPenalty: 0.006, -noAccessPenalty: 0.045, -lowLoyaltyTransitPenalty: 0.012, -foreignTransitPenalty: 0.008 -}), -culture: Object.freeze({ -spreadRadius: 3, -cityWeight: 0.035, -routeWeight: 1.35, -minimumInfluence: 0.18 -}), -route: Object.freeze({ -maxRouteLength: 42, -pheromoneDecay: 0.996, -pheromoneDiffusion: 0.045, -maxPheromone: 18, -routePheromoneBuild: 0.18, -routePheromoneMaintain: 0.12, -routeUpkeepPerTile: 0.018, -routeWeakThreshold: 8, -routeUnsupportedDecay: 7, -routeMaintainedBoost: 10 -}), -disaster: Object.freeze({ -damageScale: 1.5, -majorLossRate: 0.05, -checkIntervalYears: 8, -baseChance: 0.76, -minRadius: 6, -maxRadius: 34, -rareLargeChance: 0.10, -largeRadiusMin: 28, -largeRadiusMax: 54, -minIntensity: 0.25, -maxIntensity: 0.95, -visualDurationYears: 18, -maxActiveVisuals: 12, -maxHistory: 160 -}), -frontierWave: Object.freeze({ -enabledAfterYears: 300, -intervalYears: 80, -chance: 0.45, -minAgents: 60, -maxAgents: 140, -maxPopulationRatio: 1.28, -edgeBand: 4, -mutation: 0.08, -minResources: 12, -maxResources: 28 -}) -}); -function years(value) { -return value * WEEKS_PER_YEAR; -} -const elementIds = [ -"world", "toggleRun", "stepOnce", "resetWorld", -"speed", "agentCount", "worldSize", "viewMode", "year", "activeGroups", "urbanPopulation", -"ethnicities", "cities", "polities", "wars", "routes", "farmingKnowledge", "metallurgyKnowledge", -"deaths", "frameCost", "ethnicityList", "legend", "tooltip", "stateGraph", "historyRange", -"historyFilter", "historySort", "historyMetric", "toggleActiveStates", "togglePastStates", -"stateGraphInfo", "stateGraphTooltip" -]; -const els = Object.fromEntries(elementIds.map(id => [id === "world" ? "canvas" : id, document.getElementById(id)])); -els.sim = document.querySelector(".sim"); -const ctx = els.canvas.getContext("2d", { alpha: false }); -let sim; -let running = true; -let lastStatsAt = 0; -let lastGraphRenderAt = 0; -let lastRenderAt = 0; -let lastSimTickAt = 0; -let renderDirty = true; -let loopTimer = null; -let loopScheduled = false; -let hoverState = null; -let renderImage = null; -let renderImageSize = 0; -const LoopConfig = Object.freeze({ -simTickMs: 33, -renderMs: 66, -stepBudgetMs: 4.5, -idlePollMs: 180, -hiddenPollMs: 1000 -}); -const graphState = { -filter: "all", -sort: "important", -metric: "power", -showActive: true, -showPast: true, -hoverPolityId: null, -rows: [], -markers: [], -scale: null -}; -const legendByMode = { -terrain: () => terrainInfo.map(t => `${t.name}`).join(""), -ethnicity: () => "Agent and city colors show lineage. Land remains terrain-colored.", -pressure: () => "High local population pressure", -polities: () => "Color = city-centered state. Uncolored cities are independent.", -technology: () => "Farming knowledgeMetallurgy knowledge", -pheromone: () => "Pheromone strengthFormal trade routes", -resources: () => "Regenerating local resource stock" -}; class Rng { constructor(seed) { this.seed = seed >>> 0; @@ -254,9 +90,8 @@ const temp = this.temperature[i]; const humid = this.humidity[i]; let t = this.terrain[i]; if (t !== Terrain.WATER) { -if (elevation > seaLevel + 0.42) t = minerals > 0.56 ? Terrain.MINERAL : Terrain.MOUNTAIN; +if (elevation > seaLevel + 0.42) t = Terrain.MOUNTAIN; else if (humid < 0.15 && temp > 0.58) t = Terrain.DESERT; -else if (humid > 0.72 && temp > 0.25 && temp < 0.88) t = Terrain.FERTILE; else if (humid > 0.5 && temp > 0.18) t = Terrain.FOREST; else t = Terrain.PLAINS; } @@ -294,7 +129,6 @@ if (waterScore <= 0) continue; const boost = Math.min(0.32, waterScore * 0.08); nextFertility[i] = clamp(this.fertility[i] + boost, 0, 1); if (this.terrain[i] === Terrain.DESERT && waterScore > 1.2) this.terrain[i] = Terrain.PLAINS; -if ((this.terrain[i] === Terrain.PLAINS || this.terrain[i] === Terrain.FOREST) && nextFertility[i] > 0.82) this.terrain[i] = Terrain.FERTILE; } } for (let i = 0; i < this.count; i++) { @@ -1031,7 +865,6 @@ return clamp(mobility * 0.75 + (1 - sedentary) * 0.55, 0, 1); } farmabilityAt(tile) { const t = this.world.terrain[tile]; -if (t === Terrain.FERTILE) return 1.0; if (t === Terrain.PLAINS) return 0.75; if (t === Terrain.FOREST) return 0.55; if (t === Terrain.DESERT) return 0.25; @@ -1095,7 +928,7 @@ if ((agent.tech?.metallurgy || 0) <= 0.02) { const metallurgyBase = 0.00011; const mineral = clamp(w.mineral[tile], 0, 1); const mineralTerrainBonus = -w.terrain[tile] === Terrain.MINERAL || w.terrain[tile] === Terrain.MOUNTAIN +w.terrain[tile] === Terrain.MOUNTAIN ? 1.8 : 1.0; const metallurgyChance = @@ -1543,7 +1376,7 @@ for (const a of this.agents) { if (!a.alive) continue; const local = w.idx(a.x, a.y); if (a.settled < 3 && w.pressure[local] < 2) continue; -if (w.terrain[local] === Terrain.WATER || w.fertility[local] < 0.24) continue; +if (w.terrain[local] === Terrain.WATER) continue; const cx = clamp(Math.round(a.x / 4) * 4, 0, w.size - 1); const cy = clamp(Math.round(a.y / 4) * 4, 0, w.size - 1); const i = w.idx(cx, cy); @@ -2955,6 +2788,7 @@ for (const polity of this.polities) { const instability = this.polityInstability(polity); const agePressure = this.polityAgePressure(polity); const threshold = clamp(0.14 + instability * 0.05 + agePressure * 0.03, 0.14, 0.28); +const rebellions = []; for (const city of this.getPolityCities(polity)) { if (city.id === polity.centerCityId || city.loyalty >= threshold) continue; const chance = @@ -2964,13 +2798,25 @@ agePressure * 0.010; if (this.rng.next() < chance) { const rebellionLoyalty = city.loyalty ?? 0; this.removeCityFromPolity(city); -this.addPolityEvent(polity.id, "rebellion", this.year, { +rebellions.push({ cityId: city.id, population: city.population || 0, loyalty: rebellionLoyalty -}, 3); +}); } } +if (rebellions.length === 1) { +this.addPolityEvent(polity.id, "rebellion", this.year, rebellions[0], 1); +} else if (rebellions.length > 1) { +const population = rebellions.reduce((sum, rebellion) => sum + (rebellion.population || 0), 0); +const avgLoyalty = rebellions.reduce((sum, rebellion) => sum + (rebellion.loyalty || 0), 0) / rebellions.length; +this.addPolityEvent(polity.id, "rebellion", this.year, { +cityIds: rebellions.map(rebellion => rebellion.cityId), +cityCount: rebellions.length, +population, +loyalty: avgLoyalty +}, 3); +} } } enforcePolityContinuity(polity) { @@ -2993,7 +2839,7 @@ const isolated = cities.filter(city => !reachable.has(city.id)); if (!isolated.length) return cities; for (const city of isolated) { this.removeCityFromPolity(city); -city.loyalty = clamp(city.loyalty - 0.12, 0, 1); +city.loyalty = clamp(city.loyalty - 0.28, 0, 1); } polity.cohesion = clamp((polity.cohesion ?? 0.6) - isolated.length * 0.035, 0, 1); polity.legitimacy = clamp((polity.legitimacy ?? 0.7) - isolated.length * 0.02, 0, 1); @@ -3497,1134 +3343,3 @@ for (const a of candidates) a.ethnicity = newId; } } } -function render() { -const start = performance.now(); -const w = sim.world; -const size = w.size; -if (!renderImage || renderImageSize !== size) { -renderImage = ctx.createImageData(size, size); -renderImageSize = size; -} -const image = renderImage; -const data = image.data; -const mode = els.viewMode.value; -const cityPolityColor = new Map(); -if (mode === "polities") { -for (const city of sim.cities) { -if (city.polityId === null) continue; -const polity = cityPolity(city); -if (!polity) continue; -const isGraphHover = graphState.hoverPolityId === polity.id; -cityPolityColor.set(city.id, { -color: polity.color, -isGraphHover -}); -} -} -for (let i = 0; i < w.count; i++) { -let color; -if (mode === "resources") { -const v = clamp(w.resource[i] / 30, 0, 1); -color = mix([28, 36, 40], [107, 188, 85], v); -} else if (mode === "ethnicity") { -color = terrainInfo[w.terrain[i]].color; -if (w.city[i] >= 0) { -const city = sim.getCityById(w.city[i]); -if (city) color = mix(color, cityMajorityColor(city), 0.72); -} -} else if (mode === "pressure") { -const v = clamp(w.pressure[i] / 12, 0, 1); -color = mix(terrainInfo[w.terrain[i]].color, [210, 73, 67], v); -} else if (mode === "polities") { -color = terrainInfo[w.terrain[i]].color; -if (w.city[i] >= 0) { -const polityColor = cityPolityColor.get(w.city[i]); -if (polityColor) { -color = mix(color, polityColor.color, polityColor.isGraphHover ? 0.82 : 0.5); -if (graphState.hoverPolityId !== null && !polityColor.isGraphHover) color = mix(color, [16, 18, 19], 0.28); -} -} -} else if (mode === "technology") { -color = mix(terrainInfo[w.terrain[i]].color, [44, 42, 48], 0.35); -} else if (mode === "pheromone") { -const v = clamp(w.pheromone[i] / SimConfig.route.maxPheromone, 0, 1); -color = mix(mix(terrainInfo[w.terrain[i]].color, [18, 20, 18], 0.58), [216, 177, 86], v); -} else { -color = terrainInfo[w.terrain[i]].color; -} -const p = i * 4; -data[p] = color[0]; -data[p + 1] = color[1]; -data[p + 2] = color[2]; -data[p + 3] = 255; -} -ctx.putImageData(image, 0, 0); -renderDisasters(); -drawTradeLinks(); -drawAgentsAndCities(mode); -drawGraphPolityHighlight(); -maybeRenderStateGraph(); -els.frameCost.textContent = `${Math.round(performance.now() - start)}ms`; -} -function renderDisasters() { -if (!sim?.disasters?.length) return; -sim.disasters = sim.disasters.filter(disaster => sim.year <= disaster.expires); -if (!sim.disasters.length) return; -ctx.save(); -ctx.globalCompositeOperation = "source-over"; -for (const disaster of sim.disasters) { -const duration = Math.max(1, disaster.expires - disaster.year); -const ageFraction = clamp((sim.year - disaster.year) / duration, 0, 1); -const alpha = (1 - ageFraction) * (0.10 + (disaster.intensity || 0.5) * 0.22); -if (alpha <= 0.005) continue; -const innerRadius = Math.max(1, disaster.radius * 0.32); -const gradient = ctx.createRadialGradient(disaster.x, disaster.y, innerRadius, disaster.x, disaster.y, disaster.radius); -gradient.addColorStop(0, `rgba(211, 95, 84, ${alpha * 1.35})`); -gradient.addColorStop(0.55, `rgba(211, 95, 84, ${alpha * 0.65})`); -gradient.addColorStop(1, "rgba(211, 95, 84, 0)"); -ctx.fillStyle = gradient; -drawGraphCircle(ctx, disaster.x, disaster.y, disaster.radius); -ctx.strokeStyle = `rgba(236, 126, 111, ${alpha * 0.85})`; -ctx.lineWidth = 1; -strokeCircle(ctx, disaster.x, disaster.y, disaster.radius); -} -ctx.restore(); -} -function rgb(color, boost = 0) { -return `rgb(${Math.min(255, color[0] + boost)}, ${Math.min(255, color[1] + boost)}, ${Math.min(255, color[2] + boost)})`; -} -function rgba(color, alpha, boost = 0) { -return `rgba(${Math.min(255, color[0] + boost)}, ${Math.min(255, color[1] + boost)}, ${Math.min(255, color[2] + boost)}, ${alpha})`; -} -function fillSquare(g, x, y, radius) { -g.fillRect(x - radius, y - radius, radius * 2 + 1, radius * 2 + 1); -} -function strokeLine(g, x1, y1, x2, y2) { -g.beginPath(); -g.moveTo(x1, y1); -g.lineTo(x2, y2); -g.stroke(); -} -function strokeCircle(g, x, y, r) { -g.beginPath(); -g.arc(x, y, r, 0, Math.PI * 2); -g.stroke(); -} -function drawTradeLinks() { -const w = sim.world; -ctx.save(); -const currentLinkTiles = new Set(); -for (const link of sim.tradeLinks) { -for (const tile of link.path || []) currentLinkTiles.add(tile); -} -ctx.globalAlpha = 0.24; -ctx.fillStyle = "#d9b650"; -for (const i of sim.activeTradeRouteTiles || []) { -if (currentLinkTiles.has(i)) continue; -ctx.fillRect(i % w.size, Math.floor(i / w.size), 1, 1); -} -if (!sim.tradeLinks.length) { -ctx.restore(); -return; -} -for (const link of sim.tradeLinks) { -ctx.globalAlpha = clamp(0.12 + link.strength * 0.35, 0.16, 0.42); -ctx.fillStyle = "#ffd75a"; -for (const tile of link.path || []) { -ctx.fillRect(tile % w.size, Math.floor(tile / w.size), 1, 1); -} -} -ctx.restore(); -} -function drawAgentsAndCities(mode) { -ctx.save(); -if (mode !== "ethnicity") { -for (const city of sim.cities) { -const radius = cityRenderRadius(city); -const color = cityDisplayColor(city, mode); -ctx.fillStyle = rgba(color, 0.72); -ctx.globalAlpha = 0.88; -fillSquare(ctx, city.x, city.y, radius); -} -} -ctx.globalAlpha = 1; -if (mode === "technology") { -for (const a of sim.agents) { -sim.ensureAgentTech(a); -const farming = techLevel(a, "farming"); -const metallurgy = techLevel(a, "metallurgy"); -const tech = clamp(Math.max(farming, metallurgy), 0, 1); -if (tech <= 0.01) continue; -const color = mix([95, 171, 91], [202, 169, 102], metallurgy / Math.max(0.001, farming + metallurgy)); -ctx.fillStyle = rgba(color, clamp(0.32 + tech * 0.68, 0.32, 1)); -ctx.fillRect(a.x, a.y, 1, 1); -} -} else if (mode === "ethnicity") { -for (const a of sim.agents) { -const e = sim.ethnicities.get(a.ethnicity); -if (!e) continue; -ctx.fillStyle = rgb(e.color); -ctx.fillRect(a.x, a.y, 1, 1); -} -} else { -ctx.fillStyle = "#eeeccf"; -for (const tile of sim.tileAgents.keys()) { -ctx.fillRect(tile % sim.world.size, Math.floor(tile / sim.world.size), 1, 1); -} -} -for (const city of sim.cities) { -if (mode === "ethnicity") { -const radius = cityRenderRadius(city); -const color = cityDisplayColor(city, mode); -ctx.globalAlpha = 0.90; -ctx.fillStyle = rgba(color, 0.78); -fillSquare(ctx, city.x, city.y, radius); -ctx.globalAlpha = 1; -} -const color = cityDisplayColor(city, mode); -ctx.fillStyle = rgb(color, 55); -ctx.fillRect(city.x, city.y, 1, 1); -} -ctx.restore(); -} -function drawGraphPolityHighlight() { -const polityId = graphState.hoverPolityId; -if (polityId === null) return; -const polity = sim.getPolityById(polityId); -if (!polity) return; -const cities = sim.getPolityCities(polity); -if (!cities.length) return; -ctx.save(); -ctx.lineWidth = 1; -for (const city of cities) { -const radius = Math.max(3, cityRenderRadius(city) + 2); -const color = polity.color || [238, 232, 188]; -ctx.globalAlpha = city.id === polity.centerCityId ? 0.95 : 0.72; -ctx.strokeStyle = rgb(color, 72); -ctx.strokeRect(city.x - radius, city.y - radius, radius * 2 + 1, radius * 2 + 1); -ctx.globalAlpha = 0.32; -ctx.fillStyle = rgb(color); -ctx.fillRect(city.x - radius + 1, city.y - radius + 1, Math.max(1, radius * 2 - 1), Math.max(1, radius * 2 - 1)); -} -ctx.restore(); -} -function cityRenderRadius(city) { -return clamp(Math.floor(Math.sqrt(city.population) / 12), 1, 7); -} -function cityMajorityColor(city) { -const id = dominantComposition(city.ethnicityComposition); -return sim.ethnicities.get(id)?.color || [242, 215, 134]; -} -function cityPolity(city) { -return city?.polityId != null ? sim.getPolityById(city.polityId) : null; -} -function cityDisplayColor(city, mode) { -if (mode === "polities") { -const polity = cityPolity(city); -if (polity) return polity.color; -return [218, 205, 154]; -} -return cityMajorityColor(city); -} -function techLevel(holder, key) { -return holder?.tech?.[key] || 0; -} -function knowledgeLevel(city, key) { -return city?.knowledge?.[key] || 0; -} -function showTooltip(event) { -const rect = els.canvas.getBoundingClientRect(); -const simRect = els.sim.getBoundingClientRect(); -const x = Math.floor((event.clientX - rect.left) / rect.width * sim.world.size); -const y = Math.floor((event.clientY - rect.top) / rect.height * sim.world.size); -hoverState = { -x, -y, -left: event.clientX - simRect.left + 16, -top: event.clientY - simRect.top + 16, -width: simRect.width, -height: simRect.height -}; -renderTooltip(); -} -function tooltipRow(label, value, show = true) { -return show ? `${label}${value}` : ""; -} -function tooltipSection(title, items) { -const body = items.filter(Boolean).join(""); -return body ? `

${title}

${body}
` : ""; -} -function renderTooltip() { -if (!hoverState) return; -const x = hoverState.x; -const y = hoverState.y; -if (x < 0 || y < 0 || x >= sim.world.size || y >= sim.world.size) { -hideTooltip(); -return; -} -const w = sim.world; -const i = w.idx(x, y); -const agent = findAgentAt(x, y); -const city = w.city[i] >= 0 ? sim.getCityById(w.city[i]) : null; -const terrain = terrainInfo[w.terrain[i]]; -const ethnicity = agent ? sim.ethnicities.get(agent.ethnicity) : null; -const waterInfluence = waterInfluenceAt(w, x, y).toFixed(2); -const cityEthnicity = city ? dominantComposition(city.ethnicityComposition) : null; -const mismatch = agent ? sim.climateMismatch(agent.ethnicity, i) : 0; -const polity = cityPolity(city); -const regionalEthnicity = w.dominantEthnicity[i] >= 0 ? `E${w.dominantEthnicity[i]}` : "-"; -els.tooltip.innerHTML = ` - ${city ? `City #${city.id}` : agent ? "Agent group" : terrain.name} - ${tooltipSection("Tile", [ - tooltipRow("Position", `${x}, ${y}`), - tooltipRow("Terrain", terrain.name), - tooltipRow("Resources", w.resource[i].toFixed(1)), - tooltipRow("Fertility", w.fertility[i].toFixed(2)), - tooltipRow("Minerals", w.mineral[i].toFixed(2)), - tooltipRow("Temp / humid", `${w.temperature[i].toFixed(2)} / ${w.humidity[i].toFixed(2)}`), - tooltipRow("Water", waterInfluence), - tooltipRow("Pressure", w.pressure[i].toFixed(0)), - tooltipRow("Pheromone", w.pheromone[i].toFixed(1)), - tooltipRow("Route", w.tradeRoute[i], w.tradeRoute[i]) - ])} - ${tooltipSection("City & State", [ - tooltipRow("Population", city?.population.toLocaleString(), city), - tooltipRow("Food stock", city?.storedResources.toFixed(1), city), - tooltipRow("Supply stress", (city?.supplyStress || 0).toFixed(2), city), - tooltipRow("Trade", city ? `${city.tradeLinks.size} links, ${(city.tradeValue || 0).toFixed(2)} value` : "", city), - tooltipRow("Knowledge", city ? `${knowledgeLevel(city, "farming").toFixed(2)} farm / ${knowledgeLevel(city, "metallurgy").toFixed(2)} metal` : "", city), - tooltipRow("City majority", `E${cityEthnicity}`, cityEthnicity), - city ? cityEthnicityPie(city) : "", - tooltipRow("State", polity ? `#${polity.id}` : "Independent", city), - tooltipRow("Loyalty", city?.loyalty.toFixed(2), city), - tooltipRow("Charisma", clamp(polity?.charisma ?? 1, 0.5, 1.5).toFixed(2), polity), - tooltipRow("Leader tenure", polity ? `${Math.floor((sim.year - (polity.leaderStarted ?? polity.founded ?? sim.year)) / WEEKS_PER_YEAR)}y` : "", polity), - tooltipRow("Treasury", polity?.treasury.toFixed(1), polity), - tooltipRow("Capital", polity && city ? polity.centerCityId === city.id ? "yes" : "no" : "", polity) - ])} - ${tooltipSection("Culture & Agent", [ - tooltipRow("Local culture", `${regionalEthnicity} / ${w.cultureDiversity[i].toFixed(2)}`), - tooltipRow("Agent ethnicity", `E${agent?.ethnicity}`, agent), - tooltipRow("Lineage pop", ethnicity?.population, ethnicity), - tooltipRow("Climate pref", ethnicity ? `${ethnicity.climateTemp.toFixed(2)} / ${ethnicity.climateHumidity.toFixed(2)}` : "", ethnicity), - tooltipRow("Climate mismatch", mismatch.toFixed(2), agent), - tooltipRow("Sedentary", agent ? agent.traits.sedentary.toFixed(2) : "", agent), - tooltipRow("Ethnocentrism", agent ? agent.traits.ethnocentrism.toFixed(2) : "", agent), - tooltipRow("Farming", agent ? `${techLevel(agent, "farming").toFixed(3)} / work ${(agent.farmingWork || 0).toFixed(2)}` : "", agent), - tooltipRow("Metallurgy", techLevel(agent, "metallurgy").toFixed(3), agent), - tooltipRow("Stored", agent?.resources.toFixed(1), agent) - ])} - `; -els.tooltip.hidden = false; -const margin = 8; -const width = els.tooltip.offsetWidth; -const height = els.tooltip.offsetHeight; -let left = hoverState.left; -let top = hoverState.top; -if (left + width + margin > hoverState.width) left = hoverState.left - width - 32; -if (top + height + margin > hoverState.height) top = hoverState.height - height - margin; -els.tooltip.style.left = `${clamp(left, margin, Math.max(margin, hoverState.width - width - margin))}px`; -els.tooltip.style.top = `${clamp(top, margin, Math.max(margin, hoverState.height - height - margin))}px`; -} -function cityEthnicityPie(city) { -if (!city?.ethnicityComposition?.size) return ""; -const entries = [...city.ethnicityComposition] -.filter(([, count]) => count > 0) -.sort((a, b) => b[1] - a[1]); -const total = entries.reduce((sum, [, count]) => sum + count, 0); -if (total <= 0) return ""; -const top = entries.slice(0, 5); -const other = entries.slice(5).reduce((sum, [, count]) => sum + count, 0); -const slices = other > 0 ? [...top, [0, other]] : top; -let cursor = 0; -const gradient = slices.map(([id, count]) => { -const start = cursor / total * 100; -cursor += count; -const end = cursor / total * 100; -const ethnicity = id ? sim.ethnicities.get(id) : null; -const color = ethnicity?.color || [122, 130, 126]; -return `rgb(${color.join(",")}) ${start.toFixed(2)}% ${end.toFixed(2)}%`; -}).join(", "); -const labels = slices.map(([id, count]) => { -const ethnicity = id ? sim.ethnicities.get(id) : null; -const color = ethnicity?.color || [122, 130, 126]; -const label = id ? `E${id}` : "Other"; -return `${label} ${Math.round(count / total * 100)}%`; -}).join(""); -return ` -
-
-
${labels}
-
-`; -} -function hideTooltip() { -hoverState = null; -els.tooltip.hidden = true; -} -function findAgentAt(x, y) { -const directIndex = sim.world.idx(x, y); -return sim.tileAgents.get(directIndex)?.[0] || null; -} -function waterInfluenceAt(world, x, y) { -let score = 0; -for (let dy = -3; dy <= 3; dy++) { -for (let dx = -3; dx <= 3; dx++) { -const d = Math.abs(dx) + Math.abs(dy); -if (!d || d > 3) continue; -const tx = x + dx; -const ty = y + dy; -if (tx < 0 || ty < 0 || tx >= world.size || ty >= world.size) continue; -if (world.terrain[world.idx(tx, ty)] === Terrain.WATER) score += (4 - d) / 4; -} -} -return score; -} -function updateStats(force = false) { -const now = performance.now(); -if (!force && now - lastStatsAt < SimConfig.render.statsThrottleMs) return; -lastStatsAt = now; -const livingEthnicities = [...sim.ethnicities.values()].filter(e => e.population > 0); -const urbanPopulation = sim.cities.reduce((sum, c) => sum + c.population, 0); -let farmingTotal = 0; -let metallurgyTotal = 0; -let farmingHolders = 0; -let metallurgyHolders = 0; -for (const a of sim.agents) { -sim.ensureAgentTech(a); -farmingTotal += techLevel(a, "farming"); -metallurgyTotal += techLevel(a, "metallurgy"); -if (techLevel(a, "farming") > 0.02) farmingHolders++; -if (techLevel(a, "metallurgy") > 0.02) metallurgyHolders++; -} -const agentCount = Math.max(1, sim.agents.length); -const stats = { -year: formatSimDate(sim.year), -activeGroups: sim.agents.length.toLocaleString(), -urbanPopulation: Math.floor(urbanPopulation).toLocaleString(), -ethnicities: livingEthnicities.length.toLocaleString(), -cities: sim.cities.length.toLocaleString(), -polities: sim.polities.length.toLocaleString(), -wars: sim.wars.length.toLocaleString(), -routes: sim.tradeLinks.length.toLocaleString(), -farmingKnowledge: `${(farmingTotal / agentCount).toFixed(4)} (${farmingHolders})`, -metallurgyKnowledge: `${(metallurgyTotal / agentCount).toFixed(4)} (${metallurgyHolders})`, -deaths: sim.deaths.toLocaleString() -}; -for (const [id, value] of Object.entries(stats)) { -if (els[id]) els[id].textContent = value; -} -const top = livingEthnicities.sort((a, b) => b.population - a.population).slice(0, 9); -els.ethnicityList.innerHTML = top.map(e => ( -`
  • ` + -`E${e.id} pop ${e.population.toLocaleString()} div ${e.diversity.toFixed(2)} parent ${e.parent || "-"}
  • ` -)).join(""); -maybeRenderStateGraph(); -} -function setLegend() { -const mode = els.viewMode.value; -els.legend.innerHTML = (legendByMode[mode] || legendByMode.resources)(); -} -function maybeRenderStateGraph() { -const now = performance.now(); -if (now - lastGraphRenderAt < SimConfig.render.graphThrottleMs) return; -lastGraphRenderAt = now; -renderStateGraph(); -} -function sampleGraphPower(sample) { -if (Number.isFinite(sample?.power)) return sample.power; -return Math.sqrt(sample?.population || 0) * 1.35 + -Math.sqrt(Math.max(0, sample?.treasury || 0)) * 1.15 + -(sample?.avgLoyalty ?? 0.5) * 16; -} -const graphMetrics = { -power: { -value: sampleGraphPower, -format: value => value.toFixed(1) -}, -population: { -value: sample => sample?.population || 0, -format: value => Math.round(value).toLocaleString() -}, -cities: { -value: sample => sample?.cities || 0, -format: value => Math.round(value).toLocaleString() -}, -loyalty: { -value: sample => sample?.avgLoyalty ?? 0.5, -format: value => `${Math.round(clamp(value, 0, 1) * 100)}%` -} -}; -function graphSampleValue(sample, metric) { -return (graphMetrics[metric] || graphMetrics.power).value(sample); -} -function formatGraphValue(value, metric) { -return (graphMetrics[metric] || graphMetrics.power).format(value); -} -function renderStateGraph() { -const canvas = els.stateGraph; -if (!canvas || !sim) return; -const rect = canvas.getBoundingClientRect(); -if (!rect.width) return; -const historyWindowSpan = years(SimConfig.render.historyWindowYears); -const historyWindowEnd = sim.year; -const historyWindowStart = Math.max(0, historyWindowEnd - historyWindowSpan); -graphState.filter = els.historyFilter?.value || graphState.filter; -graphState.sort = els.historySort?.value || graphState.sort; -graphState.metric = els.historyMetric?.value || graphState.metric; -const histories = sim.getAllPolityHistories() -.filter(history => (history.ended ?? sim.year) >= historyWindowStart) -.map(history => ({ -...history, -visibleFounded: Math.max(history.founded ?? 0, historyWindowStart), -visibleSamples: (history.samples || []).filter(sample => sample.year >= historyWindowStart) -})) -.filter(history => history.visibleSamples.length > 0 || (history.ended ?? sim.year) >= historyWindowStart) -.filter(history => { -const isActive = history.active && history.ended === null; -if (graphState.filter === "active" && !isActive) return false; -if (graphState.filter === "ended" && isActive) return false; -if (isActive && !graphState.showActive) return false; -if (!isActive && !graphState.showPast) return false; -return true; -}); -const paddingLeft = 34; -const paddingRight = 8; -const paddingTop = 18; -const paddingBottom = 22; -const rowHeight = 24; -const groupHeight = 18; -const scored = histories.map(history => { -const samples = history.visibleSamples.length ? history.visibleSamples : [{ population: 0, cities: 0, avgLoyalty: 0.5 }]; -const peakPower = Math.max(...samples.map(sample => sampleGraphPower(sample))); -const peakPopulation = Math.max(...samples.map(sample => sample.population || 0)); -const peakCities = Math.max(...samples.map(sample => sample.cities || 0)); -const peakLoyalty = Math.max(...samples.map(sample => sample.avgLoyalty ?? 0.5)); -const peakMetric = Math.max(...samples.map(sample => graphSampleValue(sample, graphState.metric))); -const lifespan = (history.ended ?? sim.year) - history.visibleFounded; -const importance = peakPower * 1.6 + -peakCities * 130 + -Math.sqrt(Math.max(0, peakPopulation)) * 6 + -lifespan * 0.35; -return { history, peakPopulation, peakCities, peakLoyalty, peakPower, peakMetric, importance }; -}); -const compareRows = (a, b) => { -if (graphState.sort === "oldest") { -return ((a.history.founded ?? 0) - (b.history.founded ?? 0)) || (a.history.id - b.history.id); -} -if (graphState.sort === "strongest") { -return (b.peakPower - a.peakPower) || ((a.history.founded ?? 0) - (b.history.founded ?? 0)); -} -if (graphState.sort === "largest") { -return (b.peakPopulation - a.peakPopulation) || (b.peakCities - a.peakCities); -} -const activeDelta = (b.history.active ? 1 : 0) - (a.history.active ? 1 : 0); -if (graphState.sort === "active") { -return activeDelta || (b.importance - a.importance) || (a.history.id - b.history.id); -} -return activeDelta || (b.importance - a.importance) || ((a.history.founded ?? 0) - (b.history.founded ?? 0)) || (a.history.id - b.history.id); -}; -const selected = scored.sort(compareRows).slice(0, 90).sort(compareRows); -const activeRows = selected.filter(item => item.history.active && item.history.ended === null); -const pastRows = selected.filter(item => !(item.history.active && item.history.ended === null)); -const displayRows = []; -if (graphState.showActive && graphState.filter !== "ended" && activeRows.length) { -displayRows.push({ type: "group", label: `Living ${activeRows.length}` }); -for (const item of activeRows) displayRows.push({ type: "state", item }); -} -if (graphState.showPast && graphState.filter !== "active" && pastRows.length) { -displayRows.push({ type: "group", label: `Past ${pastRows.length}` }); -for (const item of pastRows) displayRows.push({ type: "state", item }); -} -const logicalHeight = paddingTop + -displayRows.reduce((sum, row) => sum + (row.type === "group" ? groupHeight : rowHeight), 0) + -paddingBottom; -canvas.style.height = `${logicalHeight}px`; -const updatedRect = canvas.getBoundingClientRect(); -const dpr = window.devicePixelRatio || 1; -const width = Math.max(1, Math.floor(updatedRect.width * dpr)); -const height = Math.max(1, Math.floor(logicalHeight * dpr)); -if (canvas.width !== width || canvas.height !== height) { -canvas.width = width; -canvas.height = height; -} -const g = canvas.getContext("2d"); -g.setTransform(dpr, 0, 0, dpr, 0, 0); -const w = updatedRect.width; -const h = logicalHeight; -g.clearRect(0, 0, w, h); -g.fillStyle = "#101315"; -g.fillRect(0, 0, w, h); -if (!histories.length || !selected.length || !displayRows.length) { -if (els.historyRange) els.historyRange.textContent = "-"; -graphState.rows = []; -graphState.markers = []; -graphState.scale = null; -g.fillStyle = "#7f8984"; -g.font = "12px ui-sans-serif, system-ui, sans-serif"; -g.fillText("No state history yet", 16, 28); -return; -} -let minYear = historyWindowStart; -let maxYear = historyWindowEnd; -for (const item of selected) { -const history = item.history; -minYear = Math.min(minYear, history.visibleFounded); -maxYear = Math.max(maxYear, history.ended ?? sim.year); -} -if (els.historyRange) els.historyRange.textContent = `${formatGraphYear(minYear)}-${formatGraphYear(maxYear)}`; -const plotWidth = Math.max(1, w - paddingLeft - paddingRight); -const yearToX = year => paddingLeft + ((clamp(year, minYear, maxYear) - minYear) / Math.max(1, maxYear - minYear)) * plotWidth; -const xToYear = x => minYear + ((clamp(x, paddingLeft, w - paddingRight) - paddingLeft) / plotWidth) * Math.max(1, maxYear - minYear); -const rows = []; -let cursorY = paddingTop; -for (const displayRow of displayRows) { -if (displayRow.type === "group") { -rows.push({ ...displayRow, y: cursorY + groupHeight * 0.5, height: groupHeight }); -cursorY += groupHeight; -continue; -} -const item = displayRow.item; -rows.push({ -...item, -type: "state", -y: cursorY + rowHeight * 0.5, -height: rowHeight, -color: item.history.color || hslToRgb((item.history.id * 0.38196601125) % 1, 0.58, 0.62), -samples: (item.history.visibleSamples || []) -.filter(sample => Number.isFinite(sample.year)) -.sort((a, b) => a.year - b.year) -}); -cursorY += rowHeight; -} -let minMetric = Infinity; -let maxMetric = -Infinity; -let minCities = Infinity; -let maxCities = -Infinity; -for (const row of rows.filter(row => row.type === "state")) { -for (const sample of row.samples) { -const value = graphSampleValue(sample, graphState.metric); -minMetric = Math.min(minMetric, value); -maxMetric = Math.max(maxMetric, value); -minCities = Math.min(minCities, sample.cities || 0); -maxCities = Math.max(maxCities, sample.cities || 0); -} -} -if (!Number.isFinite(minMetric) || !Number.isFinite(maxMetric)) { -minMetric = 0; -maxMetric = 1; -} -if (!Number.isFinite(minCities) || !Number.isFinite(maxCities)) { -minCities = 0; -maxCities = 1; -} -graphState.rows = rows.filter(row => row.type === "state"); -graphState.markers = []; -graphState.scale = { minYear, maxYear, paddingLeft, paddingRight, plotWidth, width: w, xToYear }; -const axisY = h - paddingBottom + 4; -g.strokeStyle = "rgba(168, 177, 170, 0.22)"; -g.lineWidth = 1; -strokeLine(g, paddingLeft, axisY, w - paddingRight, axisY); -g.fillStyle = "#8c9690"; -g.font = "10px ui-sans-serif, system-ui, sans-serif"; -g.textAlign = "left"; -g.fillText(formatGraphYear(minYear), paddingLeft, h - 5); -g.textAlign = "center"; -g.fillText(formatGraphYear((minYear + maxYear) / 2), paddingLeft + plotWidth / 2, h - 5); -g.textAlign = "right"; -g.fillText(formatGraphYear(maxYear), w - paddingRight, h - 5); -const topEvents = (sim.graphEvents || []) -.filter(event => event.importance >= 2) -.filter(event => event.year >= minYear && event.year <= maxYear) -.filter(event => graphEventTypes[event.type]); -const topCollisions = new Map(); -for (const event of topEvents) { -const x = yearToX(event.year); -const bucket = Math.round(x / 7); -const count = topCollisions.get(bucket) || 0; -topCollisions.set(bucket, count + 1); -const y = Math.max(7, paddingTop * 0.5 + ([-3, 0, 3][count % 3])); -const r = event.importance >= 4 ? 5 : event.importance >= 3 ? 4 : 3; -const graphEvent = graphEventTypes[event.type]; -g.fillStyle = graphEvent.color; -graphEvent.draw(g, x, y, r); -graphState.markers.push({ row: null, event, x, y, radius: r + 3 }); -} -rows.forEach(row => { -const alpha = row.type === "group" ? 0.16 : 0.12; -if (row.type === "group") { -g.fillStyle = "#7f8984"; -g.font = "10px ui-sans-serif, system-ui, sans-serif"; -g.textAlign = "left"; -g.fillText(row.label, 4, row.y + 3); -} -g.strokeStyle = `rgba(168, 177, 170, ${alpha})`; -g.lineWidth = 1; -strokeLine(g, paddingLeft, row.y, w - paddingRight, row.y); -}); -rows.forEach(row => { -if (row.type !== "state") return; -const history = row.history; -g.textAlign = "left"; -g.fillStyle = "#a8b1aa"; -g.font = "9px ui-sans-serif, system-ui, sans-serif"; -g.fillText(`S${history.id}`, 4, row.y + 3); -const inactiveMultiplier = history.active ? 1 : 0.65; -const strokeSegment = (fromYear, toYear, metricValue, cities, alphaScale = 1) => { -if (toYear <= fromYear) return; -const normalizedMetric = (metricValue - minMetric) / Math.max(1, maxMetric - minMetric); -const metricT = clamp(normalizedMetric, 0, 1); -const cityT = clamp((cities - minCities) / Math.max(1, maxCities - minCities), 0, 1); -const lowColor = mix([56, 62, 60], row.color, 0.34); -const highColor = mix(row.color, [244, 246, 238], 0.18); -const segmentColor = mix(lowColor, highColor, metricT); -let alpha = (0.22 + metricT * 0.76) * inactiveMultiplier * alphaScale; -alpha = clamp(alpha, 0.10, 0.96); -const thickness = clamp(3.5 + cityT * 5.5 + metricT * 4.5, 3.5, 13); -g.lineWidth = thickness; -g.lineCap = "round"; -g.strokeStyle = `rgba(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]}, ${clamp(alpha * 0.28, 0.08, 0.28)})`; -strokeLine(g, yearToX(fromYear), row.y, yearToX(toYear), row.y); -g.strokeStyle = `rgba(${segmentColor[0]}, ${segmentColor[1]}, ${segmentColor[2]}, ${alpha})`; -g.lineWidth = Math.max(2, thickness * 0.62); -strokeLine(g, yearToX(fromYear), row.y, yearToX(toYear), row.y); -g.lineCap = "butt"; -}; -if (row.samples.length > 1) { -if (history.visibleFounded < row.samples[0].year) { -strokeSegment(history.visibleFounded, row.samples[0].year, graphSampleValue(row.samples[0], graphState.metric), row.samples[0].cities, 0.42); -} -for (let i = 0; i < row.samples.length - 1; i++) { -const sampleA = row.samples[i]; -const sampleB = row.samples[i + 1]; -strokeSegment( -sampleA.year, -sampleB.year, -(graphSampleValue(sampleA, graphState.metric) + graphSampleValue(sampleB, graphState.metric)) * 0.5, -((sampleA.cities || 0) + (sampleB.cities || 0)) * 0.5 -); -} -const lastSample = row.samples[row.samples.length - 1]; -const endYear = history.ended ?? sim.year; -if (lastSample.year < endYear) { -strokeSegment(lastSample.year, endYear, graphSampleValue(lastSample, graphState.metric), lastSample.cities, 0.55); -} -} else { -const sample = row.samples[0] || { population: 0, cities: row.peakCities, avgLoyalty: 0.5 }; -strokeSegment(history.visibleFounded, history.ended ?? sim.year, graphSampleValue(sample, graphState.metric), sample.cities || row.peakCities); -} -}); -rows.forEach(row => { -if (row.type !== "state") return; -const events = (row.history.events || []) -.filter(event => event.importance >= 2) -.filter(event => event.year >= minYear && event.year <= maxYear) -.filter(event => graphEventTypes[event.type]); -const collisions = new Map(); -for (const event of events) { -const x = yearToX(event.year); -const bucket = Math.round(x / 7); -const count = collisions.get(bucket) || 0; -collisions.set(bucket, count + 1); -const y = row.y + ([-4, 0, 4][count % 3]); -const r = event.importance >= 4 ? 5 : event.importance >= 3 ? 4 : 3; -const graphEvent = graphEventTypes[event.type]; -g.fillStyle = graphEvent.color; -graphEvent.draw(g, x, y, r); -graphState.markers.push({ row, event, x, y, radius: r + 3 }); -} -}); -} -function drawGraphCircle(g, x, y, r) { -g.beginPath(); -g.arc(x, y, r, 0, Math.PI * 2); -g.fill(); -} -function drawGraphPolygon(g, points) { -g.beginPath(); -g.moveTo(points[0][0], points[0][1]); -for (let i = 1; i < points.length; i++) g.lineTo(points[i][0], points[i][1]); -g.closePath(); -g.fill(); -} -function drawGraphDiamond(g, x, y, r) { -drawGraphPolygon(g, [[x, y - r], [x + r, y], [x, y + r], [x - r, y]]); -} -function drawGraphTriangleUp(g, x, y, r) { -drawGraphPolygon(g, [[x, y - r], [x + r, y + r], [x - r, y + r]]); -} -function drawGraphTriangleDown(g, x, y, r) { -drawGraphPolygon(g, [[x, y + r], [x + r, y - r], [x - r, y - r]]); -} -const graphEventTypes = { -capitalShift: { -label: "capital shift", -color: "rgba(227, 179, 65, 0.95)", -draw: drawGraphDiamond, -summary: data => `capital #${data.oldCenterCityId ?? "-"} to #${data.newCenterCityId ?? "-"}` -}, -disaster: { -label: "major disaster", -color: "rgba(211, 95, 84, 0.95)", -draw: drawGraphCircle, -summary: data => `lost ${Math.round((data.lossRate || 0) * 100)}%, ${Math.round(data.populationLoss || 0).toLocaleString()} people, ${data.affectedCities || 0} cities` -}, -famine: { -label: "famine", -color: "rgba(227, 128, 65, 0.90)", -draw: drawGraphTriangleDown, -summary: data => `poor cities ${Math.round((data.poorRate || 0) * 100)}%, food ${Number(data.avgPerCapitaFood || 0).toFixed(3)}/cap` -}, -rebellion: { -label: "rebellion", -color: "rgba(236, 126, 111, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `city #${data.cityId ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}, loyalty ${Number(data.loyalty || 0).toFixed(2)}` -}, -newEthnicity: { -label: "new ethnicity", -color: "rgba(105, 181, 120, 0.95)", -draw: drawGraphDiamond, -summary: data => `E${data.ethnicity ?? "-"}, ${Math.round(data.population || 0).toLocaleString()} frontier groups` -} -}; -function graphEventLabel(event) { -return graphEventTypes[event.type]?.label || event.type; -} -function graphEventSummary(event) { -return graphEventTypes[event.type]?.summary(event.data || {}) || ""; -} -function showStateGraphMarkerTooltip(marker, pointerX, pointerY) { -if (!els.stateGraphTooltip) return; -const title = marker.row -? `S${marker.row.history.id} ${graphEventLabel(marker.event)}` -: graphEventLabel(marker.event); -els.stateGraphTooltip.innerHTML = ` - ${title} - ${formatGraphYear(marker.event.year)} - ${graphEventSummary(marker.event)} - `; -els.stateGraphTooltip.hidden = false; -const scroll = els.stateGraph.parentElement; -const maxLeft = Math.max(8, (scroll?.clientWidth || 260) - els.stateGraphTooltip.offsetWidth - 8); -const left = clamp(pointerX + 10, 8, maxLeft); -const top = Math.max(8, pointerY - els.stateGraphTooltip.offsetHeight - 10); -els.stateGraphTooltip.style.left = `${left}px`; -els.stateGraphTooltip.style.top = `${top}px`; -} -function hideStateGraphMarkerTooltip() { -if (els.stateGraphTooltip) els.stateGraphTooltip.hidden = true; -} -function updateStateGraphInfo(event) { -if (!els.stateGraphInfo || !graphState.rows.length || !graphState.scale) return; -const y = event.offsetY; -const x = event.offsetX; -const marker = (graphState.markers || []) -.map(candidate => ({ candidate, distance: Math.hypot(candidate.x - x, candidate.y - y) })) -.filter(item => item.distance <= item.candidate.radius); -const nearestMarker = bestBy(marker, item => -item.distance)?.candidate; -if (nearestMarker) { -if (!nearestMarker.row) { -els.stateGraphInfo.textContent = `${formatGraphYear(nearestMarker.event.year)} ${graphEventLabel(nearestMarker.event)}`; -showStateGraphMarkerTooltip(nearestMarker, x, y); -if (graphState.hoverPolityId !== null) { -graphState.hoverPolityId = null; -if (!running) render(); -} -return; -} -const status = nearestMarker.row.history.active && nearestMarker.row.history.ended === null ? "living" : "past"; -els.stateGraphInfo.textContent = `S${nearestMarker.row.history.id} ${status} ${formatGraphYear(nearestMarker.event.year)} ${graphEventLabel(nearestMarker.event)}`; -showStateGraphMarkerTooltip(nearestMarker, x, y); -if (graphState.hoverPolityId !== nearestMarker.row.history.id) { -graphState.hoverPolityId = nearestMarker.row.history.id; -if (!running) render(); -} -return; -} -const row = graphState.rows -.map(candidate => ({ candidate, distance: Math.abs(candidate.y - y) })) -.filter(item => item.distance <= item.candidate.height * 0.5); -const nearestRow = bestBy(row, item => -item.distance)?.candidate; -if (!nearestRow) { -els.stateGraphInfo.textContent = "Hover a row for details"; -hideStateGraphMarkerTooltip(); -if (graphState.hoverPolityId !== null) { -graphState.hoverPolityId = null; -if (!running) render(); -} -return; -} -if (graphState.hoverPolityId !== nearestRow.history.id) { -graphState.hoverPolityId = nearestRow.history.id; -if (!running) render(); -} -hideStateGraphMarkerTooltip(); -const year = graphState.scale.xToYear(x); -const samples = nearestRow.samples.length ? nearestRow.samples : [{ -year, -population: 0, -cities: nearestRow.peakCities, -avgLoyalty: 0.5, -power: nearestRow.peakPower -}]; -const sample = bestBy(samples, candidate => -Math.abs((candidate.year ?? year) - year)); -const metricValue = graphSampleValue(sample, graphState.metric); -const status = nearestRow.history.active && nearestRow.history.ended === null ? "living" : "past"; -els.stateGraphInfo.textContent = -`S${nearestRow.history.id} ${status} ${formatGraphYear(sample.year ?? year)} ` + -`${graphState.metric} ${formatGraphValue(metricValue, graphState.metric)} ` + -`pop ${Math.round(sample.population || 0).toLocaleString()} ` + -`cities ${Math.round(sample.cities || 0).toLocaleString()} ` + -`loyalty ${formatGraphValue(sample.avgLoyalty ?? 0.5, "loyalty")}`; -} -function clearStateGraphInfo() { -if (els.stateGraphInfo) els.stateGraphInfo.textContent = "Hover a row for details"; -hideStateGraphMarkerTooltip(); -if (graphState.hoverPolityId !== null) { -graphState.hoverPolityId = null; -if (!running) render(); -} -} -function formatGraphYear(week) { -return `${Math.floor(week / WEEKS_PER_YEAR).toLocaleString()}y`; -} -function formatSimDate(week) { -const year = Math.floor(week / WEEKS_PER_YEAR); -const weekOfYear = week % WEEKS_PER_YEAR; -const monthOfYear = Math.floor(weekOfYear / WEEKS_PER_MONTH) + 1; -const weekOfMonth = weekOfYear % WEEKS_PER_MONTH + 1; -return `${year.toLocaleString()}y ${monthOfYear}m ${weekOfMonth}w`; -} -function requestRender() { -renderDirty = true; -} -function drawFrame(forceStats = false) { -render(); -updateStats(forceStats); -renderTooltip(); -renderDirty = false; -lastRenderAt = performance.now(); -} -function scheduleLoop() { -if (loopScheduled) return; -loopScheduled = true; -const delay = document.hidden -? LoopConfig.hiddenPollMs -: running ? 0 : LoopConfig.idlePollMs; -if (delay > 0) { -loopTimer = setTimeout(() => { -loopTimer = null; -requestAnimationFrame(loop); -}, delay); -} else { -requestAnimationFrame(loop); -} -} -function loop(now = performance.now()) { -loopScheduled = false; -if (running && !document.hidden && now - lastSimTickAt >= LoopConfig.simTickMs) { -lastSimTickAt = now; -const steps = Number(els.speed.value); -const stepBudget = LoopConfig.stepBudgetMs * Math.max(1, steps); -const loopStart = performance.now(); -let completedSteps = 0; -for (let i = 0; i < steps; i++) { -sim.step(); -completedSteps++; -if (completedSteps > 0 && performance.now() - loopStart > stepBudget) break; -} -if (completedSteps > 0) requestRender(); -} -const shouldRender = !document.hidden && -(renderDirty || (running && now - lastRenderAt >= LoopConfig.renderMs)); -if (shouldRender) drawFrame(); -scheduleLoop(); -} -function reset() { -const size = Number(els.worldSize.value); -const count = Number(els.agentCount.value); -els.canvas.width = size; -els.canvas.height = size; -renderImage = null; -renderImageSize = 0; -sim = new Simulation(size, count); -setLegend(); -drawFrame(true); -renderStateGraph(); -} -function clamp(v, min, max) { -return Math.max(min, Math.min(max, v)); -} -function bestBy(items, score) { -let best = null; -let bestScore = -Infinity; -for (const item of items) { -const value = score(item); -if (value > bestScore) { -best = item; -bestScore = value; -} -} -return best; -} -function smoothstep(t) { -return t * t * (3 - 2 * t); -} -const traitFields = [ -["mobility", traits => traits.mobility, 0.02, 1, 1, 1], -["resourceAttraction", traits => traits.resourceAttraction, 0.05, 1.2, 1, 1], -["assimilation", traits => traits.assimilation, 0, 0.75, 1, 1], -["ethnocentrism", traits => traits.ethnocentrism, 0, 1.2, 1, 1], -["reproductionThreshold", traits => traits.reproductionThreshold, 12, 48, 16, 1 / 48], -["sedentary", traits => traits.sedentary, 0, 1, 1, 1] -]; -function mutateTraits(traits, rng, amount) { -return Object.fromEntries(traitFields.map(([key, get, min, max, mutationScale]) => [ -key, -clamp(get(traits) + rng.range(-amount * mutationScale, amount * mutationScale), min, max) -])); -} -function blendTraits(a, b, t) { -return Object.fromEntries(traitFields.map(([key, get]) => [key, lerp(get(a), get(b), t)])); -} -function emptyTraitSums() { -return Object.fromEntries(traitFields.map(([key]) => [key, 0])); -} -function addTraits(sum, traits) { -for (const [key, get, , , , sumScale] of traitFields) sum[key] += get(traits) * sumScale; -} -function averageTraits(sum, count) { -return Object.fromEntries(traitFields.map(([key, , , , , sumScale]) => [key, sum[key] / count / sumScale])); -} -function compositionTotal(composition) { -return [...composition.values()].reduce((sum, value) => sum + value, 0); -} -function addBirthsToComposition(composition, births, rng = null) { - const entries = [...composition.entries()]; - const total = entries.reduce((sum, [, value]) => sum + value, 0); - if (!total || births <= 0) return; - - for (let n = 0; n < births; n++) { - let r = (rng ? rng.next() : Math.random()) * total; - for (const [id, count] of entries) { - r -= count; - if (r <= 0) { - composition.set(id, (composition.get(id) || 0) + 1); - break; - } - } - } -} -function removeFromComposition(composition, loss) { -let remaining = loss; -const total = compositionTotal(composition); -if (!total) return; -for (const [id, count] of [...composition]) { -const removed = Math.min(count, Math.ceil(loss * (count / total))); -composition.set(id, Math.max(0, count - removed)); -remaining -= removed; -if (composition.get(id) <= 0) composition.delete(id); -if (remaining <= 0) break; -} -} -function dominantComposition(composition) { -let bestId = null; -let bestCount = 0; -for (const [id, count] of composition) { -if (count > bestCount) { -bestId = id; -bestCount = count; -} -} -return bestId; -} -function traitDistance(a, b) { -return traitFields.reduce((sum, [, get, , , , distanceScale]) => sum + Math.abs(get(a) - get(b)) * distanceScale, 0); -} -function hslToRgb(h, s, l) { -const hue = (p, q, t) => { -if (t < 0) t += 1; -if (t > 1) t -= 1; -if (t < 1 / 6) return p + (q - p) * 6 * t; -if (t < 1 / 2) return q; -if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; -return p; -}; -const q = l < 0.5 ? l * (1 + s) : l + s - l * s; -const p = 2 * l - q; -return [ -Math.round(hue(p, q, h + 1 / 3) * 255), -Math.round(hue(p, q, h) * 255), -Math.round(hue(p, q, h - 1 / 3) * 255) -]; -} -function mix(a, b, t) { -return [ -Math.round(lerp(a[0], b[0], t)), -Math.round(lerp(a[1], b[1], t)), -Math.round(lerp(a[2], b[2], t)) -]; -} -function lerp(a, b, t) { -return a + (b - a) * t; -} -function refreshStateGraph() { -renderStateGraph(); -clearStateGraphInfo(); -} -els.toggleRun.addEventListener("click", () => { -running = !running; -els.toggleRun.textContent = running ? "Pause" : "Run"; -lastSimTickAt = 0; -if (running && loopTimer) { -clearTimeout(loopTimer); -loopTimer = null; -loopScheduled = false; -scheduleLoop(); -} else if (running) { -scheduleLoop(); -} -}); -els.stepOnce.addEventListener("click", () => { -sim.step(); -requestRender(); -drawFrame(true); -renderStateGraph(); -}); -els.resetWorld.addEventListener("click", reset); -for (const control of [els.worldSize, els.agentCount]) control.addEventListener("change", reset); -els.viewMode.addEventListener("change", () => { -setLegend(); -requestRender(); -drawFrame(); -}); -els.canvas.addEventListener("mousemove", showTooltip); -els.canvas.addEventListener("mouseleave", hideTooltip); -for (const control of [els.historyFilter, els.historySort, els.historyMetric]) { -control?.addEventListener("change", refreshStateGraph); -} -els.toggleActiveStates?.addEventListener("click", () => { -graphState.showActive = !graphState.showActive; -els.toggleActiveStates.setAttribute("aria-pressed", String(graphState.showActive)); -refreshStateGraph(); -}); -els.togglePastStates?.addEventListener("click", () => { -graphState.showPast = !graphState.showPast; -els.togglePastStates.setAttribute("aria-pressed", String(graphState.showPast)); -refreshStateGraph(); -}); -els.stateGraph?.addEventListener("mousemove", updateStateGraphInfo); -els.stateGraph?.addEventListener("mouseleave", clearStateGraphInfo); -document.addEventListener("visibilitychange", () => { -lastSimTickAt = 0; -requestRender(); -if (!document.hidden && loopTimer) { -clearTimeout(loopTimer); -loopTimer = null; -loopScheduled = false; -scheduleLoop(); -} -}); -reset(); -loop(); diff --git a/index.html b/index.html index 269d45d..0e6abfb 100644 --- a/index.html +++ b/index.html @@ -96,8 +96,6 @@ @@ -57,7 +57,7 @@
    Date
    0y 1m
    -
    Active groups
    0
    +
    Field population
    0
    Urban population
    0
    Ethnicities
    0
    Cities
    0
    @@ -66,7 +66,7 @@
    Trade routes
    0
    Farming knowledge
    0.000
    Metallurgy knowledge
    0.000
    -
    Collapse deaths
    0
    +
    Deaths
    0
    Frame cost
    0ms
    diff --git a/render.js b/render.js index c86688d..105ccbe 100644 --- a/render.js +++ b/render.js @@ -79,7 +79,13 @@ if (graphState.hoverPolityId !== null && !polityColor.isGraphHover) color = mix( } } } else if (mode === "technology") { -color = mix(terrainInfo[w.terrain[i]].color, [44, 42, 48], 0.35); +const farming = w.farmingKnowledge?.[i] || 0; +const metallurgy = w.metallurgyKnowledge?.[i] || 0; +const tech = clamp(Math.max(farming, metallurgy), 0, 1); +const techColor = mix([95, 171, 91], [202, 169, 102], metallurgy / Math.max(0.001, farming + metallurgy)); +color = tech > 0.01 +? mix(terrainInfo[w.terrain[i]].color, techColor, clamp(0.12 + tech * 0.62, 0.12, 0.74)) +: mix(terrainInfo[w.terrain[i]].color, [44, 42, 48], 0.35); } else if (mode === "pheromone") { const v = clamp(w.pheromone[i] / SimConfig.route.maxPheromone, 0, 1); color = mix(mix(terrainInfo[w.terrain[i]].color, [18, 20, 18], 0.58), [216, 177, 86], v); @@ -95,8 +101,9 @@ data[p + 3] = 255; ctx.putImageData(image, 0, 0); renderDisasters(); drawTradeLinks(); +drawNomadBands(); drawCampaigns(); -drawAgentsAndCities(mode); +drawPopulationAndCities(mode); drawGraphPolityHighlight(); maybeRenderStateGraph(); els.frameCost.textContent = `${Math.round(performance.now() - start)}ms`; @@ -205,7 +212,39 @@ fillSquare(ctx, x, y, 1); } ctx.restore(); } -function drawAgentsAndCities(mode) { +function drawNomadBands() { +if (!sim?.nomadBands?.length) return; +const w = sim.world; +ctx.save(); +for (const band of sim.nomadBands) { +const ethnicityColor = sim.ethnicities.get(band.ethnicityId)?.color || [216, 177, 86]; +ctx.globalAlpha = 0.07; +ctx.fillStyle = rgba(ethnicityColor, 0.45); +for (const tile of band.influenceTiles || []) { +ctx.fillRect(tile % w.size, Math.floor(tile / w.size), 1, 1); +} +ctx.globalAlpha = 0.34; +ctx.strokeStyle = band.mode === "raiding" || band.mode === "invading" +? "rgba(232, 101, 76, 0.95)" +: band.mode === "settling" +? "rgba(202, 169, 102, 0.9)" +: rgba(ethnicityColor, 0.9, 18); +ctx.lineWidth = 1; +strokeCircle(ctx, band.x + 0.5, band.y + 0.5, Math.max(2.5, band.radius * 0.45)); +if (band.mode === "confederating") { +ctx.globalAlpha = 0.26; +strokeCircle(ctx, band.x + 0.5, band.y + 0.5, Math.max(4, band.radius * 0.68)); +} +ctx.globalAlpha = 0.22; +ctx.fillStyle = rgba(ethnicityColor, 0.9, 22); +for (const tile of band.trailTiles || []) ctx.fillRect(tile % w.size, Math.floor(tile / w.size), 1, 1); +ctx.globalAlpha = 0.82; +ctx.fillStyle = rgba(ethnicityColor, 0.95, 36); +fillSquare(ctx, Math.round(band.x), Math.round(band.y), 1); +} +ctx.restore(); +} +function drawPopulationAndCities(mode) { ctx.save(); if (mode !== "ethnicity") { for (const city of sim.cities) { @@ -218,23 +257,18 @@ fillSquare(ctx, city.x, city.y, radius); } ctx.globalAlpha = 1; if (mode === "technology") { -for (const a of sim.agents) { -sim.ensureAgentTech(a); -const farming = techLevel(a, "farming"); -const metallurgy = techLevel(a, "metallurgy"); -const tech = clamp(Math.max(farming, metallurgy), 0, 1); -if (tech <= 0.01) continue; -const color = mix([95, 171, 91], [202, 169, 102], metallurgy / Math.max(0.001, farming + metallurgy)); -ctx.fillStyle = rgba(color, clamp(0.32 + tech * 0.68, 0.32, 1)); -ctx.fillRect(a.x, a.y, 1, 1); -} +// Tile-level technology is rendered in the base pass. } else if (mode === "ethnicity") { -// Phase 2: ethnicity view is driven by tile-level population/culture fields. -// Individual agents remain in the simulation but no longer define this layer. +// Ethnicity view is driven by tile-level population/culture fields. } else { -ctx.fillStyle = "#eeeccf"; -for (const tile of sim.tileAgents.keys()) { -ctx.fillRect(tile % sim.world.size, Math.floor(tile / sim.world.size), 1, 1); +const w = sim.world; +ctx.fillStyle = "rgba(238, 236, 207, 0.16)"; +for (let tile = 0; tile < w.count; tile++) { +const pop = w.population?.[tile] || 0; +if (pop < 6) continue; +const alpha = clamp(Math.log1p(pop) / Math.log(160), 0.04, 0.18); +ctx.fillStyle = `rgba(238, 236, 207, ${alpha})`; +ctx.fillRect(tile % w.size, Math.floor(tile / w.size), 1, 1); } } for (const city of sim.cities) { @@ -329,23 +363,23 @@ return; } const w = sim.world; const i = w.idx(x, y); -const agent = findAgentAt(x, y); const city = w.city[i] >= 0 ? sim.getCityById(w.city[i]) : null; const terrain = terrainInfo[w.terrain[i]]; -const ethnicity = agent ? sim.ethnicities.get(agent.ethnicity) : null; const waterInfluence = waterInfluenceAt(w, x, y).toFixed(2); const cityEthnicity = city ? dominantComposition(city.ethnicityComposition) : null; -const mismatch = agent ? sim.climateMismatch(agent.ethnicity, i) : 0; const polity = cityPolity(city); const territoryId = w.polity?.[i] ?? -1; const territoryPolity = territoryId >= 0 ? sim.getPolityById(territoryId) : null; const ethnicMix = sim.tileEthnicMix?.get(i); const tileDominantEthnicity = ethnicMix?.size ? dominantComposition(ethnicMix) : w.dominantEthnicity[i]; const regionalEthnicity = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? `E${tileDominantEthnicity}` : "-"; +const regionalLineage = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? sim.ethnicities.get(tileDominantEthnicity) : null; +const mismatch = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? sim.climateMismatch(tileDominantEthnicity, i) : 0; const tilePopulation = w.population?.[i] || 0; const nearbyCampaigns = activeCampaignsNear(i); +const nearbyNomad = activeNomadNear(i); els.tooltip.innerHTML = ` - ${city ? `City #${city.id}` : agent ? "Agent group" : terrain.name} + ${city ? `City #${city.id}` : terrain.name} ${tooltipSection("Tile", [ tooltipRow("Position", `${x}, ${y}`), tooltipRow("Terrain", terrain.name), @@ -367,6 +401,16 @@ els.tooltip.innerHTML = ` tooltipRow("Dominant ethnicity", regionalEthnicity), tooltipRow("Tile population", tilePopulation >= 10 ? Math.round(tilePopulation).toLocaleString() : tilePopulation.toFixed(1)) ])} + ${tooltipSection("Nomads", [ + tooltipRow("Band", nearbyNomad ? `${nearbyNomad.name} #${nearbyNomad.id}` : "", nearbyNomad), + tooltipRow("Mode", nearbyNomad?.mode, nearbyNomad), + tooltipRow("Population", nearbyNomad ? Math.round(nearbyNomad.population).toLocaleString() : "", nearbyNomad), + tooltipRow("Ethnicity", nearbyNomad ? `E${nearbyNomad.ethnicityId}` : "", nearbyNomad), + tooltipRow("Cohesion", nearbyNomad?.cohesion.toFixed(2), nearbyNomad), + tooltipRow("Prestige", nearbyNomad?.prestige.toFixed(2), nearbyNomad), + tooltipRow("Resources", nearbyNomad?.resources.toFixed(1), nearbyNomad), + tooltipRow("Herds", nearbyNomad?.herds.toFixed(1), nearbyNomad) + ])} ${tooltipSection("City & State", [ tooltipRow("Population", city?.population.toLocaleString(), city), tooltipRow("Food stock", city?.storedResources.toFixed(1), city), @@ -382,17 +426,15 @@ els.tooltip.innerHTML = ` tooltipRow("Treasury", polity?.treasury.toFixed(1), polity), tooltipRow("Capital", polity && city ? polity.centerCityId === city.id ? "yes" : "no" : "", polity) ])} - ${tooltipSection("Culture & Agent", [ + ${tooltipSection("Culture", [ tooltipRow("Local culture", `${regionalEthnicity} / ${w.cultureDiversity[i].toFixed(2)}`), - tooltipRow("Agent ethnicity", `E${agent?.ethnicity}`, agent), - tooltipRow("Lineage pop", ethnicity?.population, ethnicity), - tooltipRow("Climate pref", ethnicity ? `${ethnicity.climateTemp.toFixed(2)} / ${ethnicity.climateHumidity.toFixed(2)}` : "", ethnicity), - tooltipRow("Climate mismatch", mismatch.toFixed(2), agent), - tooltipRow("Sedentary", agent ? agent.traits.sedentary.toFixed(2) : "", agent), - tooltipRow("Ethnocentrism", agent ? agent.traits.ethnocentrism.toFixed(2) : "", agent), - tooltipRow("Farming", agent ? `${techLevel(agent, "farming").toFixed(3)} / work ${(agent.farmingWork || 0).toFixed(2)}` : "", agent), - tooltipRow("Metallurgy", techLevel(agent, "metallurgy").toFixed(3), agent), - tooltipRow("Stored", agent?.resources.toFixed(1), agent) + tooltipRow("Lineage pop", regionalLineage?.population?.toLocaleString(), regionalLineage), + tooltipRow("Climate pref", regionalLineage ? `${regionalLineage.climateTemp.toFixed(2)} / ${regionalLineage.climateHumidity.toFixed(2)}` : "", regionalLineage), + tooltipRow("Climate mismatch", mismatch.toFixed(2), regionalLineage), + tooltipRow("Settled pop", (w.settledPopulation?.[i] || 0).toFixed(1), tilePopulation > 0), + tooltipRow("Mobile pop", (w.mobilePopulation?.[i] || 0).toFixed(1), tilePopulation > 0), + tooltipRow("Farming", (w.farmingKnowledge?.[i] || 0).toFixed(3)), + tooltipRow("Metallurgy", (w.metallurgyKnowledge?.[i] || 0).toFixed(3)) ])} `; els.tooltip.hidden = false; @@ -459,9 +501,23 @@ labels.push(`${campaign.type.replaceAll("_", " ")} ${Math.round(clamp(campaign.p } return labels.slice(0, 2).join("; "); } -function findAgentAt(x, y) { -const directIndex = sim.world.idx(x, y); -return sim.tileAgents.get(directIndex)?.[0] || null; +function activeNomadNear(tile) { +if (!sim?.nomadBands?.length) return null; +const w = sim.world; +const x = tile % w.size; +const y = Math.floor(tile / w.size); +let best = null; +let bestDistance = Infinity; +for (const band of sim.nomadBands) { +const distance = Math.abs(Math.round(band.x) - x) + Math.abs(Math.round(band.y) - y); +const inInfluence = w.nomadBand?.[tile] === band.id; +if (!inInfluence && distance > Math.max(3, Math.floor(band.radius * 0.55))) continue; +if (distance < bestDistance) { +best = band; +bestDistance = distance; +} +} +return best; } function waterInfluenceAt(world, x, y) { let score = 0; @@ -487,25 +543,29 @@ let farmingTotal = 0; let metallurgyTotal = 0; let farmingHolders = 0; let metallurgyHolders = 0; -for (const a of sim.agents) { -sim.ensureAgentTech(a); -farmingTotal += techLevel(a, "farming"); -metallurgyTotal += techLevel(a, "metallurgy"); -if (techLevel(a, "farming") > 0.02) farmingHolders++; -if (techLevel(a, "metallurgy") > 0.02) metallurgyHolders++; +for (let i = 0; i < sim.world.count; i++) { +const pop = sim.world.population?.[i] || 0; +if (pop <= 0) continue; +farmingTotal += (sim.world.farmingKnowledge?.[i] || 0) * pop; +metallurgyTotal += (sim.world.metallurgyKnowledge?.[i] || 0) * pop; +if ((sim.world.farmingKnowledge?.[i] || 0) > 0.02) farmingHolders++; +if ((sim.world.metallurgyKnowledge?.[i] || 0) > 0.02) metallurgyHolders++; } -const agentCount = Math.max(1, sim.agents.length); +const fieldPopulation = sim.world.population +? Array.from(sim.world.population).reduce((sum, value) => sum + value, 0) +: 0; +const knowledgeDenominator = Math.max(1, fieldPopulation); const stats = { year: formatSimDate(sim.year), -activeGroups: sim.agents.length.toLocaleString(), +activeGroups: Math.round(fieldPopulation).toLocaleString(), urbanPopulation: Math.floor(urbanPopulation).toLocaleString(), ethnicities: livingEthnicities.length.toLocaleString(), cities: sim.cities.length.toLocaleString(), polities: sim.polities.length.toLocaleString(), wars: sim.wars.length.toLocaleString(), routes: sim.tradeLinks.length.toLocaleString(), -farmingKnowledge: `${(farmingTotal / agentCount).toFixed(4)} (${farmingHolders})`, -metallurgyKnowledge: `${(metallurgyTotal / agentCount).toFixed(4)} (${metallurgyHolders})`, +farmingKnowledge: `${(farmingTotal / knowledgeDenominator).toFixed(4)} (${farmingHolders})`, +metallurgyKnowledge: `${(metallurgyTotal / knowledgeDenominator).toFixed(4)} (${metallurgyHolders})`, deaths: sim.deaths.toLocaleString() }; for (const [id, value] of Object.entries(stats)) { @@ -880,7 +940,7 @@ newEthnicity: { label: "new ethnicity", color: "rgba(105, 181, 120, 0.95)", draw: drawGraphDiamond, -summary: data => `E${data.ethnicity ?? "-"}, ${Math.round(data.population || 0).toLocaleString()} frontier groups` +summary: data => `E${data.ethnicity ?? "-"}, ${Math.round(data.population || 0).toLocaleString()} frontier population` }, campaign: { label: "campaign", @@ -924,6 +984,54 @@ color: "rgba(236, 126, 111, 0.95)", draw: drawGraphTriangleUp, summary: data => `${data.outcome || "war"} vs S${data.targetPolityId ?? "-"}` }, +nomadBand: { +label: "nomad band", +color: "rgba(210, 184, 104, 0.95)", +draw: drawGraphDiamond, +summary: data => `band #${data.bandId ?? "-"}, E${data.ethnicity ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}` +}, +nomadTrade: { +label: "nomad trade", +color: "rgba(216, 177, 86, 0.95)", +draw: drawGraphCircle, +summary: data => `band #${data.bandId ?? "-"} with city #${data.cityId ?? "-"}` +}, +nomadRaid: { +label: "nomad raid", +color: "rgba(232, 101, 76, 0.95)", +draw: drawGraphTriangleDown, +summary: data => `band #${data.bandId ?? "-"} raided city #${data.cityId ?? "-"}` +}, +nomadConquest: { +label: "nomad conquest", +color: "rgba(202, 87, 78, 0.95)", +draw: drawGraphTriangleUp, +summary: data => `band #${data.bandId ?? "-"}, city #${data.cityId ?? "-"}, ${data.outcome || "conquest"}` +}, +nomadConfederation: { +label: "nomad confederation", +color: "rgba(191, 162, 91, 0.95)", +draw: drawGraphDiamond, +summary: data => `band #${data.bandId ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}` +}, +nomadSplit: { +label: "nomad split", +color: "rgba(151, 130, 91, 0.95)", +draw: drawGraphTriangleDown, +summary: data => `band #${data.bandId ?? "-"} split #${data.newBandId ?? "-"}` +}, +nomadMerge: { +label: "nomad merge", +color: "rgba(170, 145, 91, 0.95)", +draw: drawGraphDiamond, +summary: data => `band #${data.mergedBandId ?? "-"} joined #${data.bandId ?? "-"}` +}, +sedentarization: { +label: "sedentarization", +color: "rgba(202, 169, 102, 0.95)", +draw: drawGraphCircle, +summary: data => `band #${data.bandId ?? "-"} settled ${Math.round(data.population || 0).toLocaleString()} in city #${data.cityId ?? "-"}` +}, war: { label: "war", color: "rgba(202, 87, 78, 0.95)", diff --git a/utils.js b/utils.js index 7b1e571..5348bc8 100644 --- a/utils.js +++ b/utils.js @@ -43,7 +43,9 @@ function averageTraits(sum, count) { return Object.fromEntries(traitFields.map(([key, , , , , sumScale]) => [key, sum[key] / count / sumScale])); } function compositionTotal(composition) { -return [...composition.values()].reduce((sum, value) => sum + value, 0); +let sum = 0; +for (const value of composition.values()) sum += value; +return sum; } function addBirthsToComposition(composition, births, rng = null) { const entries = [...composition.entries()]; From 8f80997b0d1c93becad5699b93eb82a4781b9b7d Mon Sep 17 00:00:00 2001 From: 33333-33333 Date: Wed, 16 Sep 2026 20:53:17 +0900 Subject: [PATCH 7/8] ooo --- .tmp-edge-annexation/Crashpad/metadata | 0 .tmp-edge-annexation/Crashpad/settings.dat | Bin 0 -> 288 bytes .../Crashpad/throttle_store.dat | 1 + .../Default/Affiliation Database | Bin 0 -> 53248 bytes .../Default/Affiliation Database-journal | 0 .../Default/BookmarkMergedSurfaceOrdering | 2 + .../Default/Cache/Cache_Data/data_0 | Bin 0 -> 45056 bytes .../Default/Cache/Cache_Data/data_1 | Bin 0 -> 270336 bytes .../Default/Cache/Cache_Data/data_2 | Bin 0 -> 8192 bytes .../Default/Cache/Cache_Data/data_3 | Bin 0 -> 4202496 bytes .../Default/Cache/Cache_Data/index | Bin 0 -> 524656 bytes .../Default/Cache/No_Vary_Search/journal.baj | 1 + .../Default/Cache/No_Vary_Search/snapshot.baf | Bin 0 -> 20 bytes .../Default/ClientCertificates/LOCK | 0 .../Default/ClientCertificates/LOG | 0 .../Default/Code Cache/js/2a8a6f695a3ff316_0 | Bin 0 -> 303 bytes .../Default/Code Cache/js/2cca9bc741a6516d_0 | Bin 0 -> 306 bytes .../Default/Code Cache/js/5cce1706364839f1_0 | Bin 0 -> 307 bytes .../Default/Code Cache/js/5fbb54f36261c413_0 | Bin 0 -> 308 bytes .../Default/Code Cache/js/7de0dc67a2b3a69c_0 | Bin 0 -> 307 bytes .../Default/Code Cache/js/8020acacb3d13763_0 | Bin 0 -> 321 bytes .../Default/Code Cache/js/8bb1867be67136eb_0 | Bin 0 -> 305 bytes .../Default/Code Cache/js/945cb8fb56d09a8e_0 | Bin 0 -> 321 bytes .../Default/Code Cache/js/b21fb45197b9c728_0 | Bin 0 -> 303 bytes .../Default/Code Cache/js/ba678a2fbd8c358c_0 | Bin 0 -> 298 bytes .../Default/Code Cache/js/baded5730168391f_0 | Bin 0 -> 313 bytes .../Default/Code Cache/js/e94999eac39dfd99_0 | Bin 0 -> 317 bytes .../Default/Code Cache/js/e9a142a21b9ad9ef_0 | Bin 0 -> 297 bytes .../Default/Code Cache/js/ebce9e52a869b921_0 | Bin 0 -> 303 bytes .../Default/Code Cache/js/index | Bin 0 -> 24 bytes .../Code Cache/js/index-dir/the-real-index | Bin 0 -> 384 bytes .../Default/Code Cache/wasm/index | Bin 0 -> 24 bytes .../Code Cache/wasm/index-dir/the-real-index | Bin 0 -> 48 bytes .../Default/DawnGraphiteCache/data_0 | Bin 0 -> 8192 bytes .../Default/DawnGraphiteCache/data_1 | Bin 0 -> 270336 bytes .../Default/DawnGraphiteCache/data_2 | Bin 0 -> 8192 bytes .../Default/DawnGraphiteCache/data_3 | Bin 0 -> 8192 bytes .../Default/DawnGraphiteCache/index | Bin 0 -> 262512 bytes .../Default/DawnWebGPUCache/data_0 | Bin 0 -> 8192 bytes .../Default/DawnWebGPUCache/data_1 | Bin 0 -> 270336 bytes .../Default/DawnWebGPUCache/data_2 | Bin 0 -> 8192 bytes .../Default/DawnWebGPUCache/data_3 | Bin 0 -> 8192 bytes .../Default/DawnWebGPUCache/index | Bin 0 -> 262512 bytes .../Default/DualEngine/SiteList-Consumer.json | 1 + .../DualEngine/SiteList-Enterprise.json | 1 + .../EdgeHubAppUsage/EdgeHubAppUsageSQLite.db | Bin 0 -> 32768 bytes .../EdgeHubAppUsageSQLite.db-journal | 0 .../LOCK | 0 .../EdgePushStorageWithConnectTokenAndKey/LOG | 0 .../Default/Extension Rules/000003.log | Bin 0 -> 171 bytes .../Default/Extension Rules/CURRENT | 1 + .../Default/Extension Rules/LOCK | 0 .../Default/Extension Rules/LOG | 2 + .../Default/Extension Rules/MANIFEST-000001 | Bin 0 -> 41 bytes .../Default/Extension Scripts/000003.log | Bin 0 -> 171 bytes .../Default/Extension Scripts/CURRENT | 1 + .../Default/Extension Scripts/LOCK | 0 .../Default/Extension Scripts/LOG | 2 + .../Default/Extension Scripts/MANIFEST-000001 | Bin 0 -> 41 bytes .../Default/Extension State/000003.log | Bin 0 -> 513 bytes .../Default/Extension State/CURRENT | 1 + .../Default/Extension State/LOCK | 0 .../Default/Extension State/LOG | 2 + .../Default/Extension State/MANIFEST-000001 | Bin 0 -> 41 bytes .tmp-edge-annexation/Default/Favicons | Bin 0 -> 20480 bytes .tmp-edge-annexation/Default/Favicons-journal | 0 .tmp-edge-annexation/Default/GPUCache/data_0 | Bin 0 -> 8192 bytes .tmp-edge-annexation/Default/GPUCache/data_1 | Bin 0 -> 270336 bytes .tmp-edge-annexation/Default/GPUCache/data_2 | Bin 0 -> 8192 bytes .tmp-edge-annexation/Default/GPUCache/data_3 | Bin 0 -> 8192 bytes .tmp-edge-annexation/Default/GPUCache/index | Bin 0 -> 262512 bytes .tmp-edge-annexation/Default/History | Bin 0 -> 212992 bytes .tmp-edge-annexation/Default/History-journal | 0 .tmp-edge-annexation/Default/HubApps Icons | Bin 0 -> 28672 bytes .../Default/HubApps Icons-journal | 0 .tmp-edge-annexation/Default/LOCK | 0 .tmp-edge-annexation/Default/LOG | 0 .../000003.log | 0 .../jdiccldimpdaibmpdkjnbmckianbfold/CURRENT | 1 + .../jdiccldimpdaibmpdkjnbmckianbfold/LOCK | 0 .../jdiccldimpdaibmpdkjnbmckianbfold/LOG | 2 + .../MANIFEST-000001 | Bin 0 -> 41 bytes .../Default/Local Storage/leveldb/000003.log | Bin 0 -> 30 bytes .../Default/Local Storage/leveldb/CURRENT | 1 + .../Default/Local Storage/leveldb/LOCK | 0 .../Default/Local Storage/leveldb/LOG | 2 + .../Local Storage/leveldb/MANIFEST-000001 | Bin 0 -> 41 bytes .tmp-edge-annexation/Default/Login Data | Bin 0 -> 51200 bytes .../Default/Login Data For Account | Bin 0 -> 51200 bytes .../Default/Login Data For Account-journal | 0 .../Default/Login Data-journal | 0 .tmp-edge-annexation/Default/Network/Cookies | Bin 0 -> 20480 bytes .../Default/Network/Cookies-journal | 0 .../Default/Network/Device Bound Sessions | Bin 0 -> 20480 bytes .../Network/Device Bound Sessions-journal | 0 .../Default/Network/Network Persistent State | 1 + .../Default/Network/NetworkDataMigrated | 0 .../Default/Network/Reporting and NEL | Bin 0 -> 36864 bytes .../Default/Network/Reporting and NEL-journal | 0 .../Network/SCT Auditing Pending Reports | 1 + .../Default/Network/Sdch Dictionaries | 1 + .../Default/Network/Trust Tokens | Bin 0 -> 36864 bytes .../Default/Network/Trust Tokens-journal | 0 .../Default/Nurturing/campaign_history | Bin 0 -> 20480 bytes .../Nurturing/campaign_history-journal | 0 .../Default/PersistentOriginTrials/LOCK | 0 .../Default/PersistentOriginTrials/LOG | 0 .tmp-edge-annexation/Default/Preferences | 1 + .tmp-edge-annexation/Default/README | 1 + .../Default/Secure Preferences | 1 + .../Default/ServerCertificate | Bin 0 -> 20480 bytes .../Default/ServerCertificate-journal | 0 .../Service Worker/Database/000003.log | Bin 0 -> 1038 bytes .../Default/Service Worker/Database/CURRENT | 1 + .../Default/Service Worker/Database/LOCK | 0 .../Default/Service Worker/Database/LOG | 2 + .../Service Worker/Database/MANIFEST-000001 | Bin 0 -> 41 bytes .../ScriptCache/2cc80dabc69f58b6_0 | Bin 0 -> 318069 bytes .../Default/Service Worker/ScriptCache/index | Bin 0 -> 24 bytes .../ScriptCache/index-dir/the-real-index | Bin 0 -> 72 bytes .../Default/Session Storage/000003.log | Bin 0 -> 163 bytes .../Default/Session Storage/CURRENT | 1 + .../Default/Session Storage/LOCK | 0 .../Default/Session Storage/LOG | 2 + .../Default/Session Storage/MANIFEST-000001 | Bin 0 -> 41 bytes .../Sessions/Session_13434014282025592 | Bin 0 -> 2131 bytes .../Default/Sessions/Tabs_13434014282107761 | Bin 0 -> 1812 bytes .../Default/Shared Dictionary/cache/index | Bin 0 -> 24 bytes .../cache/index-dir/the-real-index | Bin 0 -> 48 bytes .../Default/Shared Dictionary/db | Bin 0 -> 45056 bytes .../Default/Shared Dictionary/db-journal | 0 .../Site Characteristics Database/000003.log | Bin 0 -> 40 bytes .../Site Characteristics Database/CURRENT | 1 + .../Site Characteristics Database/LOCK | 0 .../Default/Site Characteristics Database/LOG | 2 + .../MANIFEST-000001 | Bin 0 -> 41 bytes .../def/Code Cache/js/6f3a0dc5e6916f1e_0 | Bin 0 -> 309 bytes .../def/Code Cache/js/index | Bin 0 -> 24 bytes .../Code Cache/js/index-dir/the-real-index | Bin 0 -> 72 bytes .../def/Code Cache/wasm/index | Bin 0 -> 24 bytes .../Code Cache/wasm/index-dir/the-real-index | Bin 0 -> 48 bytes .../def/DawnGraphiteCache/data_0 | Bin 0 -> 8192 bytes .../def/DawnGraphiteCache/data_1 | Bin 0 -> 270336 bytes .../def/DawnGraphiteCache/data_2 | Bin 0 -> 8192 bytes .../def/DawnGraphiteCache/data_3 | Bin 0 -> 8192 bytes .../def/DawnGraphiteCache/index | Bin 0 -> 262512 bytes .../def/DawnWebGPUCache/data_0 | Bin 0 -> 8192 bytes .../def/DawnWebGPUCache/data_1 | Bin 0 -> 270336 bytes .../def/DawnWebGPUCache/data_2 | Bin 0 -> 8192 bytes .../def/DawnWebGPUCache/data_3 | Bin 0 -> 8192 bytes .../def/DawnWebGPUCache/index | Bin 0 -> 262512 bytes .../def/GPUCache/data_0 | Bin 0 -> 8192 bytes .../def/GPUCache/data_1 | Bin 0 -> 270336 bytes .../def/GPUCache/data_2 | Bin 0 -> 8192 bytes .../def/GPUCache/data_3 | Bin 0 -> 8192 bytes .../def/GPUCache/index | Bin 0 -> 262512 bytes .../def/Local Storage/leveldb/000003.log | Bin 0 -> 30 bytes .../def/Local Storage/leveldb/CURRENT | 1 + .../def/Local Storage/leveldb/LOCK | 0 .../def/Local Storage/leveldb/LOG | 2 + .../def/Local Storage/leveldb/MANIFEST-000001 | Bin 0 -> 41 bytes .../def/Network/Device Bound Sessions | Bin 0 -> 20480 bytes .../def/Network/Device Bound Sessions-journal | 0 .../def/Network/Network Persistent State | 1 + .../def/Network/NetworkDataMigrated | 0 .../def/Network/SCT Auditing Pending Reports | 1 + .../def/Network/Trust Tokens | Bin 0 -> 36864 bytes .../def/Network/Trust Tokens-journal | 0 .../def/Session Storage/000003.log | Bin 0 -> 49 bytes .../def/Session Storage/CURRENT | 1 + .../def/Session Storage/LOCK | 0 .../def/Session Storage/LOG | 2 + .../def/Session Storage/MANIFEST-000001 | Bin 0 -> 41 bytes .../def/Shared Dictionary/cache/index | Bin 0 -> 24 bytes .../cache/index-dir/the-real-index | Bin 0 -> 48 bytes .../def/Shared Dictionary/db | Bin 0 -> 45056 bytes .../def/Shared Dictionary/db-journal | 0 .../def/declarative_performance_observer.db | Bin 0 -> 32768 bytes ...eclarative_performance_observer.db-journal | 0 .../Default/Sync Data/LevelDB/000003.log | Bin 0 -> 137 bytes .../Default/Sync Data/LevelDB/CURRENT | 1 + .../Default/Sync Data/LevelDB/LOCK | 0 .../Default/Sync Data/LevelDB/LOG | 2 + .../Default/Sync Data/LevelDB/MANIFEST-000001 | Bin 0 -> 41 bytes .tmp-edge-annexation/Default/Top Sites | Bin 0 -> 20480 bytes .../Default/Top Sites-journal | 0 .tmp-edge-annexation/Default/Vpn Tokens | Bin 0 -> 28672 bytes .../Default/Vpn Tokens-journal | 0 .tmp-edge-annexation/Default/Web Data | Bin 0 -> 241664 bytes .tmp-edge-annexation/Default/Web Data-journal | 0 .../Default/WebStorage/QuotaManager | Bin 0 -> 40960 bytes .../Default/WebStorage/QuotaManager-journal | 0 .../Default/arbitration_service_config.json | 195 ++ .../Default/commerce_subscription_db/LOCK | 0 .../Default/commerce_subscription_db/LOG | 0 .../declarative_performance_observer.db | Bin 0 -> 32768 bytes ...eclarative_performance_observer.db-journal | 0 .../Default/discount_infos_db/LOCK | 0 .../Default/discount_infos_db/LOG | 0 .../Default/discounts_db/LOCK | 0 .tmp-edge-annexation/Default/discounts_db/LOG | 0 .../Default/load_statistics.db | Bin 0 -> 4096 bytes .../Default/load_statistics.db-shm | Bin 0 -> 32768 bytes .../Default/load_statistics.db-wal | Bin 0 -> 70072 bytes .../Default/parcel_tracking_db/LOCK | 0 .../Default/parcel_tracking_db/LOG | 0 .../Default/shared_proto_db/000003.log | Bin 0 -> 19 bytes .../Default/shared_proto_db/CURRENT | 1 + .../Default/shared_proto_db/LOCK | 0 .../Default/shared_proto_db/LOG | 2 + .../Default/shared_proto_db/MANIFEST-000001 | Bin 0 -> 41 bytes .../shared_proto_db/metadata/000003.log | Bin 0 -> 474 bytes .../Default/shared_proto_db/metadata/CURRENT | 1 + .../Default/shared_proto_db/metadata/LOCK | 0 .../Default/shared_proto_db/metadata/LOG | 2 + .../shared_proto_db/metadata/MANIFEST-000001 | Bin 0 -> 41 bytes .../FirstLaunchAfterInstallation | 0 .../SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db | 0 .../cache.db-wal | 0 .../cache.journal | 0 .tmp-edge-annexation/GrShaderCache/data_0 | Bin 0 -> 8192 bytes .tmp-edge-annexation/GrShaderCache/data_1 | Bin 0 -> 270336 bytes .tmp-edge-annexation/GrShaderCache/data_2 | Bin 0 -> 8192 bytes .tmp-edge-annexation/GrShaderCache/data_3 | Bin 0 -> 8192 bytes .tmp-edge-annexation/GrShaderCache/index | Bin 0 -> 262512 bytes .tmp-edge-annexation/Last Version | 1 + .tmp-edge-annexation/Local State | 1 + .../Nurturing/campaign_history | Bin 0 -> 20480 bytes .../Nurturing/campaign_history-journal | 0 .tmp-edge-annexation/ShaderCache/data_0 | Bin 0 -> 8192 bytes .tmp-edge-annexation/ShaderCache/data_1 | Bin 0 -> 270336 bytes .tmp-edge-annexation/ShaderCache/data_2 | Bin 0 -> 8192 bytes .tmp-edge-annexation/ShaderCache/data_3 | Bin 0 -> 8192 bytes .tmp-edge-annexation/ShaderCache/index | Bin 0 -> 262512 bytes .../SmartScreen/RemoteData/customSettings | 1 + ...mSettings_F95BA787499AB4FA9EFFF472CE383A14 | 1 + .../SmartScreen/RemoteData/edgeSettings | 1 + .../SmartScreen/RemoteData/edgeSettings_2.0-0 | 1 + .tmp-edge-annexation/Variations | 1 + .tmp-edge-annexation/VariationsRuntimeSeedV2 | Bin 0 -> 19 bytes .tmp-edge-annexation/VariationsSafeSeedV2 | Bin 0 -> 11 bytes .tmp-edge-annexation/VariationsSeedV2 | Bin 0 -> 816 bytes .tmp-edge-annexation/en-US-10-1.bdic | Bin 0 -> 451968 bytes MODIFICATION_NOTES.md | 321 +++ README.md | 11 + annexation_policy_probe.html | 70 + app-state.js | 31 +- boot.js | 142 +- config.js | 130 +- engine.js | 1892 ++++++++++++----- index.html | 177 +- render.js | 694 +++--- styles.css | 200 +- tests/modifications.test.cjs | 600 ++++++ tests/simulation.test.cjs | 478 +++++ utils.js | 9 - 256 files changed, 4044 insertions(+), 966 deletions(-) create mode 100644 .tmp-edge-annexation/Crashpad/metadata create mode 100644 .tmp-edge-annexation/Crashpad/settings.dat create mode 100644 .tmp-edge-annexation/Crashpad/throttle_store.dat create mode 100644 .tmp-edge-annexation/Default/Affiliation Database create mode 100644 .tmp-edge-annexation/Default/Affiliation Database-journal create mode 100644 .tmp-edge-annexation/Default/BookmarkMergedSurfaceOrdering create mode 100644 .tmp-edge-annexation/Default/Cache/Cache_Data/data_0 create mode 100644 .tmp-edge-annexation/Default/Cache/Cache_Data/data_1 create mode 100644 .tmp-edge-annexation/Default/Cache/Cache_Data/data_2 create mode 100644 .tmp-edge-annexation/Default/Cache/Cache_Data/data_3 create mode 100644 .tmp-edge-annexation/Default/Cache/Cache_Data/index create mode 100644 .tmp-edge-annexation/Default/Cache/No_Vary_Search/journal.baj create mode 100644 .tmp-edge-annexation/Default/Cache/No_Vary_Search/snapshot.baf create mode 100644 .tmp-edge-annexation/Default/ClientCertificates/LOCK create mode 100644 .tmp-edge-annexation/Default/ClientCertificates/LOG create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/2a8a6f695a3ff316_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/2cca9bc741a6516d_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/5cce1706364839f1_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/5fbb54f36261c413_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/7de0dc67a2b3a69c_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/8020acacb3d13763_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/8bb1867be67136eb_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/945cb8fb56d09a8e_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/b21fb45197b9c728_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/ba678a2fbd8c358c_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/baded5730168391f_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/e94999eac39dfd99_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/e9a142a21b9ad9ef_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/ebce9e52a869b921_0 create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/index create mode 100644 .tmp-edge-annexation/Default/Code Cache/js/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Code Cache/wasm/index create mode 100644 .tmp-edge-annexation/Default/Code Cache/wasm/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/DawnGraphiteCache/data_0 create mode 100644 .tmp-edge-annexation/Default/DawnGraphiteCache/data_1 create mode 100644 .tmp-edge-annexation/Default/DawnGraphiteCache/data_2 create mode 100644 .tmp-edge-annexation/Default/DawnGraphiteCache/data_3 create mode 100644 .tmp-edge-annexation/Default/DawnGraphiteCache/index create mode 100644 .tmp-edge-annexation/Default/DawnWebGPUCache/data_0 create mode 100644 .tmp-edge-annexation/Default/DawnWebGPUCache/data_1 create mode 100644 .tmp-edge-annexation/Default/DawnWebGPUCache/data_2 create mode 100644 .tmp-edge-annexation/Default/DawnWebGPUCache/data_3 create mode 100644 .tmp-edge-annexation/Default/DawnWebGPUCache/index create mode 100644 .tmp-edge-annexation/Default/DualEngine/SiteList-Consumer.json create mode 100644 .tmp-edge-annexation/Default/DualEngine/SiteList-Enterprise.json create mode 100644 .tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db create mode 100644 .tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db-journal create mode 100644 .tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOCK create mode 100644 .tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOG create mode 100644 .tmp-edge-annexation/Default/Extension Rules/000003.log create mode 100644 .tmp-edge-annexation/Default/Extension Rules/CURRENT create mode 100644 .tmp-edge-annexation/Default/Extension Rules/LOCK create mode 100644 .tmp-edge-annexation/Default/Extension Rules/LOG create mode 100644 .tmp-edge-annexation/Default/Extension Rules/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Extension Scripts/000003.log create mode 100644 .tmp-edge-annexation/Default/Extension Scripts/CURRENT create mode 100644 .tmp-edge-annexation/Default/Extension Scripts/LOCK create mode 100644 .tmp-edge-annexation/Default/Extension Scripts/LOG create mode 100644 .tmp-edge-annexation/Default/Extension Scripts/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Extension State/000003.log create mode 100644 .tmp-edge-annexation/Default/Extension State/CURRENT create mode 100644 .tmp-edge-annexation/Default/Extension State/LOCK create mode 100644 .tmp-edge-annexation/Default/Extension State/LOG create mode 100644 .tmp-edge-annexation/Default/Extension State/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Favicons create mode 100644 .tmp-edge-annexation/Default/Favicons-journal create mode 100644 .tmp-edge-annexation/Default/GPUCache/data_0 create mode 100644 .tmp-edge-annexation/Default/GPUCache/data_1 create mode 100644 .tmp-edge-annexation/Default/GPUCache/data_2 create mode 100644 .tmp-edge-annexation/Default/GPUCache/data_3 create mode 100644 .tmp-edge-annexation/Default/GPUCache/index create mode 100644 .tmp-edge-annexation/Default/History create mode 100644 .tmp-edge-annexation/Default/History-journal create mode 100644 .tmp-edge-annexation/Default/HubApps Icons create mode 100644 .tmp-edge-annexation/Default/HubApps Icons-journal create mode 100644 .tmp-edge-annexation/Default/LOCK create mode 100644 .tmp-edge-annexation/Default/LOG create mode 100644 .tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/000003.log create mode 100644 .tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/CURRENT create mode 100644 .tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOCK create mode 100644 .tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOG create mode 100644 .tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Local Storage/leveldb/000003.log create mode 100644 .tmp-edge-annexation/Default/Local Storage/leveldb/CURRENT create mode 100644 .tmp-edge-annexation/Default/Local Storage/leveldb/LOCK create mode 100644 .tmp-edge-annexation/Default/Local Storage/leveldb/LOG create mode 100644 .tmp-edge-annexation/Default/Local Storage/leveldb/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Login Data create mode 100644 .tmp-edge-annexation/Default/Login Data For Account create mode 100644 .tmp-edge-annexation/Default/Login Data For Account-journal create mode 100644 .tmp-edge-annexation/Default/Login Data-journal create mode 100644 .tmp-edge-annexation/Default/Network/Cookies create mode 100644 .tmp-edge-annexation/Default/Network/Cookies-journal create mode 100644 .tmp-edge-annexation/Default/Network/Device Bound Sessions create mode 100644 .tmp-edge-annexation/Default/Network/Device Bound Sessions-journal create mode 100644 .tmp-edge-annexation/Default/Network/Network Persistent State create mode 100644 .tmp-edge-annexation/Default/Network/NetworkDataMigrated create mode 100644 .tmp-edge-annexation/Default/Network/Reporting and NEL create mode 100644 .tmp-edge-annexation/Default/Network/Reporting and NEL-journal create mode 100644 .tmp-edge-annexation/Default/Network/SCT Auditing Pending Reports create mode 100644 .tmp-edge-annexation/Default/Network/Sdch Dictionaries create mode 100644 .tmp-edge-annexation/Default/Network/Trust Tokens create mode 100644 .tmp-edge-annexation/Default/Network/Trust Tokens-journal create mode 100644 .tmp-edge-annexation/Default/Nurturing/campaign_history create mode 100644 .tmp-edge-annexation/Default/Nurturing/campaign_history-journal create mode 100644 .tmp-edge-annexation/Default/PersistentOriginTrials/LOCK create mode 100644 .tmp-edge-annexation/Default/PersistentOriginTrials/LOG create mode 100644 .tmp-edge-annexation/Default/Preferences create mode 100644 .tmp-edge-annexation/Default/README create mode 100644 .tmp-edge-annexation/Default/Secure Preferences create mode 100644 .tmp-edge-annexation/Default/ServerCertificate create mode 100644 .tmp-edge-annexation/Default/ServerCertificate-journal create mode 100644 .tmp-edge-annexation/Default/Service Worker/Database/000003.log create mode 100644 .tmp-edge-annexation/Default/Service Worker/Database/CURRENT create mode 100644 .tmp-edge-annexation/Default/Service Worker/Database/LOCK create mode 100644 .tmp-edge-annexation/Default/Service Worker/Database/LOG create mode 100644 .tmp-edge-annexation/Default/Service Worker/Database/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Service Worker/ScriptCache/2cc80dabc69f58b6_0 create mode 100644 .tmp-edge-annexation/Default/Service Worker/ScriptCache/index create mode 100644 .tmp-edge-annexation/Default/Service Worker/ScriptCache/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Session Storage/000003.log create mode 100644 .tmp-edge-annexation/Default/Session Storage/CURRENT create mode 100644 .tmp-edge-annexation/Default/Session Storage/LOCK create mode 100644 .tmp-edge-annexation/Default/Session Storage/LOG create mode 100644 .tmp-edge-annexation/Default/Session Storage/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Sessions/Session_13434014282025592 create mode 100644 .tmp-edge-annexation/Default/Sessions/Tabs_13434014282107761 create mode 100644 .tmp-edge-annexation/Default/Shared Dictionary/cache/index create mode 100644 .tmp-edge-annexation/Default/Shared Dictionary/cache/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Shared Dictionary/db create mode 100644 .tmp-edge-annexation/Default/Shared Dictionary/db-journal create mode 100644 .tmp-edge-annexation/Default/Site Characteristics Database/000003.log create mode 100644 .tmp-edge-annexation/Default/Site Characteristics Database/CURRENT create mode 100644 .tmp-edge-annexation/Default/Site Characteristics Database/LOCK create mode 100644 .tmp-edge-annexation/Default/Site Characteristics Database/LOG create mode 100644 .tmp-edge-annexation/Default/Site Characteristics Database/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/js/6f3a0dc5e6916f1e_0 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/js/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/js/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/wasm/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/wasm/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_0 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_1 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_2 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_3 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_0 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_1 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_2 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_3 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_0 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_1 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_2 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_3 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/000003.log create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/CURRENT create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOCK create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOG create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions-journal create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Network Persistent State create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/NetworkDataMigrated create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/SCT Auditing Pending Reports create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Trust Tokens create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Trust Tokens-journal create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Session Storage/000003.log create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Session Storage/CURRENT create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Session Storage/LOCK create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Session Storage/LOG create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Session Storage/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/cache/index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/cache/index-dir/the-real-index create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db-journal create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db create mode 100644 .tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db-journal create mode 100644 .tmp-edge-annexation/Default/Sync Data/LevelDB/000003.log create mode 100644 .tmp-edge-annexation/Default/Sync Data/LevelDB/CURRENT create mode 100644 .tmp-edge-annexation/Default/Sync Data/LevelDB/LOCK create mode 100644 .tmp-edge-annexation/Default/Sync Data/LevelDB/LOG create mode 100644 .tmp-edge-annexation/Default/Sync Data/LevelDB/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/Top Sites create mode 100644 .tmp-edge-annexation/Default/Top Sites-journal create mode 100644 .tmp-edge-annexation/Default/Vpn Tokens create mode 100644 .tmp-edge-annexation/Default/Vpn Tokens-journal create mode 100644 .tmp-edge-annexation/Default/Web Data create mode 100644 .tmp-edge-annexation/Default/Web Data-journal create mode 100644 .tmp-edge-annexation/Default/WebStorage/QuotaManager create mode 100644 .tmp-edge-annexation/Default/WebStorage/QuotaManager-journal create mode 100644 .tmp-edge-annexation/Default/arbitration_service_config.json create mode 100644 .tmp-edge-annexation/Default/commerce_subscription_db/LOCK create mode 100644 .tmp-edge-annexation/Default/commerce_subscription_db/LOG create mode 100644 .tmp-edge-annexation/Default/declarative_performance_observer.db create mode 100644 .tmp-edge-annexation/Default/declarative_performance_observer.db-journal create mode 100644 .tmp-edge-annexation/Default/discount_infos_db/LOCK create mode 100644 .tmp-edge-annexation/Default/discount_infos_db/LOG create mode 100644 .tmp-edge-annexation/Default/discounts_db/LOCK create mode 100644 .tmp-edge-annexation/Default/discounts_db/LOG create mode 100644 .tmp-edge-annexation/Default/load_statistics.db create mode 100644 .tmp-edge-annexation/Default/load_statistics.db-shm create mode 100644 .tmp-edge-annexation/Default/load_statistics.db-wal create mode 100644 .tmp-edge-annexation/Default/parcel_tracking_db/LOCK create mode 100644 .tmp-edge-annexation/Default/parcel_tracking_db/LOG create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/000003.log create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/CURRENT create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/LOCK create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/LOG create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/metadata/000003.log create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/metadata/CURRENT create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/metadata/LOCK create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/metadata/LOG create mode 100644 .tmp-edge-annexation/Default/shared_proto_db/metadata/MANIFEST-000001 create mode 100644 .tmp-edge-annexation/FirstLaunchAfterInstallation create mode 100644 .tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db create mode 100644 .tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db-wal create mode 100644 .tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.journal create mode 100644 .tmp-edge-annexation/GrShaderCache/data_0 create mode 100644 .tmp-edge-annexation/GrShaderCache/data_1 create mode 100644 .tmp-edge-annexation/GrShaderCache/data_2 create mode 100644 .tmp-edge-annexation/GrShaderCache/data_3 create mode 100644 .tmp-edge-annexation/GrShaderCache/index create mode 100644 .tmp-edge-annexation/Last Version create mode 100644 .tmp-edge-annexation/Local State create mode 100644 .tmp-edge-annexation/Nurturing/campaign_history create mode 100644 .tmp-edge-annexation/Nurturing/campaign_history-journal create mode 100644 .tmp-edge-annexation/ShaderCache/data_0 create mode 100644 .tmp-edge-annexation/ShaderCache/data_1 create mode 100644 .tmp-edge-annexation/ShaderCache/data_2 create mode 100644 .tmp-edge-annexation/ShaderCache/data_3 create mode 100644 .tmp-edge-annexation/ShaderCache/index create mode 100644 .tmp-edge-annexation/SmartScreen/RemoteData/customSettings create mode 100644 .tmp-edge-annexation/SmartScreen/RemoteData/customSettings_F95BA787499AB4FA9EFFF472CE383A14 create mode 100644 .tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings create mode 100644 .tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings_2.0-0 create mode 100644 .tmp-edge-annexation/Variations create mode 100644 .tmp-edge-annexation/VariationsRuntimeSeedV2 create mode 100644 .tmp-edge-annexation/VariationsSafeSeedV2 create mode 100644 .tmp-edge-annexation/VariationsSeedV2 create mode 100644 .tmp-edge-annexation/en-US-10-1.bdic create mode 100644 MODIFICATION_NOTES.md create mode 100644 annexation_policy_probe.html create mode 100644 tests/modifications.test.cjs create mode 100644 tests/simulation.test.cjs diff --git a/.tmp-edge-annexation/Crashpad/metadata b/.tmp-edge-annexation/Crashpad/metadata new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Crashpad/settings.dat b/.tmp-edge-annexation/Crashpad/settings.dat new file mode 100644 index 0000000000000000000000000000000000000000..f6066a3babe2809e12addb7110465311751112ec GIT binary patch literal 288 zcmXR;32xm9}HR=yS6$H`Z>OsUX6&D$(8HQ&OysJOtu#miOO z#M3j)z1Y*;%f&pjJk7;Ft2DR3-_SeD#8wGr%HW}m&C*g+6H`-kjnY!gbxl&t40Mx{ ejm&hDjVz7LjLZ^^EsYG2UAx>r^{s1GqaFZ73?qdA literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Crashpad/throttle_store.dat b/.tmp-edge-annexation/Crashpad/throttle_store.dat new file mode 100644 index 0000000..9639e1b --- /dev/null +++ b/.tmp-edge-annexation/Crashpad/throttle_store.dat @@ -0,0 +1 @@ +level=none expiry=0 diff --git a/.tmp-edge-annexation/Default/Affiliation Database b/.tmp-edge-annexation/Default/Affiliation Database new file mode 100644 index 0000000000000000000000000000000000000000..3ad9328ccd0d59ac80a19c1515c961e3ffe97a02 GIT binary patch literal 53248 zcmeI)O>g5w7{GD6ZsI0=araPJs6v`*LBwhTia2oS0YYk)s%g5Lrie;NmN%IeYxCCF zS$2;pdMB5>(<$1mtz(FkK_tax zyW8|5@v*k8>ALor5SpeX)N@lkCyzDtW_40fullX`i{2)*4}bh+)A~o-NWIXkE9=*- zpSI-2pIh&3e6wCn|CT;Zy-05@YRq;75I_I{1Q0;re<#phH*Lq!`|m{lqMsBZu&t>d{w9vzbsTl`Lrs^=cQ6soR^Otox77A z9OqyoX`ec}7PRW}S$N%0KN@;|FKQ3VUi`3LK3?AJ8)?%%-q-u@4tF25X}3Ii?Ok=- zy-w(bGV+4DH>^=xYYjgP$93!D0UVVN-LJ)4+KSV%m}xIEqk}trEoIv7n|jgfHs*FA z{kASl8_qrdrC(FS>vaR?Cb4GP`}_L$g<;%gdOA}~#UeLTDKbG_9F?o?1Ggd`R*p^z zl?!p~UWmeZ_4KH$nx44jYF13oElQ{52d~F@WHUX|BmqRl{lcxd<)V8w^^~DHr!yGg zp<8lQN)-!d#loSR6@wh|;;EDswQv2_mGn9)lHawvbv6FRB+s0_X`1#)PVeu%mJp-R zH)Zp&>`wAxI`;AAwT1DR*E$xH@e!s;adVI`?Oaa(!HGv?yx;7Zlk;OTJ?b3_$|&;n zAnY{!=U&Ti$_f7@D}tK325*JsjWK&QB}`MwaXw8Z?X%pXSz#8>%g=5xAFd_`*TcmS ze>|;(^13HmH91pE#OP-#GlTJERZFLzGfaDLPrrFT7Er0`M$?K6S7S$dwf(>9>_HC(Q!wVNG33e;k;_f##csdeJ~`iik@jSHV_>&E?i z&8FY+!pM($VJ@FmV=}Cln)TB9+xp{<4v=mkfB*srAbDJP<$t0R#|0 z009ILKmY**5I|sw1-SoT;@~ng1Q0*~0R#|0009ILKmY**#sYl)pHx5q0R#|0009IL zKmY**5I|u01^E5{^2eAFB7gt_2q1s}0tg_000Iag!2LftfB*srAb|K{cvJV?4Je;W(O%?^&?Kytzb=76Jqa5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV6Tf0-uN5Uq{t<|H=3N+R^iQZD}oGbHOQ# z>a+IA{|U2Xg?YAbYlS`kp>=QP`E`2Fr}}*#qJ!S?TNvC=i!ZzN)p6V$%~$60)8O%} z7k0ybeAB-!%iH243}X zCt)&d-xcj%x83VpRE7DskrN<5fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 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 z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz`$f6 D&aT+B literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Cache/Cache_Data/index b/.tmp-edge-annexation/Default/Cache/Cache_Data/index new file mode 100644 index 0000000000000000000000000000000000000000..b8eb446e816e4b72f11ad0b5613aa28578b9a6c4 GIT binary patch literal 524656 zcmeIuu?>ST6a>(3(`ST8X=x%hWdu;#OhAX|G8F~Falrt{dTxBWU)|e&-5SwFivK%u znj>;4Ki}8TFYkCfOVwPc4XSZtmCtz9oi{%L0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly(6B&`G&MZWGy((&5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly jK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ;3fh)2IL2y literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Cache/No_Vary_Search/journal.baj b/.tmp-edge-annexation/Default/Cache/No_Vary_Search/journal.baj new file mode 100644 index 0000000..54fe66e --- /dev/null +++ b/.tmp-edge-annexation/Default/Cache/No_Vary_Search/journal.baj @@ -0,0 +1 @@ +$F~ \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Cache/No_Vary_Search/snapshot.baf b/.tmp-edge-annexation/Default/Cache/No_Vary_Search/snapshot.baf new file mode 100644 index 0000000000000000000000000000000000000000..8912405f361089375a773ff93370d55411ac14de GIT binary patch literal 20 ScmYfLnR`R!D}DXED>%|`J_BReT4KP5jgH&H(+F*!TED8Do>MK7yZfr}g?ZaDHzcg_Fx zg%RWqEWiOM#sU>@pR*+KD?5uuqEvX;r9LM2`seCf7HjL6rbU0Vd$nVUAu~{2=CS>f zP~{BM%mw&CY*nLQx2!Mhn6dJf#FOcp-0tO0=w9`R!D}DW}l+5Jh zoRrMmf|SI}Bp{icm6w#8oSm7Nmz0*DlcJwknv$6xTvC*pn44OpmsPC5MUE*q9C@d^ z=KuP_2yzM*-~be3fr^(bvQ+uzKlPv0=ZeBRn?K%;`cPiNcG&!d{DhTCvU?Y1Fay

    z?#a|*mChr2?ueVglD>~D9vuFCCWF7;s&-`{>`k(b=Jt!tB?U5L8(>Wu0+=KdovH-PkC L6_~fp2WkKSS?TL%rDP^2 z=cHuj7NjI*CIQLpth}V$yn zJKZ(^*B3^RW3T`Rpco5OTr4O|>avW1!pa3}avrcnt9?A^*YdrM-LtDe+o9mpBr9g1 zy3AwyC85e0PMHbtgV@^N)79M8o~|mKlNRW_dH;d%)e{Wwx-MmYI@@34#)<{kVQv8F MpJwzT#0P2s0G8-wN&o-= literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/7de0dc67a2b3a69c_0 b/.tmp-edge-annexation/Default/Code Cache/js/7de0dc67a2b3a69c_0 new file mode 100644 index 0000000000000000000000000000000000000000..b5c197e20c3a60079a62dd8a8ef48d04c515f327 GIT binary patch literal 307 zcmXqrDOxU_`}+?o0|P@n5YP5oc?n1{#Al~gCTA4o=cekWR+OaX6=&w>S?TL%rDP^2 z=cHuj7NjI*CIQLpth}V$%(T>!%-mFu)SQCUBE76)1uk-ox#7q= z-8KK$7epE{eN|NFt?=MOOh z)ny*rF9}u7aMDbGAH-g!esgwx{Z!3jrByc)!mjcg`+3anOMT(kIF+4I=Fo{ZFgJko MPxrL>;R7`Q00tFkga7~l literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/8020acacb3d13763_0 b/.tmp-edge-annexation/Default/Code Cache/js/8020acacb3d13763_0 new file mode 100644 index 0000000000000000000000000000000000000000..cd9a06aa16201d75300fc43e82dc5fd6a4f3e5c6 GIT binary patch literal 321 zcmXqrDOxU_`}+?o0|P@Z5Nm$VNe5C4@!6@B$r(lYxv9FT6(y;8#hLkeR{Hu`DVfR1 zIVqXB1u2P{NkB3?D=#TGIXg2kFDWfQCq=(3KQlSiC$qQ&!3xgIOV3Fy$5wX2rNUZBKS>TFd{<{&b|_b{^HO ze}y`kf$B1k?U#fqXEvB QJj@Ls{a%@kwmwh;0BhE3bpQYW literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/8bb1867be67136eb_0 b/.tmp-edge-annexation/Default/Code Cache/js/8bb1867be67136eb_0 new file mode 100644 index 0000000000000000000000000000000000000000..588606ba36d102f24d7dea6c8010bb982c65c472 GIT binary patch literal 305 zcmXqrDOxU_`}+?o0|P@X5L>by+ytZ;;QZkd1 zb5b&M3sMp@lYnG)R$fwWa&~57UQ$|qPKthceo=~3eraAxVo{}DRYg_?&8s)n_AgFqI>YJzCQ?`LK*^@9EFw0wRhsh5Ky{hN z_De#QGjN&<@PpVJeqJ`&pS$dLFwfrByyUAZJ8Mh1{yOhCQ*reFA*};74lp->^rvVE Jo%Mkl004|kWupK9 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/945cb8fb56d09a8e_0 b/.tmp-edge-annexation/Default/Code Cache/js/945cb8fb56d09a8e_0 new file mode 100644 index 0000000000000000000000000000000000000000..1d6ae3b377877e3209499721c266dae15f026ef0 GIT binary patch literal 321 zcmXqrDOxU_`}+?o0|P@Z5dRb7{RN~L;QZkd1 zb5b&M3sMp@lYnG)R$fwWa&~57UQ$|qPKth6er9s2PiAomf)$inSejZ~l3JvfRjj~8 zj-fXkd8fPP|N6oRav2uj02E_^iq}rMINj!H;B%`D7VrMD1T;=8(#hT){b^2Yd8PiE zCov7oKy{hN_De#QGn_IL;0Lh-!cw&g`ZJ>UEL-!rA!@S?TL%rDP^2 z=cHuj7NjI*CIQLpth}V$K;)`vu;4Znnls$TsYI*4np!nS&?aYhAIe`%7UJ%ncy@N6xRm I;R7`Q064&D3jhEB literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/ba678a2fbd8c358c_0 b/.tmp-edge-annexation/Default/Code Cache/js/ba678a2fbd8c358c_0 new file mode 100644 index 0000000000000000000000000000000000000000..be4ed8b89fb2cde155c710ef63c1df6d40a2f00b GIT binary patch literal 298 zcmXqrDOxU_`}+?o0|P@D5GzW1WB@6K`0Uim`R!D}DXE?9|NM zjQsShl!Cm1%-qDp3?K$7)-TB@&CAxyDpuekNB0d!-s!ISzrHYnoPY&5 z0L56K;+<=a%_TdoJI;*jnH?_tK}*p{a_YmTj~`rA1paLmFOOsfs>?jKUlOXE!N6RA zAH;rnCM90YF|vh}Mt}nR2KjcVt9xGpQ#3lP{zH07D_Z|c%1#e;o zs>?jKUlOXE;k20mKZyNvMZJ#ryGd!M{W8}5>xzlpwq)t~JDrkI*EIth9sWF$hq(cy M|AT7QTOX(a08u<>!~g&Q literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/e94999eac39dfd99_0 b/.tmp-edge-annexation/Default/Code Cache/js/e94999eac39dfd99_0 new file mode 100644 index 0000000000000000000000000000000000000000..6b47c1ba6032ebcf678bb70d20d68d05b624f641 GIT binary patch literal 317 zcmXqrDOxU_`}+?o0|P@R5NFw(ybh!o;QZkd1 zb5b&M3sMp@lYnG)R$fwWa&~57UQ$|qPKthceo=~3eraAxVo{}QS!!O1Z(?3zdTNng zRT?15k_wD&B3knm1yS^?sqCvWZL554@if!*TSGWVv&D&qNdC>#^qls+BuU7P*{Jidrx|`vX VH3loMmcZNq(r+Io^Uw!s002PVX|DhP literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/e9a142a21b9ad9ef_0 b/.tmp-edge-annexation/Default/Code Cache/js/e9a142a21b9ad9ef_0 new file mode 100644 index 0000000000000000000000000000000000000000..01d97925421fdff882511b164b402f40c24d5d3a GIT binary patch literal 297 zcmXqrDOxU_`}+?o0|P@T5a$_nO#@O4@!6@B$r(lYxv9FT6(y;8#hLkeR{Hu`DVfR1 zIVqXB1u2P{NkB3?D=#TGIXg2kFDWfQCq=)wI5$Txt5|`H9L+Zzd8fPP|N6oRasd|L z02E_^ihr>+?tU@7kn^8i1GjUgMz0u)?nAYm85UbC4W%V~<$IZd>N1b*mxL;3U@#Zp z2eCC)oSwthZ^b#|`N}0xv3o)oYMy`I{OkLyV28zAJNB(x4s!!Yf8i2i5g(`l08iRo A?*IS* literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/ebce9e52a869b921_0 b/.tmp-edge-annexation/Default/Code Cache/js/ebce9e52a869b921_0 new file mode 100644 index 0000000000000000000000000000000000000000..f5f15fcb4c38b71d3a71742ff6ef1c2bea1ba6c5 GIT binary patch literal 303 zcmXqrDOxU_`}+?o0|P@f5dZXuvjI{J@!6@B$r(lYxv9FT6(y;8#hLkeR{HvBnb}EM zNvXL>dAVsB1qE4YKsq}yBPAm(KO-Y6H(fs|F*!TED8Do>MK7yZfr}g?ZaDHzcg_Fx zg%RWqEWiOM#sU@RpRe}(;x&KmPl1}3g=R^=nCN$xf$OVgAXm^cg?SbN+nIstGLP+- zgeqrnG8fg&xW`}*AS4f5>2e!L#$29W*`p41yY GPy+zE24Kek literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/index b/.tmp-edge-annexation/Default/Code Cache/js/index new file mode 100644 index 0000000000000000000000000000000000000000..79bd403ac665228853dd8fa54b8f4427af1721c0 GIT binary patch literal 24 TcmXqrDOxU_`}+?k11bOjQGf(4 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/js/index-dir/the-real-index b/.tmp-edge-annexation/Default/Code Cache/js/index-dir/the-real-index new file mode 100644 index 0000000000000000000000000000000000000000..48f20055bf0cefae69dd80a36bbe38c9e46ff71e GIT binary patch literal 384 zcmbX=aAj;=;H5h&XQi_wD2Xm zxV&WsWAW8{yU@j7n-xB*Zrj+6E7+a p-ecOcSHCMA!(Oq^_EDMnU0Ues6?bN?2%2~9HM)4ie=Tr00s!j~V9fvk literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/wasm/index b/.tmp-edge-annexation/Default/Code Cache/wasm/index new file mode 100644 index 0000000000000000000000000000000000000000..79bd403ac665228853dd8fa54b8f4427af1721c0 GIT binary patch literal 24 TcmXqrDOxU_`}+?k11bOjQGf(4 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Code Cache/wasm/index-dir/the-real-index b/.tmp-edge-annexation/Default/Code Cache/wasm/index-dir/the-real-index new file mode 100644 index 0000000000000000000000000000000000000000..a806ca186b40ed34cce0e175f8ad51031c809565 GIT binary patch literal 48 mcmdO3U|=wxZ2vC5QlTidBrlZ{$VUf^K!NY}vW8l_^ceu$ZwKc9 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnGraphiteCache/data_0 b/.tmp-edge-annexation/Default/DawnGraphiteCache/data_0 new file mode 100644 index 0000000000000000000000000000000000000000..d76fb77e93ac8a536b5dbade616d63abd00626c5 GIT binary patch literal 8192 zcmeIuK?wjL5Jka{7-jo+5O1auw}mk8@B+*}b0s6M>Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnGraphiteCache/data_1 b/.tmp-edge-annexation/Default/DawnGraphiteCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnGraphiteCache/data_2 b/.tmp-edge-annexation/Default/DawnGraphiteCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnGraphiteCache/data_3 b/.tmp-edge-annexation/Default/DawnGraphiteCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnGraphiteCache/index b/.tmp-edge-annexation/Default/DawnGraphiteCache/index new file mode 100644 index 0000000000000000000000000000000000000000..13f03197c9d30ff169b16319c76f4dff5fce5ee9 GIT binary patch literal 262512 zcmeIup$&jA00h8qItdm-u&l@wtWigBOhpQ&10e6!fAZ?CyPiqSnDUNtBwy=u+oyGI z%XrfX5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N J0t9{#cmO3l1tS0e literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnWebGPUCache/data_0 b/.tmp-edge-annexation/Default/DawnWebGPUCache/data_0 new file mode 100644 index 0000000000000000000000000000000000000000..d76fb77e93ac8a536b5dbade616d63abd00626c5 GIT binary patch literal 8192 zcmeIuK?wjL5Jka{7-jo+5O1auw}mk8@B+*}b0s6M>Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnWebGPUCache/data_1 b/.tmp-edge-annexation/Default/DawnWebGPUCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnWebGPUCache/data_2 b/.tmp-edge-annexation/Default/DawnWebGPUCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnWebGPUCache/data_3 b/.tmp-edge-annexation/Default/DawnWebGPUCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DawnWebGPUCache/index b/.tmp-edge-annexation/Default/DawnWebGPUCache/index new file mode 100644 index 0000000000000000000000000000000000000000..4f47c8b5863f4cac9129e6857609194e99bd6a0e GIT binary patch literal 262512 zcmeIup$&jA00h8qItdm-U>&AojXHv3DpD{V0C}(elUH}$^-OBUly{UP`C6abKCN?G z#+y!n009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U IAn=301JHd0>i_@% literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/DualEngine/SiteList-Consumer.json b/.tmp-edge-annexation/Default/DualEngine/SiteList-Consumer.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.tmp-edge-annexation/Default/DualEngine/SiteList-Consumer.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/DualEngine/SiteList-Enterprise.json b/.tmp-edge-annexation/Default/DualEngine/SiteList-Enterprise.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.tmp-edge-annexation/Default/DualEngine/SiteList-Enterprise.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db b/.tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db new file mode 100644 index 0000000000000000000000000000000000000000..6bccdac1db47b1c61b2acee4498e0142ab7924bc GIT binary patch literal 32768 zcmeI(&rj1}7zglng%usMXe2xA;G1xO#i1@nFC270MdBPXHkH$x7y2?9)^@fXVaFvN z{0IC?{1?2Cc=q7UgI5!89(~*WprsDw2ISkMbnW}n=XpPSc$2qdTbmWr=VZ@uE#{Ml z(u^d_(o;etNs`4rCHCPqDPBwrPsA~3|JNo<_db5fYQH5l^F+!XXrHFPWtXS*%vW)W z4FV8=00bZa0SG_<0+&socUx6+cS>@Po3_D^Si4Qb7yF$Z8k`u+XSCz7CZAfV>E*gk z)~l=fTQcfMHmW4qc_C~!iez`6*-dWHoo*5EtTJITrg233Hws&m;nY}er@D{HFml5}@7AQ6TNLrOM)5kf>DVEGX(R)t z69J?B$3*-OlW0YYp=_-mFMLe zsczIswNa^%Msxubj5xR#(#S_ z^nRl)#9}v(H+S6DnAU#WplbgTHde-GwI`@Y?~Ew+mdS0Oo*Mi~eiqx^H*HSO7{cHd zL9RBBk7QMUR&G@4WPZ`$hrBhP4D5K(p^x%8`KHlbX=AFLAk9;mB3`5KodrrK2 z{O@`MG|cHiVI`H$y(x_=xMY#gQu3N2CfaaqpABZ*naeiqB3}qV00Izz00bZa0SG_< z0uX=z1kNLHJ?M<}|9QyJ7XlD~00bZa0SG_<0uX=z1R!wf1cJ~1745U6{nWmT12zai z00Izz00bZa0SG_<0uX=z1TLsRUQw2`7V~_%>sW2(o8tQ}bnsP#$C;Fp*M=uEvNCtm zvRIpXKJz=?Vk!9iU(t>w?O6Mz{kWh5L|PDl00bZa0SG_<0uX=z1Rwwb2=oQ=%91?h z8Gw>e^77yjKk literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db-journal b/.tmp-edge-annexation/Default/EdgeHubAppUsage/EdgeHubAppUsageSQLite.db-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOCK b/.tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOG b/.tmp-edge-annexation/Default/EdgePushStorageWithConnectTokenAndKey/LOG new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Extension Rules/000003.log b/.tmp-edge-annexation/Default/Extension Rules/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..192989b54bc53d1bca30428f0f2bcb5ff44fb9a5 GIT binary patch literal 171 VcmX?+_RN%rfsv5`0Zt53Apo`~6%YUb literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Extension Rules/CURRENT b/.tmp-edge-annexation/Default/Extension Rules/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension Rules/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension Rules/LOCK b/.tmp-edge-annexation/Default/Extension Rules/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Extension Rules/LOG b/.tmp-edge-annexation/Default/Extension Rules/LOG new file mode 100644 index 0000000..ab20211 --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension Rules/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:00.872 38d0 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension Rules since it was missing. +2026/09/16-15:38:00.906 38d0 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension Rules/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension Rules/MANIFEST-000001 b/.tmp-edge-annexation/Default/Extension Rules/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Extension Scripts/000003.log b/.tmp-edge-annexation/Default/Extension Scripts/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..192989b54bc53d1bca30428f0f2bcb5ff44fb9a5 GIT binary patch literal 171 VcmX?+_RN%rfsv5`0Zt53Apo`~6%YUb literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Extension Scripts/CURRENT b/.tmp-edge-annexation/Default/Extension Scripts/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension Scripts/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension Scripts/LOCK b/.tmp-edge-annexation/Default/Extension Scripts/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Extension Scripts/LOG b/.tmp-edge-annexation/Default/Extension Scripts/LOG new file mode 100644 index 0000000..4f67d17 --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension Scripts/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:00.914 38d0 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension Scripts since it was missing. +2026/09/16-15:38:00.934 38d0 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension Scripts/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension Scripts/MANIFEST-000001 b/.tmp-edge-annexation/Default/Extension Scripts/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Extension State/000003.log b/.tmp-edge-annexation/Default/Extension State/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..9515a1233c9b39a54a8bae19101439309ec4adf2 GIT binary patch literal 513 acmX?+_RN%rfsv5`0ZxnxK?7qXgaiOs7(Xrm literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Extension State/CURRENT b/.tmp-edge-annexation/Default/Extension State/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension State/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension State/LOCK b/.tmp-edge-annexation/Default/Extension State/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Extension State/LOG b/.tmp-edge-annexation/Default/Extension State/LOG new file mode 100644 index 0000000..7348e8b --- /dev/null +++ b/.tmp-edge-annexation/Default/Extension State/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:01.289 2334 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension State since it was missing. +2026/09/16-15:38:01.378 2334 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Extension State/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Extension State/MANIFEST-000001 b/.tmp-edge-annexation/Default/Extension State/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Favicons b/.tmp-edge-annexation/Default/Favicons new file mode 100644 index 0000000000000000000000000000000000000000..56e14d600389e4756be4ef6cb988f8136191e2dc GIT binary patch literal 20480 zcmeI2PjAyO7{=qKtJ_UufHdV$O|mp98m+)4PN+ho+rk)xmX&s57ou#-SVuU;8upJr`L-{u4J&S{D$#{4H?5e ztdJizrF+Ba&*L#IwLomyr)PEAwcc1>Vw8uVg*2>}7CrPPrP|{Z=_Z1~0uLhemfNU? zkyvi!M6Qny3@%&b9=;>lb{Tv-MzvMp@Pe4!#A?}9$Cokek&gE$ce&y+H0s^cDXJ|k zkxx3e_iD}%@}Xj^=dF}mGmWcrP!aQ1GB%AOdsWcvZH)|bSwA3Do1Z7$2SJo|hueOR3`FJE zq~AHGBR#TmervmI3@i(FY}Y!D++4pKiD}t+q6FVJ@2DpBcFXSYW>B_#57vtRsfwQ* ze?M1dMONuIh5n*H#03ciKmY_l00cnbnh;2;YIZI-s_i%HEt|XI6lxtiZO?5s9?eA5 zS97V0r=1V7ykqRBnW^22!H?xfWV{>!2UleGYy>}00JNY0wB;Qfc?ME z0(T$)0w4eaATTKef*1UQHvuO_F?50e2!H?xfB*!3m00ck)`#;tI2!H?xfB*Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/GPUCache/data_1 b/.tmp-edge-annexation/Default/GPUCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/GPUCache/data_2 b/.tmp-edge-annexation/Default/GPUCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/GPUCache/data_3 b/.tmp-edge-annexation/Default/GPUCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/GPUCache/index b/.tmp-edge-annexation/Default/GPUCache/index new file mode 100644 index 0000000000000000000000000000000000000000..ea819f85537fe600ca0d5ad3b79bad2f0ad43ec9 GIT binary patch literal 262512 zcmeIup$&jA00h8qsu=={A#BPDtWigBOhpQ&10e6!fAZ?CyPiqSnDUNtBwy=upXP08 z>v+=%5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N J0t9{#cmU}O1p5F0 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/History b/.tmp-edge-annexation/Default/History new file mode 100644 index 0000000000000000000000000000000000000000..59f8d1943ac3734e6f76ceb081c85f09bb341f8f GIT binary patch literal 212992 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 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/HubApps Icons-journal b/.tmp-edge-annexation/Default/HubApps Icons-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/LOCK b/.tmp-edge-annexation/Default/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/LOG b/.tmp-edge-annexation/Default/LOG new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/000003.log b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/000003.log new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/CURRENT b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOCK b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOG b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOG new file mode 100644 index 0000000..00cd70f --- /dev/null +++ b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:01.629 21ac Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Local Extension Settings\jdiccldimpdaibmpdkjnbmckianbfold since it was missing. +2026/09/16-15:38:01.682 21ac Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Local Extension Settings\jdiccldimpdaibmpdkjnbmckianbfold/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/MANIFEST-000001 b/.tmp-edge-annexation/Default/Local Extension Settings/jdiccldimpdaibmpdkjnbmckianbfold/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Local Storage/leveldb/000003.log b/.tmp-edge-annexation/Default/Local Storage/leveldb/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..988af4977dd715e21e5842a55da64d286b7c1c5c GIT binary patch literal 30 ecmbOweaBRsfsv5`0zfn)dzfobu&2Ktqagr7=>$Ol literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Local Storage/leveldb/CURRENT b/.tmp-edge-annexation/Default/Local Storage/leveldb/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Local Storage/leveldb/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Local Storage/leveldb/LOCK b/.tmp-edge-annexation/Default/Local Storage/leveldb/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Local Storage/leveldb/LOG b/.tmp-edge-annexation/Default/Local Storage/leveldb/LOG new file mode 100644 index 0000000..4ebc52d --- /dev/null +++ b/.tmp-edge-annexation/Default/Local Storage/leveldb/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:00.940 3544 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Local Storage\leveldb since it was missing. +2026/09/16-15:38:00.964 3544 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Local Storage\leveldb/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Local Storage/leveldb/MANIFEST-000001 b/.tmp-edge-annexation/Default/Local Storage/leveldb/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Login Data b/.tmp-edge-annexation/Default/Login Data new file mode 100644 index 0000000000000000000000000000000000000000..49af46e50d5051f43c2190ecc67efca947e1dc06 GIT binary patch literal 51200 zcmeI5&u`o28OKFYCgUVd;-)TVWIH15sr3hcN;d)p2>?mFzSIy9@&c40}k56e-Dx4hhi8Um2Fg z_kG^?ecsReyg#S}Uq0BbyP;tFe$cie!CoM2=Wy8I?eDAV+Pr7WkUM_6Ylm*W^qZH<>W%rduGMRb`r3TEZFjj0?XV|* zxN?#DH>01H^xx}$)lc<*>EFDl4x?TW009sH0T2Lz0fE=mZROeLfSFg-b>%6?fXWSZ zO*!Kfpk7jMDE%`)`HK45Z0-aQ-T%{<{&;}^2!H?xfB*=bBLdO=KlcA~G~nne2!H?x zfB*;(0o?y13_t(`KmY_l;QSH5{r~wJbMzPlKmY_l00eOVj~D;}5C8!X0D<#I0Q>*> z8*}s+1V8`;KmY`=|04!K00ck)1VG^Y5x~FypT99jk3j$gKmY_lU{3!}Nh?1p=?D5h z)QbM2@*m2Nls_u3l>SaX&+~QfqGtT;j#6?-ckP}jGQKvUCGjSt%uM}!X(%7;exTM>~ zdx6J3tToqvT5Gb#)(&gz*6USfJ0az!WHr_w=j4selK!+@+4byW9zjd}t}@pd z2D>j>A|TDP;dFWAcKN3w@VVo;&Qa=Il^uvqR-o(ocB`+1Hn8aWQpOr;*`Rf8H;{eD z+{|fqzq$EAt@)6>Z#`tS-JPw?1_jFpR%55iVy>|oOTL>Kc(!4^SKF=cus5r$?LT%q z2Yk=-og>0bLhLDmXlycsZNKI2y8~on>ynXxT);)!cC*N&*ho@~C}R%;;RyHfpi;6u zw1dcoz1oHzP&qZ!`sn%Q%#(K8f*xcT=^3ygq@A@+`mlDsbD$CGk7Wv6!nzt&N@sq`& z4XqdY@miO-C;3XUWX$Xk8|4A{TU3 zmaG6db91Sz8EXq?ITf|QSE6^7_KH~bXHNaHbV2!|q<^UWsq*v6b@jL9i|R+p7us8; zN7}45t2p1jU1i!m3a{wKnyH-3$Du?kf}kyvQ)KWYwrFw+nT2P3HQ$enc+!piL@?=Y7)^NJ=4yJC?de3TFjdklm zdIBKFckgdRCx!LegZ0{m6?J99s$01fT2rlNGv4Vp8=E_uwR-(ww9rzbwNYi!#2TJd z=?v=cIZxjVY46!jmNwf46Y&8&@nJ2xCv`*}^uiG+!B)dg(K5RyXe4Q9e&ry>T|< z(k>RFYn(;S+jJz@3kjNj<8FA&^JkbWRI4mGJn`sElescD3%ZiGd*jYl`4d1$r^y4_ zwhMdie&DzH9v#1E^B$=M#0Q>(0kYEA=AOHd&00L7+0N?*l*?^)uAOHd& z00JN|0Ri0qPXGxfAOHd&00JN|WdyMQPuYN?J0Ji8AOHd&FaZI4|33jFn1BEXfB*=9 zz?2cd{y${{itc~_2!H?xfWQO<@csV;kYEA=AOHd&00L7+AiDq8)jyZC-)KjgTKQjP zt#XYn@d5!5_zno;;l({=8UF1I}khLcsBL`Y?l*Ppa`9(|lPo zer%kjTb$Ie68|wy-o36HhM}DDMC3GTJkEKgC}A3c-8R%I6F5=%nfC-;!U#Fy`f}(V_&y>4P u8U=^`C%Ixt=cDY{DH-Js)sX5$7stfJ{r`7hk%x;Q00JNY0wD053H%?tMXh-N literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Login Data For Account b/.tmp-edge-annexation/Default/Login Data For Account new file mode 100644 index 0000000000000000000000000000000000000000..49af46e50d5051f43c2190ecc67efca947e1dc06 GIT binary patch literal 51200 zcmeI5&u`o28OKFYCgUVd;-)TVWIH15sr3hcN;d)p2>?mFzSIy9@&c40}k56e-Dx4hhi8Um2Fg z_kG^?ecsReyg#S}Uq0BbyP;tFe$cie!CoM2=Wy8I?eDAV+Pr7WkUM_6Ylm*W^qZH<>W%rduGMRb`r3TEZFjj0?XV|* zxN?#DH>01H^xx}$)lc<*>EFDl4x?TW009sH0T2Lz0fE=mZROeLfSFg-b>%6?fXWSZ zO*!Kfpk7jMDE%`)`HK45Z0-aQ-T%{<{&;}^2!H?xfB*=bBLdO=KlcA~G~nne2!H?x zfB*;(0o?y13_t(`KmY_l;QSH5{r~wJbMzPlKmY_l00eOVj~D;}5C8!X0D<#I0Q>*> z8*}s+1V8`;KmY`=|04!K00ck)1VG^Y5x~FypT99jk3j$gKmY_lU{3!}Nh?1p=?D5h z)QbM2@*m2Nls_u3l>SaX&+~QfqGtT;j#6?-ckP}jGQKvUCGjSt%uM}!X(%7;exTM>~ zdx6J3tToqvT5Gb#)(&gz*6USfJ0az!WHr_w=j4selK!+@+4byW9zjd}t}@pd z2D>j>A|TDP;dFWAcKN3w@VVo;&Qa=Il^uvqR-o(ocB`+1Hn8aWQpOr;*`Rf8H;{eD z+{|fqzq$EAt@)6>Z#`tS-JPw?1_jFpR%55iVy>|oOTL>Kc(!4^SKF=cus5r$?LT%q z2Yk=-og>0bLhLDmXlycsZNKI2y8~on>ynXxT);)!cC*N&*ho@~C}R%;;RyHfpi;6u zw1dcoz1oHzP&qZ!`sn%Q%#(K8f*xcT=^3ygq@A@+`mlDsbD$CGk7Wv6!nzt&N@sq`& z4XqdY@miO-C;3XUWX$Xk8|4A{TU3 zmaG6db91Sz8EXq?ITf|QSE6^7_KH~bXHNaHbV2!|q<^UWsq*v6b@jL9i|R+p7us8; zN7}45t2p1jU1i!m3a{wKnyH-3$Du?kf}kyvQ)KWYwrFw+nT2P3HQ$enc+!piL@?=Y7)^NJ=4yJC?de3TFjdklm zdIBKFckgdRCx!LegZ0{m6?J99s$01fT2rlNGv4Vp8=E_uwR-(ww9rzbwNYi!#2TJd z=?v=cIZxjVY46!jmNwf46Y&8&@nJ2xCv`*}^uiG+!B)dg(K5RyXe4Q9e&ry>T|< z(k>RFYn(;S+jJz@3kjNj<8FA&^JkbWRI4mGJn`sElescD3%ZiGd*jYl`4d1$r^y4_ zwhMdie&DzH9v#1E^B$=M#0Q>(0kYEA=AOHd&00L7+0N?*l*?^)uAOHd& z00JN|0Ri0qPXGxfAOHd&00JN|WdyMQPuYN?J0Ji8AOHd&FaZI4|33jFn1BEXfB*=9 zz?2cd{y${{itc~_2!H?xfWQO<@csV;kYEA=AOHd&00L7+AiDq8)jyZC-)KjgTKQjP zt#XYn@d5!5_zno;;l({=8UF1I}khLcsBL`Y?l*Ppa`9(|lPo zer%kjTb$Ie68|wy-o36HhM}DDMC3GTJkEKgC}A3c-8R%I6F5=%nfC-;!U#Fy`f}(V_&y>4P u8U=^`C%Ixt=cDY{DH-Js)sX5$7stfJ{r`7hk%x;Q00JNY0wD053H%?tMXh-N literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Login Data For Account-journal b/.tmp-edge-annexation/Default/Login Data For Account-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Login Data-journal b/.tmp-edge-annexation/Default/Login Data-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Network/Cookies b/.tmp-edge-annexation/Default/Network/Cookies new file mode 100644 index 0000000000000000000000000000000000000000..ae50c91ac6bf43a29795e77ac8b32b9d47c99bd7 GIT binary patch literal 20480 zcmeI&Jx|*}7zc1W22xt6VL%zu;RHiLN?#~+DMJb1(x_=DX;Q&t8RsA_iEYkjN=7O% z(1EQVqGP{8w@Q`z6}oh-)U8XU-USCj?2M=q{4JT-_nPN-ms5P<^?K3alx%yfX>l^A zj47(BEE1w9N?M$Q;_MvqdZ2S7Ue&JaewS(G{>N{lBY%~F;bTSL(Z3HLk1X~pjC2S< z00Izz00ba#tptwdwR9$%RX;rC)>ebsp114JAbJ^CE*trZK`QyBqCuj>X`4}tJDzKX z+$M!m#aK1Uq_kEcrE0O5t9t=AcWH}Mj17_0N#>q!ZZoS%%|LwdODN!qyq-GyRwL|9 zqprk#%^W@%NM{~r)%UZGTcZcj)HFla*$b)Joi-TF;cBU{ zUNuBhE5=4=Dqkp1)=Hi9>CPn1k@&pLkv<{kh@8VYA}3*vTo{qFTR8$V`k&O>YqiKA z*#9K3t)?>*6YAlE_Tt{8Tue}Ir7kS%GG$sW*u}Nd>YIFd`FZ|)IVaJ_=2f}yGGE># zFO1C`IbC_XiqG6l4P_Q4RHgmF3-%gviMK-TweL;YgE=ezYQo`$v=|lVpnjz2zw{sa z7yXmC!~p>aKmY;|fB*y_009U<00Izzz-0(brnQ1@drh%n<%qrC_U@dyFLx%z=B^ty zwJnpA6+MJq@ zK9toK)IPfa+AS@sMtcCM+uGD{*A9UE{a^gkKMn{$00Izz00bZa0SG_<0uX=z1g@}v i{QV!#|5tc`5gG&_009U<00Izz00bZa0SG`q2>b)E2)W1r literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Network/Cookies-journal b/.tmp-edge-annexation/Default/Network/Cookies-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Network/Device Bound Sessions b/.tmp-edge-annexation/Default/Network/Device Bound Sessions new file mode 100644 index 0000000000000000000000000000000000000000..fbc96d784a5f3e361b0a09d46d5d30c7ca603ef5 GIT binary patch literal 20480 zcmeI&!D`zu7zc34O51IvQFjPA`0_zvYarPOJ?5}E#cX9>vbxS#PeN(k5@y$Ftd#E9 zhuC}cA$BPY_6$4hI@oQ;N!`yTR0$+F29hX4d1009U<00Izz z00bZa0SL?lj99C;TKvj4dYGlh!}3U#X<3enGi8R^V!yH*hd~lj5_F@G7O&DaeM~=5 z5`IXUG@cZupl;OfHtAiw_cn+R=}maJZD%wZFDk3`gBE9_v*Yx#JkRWwS?Q@MZu@HS zzN)=AvU0-L>a`lbdVU*ro*M0{_g{E!#66Cpe(%-$Al`i)#MJ92)Eh(*4SIX~gK$2y zCSB-kn$AyeJoQ%Vo!YWM-4j&X9o=63fivB(Rmd+){*>SC2?YWWfB*y_009U<00Izz z00bZafjcVT3(=98E{!@W^077}n;B6T>BMD4cGf-N%UNfWi>=3buE(l0+Dyw<`;lFf zkT*=;$Y1iu9bF*8f&c^{009U<00Izz00bZa0SG|guYfN)d`S*KtP7w2O96OQvGs5+ z1K_^@+n@eXAOHafKmY;|fB*y_009U<00I!W#{%yAKlcCk_yuEW5P$##AOHafKmY;| MfB*y_00ArT2MdRy!2kdN literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Network/Device Bound Sessions-journal b/.tmp-edge-annexation/Default/Network/Device Bound Sessions-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Network/Network Persistent State b/.tmp-edge-annexation/Default/Network/Network Persistent State new file mode 100644 index 0000000..ba768d8 --- /dev/null +++ b/.tmp-edge-annexation/Default/Network/Network Persistent State @@ -0,0 +1 @@ +{"net":{"http_server_properties":{"servers":[{"anonymization":["HAAAABUAAABodHRwczovL21pY3Jvc29mdC5jb20AAAA=",false,0],"server":"https://edge.microsoft.com","supports_spdy":true}],"version":5},"network_qualities":{"CAISABiAgICA+P////8B":"4G"}}} \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Network/NetworkDataMigrated b/.tmp-edge-annexation/Default/Network/NetworkDataMigrated new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Network/Reporting and NEL b/.tmp-edge-annexation/Default/Network/Reporting and NEL new file mode 100644 index 0000000000000000000000000000000000000000..a24d6edbd90d99f586402275577bd40b784cb1bf GIT binary patch literal 36864 zcmeI&O-~a+7zglOw)Dk{3kT9eFOv`=Bo$L@!hr);+#sPAsl~`?vTUdAgzfISv&+j3 zCB($L-^dGziJ!rPR}*huOq?xLO6Xz}qan?Ilc61Ey6pU(XQ%B9FE%SYV5I5#9Wx*$ zWl~X9j&IvQRXx}mpcJ%`EKZm*oO2< z%_!FmQZGNQ7$mkEnIpvEyQFTss*~!5EL)XIfe_c{E$&cZwONP7wYFUm#I;4&OV+A& zW7VkjpSXM3)G-H~l?%!p%MKfiig2glc1-SwLFZrx9`~7`p`b#(f>EhswFmXIO%YJj zvX~gA_f~anbITxemj++xSwy4#U5SQQAQyuvM2hqCo9SeZEvpK58tg#4w&iDNYKDOf zn5@&-D9~bTQ|7HVp30R<>Padl69(jfNd6)E;wHsC^zAEINGs=wvG2gzp^ z<9n<@xkt@LL*8TJN@Ol_{z}vE_oWEW?#ZTaS^;+*A}6a#|1{AwxgGk9#&#HbviQeS zK=-y^OeAybvvCR2A5vQEuZ=g=RBn1&eRIE?AsrUTc`-1@E@edYo4H+fNGcoE)tBYk z%G2`2j7rW^{&{WfS-G}N){X4~*)#2s^>?4YJC@8XO~+ke^cQF``l-n`)O7TwIw6au ze^m5u`WN|t0|F3$00bZa0SG_<0uX=z1Rwx`8!C|3v?aZ}{9(Br&kVR+NTz$t7jnVn zL3T{b>%GdPs?AJwI;KZOU`2Ih_0mjfE009U<00Izz00bZa0SG_<0#X3`|40J}KmY;|fB*y_009U< z00Izzz~~EL|9|vjj1fWr0uX=z1Rwwb2tWV=5P$##u>X%7fB*y_009U<00Izz00bZa i0SJt~0QUb!KgJj#1Rwwb2tWV=5P$##AOHafK;Rdq`(?lY literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Network/Reporting and NEL-journal b/.tmp-edge-annexation/Default/Network/Reporting and NEL-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Network/SCT Auditing Pending Reports b/.tmp-edge-annexation/Default/Network/SCT Auditing Pending Reports new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/.tmp-edge-annexation/Default/Network/SCT Auditing Pending Reports @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Network/Sdch Dictionaries b/.tmp-edge-annexation/Default/Network/Sdch Dictionaries new file mode 100644 index 0000000..8bca100 --- /dev/null +++ b/.tmp-edge-annexation/Default/Network/Sdch Dictionaries @@ -0,0 +1 @@ +{"SDCH":{"dictionaries":{},"version":2}} \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Network/Trust Tokens b/.tmp-edge-annexation/Default/Network/Trust Tokens new file mode 100644 index 0000000000000000000000000000000000000000..8d527ef9da45ba2c2d983219145c81ee19d5c422 GIT binary patch literal 36864 zcmeI&(QDH{9Ki9Uw>7O>mpLdA`f@PA4W=^pI3LVL(6QRNuG8&dggCPi);6_Chd%g_ zNB;o-BVPuBe}fOc3cmU1MOSIN74kUC_u!gb?!x8wxg(If?(J5C*q0|^x8=ohO`F$r zU3(&>rfE5qiz@fiv^tsU7t~Q7I3IVK(;j^KQZj#Oh1mnmJT<@0eJ~eFALs7Q9+a$c zH*p;S1Q0*~0R#|0009L4FM;H-VOU2;da@mRubY0{?M1O0hi85}a)T)9`CV1&H2rhG z>2|!J>mG;gli)OKyTWGOu^WzT*c(+xX1z-;$us}GY&Zvv71`;AaVR&cI~yzVMSbhJ zT|boD&f$`3vAo)#8mY^VhZ$*^9phC#Z=E@rEJpemiGQTlNEU=)*|wfMyc+Z6B)KNyp_-}j@eZ}i z9_`*#-a552MLX2PNUTG3(6LW$$?8t+=}Wu5`OL1%+D=2( z_N!I7U)$Q+}v}&8wFwe(M(QM%zj~B z7mK%BEwAH7u^0EE`>VH9Ov1d-%nS3U`Td3l$YUXZ00IagfB*srAbg9y>S3S#dJ=hx(sNYiuCkV!=)=P^|x;-{4llQ;291E*Cbmr^7#)me;M zC$;=6>na@|2Wx?lk&u#wGcB=hm#6AnE{bJ+u4q5e7f8j_Ku%f`nUM5f>vWKX)19wP zQ1tE0um_aK0S%ab-JTlanv9d=ogStaq~2dTLvIODMXsIXYwtIr$g$(={T zNjGLAj((=DnCGfwHp^y%1p*L&00bZa0SG_<0uX=z1Rwx`%PMfqbPVtRmvwm2F9<*Y z0uX=z1Rwwb2tWV=5P(1~VE+F*?ib7b>3-KcED(SI1Rwwb2tWV=5P$##AOHafTu6ai zj?*aTGX=Vdp2eYro@zjkd1hupJh*?O;H;D5gQ7zc34N?+E}sAGg2auJl!7P^jfY&+yqr&a-T(wN0bXDOvS z=0gnnfp#ej_8E5Ab+B8Hle48bhtg~5{sP&S6(`U0vo3y|w}*agl;{rAL>lpwtP)De zt`LL}YWtk+)8^QN!gOHw+5BydlI<_wR`?Yu6fX!r;oplFeEYVGFb@F;KmY;|fB*y_ z009U<00RGy!1xhcC|9d=92@zeuR1C~ zbua3va}j#)L-8iqf9(cG;=nuFI#y|vT_75Mt09`LP&C`Vzh%;qHj!4w#Dfz(JGuFy zFke2XQW6i2)w%xEw~x+|9GT%{Jo&b1kWnok%v_f)luIQ#elp1>QATFnnTb9-v++@V z7JjSw@|_#(y>f%=xJ0|Tf7teBG7x97KT`RRZ>~G@<$CF+0JC3+YT1_Am9&_xrWM;6 z|4R5T{=@FjAOHafKmY;|fB*y_009U<00I!WqXHGi>bx&)*`hN{PNj)$!6Z6Usg8$( z+Ooqcd^%XAZ0%u^$kRw0X-4{SZOP`u_$A?&{5Su3M-xO?5P$##AOHafKmY;|fB*y_ z009X66{xT}y`cucmRW`VD*-q~w)P-b0m$C}+duuIK>z{}fB*y_009U<00Izz00ba# kj|H;#|9Jkt$2Sz{}fB*y_009U<00Izz00gYSAIWg3p#T5? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/ServerCertificate-journal b/.tmp-edge-annexation/Default/ServerCertificate-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Service Worker/Database/000003.log b/.tmp-edge-annexation/Default/Service Worker/Database/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..0be0d7ab8760b0059e8cda45a6459de7f7b390ce GIT binary patch literal 1038 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 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Service Worker/ScriptCache/index b/.tmp-edge-annexation/Default/Service Worker/ScriptCache/index new file mode 100644 index 0000000000000000000000000000000000000000..79bd403ac665228853dd8fa54b8f4427af1721c0 GIT binary patch literal 24 TcmXqrDOxU_`}+?k11bOjQGf(4 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Service Worker/ScriptCache/index-dir/the-real-index b/.tmp-edge-annexation/Default/Service Worker/ScriptCache/index-dir/the-real-index new file mode 100644 index 0000000000000000000000000000000000000000..c5e637e4965c7004c0aec7c486a5b3abac9c6374 GIT binary patch literal 72 zcmZ=@U|?YRdhm39r9x3^NnR=^kk1IjU~roS#$wnOG5^?V-V-`sU?NbtfH~@hTD$Za E07a}19smFU literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Session Storage/000003.log b/.tmp-edge-annexation/Default/Session Storage/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..1780fb3196e2cb1dade7bf6693b88d3cef50e74f GIT binary patch literal 163 scmeylFH2jTfsv5`0zfn)ds%8xab|uVqv4w4ZhSlpj7(5j5Ji6>01Vj@fdBvi literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Session Storage/CURRENT b/.tmp-edge-annexation/Default/Session Storage/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Session Storage/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Session Storage/LOCK b/.tmp-edge-annexation/Default/Session Storage/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Session Storage/LOG b/.tmp-edge-annexation/Default/Session Storage/LOG new file mode 100644 index 0000000..014a05e --- /dev/null +++ b/.tmp-edge-annexation/Default/Session Storage/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:01.064 3544 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Session Storage since it was missing. +2026/09/16-15:38:01.133 3544 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Session Storage/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Session Storage/MANIFEST-000001 b/.tmp-edge-annexation/Default/Session Storage/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Sessions/Session_13434014282025592 b/.tmp-edge-annexation/Default/Sessions/Session_13434014282025592 new file mode 100644 index 0000000000000000000000000000000000000000..d4d807d8df18c293555607baa9408db13ca0c119 GIT binary patch literal 2131 zcmb_dy>HV{5Wlt%YG|PqAle0`h)5M`>e%_RGXPTC6;-M_F$6od)u?G4C25sP3`j7r z@lo+7AW>joM2G<-hW-z%42&Q#B9-4g`_jlX48XJAyU%xb@A-cA+O4&Z|e%~hPiblh;eTX7psbCXqc7xo_J9QYRKjM5TKB`9A6kH?rP%!e!tj28nu zvu_4u_80s9kLO?aZl~yFOlSDsF>*1DB%=9PzL(I8U8vM4^<9QRos(P&X`8xK0oNdh zn#3ng`pZ6{7JN8m4wDDVN8{TKkynqDij%ma9wtj3wx7VA;mE)VLm$-f&Xuo57bnp6t>TKnNh5Lzz=nvx| za%7Fx7!CYNKaQo|<5R%kU~vUAs5ktIuIoz`eZAwiJ9=g%pRtULW$Md*XR{l&^jdwV z-q4+9)9*Rmdf2SC!bZKeTWz&N*I(S|ZZ)Dr^a`U6ACQzzbi5#e)9}f~{whY$ z>zLk&_w^F{Td{nQ(8p!>iFBa6>8G%$JEA)J(+7@p^(-lFojTC9vFen8UmmN4Zs65~ zZW-1N5Z46?TaasrvZEsD3X4tHd*Hgzg}`PNULo?-;km1%He?rGi+zklr6%i?dWHTO z!Tsa@#zfG8KUo=6q;t zurrPs!!>A%LlNmCngKtK;KElh&Di987VKH94q`aq4Dg1^P{!BJRj3T0Lz_tH3X%UC zC*MD3`)EGE-3Xcm#YsAN-P1HB|2At08-l(MT$Bx1lzGytFCP&Zk0+5jEso# zFCg)2U_?v|4E-PY2N)Qr#E4YBdw!RuR>K0%dhhPOyLa#2(|sO18VssLbc2>&g%8~d z)UTwhyPp+Rs+HeYh!_S+*Dzf#J;-}r>?V5*(Np-Rn75&4kSiJ`x?Yl3jr{_08S}ZZ zMZ6Kk$d7Y2$BX~%uh-v?A1~88BUiXyjHZ!=MRdp5&q}!XMM|Ag-z_-wJ;|e#4k)J{ zw3u8?-m%^?uGe!WZb1S~#E2>HzIx<@~npC9aSF1*EhTCMy5JA@hAK*J~wdP=Fyp4yoNknhdivj{KuxHcq`@Z8zVKk>@5Rw^f1*PNC%#q2&^)Q3e^q^65xhW7r;|z)aln zi=o@6f1q2fL<^w{j?m8|{`ZDvAB=or_DxIsGh?5WaLzYBq)nwAUc#y06t|6W!yYO9 zZE9_YCcws671a^f!s?)9c(s9T!8-vhbG%Om+eel|ok?B#vcn56%a*+C+Kfm=wdFdc zUXg#N`TUJ9>XKK`vRxC$0x9RqKC%0VXWDi(o!Yql2qa|Mc0j^5P^PV|U#|gght@$S z)&ihD{7iNxx({T1A#DR>vk=D_Jj4p|nZSIW1AhaniySUA3%aFG=-`*=Y3hc+&?Zv4 ertSaa6+hkSx5kX}C$NR`f(zxv<~=ehboK|!!`c=A literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Shared Dictionary/cache/index b/.tmp-edge-annexation/Default/Shared Dictionary/cache/index new file mode 100644 index 0000000000000000000000000000000000000000..79bd403ac665228853dd8fa54b8f4427af1721c0 GIT binary patch literal 24 TcmXqrDOxU_`}+?k11bOjQGf(4 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Shared Dictionary/cache/index-dir/the-real-index b/.tmp-edge-annexation/Default/Shared Dictionary/cache/index-dir/the-real-index new file mode 100644 index 0000000000000000000000000000000000000000..c46ee3eba28c7fc2eab9783fd0d5fa4b7fe47aff GIT binary patch literal 48 ncmdO3U|_h+bn{Yvr9x3^NnR=^kdF=+fdUzO6b-d@=`#QT^0x?L literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Shared Dictionary/db b/.tmp-edge-annexation/Default/Shared Dictionary/db new file mode 100644 index 0000000000000000000000000000000000000000..85bff9e6fdecc32a6c4c758f73ee5bf411ae69d7 GIT binary patch literal 45056 zcmeI&&u`mg7{GBm&XP7+@laLe(8FG-s;Eg|47Oc*AsyDJ$dWBf$0`n%N!-R-VyCgQ zA840~0}^-6{0W?PJ~1H z8#>~|pN{QNe571cR8{#{2t`o}@>P|u#jz$&ii->RS52H>c3M#0|L&I!{V%0b`Bu?S z^QvqKUP1l{4EPP5I_I{1Q0*~0R;Z10$!zDyS=NP>#jF&UX1J@v}S=b zutIn2SaI3F?T4=K*;CgEs&~6)vuBFK_9x~Ov8=V|v_uhvi}g~?*j1m$k9J;6 zE(ugg1xmNeg;-P@{k3v!My!v>t`>o%s)=AdC)RNrtO|5c^mRhc@Pd?Ig{-<0X^Ol1UKKeR_yv=L-QI~N~pYudgZ?{W0~@kH(c$_*;(nKKRKX5g)ALEF|B7uQs6 z=k4*>o>)O>hqK_ln-!T+QGc!IKkI+$ul3*Gbb`c3009ILKmY**5I_I{1Q0*~fw{n@ zR#!8d0L5)>U%g}xK&xuo>U;~J@Rqi-p4b71zW_(0R#|0009ILKmY**5I_Kd)fZs>zxsVlh6o^l S00IagfB*srAbb)8&>%Vh literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Shared Dictionary/db-journal b/.tmp-edge-annexation/Default/Shared Dictionary/db-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Site Characteristics Database/000003.log b/.tmp-edge-annexation/Default/Site Characteristics Database/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..46580fb8f820d269031534af4743e7cbce94c9b0 GIT binary patch literal 40 mcmdn%pLa-+fsv5`0zfpQU`k?1Vp3vpYJ6^LNg{~DXb1qOuL*hp literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Site Characteristics Database/CURRENT b/.tmp-edge-annexation/Default/Site Characteristics Database/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Site Characteristics Database/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Site Characteristics Database/LOCK b/.tmp-edge-annexation/Default/Site Characteristics Database/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Site Characteristics Database/LOG b/.tmp-edge-annexation/Default/Site Characteristics Database/LOG new file mode 100644 index 0000000..318178c --- /dev/null +++ b/.tmp-edge-annexation/Default/Site Characteristics Database/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:00.814 dbc Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Site Characteristics Database since it was missing. +2026/09/16-15:38:00.872 dbc Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Site Characteristics Database/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Site Characteristics Database/MANIFEST-000001 b/.tmp-edge-annexation/Default/Site Characteristics Database/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/js/6f3a0dc5e6916f1e_0 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Code Cache/js/6f3a0dc5e6916f1e_0 new file mode 100644 index 0000000000000000000000000000000000000000..b2029f5891382877e9d257a35248ab920ab3a5bd GIT binary patch literal 309 zcmXqrDOxU_`}+?o0|P@N5PMJ5*aV~);3@{U@oNAY57#eEWYoD=N-v#8Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_1 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_2 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_3 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/index b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnGraphiteCache/index new file mode 100644 index 0000000000000000000000000000000000000000..ea2b5864069040d9b37ea9134d550a856dbb8936 GIT binary patch literal 262512 zcmeIup$&jA00h8qItmU$Sd|S}1J~eKf>lVtbO7YN`cGcndDWKGj4AIZd-AnDw|iRW zV;OHc0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly JK!Csx0uL;!1Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_1 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_2 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_3 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/index b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/DawnWebGPUCache/index new file mode 100644 index 0000000000000000000000000000000000000000..73685f683259f12b67ead90f12dca0c71d4cab6d GIT binary patch literal 262512 zcmeIup$&jA00h8qItmU$7?}z1xCX}z3_}X010e6!fAZ?itG1+OOnFDylCSl7@6$RT z%XrfX5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N J0t9{#cmPyG1?vC+ literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_0 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_0 new file mode 100644 index 0000000000000000000000000000000000000000..d76fb77e93ac8a536b5dbade616d63abd00626c5 GIT binary patch literal 8192 zcmeIuK?wjL5Jka{7-jo+5O1auw}mk8@B+*}b0s6M>Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_1 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_2 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_3 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/index b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/GPUCache/index new file mode 100644 index 0000000000000000000000000000000000000000..64a1f8ec069c3eee1a2238956cddd36b155ba500 GIT binary patch literal 262512 zcmeIup$&jA00h8qx(O0P7=;nhY*0sVOhpQ&10e6!fAZ?CyPiqSnDUOYCtvIH*rs)E z%XrfX5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N J0t9{#cmR4-1zP|B literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/000003.log b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..988af4977dd715e21e5842a55da64d286b7c1c5c GIT binary patch literal 30 ecmbOweaBRsfsv5`0zfn)dzfobu&2Ktqagr7=>$Ol literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/CURRENT b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOCK b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOG b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOG new file mode 100644 index 0000000..882994a --- /dev/null +++ b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:01.213 3bf0 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Storage\ext\ihmafllikibpmigkcoadcmckbfhibefp\def\Local Storage\leveldb since it was missing. +2026/09/16-15:38:01.327 3bf0 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Storage\ext\ihmafllikibpmigkcoadcmckbfhibefp\def\Local Storage\leveldb/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/MANIFEST-000001 b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Local Storage/leveldb/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions new file mode 100644 index 0000000000000000000000000000000000000000..fbc96d784a5f3e361b0a09d46d5d30c7ca603ef5 GIT binary patch literal 20480 zcmeI&!D`zu7zc34O51IvQFjPA`0_zvYarPOJ?5}E#cX9>vbxS#PeN(k5@y$Ftd#E9 zhuC}cA$BPY_6$4hI@oQ;N!`yTR0$+F29hX4d1009U<00Izz z00bZa0SL?lj99C;TKvj4dYGlh!}3U#X<3enGi8R^V!yH*hd~lj5_F@G7O&DaeM~=5 z5`IXUG@cZupl;OfHtAiw_cn+R=}maJZD%wZFDk3`gBE9_v*Yx#JkRWwS?Q@MZu@HS zzN)=AvU0-L>a`lbdVU*ro*M0{_g{E!#66Cpe(%-$Al`i)#MJ92)Eh(*4SIX~gK$2y zCSB-kn$AyeJoQ%Vo!YWM-4j&X9o=63fivB(Rmd+){*>SC2?YWWfB*y_009U<00Izz z00bZafjcVT3(=98E{!@W^077}n;B6T>BMD4cGf-N%UNfWi>=3buE(l0+Dyw<`;lFf zkT*=;$Y1iu9bF*8f&c^{009U<00Izz00bZa0SG|guYfN)d`S*KtP7w2O96OQvGs5+ z1K_^@+n@eXAOHafKmY;|fB*y_009U<00I!W#{%yAKlcCk_yuEW5P$##AOHafKmY;| MfB*y_00ArT2MdRy!2kdN literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions-journal b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Device Bound Sessions-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Network Persistent State b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Network Persistent State new file mode 100644 index 0000000..7ca9943 --- /dev/null +++ b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Network Persistent State @@ -0,0 +1 @@ +{"net":{"http_server_properties":{"servers":[],"version":5},"network_qualities":{"CAISABiAgICA+P////8B":"4G"}}} \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/NetworkDataMigrated b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/NetworkDataMigrated new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/SCT Auditing Pending Reports b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/SCT Auditing Pending Reports new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/SCT Auditing Pending Reports @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Trust Tokens b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Network/Trust Tokens new file mode 100644 index 0000000000000000000000000000000000000000..8d527ef9da45ba2c2d983219145c81ee19d5c422 GIT binary patch literal 36864 zcmeI&(QDH{9Ki9Uw>7O>mpLdA`f@PA4W=^pI3LVL(6QRNuG8&dggCPi);6_Chd%g_ zNB;o-BVPuBe}fOc3cmU1MOSIN74kUC_u!gb?!x8wxg(If?(J5C*q0|^x8=ohO`F$r zU3(&>rfE5qiz@fiv^tsU7t~Q7I3IVK(;j^KQZj#Oh1mnmJT<@0eJ~eFALs7Q9+a$c zH*p;S1Q0*~0R#|0009L4FM;H-VOU2;da@mRubY0{?M1O0hi85}a)T)9`CV1&H2rhG z>2|!J>mG;gli)OKyTWGOu^WzT*c(+xX1z-;$us}GY&Zvv71`;AaVR&cI~yzVMSbhJ zT|boD&f$`3vAo)#8mY^VhZ$*^9phC#Z=E@rEJpemiGQTlNEU=)*|wfMyc+Z6B)KNyp_-}j@eZ}i z9_`*#-a552MLX2PNUTG3(6LW$$?8t+=}Wu5`OL1%+D=2( z_N!I7U)$Q+}v}&8wFwe(M(QM%zj~B z7mK%BEwAH7u^0EE`>VH9Ov1d-%nS3U`Td3l$YUXZ00IagfB*srAbwGl7QlTidBrlZ{$VUf^Kmm0=6+^9E`V0Wha|Xiz literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db new file mode 100644 index 0000000000000000000000000000000000000000..85bff9e6fdecc32a6c4c758f73ee5bf411ae69d7 GIT binary patch literal 45056 zcmeI&&u`mg7{GBm&XP7+@laLe(8FG-s;Eg|47Oc*AsyDJ$dWBf$0`n%N!-R-VyCgQ zA840~0}^-6{0W?PJ~1H z8#>~|pN{QNe571cR8{#{2t`o}@>P|u#jz$&ii->RS52H>c3M#0|L&I!{V%0b`Bu?S z^QvqKUP1l{4EPP5I_I{1Q0*~0R;Z10$!zDyS=NP>#jF&UX1J@v}S=b zutIn2SaI3F?T4=K*;CgEs&~6)vuBFK_9x~Ov8=V|v_uhvi}g~?*j1m$k9J;6 zE(ugg1xmNeg;-P@{k3v!My!v>t`>o%s)=AdC)RNrtO|5c^mRhc@Pd?Ig{-<0X^Ol1UKKeR_yv=L-QI~N~pYudgZ?{W0~@kH(c$_*;(nKKRKX5g)ALEF|B7uQs6 z=k4*>o>)O>hqK_ln-!T+QGc!IKkI+$ul3*Gbb`c3009ILKmY**5I_I{1Q0*~fw{n@ zR#!8d0L5)>U%g}xK&xuo>U;~J@Rqi-p4b71zW_(0R#|0009ILKmY**5I_Kd)fZs>zxsVlh6o^l S00IagfB*srAbb)8&>%Vh literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db-journal b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/Shared Dictionary/db-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db new file mode 100644 index 0000000000000000000000000000000000000000..8ab056e341f8710293960742ee31589e19aadd0e GIT binary patch literal 32768 zcmeI&Pixa)90%~E>6+>OWFAVuULM%NmQ|(hxQp2gv#d+En#y(<56{|XBbYW>l9ufv zbnn57ugA+k@HKewCW3nLBKV|jq?>HUi;VJp;A!$CPo6x#PaX=-lf2liIT0sEUeI9? zS(TO~S(cs>B1uwKXid|u2TAqWjfQF1CaGG_%sujFJEU%rv~3kfw=V7Ea{9`OydSYcmxm{= zn5NK>pY*usz?GspzP)X%*GzKdWU-BogG^`1in*f5Wst;zUEDZB$%thxNySHsulO0M)ve8!Mq}f-(fAz_X-K7@* literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db-journal b/.tmp-edge-annexation/Default/Storage/ext/ihmafllikibpmigkcoadcmckbfhibefp/def/declarative_performance_observer.db-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Sync Data/LevelDB/000003.log b/.tmp-edge-annexation/Default/Sync Data/LevelDB/000003.log new file mode 100644 index 0000000000000000000000000000000000000000..80bdfdb745fd3b5b7915a588ec4c2e1cc68755e4 GIT binary patch literal 137 zcmWgS`<188z{tn|0U(-DEIzlSIKDVJBQ-ZMJ|(p{xhS)sB)^D>gK^DqH$EN)Mkc6g z5H+nmNJ|eP1U5jnJT)mkv7n$>H>E_^#WBRu$uZb9-q$t65yWBQVCP?{mIgG38Oa;~ DTkIKe literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Sync Data/LevelDB/CURRENT b/.tmp-edge-annexation/Default/Sync Data/LevelDB/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/Sync Data/LevelDB/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Sync Data/LevelDB/LOCK b/.tmp-edge-annexation/Default/Sync Data/LevelDB/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Sync Data/LevelDB/LOG b/.tmp-edge-annexation/Default/Sync Data/LevelDB/LOG new file mode 100644 index 0000000..f633f7e --- /dev/null +++ b/.tmp-edge-annexation/Default/Sync Data/LevelDB/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:00.789 3db8 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Sync Data\LevelDB since it was missing. +2026/09/16-15:38:00.829 3db8 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\Sync Data\LevelDB/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/Sync Data/LevelDB/MANIFEST-000001 b/.tmp-edge-annexation/Default/Sync Data/LevelDB/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Top Sites b/.tmp-edge-annexation/Default/Top Sites new file mode 100644 index 0000000000000000000000000000000000000000..37c0abd1c7f4605d49b5021e24ba8b27c86f1c3a GIT binary patch literal 20480 zcmeI&zi!h&90%|_pZkxhxiUl%WXPcov{FeF0SjI*l~p24LQ@CP$+{K?tlDviFAa=& z2%e)a!BPo{CtzS;MPg&*9EeGVsB0^}r~KkOpDq9Vv6uWVhX-z`0?|zdu~gzd*(8*b z$3hT7sE#Ea(`M+7IUVS2Hh)>8r26sm2LDCO!a3n@_?N;te{k7Jn1=uaAOHafKmY;| zfB*y_0D=ErU~I6JQl&!2he{qtflB&*s(-(xdB@yqJGSQt&wk=MBHz6|97Mu%UU{O~ z($R5U@uJ;$ZnuxbGv{bm&-w$|I~9$l=j=P}{HR?OswkL0bEj@Dmz)YEVefVDK7AMI z1bjJE$z<&3*YxXocd1KPO2r}_*CuJlfs$DmbIE3Vwoii(!fiG8U)t@xr}n=@M5oy} z=s0s(i!&JwgW1D(?i$M_tGFn&>Z{43EPGzdTd0uX=z1Rwwb2tWV=5P$##uA{&mYFewe-YV5kAJuB3 z(WshqyWvSt)&CQywI8Y)&uE*gOhBcO9Gn4BL@XSbYlgV1$9qNUCXB7Pmva)-gpS# z!-w#)iHXnP!K)i@9-Z!rsUb^DyllvKk{|8Nl=7QT=h7Jt4{Sg3WIvdW+(_Qnb~Ihr z9!jZcT1rJ$#j>Q;NgT_fFHhDSQ`+4RpL61;mdTxI;zWGOe-yWKXZgXJ@6d$+0tg_0 z00IagfB*srAn^YJ@3*q1W$BAsk^5@s%_n1Lm11^&7(baMXA)tWXu(1((9c#5M8yQ)%QqdR1KLdz@fj3U1pRA`>l27*jd+HC;8S}8RF7@Pn zFA`6-Z1wf5St#g>d*^8@b2pCEU+Kjyv6Qsitw+ymoyOx@N4DBs+3MN0?6vj}dd;M2 zSobkx?!YNK}Hid^3~FgGxw&UAB?T-lu;DR%8qXA-W-kGi4#U{Gz%-% z4K*f1oND4!{1D%+=m1Fz0R#|0009ILKmY**5I_I{1TF-MMpeIL4Zzqoiu&&*fK=Yt zy`ESBi1+{1pZ+NbAbk8~lJ78UhF)fB*srAb;N literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/Vpn Tokens-journal b/.tmp-edge-annexation/Default/Vpn Tokens-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/Web Data b/.tmp-edge-annexation/Default/Web Data new file mode 100644 index 0000000000000000000000000000000000000000..5c6063669cb2013a04290e807285e2cf603b30b9 GIT binary patch literal 241664 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 WfB*y_009U<00I!WX#%Pmi~kFaaz5Pv literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/WebStorage/QuotaManager-journal b/.tmp-edge-annexation/Default/WebStorage/QuotaManager-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/arbitration_service_config.json b/.tmp-edge-annexation/Default/arbitration_service_config.json new file mode 100644 index 0000000..34c6117 --- /dev/null +++ b/.tmp-edge-annexation/Default/arbitration_service_config.json @@ -0,0 +1,195 @@ +{ + "ArbitrationSignal": "notification_nsat_upper_ci-0.7", + "CustomSuppressionPolicies": { + "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.f5b8c725-cb2e-4c12-accd-73e500d88d47.AutoOpen": { + "notification_max_quick_dismiss_count": 3 + }, + "bc25fcef-8964-4e72-8287-23e2b496c128.68b8a884-6e08-46e6-8a3b-7e06ffe48ecf.AutoOpen": { + "notification_max_quick_dismiss_count": 3 + }, + "cd4688a9-e888-48ea-ad81-76193d56b1be.e06e75c1-a59a-4ab6-8361-e8b038e00a8c.AutoOpen": { + "notification_max_quick_dismiss_count": 1 + } + }, + "DynamicSuppressionBypass": { + "ExperienceIDs": [ "Nurturing.Global.OnRamp_RetriggerFREOnEdgeVersionUpgradeViaExplicitLaunch", "Nurturing.Global.OnRamp_RetriggerFREOnExplicitProtocolPDFLaunchForEdgePostDMA", "Nurturing.Global.Bing_DefaultBrowserBannerCloseBtn", "Nurturing.Global.Bing_DefaultBrowserBannerCloseBtnUpdate", "Nurturing.Global.Bing_MSStartYJCompete", "Nurturing.Global.Bing_NtpHomeStartpageUpsellFlyout", "Nurturing.Global.Fundamentals_DefaultBrowserMonitor", "Nurturing.Global.Fundamentals_DefaultBrowserMonitorOnStart", "Nurturing.Global.Fundamentals_DefaultBrowserMonitorVariant2", "Nurturing.Global.RecommendedSettingsChina", "Nurturing.Global.ContinuousImport_PasswordZeroStateV2", "Nurturing.Global.OnRamp_CIExplicitLaunchBannerUpsell", "Nurturing.Global.OnRamp_CIUpsell_ProtocolLaunch_Banner", "Nurturing.Global.EdgeGrowth_SitePinningCITopSites", "Nurturing.Global.EdgeGrowth_SitePinningWithWindowsConsent", "Nurturing.Global.EdgeGrowth_GlobalSitePinningOnCloseModal" ], + "TeamIDs": [ "NTP" ] + }, + "ExperienceCohorts": { + "DefaultCohort": { + "21f3388b-c2a5-4791-8f6e-a4cad6d17f4f.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.BingHomePage.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Covid.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Finance.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Jobs.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.KnowledgeCard.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Local.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.NTP3PCLICK.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.NotifySearchPage.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Recipe.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.SearchPage.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Sports.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Travel.Bubble": 1, + "2354565a-f412-4654-b89c-f92eaa9dbd20.Weather.Bubble": 1, + "2cb2db96-3bd0-403e-abe2-9269b3761041.AutoOpen": 1, + "2cb2db96-3bd0-403e-abe2-9269b3761041.Bubble": 1, + "439642fc-998d-4a64-8bb6-940ecaf6b60b.AutoOpen": 1, + "439642fc-998d-4a64-8bb6-940ecaf6b60b.Bubble": 1, + "523b5ef3-0b10-4154-8b62-10b2ebd00921.Bubble": 1, + "64be4f9b-3b81-4b6e-b354-0ba00d6ba485.AutoOpen": 1, + "64be4f9b-3b81-4b6e-b354-0ba00d6ba485.Bubble": 1, + "76b926d6-3738-46bf-82d7-2ab896ddf70b.MM2UpSellPopup.Bubble": 1, + "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.Bubble": 1, + "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.f5b8c725-cb2e-4c12-accd-73e500d88d47.AutoOpen": 1, + "8ac719c5-140b-4bf2-a0b7-c71617f1f377.3662f1e2-66ae-464f-b690-e7e3dc4fc662.AutoOpen": 1, + "8ac719c5-140b-4bf2-a0b7-c71617f1f377.93e5b5cd-15fc-4253-9728-d80685da304e.AutoOpen": 1, + "8ac719c5-140b-4bf2-a0b7-c71617f1f377.AutoOpen": 1, + "8ac719c5-140b-4bf2-a0b7-c71617f1f377.gaokao.Bubble": 1, + "92f1b743-e26b-433b-a1ec-912d1f0ad1fa.Bubble": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.0bdde3c3-7be8-49f1-971b-e6e2cfd62643.AutoOpen": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.128c39c6-6f70-4ce5-9d01-78978e60d666.AutoOpen": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.5ac63306-e962-42e6-8313-7e5a5b707d65.AutoOpen": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.AutoOpen": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.Bubble": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.Is1PGameDomain.Bubble": 1, + "96defd79-4015-4a32-bd09-794ff72183ef.Is3PGameDomain.Bubble": 1, + "9ce3c9c2-462f-4cc9-bbd7-57d656445be0.Bubble": 1, + "AUTOFILL_PASSWORD_NON_FUNCTIONAL_FLYOUTS": 1, + "DefaultExperience": 1, + "EdgeDownloadChromeInterceptDialog": 2, + "RewardsPromotionNotifications": 1, + "RewardsReminderNotifications": 1, + "SAN.Personalization.ConsentPrompt": 1, + "SHOPPING_AA_CONSENT": 1, + "SHOPPING_AUTO_PRODUCT_TRACKING_EXP_PRICE_DROP": 1, + "SHOPPING_AUTO_PRODUCT_TRACKING_IMP_PRICE_DROP": 1, + "SHOPPING_AUTO_PRODUCT_TRACKING_OUT_OF_STOCK": 1, + "SHOPPING_AUTO_SHOW_ABANDONED_CART": 1, + "SHOPPING_AUTO_SHOW_ADD_SPB_TO_CART_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_AMAZON_SEARCH_PC": 1, + "SHOPPING_AUTO_SHOW_ATTAINABLE_COUPONS": 1, + "SHOPPING_AUTO_SHOW_AUTOS_MARKETPLACE": 1, + "SHOPPING_AUTO_SHOW_AWARENESSEXP": 1, + "SHOPPING_AUTO_SHOW_AWARENESS_EXPANSION": 1, + "SHOPPING_AUTO_SHOW_CAMPAIGN_AWARENESS_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_CAMPAIGN_PDP_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_CASHBACK_PDP_PLUS_COUPONS": 1, + "SHOPPING_AUTO_SHOW_CJK_COUPON_FOUND": 1, + "SHOPPING_AUTO_SHOW_CJK_PRICE_DROP": 1, + "SHOPPING_AUTO_SHOW_CODEX_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_CONFIRMATION_SCRIPT": 1, + "SHOPPING_AUTO_SHOW_CONTROLLER": 1, + "SHOPPING_AUTO_SHOW_COUPONS_BACKGROUND_AUTO_APPLY": 1, + "SHOPPING_AUTO_SHOW_COUPONS_CHECKOUT": 1, + "SHOPPING_AUTO_SHOW_COUPONS_CHECKOUT_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_COUPONS_CLIPPING": 1, + "SHOPPING_AUTO_SHOW_DISCOVER_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_DISCOVER_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_EXPRESS_CHECKOUT": 1, + "SHOPPING_AUTO_SHOW_GIFT_CARD": 1, + "SHOPPING_AUTO_SHOW_GOODRX": 1, + "SHOPPING_AUTO_SHOW_GROCERY_ITEMIZED_CASHBACK": 1, + "SHOPPING_AUTO_SHOW_GROCERY_ITEMIZED_CASHBACK_LANDING": 1, + "SHOPPING_AUTO_SHOW_GUEST_DOMAIN_COUPONS": 1, + "SHOPPING_AUTO_SHOW_IBC_UPSELL": 1, + "SHOPPING_AUTO_SHOW_LOWER_PRICE_FOUND": 1, + "SHOPPING_AUTO_SHOW_LOWER_PRICE_PLUS_CASHBACK_PLUS_COUPONS": 1, + "SHOPPING_AUTO_SHOW_MOMENT_IN_TIME": 1, + "SHOPPING_AUTO_SHOW_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_ORGANIC_CASHBACK_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_OTHER_SELLER": 1, + "SHOPPING_AUTO_SHOW_OUT_OF_STOCK": 1, + "SHOPPING_AUTO_SHOW_PACKAGE_TRACKING": 1, + "SHOPPING_AUTO_SHOW_PACKAGE_TRACKING_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK_ADDRESSBAR": 1, + "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_POST_PURCHASE_TRACKING": 1, + "SHOPPING_AUTO_SHOW_PRICE_DROP_PLUS_CASHBACK": 1, + "SHOPPING_AUTO_SHOW_PRICE_DROP_PLUS_COUPONS": 1, + "SHOPPING_AUTO_SHOW_PRICE_HISTORY": 1, + "SHOPPING_AUTO_SHOW_PRICE_HISTORY_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_PRINT_GROCERY": 1, + "SHOPPING_AUTO_SHOW_PRODUCT_BEST_COUPON_CONSENT": 1, + "SHOPPING_AUTO_SHOW_PRODUCT_TRACKING_BACK_IN_STOCK": 1, + "SHOPPING_AUTO_SHOW_PRODUCT_TRACKING_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_PROFESSIONAL_REVIEWS": 1, + "SHOPPING_AUTO_SHOW_REBATES": 1, + "SHOPPING_AUTO_SHOW_REBATES_CHECKOUT": 1, + "SHOPPING_AUTO_SHOW_REBATES_ORGANIC": 1, + "SHOPPING_AUTO_SHOW_REBATES_ORGANIC_NEW": 1, + "SHOPPING_AUTO_SHOW_REBATES_PDP": 1, + "SHOPPING_AUTO_SHOW_RECOMMENDATIONS_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_SAN_CONSENT_CONFIRMATION": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_ALL_PAGES": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_CHECKOUT": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_CONFIRMATION_PAGE": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_HOME_PAGE": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_REWARDS": 1, + "SHOPPING_AUTO_SHOW_SHOPRUNNER": 1, + "SHOPPING_AUTO_SHOW_SIDEPANE_CASHBACK_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_SPB_CASHBACK_LANDING": 1, + "SHOPPING_AUTO_SHOW_SPB_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_SPB_NUDGE_MICRO_NOTIFICATION": 1, + "SHOPPING_AUTO_SHOW_SURFACE_UPSELL": 1, + "SHOPPING_AUTO_SHOW_SUSTAINABILITY_LANDING": 1, + "SHOPPING_AUTO_SHOW_TRAVEL_NOTIFICATION_CHEAPER_FLIGHTS": 1, + "SHOPPING_AUTO_SHOW_TRAVEL_NOTIFICATION_CHEAPER_HOTEL_ROOM": 1, + "SHOPPING_AUTO_SHOW_TRENDING_COUPONS": 1, + "ShorelinePrivilegedExperienceID": 1, + "TabActionsMenuVerticalTabsPromotion": 1, + "VPNFeatureNotification": 1, + "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.75a774c2-6075-ae4f-09f9-e5f5d9bef6e1.AutoOpen": 1, + "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.AutoOpen": 1, + "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.a5e9f5e1-fcee-c07b-2c44-b707ded020a3.AutoOpen": 1, + "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.c8ebbf64-e3b8-41d9-925f-4e3754151ff7.AutoOpen": 1, + "bc25fcef-8964-4e72-8287-23e2b496c128.68b8a884-6e08-46e6-8a3b-7e06ffe48ecf.AutoOpen": 1, + "bc25fcef-8964-4e72-8287-23e2b496c128.Bubble": 1, + "c8ebd871-9f47-4a0d-abd3-c1c02b4f8f53.2cfab14c-ebd6-4548-9401-30ab5afe5061.AutoOpen": 1, + "c8ebd871-9f47-4a0d-abd3-c1c02b4f8f53.AutoOpen": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.5b853177-a0be-4237-bda0-4fce5cd165c2.AutoOpen": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.8d3a928d-e911-40f0-9852-f63f6434dc7e.AutoOpen": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.AutoOpen": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.AutoOpen.PDF": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.AutoOpen.PersistentChat": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsCompeteAISite.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsCopilotJitEduAcademicAI.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsCopilotJitEduArticleAI.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsCopilotJitEduStudyAI.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsKnowledgeCardQuery.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsMsnArticleUrlFromNtpP1P2.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsShoppingNotificationNudge.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsTextPage.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsTopNewsDomain.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsTwitchNonStreamPage.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsTwitchSubPage.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.IsVideoPage.Bubble": 1, + "cd4688a9-e888-48ea-ad81-76193d56b1be.e06e75c1-a59a-4ab6-8361-e8b038e00a8c.AutoOpen": 1, + "e6723537-66ff-4f4e-ab56-a4cbaddf4e0f.MM2UpSellPopup.Bubble": 1 + } + }, + "FunctionalCohort": [ "EdgeDownloadChromeInterceptFunctionalDialog", "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.AutoOpen.Functional", "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.f5b8c725-cb2e-4c12-accd-73e500d88d47.AutoOpen.Functional", "bc25fcef-8964-4e72-8287-23e2b496c128.AutoOpen.Functional", "bc25fcef-8964-4e72-8287-23e2b496c128.68b8a884-6e08-46e6-8a3b-7e06ffe48ecf.AutoOpen.Functional", "WPOFunctionalEvent.AutofillAccountChooser.Bubble", "WPOFunctionalEvent.AutofillAutoSignin.Bubble", "WPOFunctionalEvent.AutofillPassword.Bubble", "SHOPPING_AUTO_SHOW_BING_SEARCH", "SHOPPING_AUTO_SHOW_REBATES_CONFIRMATION", "SHOPPING_AUTO_SHOW_REBATES_DEACTIVATED", "SHOPPING_AUTO_SHOW_REBATES_BING", "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK", "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK_CONFIRMATION", "SHOPPING_AUTO_SHOW_URL_PARAM_REBATES", "SHOPPING_AUTO_SHOW_URL_PARAM_PRICE_COMPARISON", "SHOPPING_AUTO_SHOW_URL_PARAM_PRICE_HISTORY", "SHOPPING_AUTO_SHOW_REBATES_ACTIVATION_FAILED", "SHOPPING_AUTO_SHOW_REBATES_SWITCHED_TO_MSA", "SHOPPING_AUTO_SHOW_ITEM_ADDED_TO_CART_FROM_OTHER_SELLER", "SHOPPING_AUTO_SHOW_VIRTUAL_CARD", "SHOPPING_AUTO_SHOW_BING_CAMPAIGN", "SHOPPING_OPEN_FLYOUT_FROM_EDGE_DRIVER", "SHOPPING_AUTO_SHOW_SUSTAINABILITY_PURCHASE", "SHOPPING_AUTO_SHOW_REWARDS_ACTIVATION_FAILED", "SHOPPING_AUTO_SHOW_REWARDS_SWITCHED_TO_MSA", "SHOPPING_AUTO_SHOW_SHOPRUNNER_CONFIRMATION", "SHOPPING_AUTO_SHOW_ENROLL_TO_CASHBACK_CONFIRMATION_NOTIFICATION", "SHOPPING_AUTO_SHOW_POST_PURCHASE_REWARDS_NOTIFICATION", "694efa4f-a304-4214-aaf7-90444bc887f5.c1c025d9-a620-4f6b-bebb-eff0cf19a671.AutoOpen.Functional" ], + "GlobalSuppressedExperiences": [ "Teams.Bubble", "Nurturing.Global.EdgeVpn_VpnFre", "Nurturing.Global.Rewards_RedemptionCoachmark_2", "Nurturing.Global.Rewards_RedemptionCoachmark_25", "Nurturing.Global.EdgeCBUD_SanPersonalizationConsentWave1Variant0", "Nurturing.Global.Bing_NewBingChatFlyout", "Copilot.AutoOpen.PDF.v2", "Nurturing.Global.PWA_SidebarSearchPromotion", "Nurturing.Global.FC_NetworkWarningFlyout", "Nurturing.Global.EdgeMobile_MobileUpsell_ChatGpt_Flyout", "E-tree.Bubble", "Nurturing.Global.EdgeEDU_BrowserFocusedTranslateNudge", "Games.Bubble", "Nurturing.Global.OnRamp_RetriggerFRECodexCoPilotAutoAprd", "Nurturing.Global.OnRamp_NurturingViaProng_Experiment", "Nurturing.Global.OnRamp_ReTriggerOnWinUpgrade", "Nurturing.Global.EdgeGrowth_CIShoppingUpsell", "Nurturing.Global.Shopping_EnableShoppingAssistance_Optin_Generic", "Nurturing.Global.Shopping_EnableShoppingAssistance", "Nurturing.Global.BrowserExperiences_TryVerticalTabs" ], + "IgnoredFunctionalNotifications": [ "Nurturing.Functional.NTP_CourtesyEngineCampaign", "Nurturing.Functional.NTP_FunctionalCampaign", "Nurturing.Functional.NTP_SettingsCampaign", "Nurturing.Functional.NTP_UpsellCampaign", "Nurturing.Functional.FN_SmartSwitchFeatureInfoView" ], + "ModelInfo": { + "segment_id": 515, + "signals": [ "notification_triggered_count", "notification_click_rate", "notification_click_rate_lower_ci", "notification_click_rate_upper_ci", "notification_dismiss_rate", "notification_dismiss_rate_lower_ci", "notification_dismiss_rate_upper_ci", "notification_ignored_rate", "notification_ignored_rate_lower_ci", "notification_ignored_rate_upper_ci", "notification_quick_dismiss_rate", "notification_quick_dismiss_rate_lower_ci", "notification_quick_dismiss_rate_upper_ci", "notification_disable_rate", "notification_disable_rate_lower_ci", "notification_disable_rate_upper_ci", "notification_snooze_rate", "notification_snooze_rate_lower_ci", "notification_snooze_rate_upper_ci" ], + "threshold_value": 0.5 + }, + "ModelSuppressionBypass": [ "Nurturing.Local.SHOPPING_AUTO_SHOW_LOWER_PRICE_FOUND", "Nurturing.Local.SHOPPING_AUTO_SHOW_REBATES_ORGANIC", "Nurturing.Local.SHOPPING_AUTO_SHOW_REBATES_CHECKOUT", "Nurturing.Local.SHOPPING_AUTO_SHOW_SPB_CASHBACK_LANDING" ], + "NotificationsAllowLists": { + }, + "PrivilegedExperiences": [ "ShorelinePrivilegedExperienceID", "SHOPPING_AUTO_SHOW_COUPONS_CHECKOUT", "SHOPPING_AUTO_SHOW_LOWER_PRICE_FOUND", "SHOPPING_AUTO_SHOW_REBATES", "SHOPPING_AUTO_SHOW_REBATES_ORGANIC", "SHOPPING_AUTO_SHOW_PRICE_HISTORY", "SHOPPING_AUTO_SHOW_REBATES_ORGANIC_NEW", "SHOPPING_AUTO_SHOW_REBATES_CHECKOUT", "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_CHECKOUT", "SHOPPING_AUTO_SHOW_EXPRESS_CHECKOUT", "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_ALL_PAGES", "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_CONFIRMATION_PAGE", "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_HOME_PAGE", "SHOPPING_AUTO_SHOW_SERVER_DRIVEN_REWARDS", "SHOPPING_AUTO_SHOW_COUPONS_CLIPPING", "SHOPPING_AUTO_SHOW_NOTIFICATION", "SHOPPING_AUTO_SHOW_OTHER_SELLER", "SHOPPING_AUTO_SHOW_PROFESSIONAL_REVIEWS", "SHOPPING_AUTO_SHOW_PACKAGE_TRACKING", "SHOPPING_AUTO_SHOW_GUEST_DOMAIN_COUPONS", "SHOPPING_AUTO_SHOW_SUSTAINABILITY_LANDING", "SHOPPING_AUTO_SHOW_ATTAINABLE_COUPONS", "SHOPPING_AUTO_SHOW_GIFT_CARD", "SHOPPING_AUTO_SHOW_PRINT_GROCERY", "SHOPPING_AUTO_SHOW_GROCERY_ITEMIZED_CASHBACK", "SHOPPING_AUTO_SHOW_CONTROLLER", "SHOPPING_AUTO_SHOW_AUTOS_MARKETPLACE", "SHOPPING_AUTO_SHOW_SHOPRUNNER", "SHOPPING_AUTO_SHOW_ABANDONED_CART", "SHOPPING_AUTO_SHOW_OUT_OF_STOCK", "SHOPPING_AUTO_SHOW_GROCERY_ITEMIZED_CASHBACK_LANDING", "SHOPPING_AUTO_SHOW_SPB_CASHBACK_LANDING", "SHOPPING_AUTO_SHOW_AWARENESSEXP", "SHOPPING_AA_CONSENT", "SHOPPING_AUTO_SHOW_SAN_CONSENT_CONFIRMATION", "SHOPPING_AUTO_SHOW_CONFIRMATION_SCRIPT", "SHOPPING_AUTO_SHOW_MOMENT_IN_TIME", "SHOPPING_AUTO_SHOW_COUPONS_CHECKOUT_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_TRENDING_COUPONS", "SHOPPING_AUTO_SHOW_RECOMMENDATIONS_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_PRODUCT_TRACKING_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_SURFACE_UPSELL", "SHOPPING_AUTO_SHOW_PRODUCT_TRACKING_BACK_IN_STOCK", "SHOPPING_AUTO_PRODUCT_TRACKING_EXP_PRICE_DROP", "SHOPPING_AUTO_PRODUCT_TRACKING_IMP_PRICE_DROP", "SHOPPING_AUTO_PRODUCT_TRACKING_OUT_OF_STOCK", "SHOPPING_AUTO_SHOW_CODEX_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_PRICE_HISTORY_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_ORGANIC_CASHBACK_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_GOODRX", "SHOPPING_AUTO_SHOW_SIDEPANE_CASHBACK_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_DISCOVER_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_REBATES_PDP", "SHOPPING_AUTO_SHOW_PRODUCT_BEST_COUPON_CONSENT", "SHOPPING_AUTO_SHOW_CAMPAIGN_PDP_NOTIFICATION", "SHOPPING_AUTO_SHOW_CAMPAIGN_AWARENESS_NOTIFICATION", "SHOPPING_AUTO_SHOW_SPB_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_PRICE_DROP_PLUS_COUPONS", "SHOPPING_AUTO_SHOW_SPB_NUDGE_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_ADD_SPB_TO_CART_MICRO_NOTIFICATION", "SHOPPING_AUTO_SHOW_CASHBACK_PDP_PLUS_COUPONS", "SHOPPING_AUTO_SHOW_PRICE_DROP_PLUS_CASHBACK", "SHOPPING_AUTO_SHOW_DISCOVER_NOTIFICATION", "SHOPPING_AUTO_SHOW_AMAZON_SEARCH_PC", "SHOPPING_AUTO_SHOW_COUPONS_BACKGROUND_AUTO_APPLY", "SHOPPING_AUTO_SHOW_PERSONALIZED_CASHBACK_ADDRESSBAR", "SHOPPING_AUTO_SHOW_TRAVEL_NOTIFICATION_CHEAPER_FLIGHTS", "SHOPPING_AUTO_SHOW_TRAVEL_NOTIFICATION_CHEAPER_HOTEL_ROOM", "SHOPPING_AUTO_SHOW_CJK_PRICE_DROP", "SHOPPING_AUTO_SHOW_CJK_COUPON_FOUND", "AUTOFILL_PASSWORD_NON_FUNCTIONAL_FLYOUTS", "76b926d6-3738-46bf-82d7-2ab896ddf70b.MM2UpSellPopup.Bubble", "e6723537-66ff-4f4e-ab56-a4cbaddf4e0f.MM2UpSellPopup.Bubble", "8ac719c5-140b-4bf2-a0b7-c71617f1f377.3662f1e2-66ae-464f-b690-e7e3dc4fc662.AutoOpen", "8ac719c5-140b-4bf2-a0b7-c71617f1f377.gaokao.Bubble", "c8ebd871-9f47-4a0d-abd3-c1c02b4f8f53.AutoOpen", "c8ebd871-9f47-4a0d-abd3-c1c02b4f8f53.2cfab14c-ebd6-4548-9401-30ab5afe5061.AutoOpen", "cd4688a9-e888-48ea-ad81-76193d56b1be.AutoOpen.PersistentChat", "cd4688a9-e888-48ea-ad81-76193d56b1be.AutoOpen.PDF", "cd4688a9-e888-48ea-ad81-76193d56b1be.8d3a928d-e911-40f0-9852-f63f6434dc7e.AutoOpen", "cd4688a9-e888-48ea-ad81-76193d56b1be.e06e75c1-a59a-4ab6-8361-e8b038e00a8c.AutoOpen", "cd4688a9-e888-48ea-ad81-76193d56b1be.5b853177-a0be-4237-bda0-4fce5cd165c2.AutoOpen", "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.AutoOpen", "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.c8ebbf64-e3b8-41d9-925f-4e3754151ff7.AutoOpen", "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.75a774c2-6075-ae4f-09f9-e5f5d9bef6e1.AutoOpen", "b7a8e9f2-6b0d-4c5b-ae7d-8a6e1f2c7a6f.a5e9f5e1-fcee-c07b-2c44-b707ded020a3.AutoOpen", "8682d0fa-50b3-4ece-aa5b-e0b33f9919e2.f5b8c725-cb2e-4c12-accd-73e500d88d47.AutoOpen", "bc25fcef-8964-4e72-8287-23e2b496c128.68b8a884-6e08-46e6-8a3b-7e06ffe48ecf.AutoOpen", "EdgeDownloadChromeInterceptDialog", "439642fc-998d-4a64-8bb6-940ecaf6b60b.AutoOpen", "694efa4f-a304-4214-aaf7-90444bc887f5.c1c025d9-a620-4f6b-bebb-eff0cf19a671.AutoOpen" ], + "ReserveApproved": { + "ExperienceIDs": [ "Nurturing.Global.Edge_SpawnNtpOptIn", "Nurturing.Global.Edge_SpawnNtpOptOut" ], + "SourceIDs": [ 3 ], + "TeamIDs": [ "Edge Consumer Content and Verticals" ] + }, + "ScenarioSuppressLists": { + }, + "SuppressedExperiences": [ ], + "TimeDelta": 5000000, + "baseConfigVersion": "41.0.0", + "configVersion": "41.0.0" +} diff --git a/.tmp-edge-annexation/Default/commerce_subscription_db/LOCK b/.tmp-edge-annexation/Default/commerce_subscription_db/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/commerce_subscription_db/LOG b/.tmp-edge-annexation/Default/commerce_subscription_db/LOG new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/declarative_performance_observer.db b/.tmp-edge-annexation/Default/declarative_performance_observer.db new file mode 100644 index 0000000000000000000000000000000000000000..8ab056e341f8710293960742ee31589e19aadd0e GIT binary patch literal 32768 zcmeI&Pixa)90%~E>6+>OWFAVuULM%NmQ|(hxQp2gv#d+En#y(<56{|XBbYW>l9ufv zbnn57ugA+k@HKewCW3nLBKV|jq?>HUi;VJp;A!$CPo6x#PaX=-lf2liIT0sEUeI9? zS(TO~S(cs>B1uwKXid|u2TAqWjfQF1CaGG_%sujFJEU%rv~3kfw=V7Ea{9`OydSYcmxm{= zn5NK>pY*usz?GspzP)X%*GzKdWU-BogG^`1in*f5Wst;zUEDZB$%thxNySHsulO0M)ve8!Mq}f-(fAz_X-K7@* literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/declarative_performance_observer.db-journal b/.tmp-edge-annexation/Default/declarative_performance_observer.db-journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/discount_infos_db/LOCK b/.tmp-edge-annexation/Default/discount_infos_db/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/discount_infos_db/LOG b/.tmp-edge-annexation/Default/discount_infos_db/LOG new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/discounts_db/LOCK b/.tmp-edge-annexation/Default/discounts_db/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/discounts_db/LOG b/.tmp-edge-annexation/Default/discounts_db/LOG new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/load_statistics.db b/.tmp-edge-annexation/Default/load_statistics.db new file mode 100644 index 0000000000000000000000000000000000000000..cc04c103cdf5416b37dcbcd114b399f735eadcdf GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYC*>h8Lt=fNV2HHI9bB nXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP#6LLQSS$G literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/load_statistics.db-shm b/.tmp-edge-annexation/Default/load_statistics.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..5e3f95ff187b233c797e2855b38600e7875003c4 GIT binary patch literal 32768 zcmeI*yG;W@5C-5i4?i#u6WJ-`)PTsSfQ$wpA#w?b0-y|9z@ilzpaCQ^gI0(X5t;dZ zX*8$RX>a!{U~cht)-t20L2I+)=+mf|)%@c6YWZ+}^L{(Je;S`$K7YL4J)SOp`F?Em zmE3pzBYpY1#kbp5)OJ)p@ASUg`!ISxV;lFiN$-2n^UOkk009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FoH=0)v<{F^qW<({|8~Htq1vOW;oeId4S>)D*}`LqedYK+e??0yPD4lAI8zDUfp$ zg+NV#oE9nsY6|SvytZ2t2!TTi1j-7`%HG_?3FIFLga82o1PBlyK!5-N0t5&UAV7cs U0RjXF5FkK+009C72>efhPxPQ9^#A|> literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/load_statistics.db-wal b/.tmp-edge-annexation/Default/load_statistics.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..026cdb0d329f0846e7662f682356ee21d0bbe197 GIT binary patch literal 70072 zcmeI*Z)h8J9LMn_mw!#xW`Z??Iyg3%4b2>-;s!(3+J&tyOS>%Hx(DO9CATdue`<0m z&M7nNkhuqf!lr_tvIn9lj;WwS+=Gd-F;Jfj_E2FyQIw%>Q(<_&EZ1JLOYIniwtF9R z$zAS}yH`oa{eGYC@3;1__lRTlPs<#Rr4F%dc>4DPzL!q;`!DB{&g~a(8JnEe?W3#o zNY){*+rBNH)irrsgh^+g=-HdlH z9=hppb)0u}oDY3rw-ehCKmY**5I_I{1Q0*~0R#}3g+R6J^o4tRoRiCSbx%&q71fMV z)>S=Q*0bqy)2eGQ85>B& z(pt;ym6CCcTHfEhzkYCBlZO(i*rr%AD(BR)u2jY|s&UI*-zX=BQ*vT79*@eSiJ@(y zF`JW!PJO)jF_Fj&}00 zEg-Iyc7etD8|SJJKmY**5I_I{1Q0*~0R#}37HFs=2rT_!jp&L zz`8!0Is(b8Bak|l)#?b02NnbnKmY**5I_I{1Q0*~fq5iQ?UsDuSdX)suLaYaV(3a) zQ%mXnirs7OdQyKVu`xE*oYZePP##V+zurBSm^Xv`(;0dZ$&cQd^p8+SaBp=4;-21Z z<^?vM@?5&|l=>=pfqC?0n+FG_0?NO#fy*^xNpWC6!-WZGcT~_%)k5Gou^lj7cjqyJR*Pq z0tg_000IagfB*srAh4(f8u9{bKY4TA8#nfPX2=VOb_AbAq*jMuS)WZ_z+>hGyh}Dr z4^I(5009ILKmY**5I|sI2ps9~_`-dC&dI^r9C0NrlPzg!-7-&{%_eWd zTyZu#blXn~m(h%w=L*IIbj3pRd~w;bGF^F|DW)rVt)SaX1!w6Jw|TWbQC!ofN9{g0 zYWs=3<^gulQ4A<^^7K{dN4GvyUBP zp2CIk2bi-&009ILKmY**5I_I{1Q0;r9tA|-zt3zJ_+{ti$6x7x;b-ay?opM)5kLR| z1Q0*~0R#|0009ILSQr8gbp&Suj<-*~|L1cv)Deh$f!}gzqORa>=PC4>bp*cPdku92 z#wrT}2q1s}0tg_000Icu3sgIOzVOyQXLW6DAUd1qdBY5FHm~~|Mx?XZq2Ue0uyi*2 zGza`6)DdVCT23)57pNmhmzk$96*ay)^>+b$G7U6w{$K>$O{;quy*7B$*I_w@sjN*fM!3foET2YiP3m`mL0Z?JE$>F zVe!71r%>GEx0!i?-51BMzw_zox5x|3hyRE;2Lup6009ILKmY**5I_I{1m;|zAuljF za_V8}kCRtt$P0+NgP`TCM1J6I^8$V|FAxYEy(2FWI2!oX^8P$U009ILKmY**5V%hS z_O|)Lot@6=n%Z1L%~dq(?vY0V-thX)R&&USPf&Wrzd`Z>tuhQvUFnQ3kYjv-Tv5$fCZ=S3 zfdw|cKrI?z<^=+W{yx6qde>`Wo`Mf$_YsaaSSN9s1B>Mh? zX1l;Z_}o{=CU)!=jRjKZf+KVxbS-pso?bYog#ZEwAbO!Gds!23Mk2jO_Fhw?R*2EBs+?vsS!ly zsXyl3KuHc1Nn>M(q|h94Lx`mFAC`QeBsYqri6ul* zi?dh~D9M8&3AK~4_xHsmKuKN{NvLZXJ>4&=110%TB%yXPF5P)+El`plMH1>-Mn;RP On}L!7sFDx|F#-VgFEi2r literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/Default/shared_proto_db/metadata/CURRENT b/.tmp-edge-annexation/Default/shared_proto_db/metadata/CURRENT new file mode 100644 index 0000000..7ed683d --- /dev/null +++ b/.tmp-edge-annexation/Default/shared_proto_db/metadata/CURRENT @@ -0,0 +1 @@ +MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/shared_proto_db/metadata/LOCK b/.tmp-edge-annexation/Default/shared_proto_db/metadata/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/Default/shared_proto_db/metadata/LOG b/.tmp-edge-annexation/Default/shared_proto_db/metadata/LOG new file mode 100644 index 0000000..53ac895 --- /dev/null +++ b/.tmp-edge-annexation/Default/shared_proto_db/metadata/LOG @@ -0,0 +1,2 @@ +2026/09/16-15:38:01.073 1660 Creating DB C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\shared_proto_db\metadata since it was missing. +2026/09/16-15:38:01.084 1660 Reusing MANIFEST C:\Users\あ\Desktop\civil\.tmp-edge-annexation\Default\shared_proto_db\metadata/MANIFEST-000001 diff --git a/.tmp-edge-annexation/Default/shared_proto_db/metadata/MANIFEST-000001 b/.tmp-edge-annexation/Default/shared_proto_db/metadata/MANIFEST-000001 new file mode 100644 index 0000000000000000000000000000000000000000..18e5cab72c1550d8dc398e3413eea91bee24db77 GIT binary patch literal 41 wcmbPQv-7AD10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei0J`GZPB~05;AINdN!< literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/FirstLaunchAfterInstallation b/.tmp-edge-annexation/FirstLaunchAfterInstallation new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db b/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db-wal b/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.db-wal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.journal b/.tmp-edge-annexation/GPUPersistentCache/DawnGraphiteCache/SWT6YJYIIFC43O4TK6OMZG5XCE3O73F5/cache.journal new file mode 100644 index 0000000..e69de29 diff --git a/.tmp-edge-annexation/GrShaderCache/data_0 b/.tmp-edge-annexation/GrShaderCache/data_0 new file mode 100644 index 0000000000000000000000000000000000000000..d76fb77e93ac8a536b5dbade616d63abd00626c5 GIT binary patch literal 8192 zcmeIuK?wjL5Jka{7-jo+5O1auw}mk8@B+*}b0s6M>Kg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/GrShaderCache/data_1 b/.tmp-edge-annexation/GrShaderCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/GrShaderCache/data_2 b/.tmp-edge-annexation/GrShaderCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/GrShaderCache/data_3 b/.tmp-edge-annexation/GrShaderCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/GrShaderCache/index b/.tmp-edge-annexation/GrShaderCache/index new file mode 100644 index 0000000000000000000000000000000000000000..423acaf6735056efa7b40558d87e8d4d37f48b87 GIT binary patch literal 262512 zcmeIuAr62r00Y1-dkY3bcrunJ;1(Q`7mg9y>S3S#dJ=hx(sNYiuCkV!=)=P^|x;-{4llQ;291E*Cbmr^7#)me;M zC$;=6>na@|2Wx?lk&u#wGcB=hm#6AnE{bJ+u4q5e7f8j_Ku%f`nUM5f>vWKX)19wP zQ1tE0um_aK0S%ab-JTlanv9d=ogStaq~2dTLvIODMXsIXYwtIr$g$(={T zNjGLAj((=DnCGfwHp^y%1p*L&00bZa0SG_<0uX=z1Rwx`%PMfqbPVtRmvwm2F9<*Y z0uX=z1Rwwb2tWV=5P(1~VE+F*?ib7b>3-KcED(SI1Rwwb2tWV=5P$##AOHafTu6ai zj?*aTGX=Vdp2eYro@zjkd1hupJh*?O;H;DKg$91PBlyK!5-N0t5&UAV7cs W0RjXF5FkK+009C72oNCfo4^Gh&;oe? literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/ShaderCache/data_1 b/.tmp-edge-annexation/ShaderCache/data_1 new file mode 100644 index 0000000000000000000000000000000000000000..dcaafa9740ee97afbdf50792612ef9f379e292dc GIT binary patch literal 270336 zcmeI%I}Lz93;@sqCjk%O-vMDm1rl%oM}vSHZXtOc`bnA&Z|#1REn zIz@m00RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PJ_E F-~kAc1(N^( literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/ShaderCache/data_2 b/.tmp-edge-annexation/ShaderCache/data_2 new file mode 100644 index 0000000000000000000000000000000000000000..c7e2eb9adcfb2d3313ec85f5c28cedda950a3f9b GIT binary patch literal 8192 zcmeIu!3h8`2n0b1_TQ7_m#U&=2(t%Qz}%M=ae7_Oi2wlt1PBlyK!5-N0t5&UAV7cs V0RjXF5FkK+009C72oTsN@Bv`}0$Tt8 literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/ShaderCache/data_3 b/.tmp-edge-annexation/ShaderCache/data_3 new file mode 100644 index 0000000000000000000000000000000000000000..5eec97358cf550862fd343fc9a73c159d4c0ab10 GIT binary patch literal 8192 zcmeIuK@9*P5CpLeAOQbv2)|PW$RO!FMnHFsm9+HS=9>r*AV7cs0RjXF5FkK+009C7 W2oNAZfB*pk1PBlyK!5;&-vkZ-dID$w literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/ShaderCache/index b/.tmp-edge-annexation/ShaderCache/index new file mode 100644 index 0000000000000000000000000000000000000000..dafa2018d2e3329983446fcf1a37cd82ba2921bb GIT binary patch literal 262512 zcmeIuAr62r00Y1-le`0iA!uI9H|7YASCN6)1CUqMCRKOc^-OBUly{UP`C6a*G;d2= z$D2-o009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U IAn=3018X@1r~m)} literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings b/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings new file mode 100644 index 0000000..997f02d --- /dev/null +++ b/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings @@ -0,0 +1 @@ +customSettings_F95BA787499AB4FA9EFFF472CE383A14 \ No newline at end of file diff --git a/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings_F95BA787499AB4FA9EFFF472CE383A14 b/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings_F95BA787499AB4FA9EFFF472CE383A14 new file mode 100644 index 0000000..ae2fefa --- /dev/null +++ b/.tmp-edge-annexation/SmartScreen/RemoteData/customSettings_F95BA787499AB4FA9EFFF472CE383A14 @@ -0,0 +1 @@ +{"forceServiceDetermination":false} \ No newline at end of file diff --git a/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings b/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings new file mode 100644 index 0000000..a89ca1f --- /dev/null +++ b/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings @@ -0,0 +1 @@ +edgeSettings_2.0-0 \ No newline at end of file diff --git a/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings_2.0-0 b/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings_2.0-0 new file mode 100644 index 0000000..3db8ccb --- /dev/null +++ b/.tmp-edge-annexation/SmartScreen/RemoteData/edgeSettings_2.0-0 @@ -0,0 +1 @@ +{"models":[],"geoidMaps":{"gw_my":"https://malaysia.smartscreen.microsoft.com/","gw_tw":"https://taiwan.smartscreen.microsoft.com/","gw_at":"https://austria.smartscreen.microsoft.com/","gw_es":"https://spain.smartscreen.microsoft.com/","gw_pl":"https://poland.smartscreen.microsoft.com/","gw_se":"https://sweden.smartscreen.microsoft.com/","gw_kr":"https://southkorea.smartscreen.microsoft.com/","gw_br":"https://brazil.smartscreen.microsoft.com/","au":"https://australia.smartscreen.microsoft.com/","dk":"https://denmark.smartscreen.microsoft.com/","gw_sg":"https://singapore.smartscreen.microsoft.com/","gw_fr":"https://france.smartscreen.microsoft.com/","gw_ca":"https://canada.smartscreen.microsoft.com/","gw_il":"https://israel.smartscreen.microsoft.com/","gw_au":"https://australia.smartscreen.microsoft.com/","gw_ffl4mod":"https://unitedstates4.ss.wd.microsoft.us/","gw_ffl4":"https://unitedstates1.ss.wd.microsoft.us/","gw_eu":"https://europe.smartscreen.microsoft.com/","gw_gr":"https://greece.smartscreen.microsoft.com/","gw_de":"https://germany.smartscreen.microsoft.com/","br":"https://brazil.smartscreen.microsoft.com/","gw_uk":"https://unitedkingdom.smartscreen.microsoft.com/","gw_it":"https://italy.smartscreen.microsoft.com/","gw_us":"https://unitedstates.smartscreen.microsoft.com/","il":"https://israel.smartscreen.microsoft.com/","es":"https://spain.smartscreen.microsoft.com/","ch":"https://switzerland.smartscreen.microsoft.com/","at":"https://austria.smartscreen.microsoft.com/","jp":"https://japan.smartscreen.microsoft.com/","kr":"https://southkorea.smartscreen.microsoft.com/","nz":"https://newzealand.smartscreen.microsoft.com/","gw_cl":"https://chile.smartscreen.microsoft.com/","pl":"https://poland.smartscreen.microsoft.com/","eu":"https://europe.smartscreen.microsoft.com/","de":"https://germany.smartscreen.microsoft.com/","gw_no":"https://norway.smartscreen.microsoft.com/","ffl4mod":"https://unitedstates4.ss.wd.microsoft.us/","gw_jp":"https://japan.smartscreen.microsoft.com/","mx":"https://mexico.smartscreen.microsoft.com/","gw_ffl5":"https://unitedstates2.ss.wd.microsoft.us/","se":"https://sweden.smartscreen.microsoft.com/","gw_ch":"https://switzerland.smartscreen.microsoft.com/","gw_ae":"https://uae.smartscreen.microsoft.com/","my":"https://malaysia.smartscreen.microsoft.com/","gw_nz":"https://newzealand.smartscreen.microsoft.com/","ca":"https://canada.smartscreen.microsoft.com/","fr":"https://france.smartscreen.microsoft.com/","gw_mx":"https://mexico.smartscreen.microsoft.com/","no":"https://norway.smartscreen.microsoft.com/","gr":"https://greece.smartscreen.microsoft.com/","gw_qa":"https://qatar.smartscreen.microsoft.com/","gw_in":"https://india.smartscreen.microsoft.com/","in":"https://india.smartscreen.microsoft.com/","tw":"https://taiwan.smartscreen.microsoft.com/","sg":"https://singapore.smartscreen.microsoft.com/","ffl5":"https://unitedstates2.ss.wd.microsoft.us/","ae":"https://uae.smartscreen.microsoft.com/","gw_dk":"https://denmark.smartscreen.microsoft.com/","gw_za":"https://southafrica.smartscreen.microsoft.com/","uk":"https://unitedkingdom.smartscreen.microsoft.com/","cl":"https://chile.smartscreen.microsoft.com/","us":"https://unitedstates.smartscreen.microsoft.com/","qa":"https://qatar.smartscreen.microsoft.com/","za":"https://southafrica.smartscreen.microsoft.com/","ffl4":"https://unitedstates1.ss.wd.microsoft.us/","it":"https://italy.smartscreen.microsoft.com/"},"sampleBuckets":{"evaluateModel":1.0,"error":1.0,"uriLookup":0.01,"userAction":1.0,"topTrafficHit":0.00007}} \ No newline at end of file diff --git a/.tmp-edge-annexation/Variations b/.tmp-edge-annexation/Variations new file mode 100644 index 0000000..18056c3 --- /dev/null +++ b/.tmp-edge-annexation/Variations @@ -0,0 +1 @@ +{"user_experience_metrics.stability.exited_cleanly":true,"variations_crash_streak":0} \ No newline at end of file diff --git a/.tmp-edge-annexation/VariationsRuntimeSeedV2 b/.tmp-edge-annexation/VariationsRuntimeSeedV2 new file mode 100644 index 0000000000000000000000000000000000000000..02d4f7526a0a51dc9a152baaa2422c96bdd79676 GIT binary patch literal 19 acmdPcs{dDkE0BSKi$RD%f@wJ-f(qy#k?0Ol-|Jupq&22evB3>1Br5y651h{1)6!B$|4mQh4yNVHBu zg-tKWVW3+9b5eo+KZPa~T51w|L&;CPK_A#y4;_F2fdGa8pJkk(b+uq@tJxWIHrICT z-58sl-0re?^A4!!28R(bZ^MZMOBCv|fV+4nov@0xKeF1EYoZnN6OkA2^A55G`3 z=3)7T0V4(kGos}0WVv=5>@*IhEse$@_sThL;+mj12a|zTso)X3@~vic{;d82hd$b3YgprqS;}@TMaIF!YxHBb zlOMD1?~5Ow@nZ@ABr=kaA}L8giD-%hC@c~Il|>>zb_k&XfdLU8IAp*8!b2m#h64Z! zd_FEEN=ng_6h_jEPf`je6}|W<1?QYEJ}HW*15WZy(GkUIMi^02d>0sB6sZ}h7vD7L zL_r##l+Qt_!!g15=A)*=A*YO#MjEN~r1&K2n32vWAEl9$9)y}?TBvauB192VXiSnM zNz(x!LgE-aZV?bQMn!=HVv?4oF}PFWsJ|Vz#URC_kbznOIH9q_%p1WHM79W0PIf60 z&{t7s8o(5#ETKyx{2-12Ixril4KGJQf_@wQS(;<2Q-y`f*zcc!Ey)GlYYwrl`p*mc z`JyOgg$)|lX`>GcA^V$3HYu6aQU2R|(aUTX7$4CD#q4UKR=X%fD@^q8T;UGJYWd literal 0 HcmV?d00001 diff --git a/.tmp-edge-annexation/en-US-10-1.bdic b/.tmp-edge-annexation/en-US-10-1.bdic new file mode 100644 index 0000000000000000000000000000000000000000..a45335846664b9a5fd6fc65f85c548ec0d9e04cf GIT binary patch literal 451968 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∾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 literal 0 HcmV?d00001 diff --git a/MODIFICATION_NOTES.md b/MODIFICATION_NOTES.md new file mode 100644 index 0000000..062a9b6 --- /dev/null +++ b/MODIFICATION_NOTES.md @@ -0,0 +1,321 @@ +# 文明シミュレータ 改修記録 + +## 目的 + +ユーザー指定の操作系・反乱・交易路・戦争損害・地形計算の変更を、既存シミュレーションの構造を維持したまま追加する。 + +## 実装した変更 + +- 「1週進める」ボタンを削除。 +- 初期人口スライダーを削除。初期人口は標準値 50,000 に固定。 +- 「再生成」を押すとダイアログを開き、その時点で世界サイズ(128 / 160 / 220 / 280)を選択する方式に変更。 +- 反乱ロジックを変更。 + - 忠誠度 30% 未満の都市が1つでもあれば反乱を自動発生。 + - 反乱が発生した場合、首都を除く忠誠度 50% 未満の全都市が同時に同一反乱勢力へ参加。 + - 30〜50%の範囲では従来のランダム性を残しつつ、忠誠度・不安定度・国家年齢から年次発生確率を算出。 +- 「災害発生」「都市建設」「交通接続」の3ボタンを追加。 + - 災害発生: 地図上の指定地点を中心に即時発生。 + - 都市建設: 地図上のクリック地点へ都市を即時建設。ユーザー建設都市は都市間隔・自動都市数上限を無視するが、水域には建設できない。 + - 交通接続: 都市を2つ順にクリックして交易路を作成。 +- ユーザー作成交易路に内部保護期間を追加し、期間終了後は通常管理へ戻るよう変更。 +- 戦争による都市人口損失と戦場タイル人口損失を従来の約 65% に軽減。 + - 戦争発生頻度・勝敗・占領判定そのものは変更していない。 +- 水域の肥沃度を計算対象外にし、常に 0 とするよう変更。 +- 既存コードの堅牢性修正。 + - `getCityById` / `getPolityById` がキャッシュ未初期化のテスト・部分実行でも動作するよう修正。 + - 完全に囲まれた小さな中立穴を領土平滑化で埋められるよう修正。 + +## 追加修正(連続介入・ヘルプ) + +- 災害発生・都市建設・交通接続が、1回成功するたびに解除されていた挙動を修正。選択した介入は同じボタンを再度押すまで継続する。 +- 交通接続は1本作成後、同じモードのまま次の1つ目の都市選択へ戻る。 +- ヘルプを現行仕様に合わせて更新し、説明量を圧縮。 +- 交通接続完了メッセージから保護期間に関する説明を削除。 + +## 追加修正(砂漠交易路・手動都市民族・征服後反乱) + +- 砂漠横断交易路の成立条件を改善。 + - 交易路経路探索では砂漠の移動コストを通常移動より軽く評価し、隊商路として横断しやすくした。 + - 都市間の直線上に砂漠が多い場合、交易路の有効距離上限を段階的に拡張する。 + - 砂漠を多く通る経路では、新規交易路に必要なフェロモン閾値と建設コストを緩和する。 + - 水域は従来どおり交易路不可。山地の高コストも維持。 +- ユーザー建設都市の民族構成を修正。 + - 建設地点の民族構成を優先して継承。 + - 地点に民族が存在しない場合は最寄りの民族構成を継承。 + - 世界内に参照可能な民族がない場合も、新しい現地民族を生成して民族構成が空にならないようにした。 +- 征服された都市に20年間の反乱猶予期間を追加。 + - 戦争占領、国境戦争、軍事併合、講和による都市移譲、遊牧民征服を対象とする。 + - 猶予期間中は忠誠度が30%未満でも反乱を自動発生せず、他都市の反乱にも参加しない。 + - 猶予終了後は通常の反乱判定へ戻る。 + +## 追加修正(国家ツールチップ・制度老朽化・制度改革) + +- 国家領土または国家所属都市にカーソルを合わせた際、ツールチップに「国家データ」を表示。 + - 国力、人口、都市数、国庫、正統性 / 結束、制度老朽化、忠誠度上限を表示する。 +- 国家に `institutionalAging`(制度老朽化度、0~1)を追加。 + - 国家成立後、年次更新ごとに徐々に増加する。 + - 忠誠度上限を `1 - institutionalAging` とし、首都を含む所属都市の忠誠度はこの上限を超えない。 +- 「制度改革」イベントを追加。 + - 老朽化度が30%を超えてから発生候補となり、老朽化が高いほど年次発生確率が上昇する。 + - 発生時は現在の老朽化度に対して -50%~+30% の相対変化をランダムに適用する。改革が逆効果になる場合もある。 + - 同一国家での連続発生を抑えるため8年間のクールダウンを設ける。 + - 国家興亡グラフへ専用の「制度改革」マーカーを記録し、老朽化度の変化前後と変化率を表示する。 + - 国家履歴サンプルにも制度老朽化度と忠誠度上限を保存する。 + +## 追加整理(不要処理・ツールチップ・回帰試験) + +- 都市ツールチップを「都市データ」と「国家データ」に分離し、民族構成の割合表示を都市データ内へ移動。 +- 国家人口表示は既存の `totalPolityPopulation()` を利用し、ツールチップ独自の人口集計を廃止。 +- 未参照の設定値11個を `config.js` から削除。 + - 人口: `softCapStart`, `hardCapScale`, `pressurePenaltyBase`, `pressureReproductionPenalty` + - 都市: `agingRestoreMinWear`, `agingRestoreCostPerWear`, `agingRestoreBudgetShare` + - 技術: `cityDiffusion` + - 文化: `spreadRadius`, `cityWeight`, `routeWeight` +- 未参照の描画/共通ヘルパー6個を削除。 +- 未参照または明示的に停止済みだったSimulationメソッド12個と、それ専用だった文化スクラッチ状態を削除。 + - 特に先頭で `return` していた旧 `expandPolities()` / `absorbIndependentCities()` を完全削除。 + - 旧地域文化更新・旧収容力単発計算・旧都市老朽化補助など、現行処理と責務が重複したコードを除去。 +- `annexation_policy_probe.html` を削除。内容は `tests/simulation.test.cjs` のNode回帰試験へ統合し、ブラウザ専用の古いモックを廃止。 +- 静的棚卸しで、`SimConfig` の未参照leaf設定値と明白な未参照関数/メソッドが0件であることを確認。 +- 制度改革の発生開始を「制度老朽化30%超」に変更。30%ちょうどでは発生しない。 + + +## 追加修正(ヘルプ・国庫上限・性能) + +- ヘルプに主要パラメータの短い説明を追加。 + - 人口 / 人口圧力、資源 / 肥沃度、農業 / 冶金、交通量、忠誠度、国庫、正統性 / 結束、制度老朽化、国力を対象とする。 +- 国家国庫に人口比例の動的上限を追加。 + - 上限は `国家人口 × 0.30`。人口増減に応じて毎年再評価する。 + - 国家ツールチップは重複表示を避けるため国庫残高のみを1行で表示する。動的上限は内部会計ロジックとヘルプで説明する。 + - 反乱時は、反乱人口比に応じて旧国家の国庫の一部を反乱国へ移す。移転額は `旧国庫 × 反乱人口比 × 0.65`。 + - 反乱後は旧国家・反乱国家とも、それぞれの新しい人口に応じた国庫上限へ収める。 +- 計算負荷をプロファイルし、結果を変えない範囲を優先して軽量化。 + - 世界生成の湿度計算を、各タイル半径10の総当たり探索から2パスのマンハッタン距離変換へ変更。旧方式との比較で浮動小数点誤差範囲まで一致することを確認。 + - 沿岸肥沃度補正は49マスの矩形走査から、実際に寄与するマンハッタン距離3以内のオフセットだけを走査する方式へ変更。 + - 人口収容力のうち、地形・肥沃度・鉱物由来の静的成分を初期化時にキャッシュ。年次処理で不要な全マップ再計算も削減し、人口だけが変わる段階では収容力の再計算をせず、圧力更新に限定。 + +## 追加修正(表示整理・都市間隔・追加軽量化) + +- 国家ツールチップの国庫表示を1行へ統一し、同じ国庫情報が二重に見える表示を解消。 +- 国家興亡グラフに「出来事アイコン」切替を追加。制度改革を含むイベントマーカーと凡例をまとめて表示 / 非表示にできる。 +- 自然生成都市の既存都市からの必要距離を従来のおおむね半分へ縮小。 + - 自然生成の最小都市間隔は `6`、競合評価半径は `9` とする。 +- ユーザー建設都市は通常の都市間隔・自動都市数上限制限を無視する。 + - ただし水域への建設は禁止し、陸地の指定座標へ直接建設する。 +- 追加プロファイルに基づき、通常進行をさらに軽量化。 + - 毎週相当で全世界を走査していた世界フィールド処理を月次へ集約。 + - 交易フェロモンは全タイル走査をやめ、値が存在するタイルと隣接域だけを疎更新。 + - 資源再生は四半期ごとにまとめ、年間再生量を維持。 + - 人口収容力は必要な変化時と年次処理に限定して再計算。 + - 民族統計の毎週更新を廃止し、履歴記録・年次処理で必要な時だけ更新。 + - 旧互換用で実利用されていなかった人口 `pressure` 配列と更新処理を削除。 + - 年次更新で重複呼び出しされていた国家危機判定を1回へ整理し、負荷とイベント判定回数の重複を解消。 + +## 追加修正(都市数上限・手動都市の水域制限) + +- 自動生成都市数の上限を `300` から `1200` へ引き上げ。 + - 自然発生都市・遠征による前哨都市など、自動生成側の共通上限として適用する。 + - ユーザー建設都市はこの自動上限を引き続き無視する。 +- ユーザー建設都市の水域建設を禁止。 + - 水域をクリックした場合は都市を生成せず、陸地を選択するようUIへ案内する。 + - 都市間隔制限は引き続き無視できるため、陸地上では既存都市の隣接地点にも建設可能。 + +## v9: 自然都市数の成長停滞を修正 + +### 原因 + +自然都市の創設判定が20年に1回で、1000年までは1回につき最大1都市に固定されていた。最大280×280マップでも創設流量が面積に比例せず、都市上限を1200へ増やしても約60都市前後で成長が鈍化しやすかった。 + +### 変更 + +- 自然都市の創設判定周期を20年から5年へ短縮。 +- 1回の創設可能数を世界面積に応じて増加。160×160で1、220×220で2、280×280で4都市まで。 +- 人口・定住性・資源・地形・既存都市との距離・創設確率は従来どおり判定し、無条件生成にはしない。 +- 面積スケーリングは `naturalCityFoundingLimit()` に集約し、設定値から調整できるようにした。 + +最大280×280では、同じ期間あたりの理論上の自然都市創設流量は旧仕様の最大16倍になる。実際の都市数は候補地、人口、都市消滅、戦争などで変動する。 + + +## v10: 都市人口・都市アイコン・民族動態の調整 + +- 再生成ダイアログから不要になった初期人口固定の案内を削除。 +- 新規都市の初期人口を自然生成・ユーザー建設ともに400へ統一。 +- 都市は人口200未満で消滅する。200ちょうどは存続可能。 +- 都市アイコンを人口帯で4段階に固定。 + - 200–999: 最小 + - 1000–3999: 中 + - 4000–5999: 大 + - 6000以上: 最大 +- 民族の新規分化速度を従来の1/4へ低下。分化判定間隔を4倍にし、分化条件そのものは維持する。 +- 総人口30未満の極小民族は年次処理で周辺民族へ吸収する。 + - 同一地点・隣接地点・同一都市で接触している民族を優先する。 + - 周辺に候補がない場合は親系統、さらに最寄りの存続民族へ統合する。 + - タイル人口、都市民族構成、遊牧集団の所属を移し替えるため、吸収によって総人口は減らない。 +- 旧仕様の「都市人口を populationScale に合わせて10倍化する」ことだけを確認していた回帰試験を削除し、現行仕様を直接検査する試験へ置換。 + +## v11: 都市表示・制度改革クールダウン・国庫都市建設 + +- 都市アイコンの人口帯を変更。 + - 200–999: 最小 + - 1000–4999: 中 + - 5000–9999: 大 + - 10000以上: 最大 +- 制度改革の再発クールダウンを50年へ変更。制度老朽化30%超という発生開始条件は維持する。 +- 国庫が人口比例上限に達した国家は、年次14%の確率で都市建設を試みる。 + - 建設成功時は、その時点の国庫上限の35%を消費する。 + - 建設候補は自国領土内の陸地に限定し、自然都市と同じ最小都市間隔を維持する。 + - 候補探索は全世界走査ではなく既存都市の周辺領土に限定し、国家数増加時の追加負荷を抑える。 + - 新都市は人口400で成立し、周辺の民族構成を継承する。 +- ヘルプの国庫・制度老朽化説明を新仕様へ同期。 + +## 主な設定値 + +`config.js` で変更可能。 + +- `SimConfig.world.initialPopulation`: 50000 +- `SimConfig.world.defaultSize`: 160 +- `SimConfig.city.maxCities`: 1200 +- `SimConfig.city.initialPopulation`: 400 +- `SimConfig.city.abandonmentPopulation`: 200 +- `SimConfig.city.naturalFoundingMinDistance`: 6 +- `SimConfig.city.naturalFoundingStartYears`: 160 +- `SimConfig.city.naturalFoundingIntervalYears`: 5 +- `SimConfig.city.naturalFoundingReferenceArea`: 25600 +- `SimConfig.city.naturalFoundingMaxPerCycle`: 8 +- `SimConfig.city.foundingCompetitionRadius`: 9 +- `SimConfig.culture.divergenceRateMultiplier`: 0.25 +- `SimConfig.culture.absorptionPopulationThreshold`: 30 +- `SimConfig.rebellion.participationLoyalty`: 0.50 +- `SimConfig.rebellion.automaticLoyalty`: 0.30 +- `SimConfig.rebellion.conquestGraceYears`: 20 +- `SimConfig.rebellion.treasuryTransferRate`: 0.65 +- `SimConfig.route.manualProtectionYears`: 25 +- `SimConfig.route.manualRouteMaxLength`: 120 +- `SimConfig.route.desertTraversalCostFactor`: 0.68 +- `SimConfig.route.desertRouteLengthBonus`: 30 +- `SimConfig.route.desertAdaptiveMaxRouteLength`: 96 +- `SimConfig.war.damageMultiplier`: 0.65 +- `SimConfig.polity.institutionalAgingAnnualIncrease`: 0.0015 +- `SimConfig.polity.institutionalReformThreshold`: 0.30 +- `SimConfig.polity.institutionalReformBaseChance`: 0.008 +- `SimConfig.polity.institutionalReformChanceScale`: 0.10 +- `SimConfig.polity.institutionalReformMaxChance`: 0.12 +- `SimConfig.polity.institutionalReformCooldownYears`: 50 +- `SimConfig.polity.institutionalReformMinChange`: -0.50 +- `SimConfig.polity.institutionalReformMaxChange`: 0.30 +- `SimConfig.polity.treasuryCapPerPopulation`: 0.30 +- `SimConfig.polity.treasuryCityFoundingChance`: 0.14 +- `SimConfig.polity.treasuryCityFoundingCostRatio`: 0.35 +- `SimConfig.polity.treasuryCityFoundingSearchRadius`: 20 + +## 検査結果 + +### 構文検査 + +`config.js`, `app-state.js`, `engine.js`, `render.js`, `boot.js` を `node --check` で確認し、構文エラーなし。 + +### 自動テスト + +実行コマンド: + +```bash +node --test tests/simulation.test.cjs tests/modifications.test.cjs +``` + +結果: **48 / 48 PASS**。 + +追加テストでは以下を個別確認した。 + +- 1週進行・初期人口スライダーがUIから削除されていること。 +- 再生成ダイアログと3種の介入ボタンが存在すること。 +- 水域肥沃度が全て0であること。 +- 忠誠度30%未満による自動反乱と50%未満都市の同時参加。 +- 手動都市建設。 +- 手動交易路の保護期間と保護終了。 +- 戦争人口損害が約65%へ軽減されていること。 +- 手動災害が履歴へ記録されること。 +- 砂漠横断交易路の距離上限・通行コスト・建設コストが緩和されること。 +- ユーザー建設都市に必ず民族構成が設定されること。 +- 征服都市が20年間反乱から保護され、期間終了後に通常判定へ戻ること。 +- 他都市で反乱が発生しても、征服保護中の都市が参加しないこと。 +- 制度老朽化が年次で増加し、同じ割合だけ忠誠度上限が低下すること。 +- 制度改革が老朽化度を -50%~+30% の範囲で相対変化させ、国家履歴イベントへ記録すること。 +- 国家ツールチップに制度老朽化・忠誠度上限を含む国家データが存在すること。 +- 国家興亡グラフに制度改革イベント種別と説明が存在すること。 +- 制度改革が30%ちょうどでは発生せず、30%超でのみ候補になること。 +- 都市の民族構成割合が「都市データ」内かつ「国家データ」より前に表示されること。 +- 旧ブラウザ併合試験をNode回帰試験へ統合し、平和併合/武力併合/他国所属都市拒否を確認すること。 +- ヘルプに主要パラメータの簡単な説明が存在すること。 +- 国庫上限が国家人口に比例し、人口減少時も上限へ収まること。 +- 反乱人口比に応じて国庫の一部が反乱国へ移転すること。 +- 国家ツールチップの国庫表示が1回だけであること。 +- 国家興亡グラフの出来事アイコンを表示 / 非表示に切り替えられること。 +- 自然生成都市の最小間隔が縮小されていること。 +- ユーザー建設都市が都市間隔・自動都市数上限を無視でき、水域では拒否されること。 +- 疎フェロモン更新が減衰・伝播を維持し、不要な全世界走査を行わないこと。 +- 自然都市の創設周期が5年となり、世界面積に応じて1回あたりの創設可能数が増えること。 +- 新規都市が人口400で成立し、199では消滅、200では存続すること。 +- 都市アイコンが指定された4つの人口帯で切り替わること。 +- 民族分化の時間スケールが1/4になり、総人口30未満の民族が隣接民族へ人口を失わず統合されること。 +- 再生成ダイアログに旧「初期人口は標準値で固定」案内が残っていないこと。 +- 都市アイコンが1000/5000/10000の新しい境界で切り替わること。 +- 制度改革が前回改革から50年間再発せず、50年経過後に再び候補になること。 +- 国庫が上限未満では都市を建設せず、上限到達時は確率判定後に上限の35%を都市建設へ投資すること。 +- 国家都市建設の投資額が大きいほど、初期人口と初期備蓄が単調に増えること。 +- 国家都市建設の候補地が広い適地群から加重抽選され、特定地点へ固定されないこと。 +- 都市老朽化のパラメータ・収容力ペナルティ・経年摩耗処理が残っていないこと。 +- 人口が過去ピークから落ちた都市ほど、食料余力がある場合に回復成長率が上がること。 + +### 長期スモークテスト + +280×280 / 初期人口50,000で180年進行し、例外なし。終了時は都市16、最小都市人口442、民族9、総人口30未満の存続民族0を確認した。都市創設は160年以降に始まるため、この試験は主に新しい消滅閾値と民族吸収処理の長期整合性確認を目的とする。 + +### 簡易性能計測 + +同一実行環境・固定乱数シードでの参考値。ブラウザ・CPUにより変動する。 + +| 計測 | v6 | v7 | 変化 | +| --- | ---: | ---: | ---: | +| 160×160 / 初期人口50,000 / 240週(通常状態) | 約 1.93 秒 | 約 0.19 秒 | 約 90%短縮 | +| 160×160 / 240週(交易フェロモン120地点を事前投入) | 約 1.91 秒 | 約 0.51 秒 | 約 73%短縮 | +| 160×160 初期化 | 約 0.66 秒 | 約 0.65 秒 | ほぼ同等 | + +今回の追加軽量化では、`updateWorldFields()` を毎週の全タイル走査から月次・疎更新へ変更した。交易フェロモンは値が存在するタイルと隣接域のみ更新し、資源再生は年間総量を維持したまま四半期単位へ集約した。人口収容力は毎回の全再計算を避け、必要な月次変化時と年次処理に限定した。民族統計も履歴記録・年次処理に必要な時点だけ更新する。 + +現状の残存コストは主に `updateCities()` と `updatePopulationCapacity()`、四半期の `regenerateResources()`。これ以上の更新頻度低下は都市成立・人口圧力・資源変動の時間解像度を変えるため、今回は行っていない。 + +### v11 追加スモーク / 性能確認 + +- 160×160 / 初期人口50,000で220年進行し、例外なし。終了時の都市人口に非有限値・負値なし。 +- 160×160 / 240週の参考計測は初期化約0.68秒、進行約0.19秒で、v7以降の軽量化水準を維持。 +- 国庫都市建設の候補探索は国庫上限到達・確率判定通過時のみ行い、通常年次では追加の全マップ走査を行わない。 + + +## v12 追加修正(都市建設分散・投資規模・長期人口) + +- 国庫都市建設の投資額を初期状態へ反映。 + - 初期人口は標準400人を下限に、投資額に比例して増加する。 + - 初期備蓄も投資額と増加した初期人口に比例して増加する。 + - 現在の係数は `treasuryCityPopulationPerCost = 0.18`、`treasuryCityReservePerCost = 0.45`。 +- 都市建設候補の偏りを緩和。 + - 自然都市は最上位付近の適地をランダム化して順位付けする。 + - 国家による国庫都市建設は、最高点から6.0点以内の適地を固定件数で切らず、候補全体から適性加重抽選する。 + - 適地評価そのもの(肥沃度、資源、人口圧力、農地、統制、交易、移動コスト)は維持する。 +- **都市老朽化を削除**。 + - `ageWear`、経年摩耗更新、老朽化による収容力低下、関連設定値を削除した。 + - 国家の「制度老朽化」は別概念なので維持する。 +- 長期都市人口の一方向減少を抑制。 + - 災害・戦争などで過去ピーク人口から落ちた都市に回復成長を付与する。 + - 回復中のみ必要備蓄・供給ストレス条件を緩めるが、人口は都市収容力を超えて増えない。 + - `postShockRecoveryGrowth = 0.045`、過剰収容時の減衰率は `overCapacityAttrition = 0.020`。 + +### v12 長期確認 + +固定乱数・32×32・初期人口8,000で500年進行した参考値: + +- 200年: 7都市 / 都市人口3,306 +- 300年: 23都市 / 都市人口14,478 +- 400年: 23都市 / 都市人口13,646 +- 500年: 28都市 / 都市人口18,545 + +短期的な減少は災害・戦争により残るが、都市老朽化による恒久的な下押しはなく、被害後に再成長できることを確認した。 diff --git a/README.md b/README.md index e69de29..148f52d 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,11 @@ +# 文明シミュレータ + +`index.html` をブラウザで開いて実行する文明シミュレータです。 + +今回の改修内容、設定値、検査結果は `MODIFICATION_NOTES.md` を参照してください。 + +テスト: + +```bash +node --test tests/simulation.test.cjs tests/modifications.test.cjs +``` diff --git a/annexation_policy_probe.html b/annexation_policy_probe.html new file mode 100644 index 0000000..14a7c59 --- /dev/null +++ b/annexation_policy_probe.html @@ -0,0 +1,70 @@ + + +annexation policy probe +

    RUNNING
    + + + + diff --git a/app-state.js b/app-state.js index 81f9eb7..5000340 100644 --- a/app-state.js +++ b/app-state.js @@ -1,10 +1,12 @@ const elementIds = [ -"world", "toggleRun", "stepOnce", "resetWorld", -"speed", "agentCount", "worldSize", "viewMode", "year", "activeGroups", "urbanPopulation", +"world", "toggleRun", "resetWorld", +"speed", "worldSize", "viewMode", "year", "activeGroups", "urbanPopulation", "ethnicities", "cities", "polities", "wars", "routes", "farmingKnowledge", "metallurgyKnowledge", -"deaths", "frameCost", "ethnicityList", "legend", "tooltip", "stateGraph", "historyRange", -"historyFilter", "historySort", "historyMetric", "toggleActiveStates", "togglePastStates", -"stateGraphInfo", "stateGraphTooltip" +"deaths", "frameCost", "ethnicityList", "fpsCounter", "legend", "tooltip", "worldTrendGraph", "stateGraph", "historyRange", +"currentDate", "historyFilter", "historySort", "historyMetric", "toggleActiveStates", "togglePastStates", "toggleEventIcons", +"stateGraphInfo", "stateGraphTooltip", "eventLegend", +"regenerateDialog", "confirmRegenerate", "cancelRegenerate", +"triggerDisaster", "buildCity", "connectCities", "interventionStatus" ]; const els = Object.fromEntries(elementIds.map(id => [id === "world" ? "canvas" : id, document.getElementById(id)])); els.sim = document.querySelector(".sim"); @@ -18,13 +20,15 @@ let lastSimTickAt = 0; let renderDirty = true; let loopTimer = null; let loopScheduled = false; +let fpsWindowStartedAt = 0; +let fpsFrames = 0; let hoverState = null; let renderImage = null; let renderImageSize = 0; const LoopConfig = Object.freeze({ simTickMs: 33, renderMs: 66, -stepBudgetMs: 4.5, +stepBudgetMs: 8, idlePollMs: 180, hiddenPollMs: 1000 }); @@ -34,6 +38,7 @@ sort: "oldest", metric: "power", showActive: true, showPast: true, +showEventIcons: true, hoverPolityId: null, rows: [], markers: [], @@ -41,11 +46,11 @@ scale: null }; const legendByMode = { terrain: () => terrainInfo.map(t => `${t.name}`).join(""), -ethnicity: () => "Ethnicity", -pressure: () => "Pressure", -polities: () => "States", -nomads: () => "Nomads", -technology: () => "Technology", -pheromone: () => "Routes", -resources: () => "Resources" +ethnicity: () => "民族の色・濃さは人口と優勢度", +pressure: () => "赤いほど人口圧力が高い", +polities: () => "", +nomads: () => "遊牧集団", +technology: () => "緑:農業 / 黄土色:冶金", +pheromone: () => "明るい黄色ほど交通量が多い", +resources: () => "明るい緑ほど資源が豊富" }; diff --git a/boot.js b/boot.js index a4f3861..9408b8a 100644 --- a/boot.js +++ b/boot.js @@ -7,6 +7,14 @@ updateStats(forceStats); renderTooltip(); renderDirty = false; lastRenderAt = performance.now(); +if (!fpsWindowStartedAt) fpsWindowStartedAt = lastRenderAt; +fpsFrames++; +const fpsElapsed = lastRenderAt - fpsWindowStartedAt; +if (fpsElapsed >= 500) { +if (els.fpsCounter) els.fpsCounter.textContent = `FPS ${Math.round(fpsFrames * 1000 / fpsElapsed)}`; +fpsWindowStartedAt = lastRenderAt; +fpsFrames = 0; +} } function scheduleLoop() { if (loopScheduled) return; @@ -28,7 +36,7 @@ loopScheduled = false; if (running && !document.hidden && now - lastSimTickAt >= LoopConfig.simTickMs) { lastSimTickAt = now; const steps = Number(els.speed.value); -const stepBudget = LoopConfig.stepBudgetMs * Math.max(1, steps); +const stepBudget = LoopConfig.stepBudgetMs; const loopStart = performance.now(); let completedSteps = 0; for (let i = 0; i < steps; i++) { @@ -38,30 +46,126 @@ if (completedSteps > 0 && performance.now() - loopStart > stepBudget) break; } if (completedSteps > 0) requestRender(); } -const shouldRender = !document.hidden && -(renderDirty || (running && now - lastRenderAt >= LoopConfig.renderMs)); +const shouldRender = !document.hidden && renderDirty && +(!running || now - lastRenderAt >= LoopConfig.renderMs); if (shouldRender) drawFrame(); scheduleLoop(); } -function reset() { -const size = Number(els.worldSize.value); -const initialPopulation = Number(els.agentCount.value); + +let interventionMode = null; +let manualRouteStartCityId = null; + +function setInterventionStatus(text) { +if (els.interventionStatus) els.interventionStatus.textContent = text; +} +function setInterventionMode(mode) { +interventionMode = interventionMode === mode ? null : mode; +manualRouteStartCityId = null; +const buttons = [ +[els.triggerDisaster, "disaster"], +[els.buildCity, "city"], +[els.connectCities, "route"] +]; +for (const [button, buttonMode] of buttons) button?.setAttribute("aria-pressed", String(interventionMode === buttonMode)); +if (interventionMode === "disaster") setInterventionStatus("災害を発生させる地点を地図上でクリックしてください。"); +else if (interventionMode === "city") setInterventionStatus("都市を建設する地点を地図上でクリックしてください。"); +else if (interventionMode === "route") setInterventionStatus("接続する1つ目の都市をクリックしてください。"); +else setInterventionStatus("ボタンを選び、地図上をクリックして実行します。"); +} +function eventToWorldCoordinates(event) { +const rect = els.canvas.getBoundingClientRect(); +return { +x: Math.floor((event.clientX - rect.left) / rect.width * sim.world.size), +y: Math.floor((event.clientY - rect.top) / rect.height * sim.world.size) +}; +} +function handleMapIntervention(event) { +if (!interventionMode || !sim) return; +const { x, y } = eventToWorldCoordinates(event); +if (x < 0 || y < 0 || x >= sim.world.size || y >= sim.world.size) return; +if (interventionMode === "disaster") { +const result = sim.triggerManualDisasterAt(x, y); +setInterventionStatus(`災害を発生させました(中心 ${result.x}, ${result.y}/半径 ${Math.round(result.radius)})。続けて地点をクリックできます。`); +requestRender(); +drawFrame(true); +renderStateGraph(); +return; +} +if (interventionMode === "city") { +const result = sim.buildCityAt(x, y); +if (!result.ok) { +setInterventionStatus(result.reason === "water" +? "水域には都市を建設できません。陸地をクリックしてください。" +: "この地点には都市を建設できません。"); +return; +} +setInterventionStatus(`都市${result.city.id}を建設しました(${result.city.x}, ${result.city.y})。続けて建設地点をクリックできます。`); +requestRender(); +drawFrame(true); +renderStateGraph(); +return; +} +if (interventionMode === "route") { +const city = cityAtDisplayTile(x, y); +if (!city) { +setInterventionStatus("都市をクリックしてください。都市アイコンの範囲内で選択できます。"); +return; +} +if (manualRouteStartCityId == null) { +manualRouteStartCityId = city.id; +setInterventionStatus(`都市${city.id}を選択しました。接続する2つ目の都市をクリックしてください。`); +return; +} +if (manualRouteStartCityId === city.id) { +setInterventionStatus("同じ都市は接続できません。別の都市をクリックしてください。"); +return; +} +const startId = manualRouteStartCityId; +const result = sim.createManualTradeRoute(startId, city.id); +manualRouteStartCityId = null; +if (!result.ok) { +const message = result.reason === "tooFar" ? `都市間が遠すぎます(上限 ${result.maxLength} タイル)。` +: result.reason === "noPath" ? "陸路で接続できる経路が見つかりませんでした。" +: "交通接続を作成できませんでした。"; +setInterventionStatus(`${message} 1つ目の都市から選び直してください。`); +return; +} +setInterventionStatus(`都市${startId}と都市${city.id}を接続しました。続けて1つ目の都市をクリックできます。`); +requestRender(); +drawFrame(true); +} +} + +function reset(size = SimConfig.world?.defaultSize ?? 160) { +const initialPopulation = SimConfig.world?.initialPopulation ?? 50000; +fpsWindowStartedAt = 0; +fpsFrames = 0; +if (els.fpsCounter) els.fpsCounter.textContent = "FPS --"; els.canvas.width = size; els.canvas.height = size; renderImage = null; renderImageSize = 0; sim = new Simulation(size, initialPopulation); +if (els.worldSize) els.worldSize.value = String(size); +interventionMode = null; +manualRouteStartCityId = null; +for (const button of [els.triggerDisaster, els.buildCity, els.connectCities]) button?.setAttribute("aria-pressed", "false"); +setInterventionStatus("ボタンを選び、地図上をクリックして実行します。"); setLegend(); drawFrame(true); renderStateGraph(); } +function openRegenerateDialog() { +if (els.worldSize && sim) els.worldSize.value = String(sim.world.size); +if (els.regenerateDialog?.showModal) els.regenerateDialog.showModal(); +} function refreshStateGraph() { renderStateGraph(); clearStateGraphInfo(); } els.toggleRun.addEventListener("click", () => { running = !running; -els.toggleRun.textContent = running ? "Pause" : "Run"; +els.toggleRun.textContent = running ? "一時停止" : "再開"; lastSimTickAt = 0; if (running && loopTimer) { clearTimeout(loopTimer); @@ -72,14 +176,16 @@ scheduleLoop(); scheduleLoop(); } }); -els.stepOnce.addEventListener("click", () => { -sim.step(); -requestRender(); -drawFrame(true); -renderStateGraph(); +els.resetWorld.addEventListener("click", openRegenerateDialog); +els.confirmRegenerate?.addEventListener("click", () => { +const size = Number(els.worldSize?.value || SimConfig.world?.defaultSize || 160); +els.regenerateDialog?.close(); +reset(size); }); -els.resetWorld.addEventListener("click", reset); -for (const control of [els.worldSize, els.agentCount]) control.addEventListener("change", reset); +els.cancelRegenerate?.addEventListener("click", () => els.regenerateDialog?.close()); +els.triggerDisaster?.addEventListener("click", () => setInterventionMode("disaster")); +els.buildCity?.addEventListener("click", () => setInterventionMode("city")); +els.connectCities?.addEventListener("click", () => setInterventionMode("route")); els.viewMode.addEventListener("change", () => { setLegend(); requestRender(); @@ -87,6 +193,7 @@ drawFrame(); }); els.canvas.addEventListener("mousemove", showTooltip); els.canvas.addEventListener("mouseleave", hideTooltip); +els.canvas.addEventListener("click", handleMapIntervention); for (const control of [els.historyFilter, els.historySort, els.historyMetric]) { control?.addEventListener("change", refreshStateGraph); } @@ -100,6 +207,11 @@ graphState.showPast = !graphState.showPast; els.togglePastStates.setAttribute("aria-pressed", String(graphState.showPast)); refreshStateGraph(); }); +els.toggleEventIcons?.addEventListener("click", () => { +graphState.showEventIcons = !graphState.showEventIcons; +els.toggleEventIcons.setAttribute("aria-pressed", String(graphState.showEventIcons)); +refreshStateGraph(); +}); els.stateGraph?.addEventListener("mousemove", updateStateGraphInfo); els.stateGraph?.addEventListener("mouseleave", clearStateGraphInfo); document.addEventListener("visibilitychange", () => { @@ -112,5 +224,5 @@ loopScheduled = false; scheduleLoop(); } }); -reset(); +reset(SimConfig.world?.defaultSize ?? 160); loop(); diff --git a/config.js b/config.js index 7a2b9c5..a120f52 100644 --- a/config.js +++ b/config.js @@ -6,34 +6,41 @@ WATER: 3, DESERT: 4 }); const terrainInfo = [ -{ name: "Plains", color: [82, 102, 74], move: 1.0, fertility: 0.55, mineral: 0.05, regen: 0.025 }, -{ name: "Forest", color: [58, 91, 68], move: 1.3, fertility: 0.62, mineral: 0.08, regen: 0.038 }, -{ name: "Mountains", color: [104, 105, 101], move: 2.6, fertility: 0.18, mineral: 0.78, regen: 0.012 }, -{ name: "Water", color: [52, 78, 103], move: 7.0, fertility: 0.04, mineral: 0.02, regen: 0.004 }, -{ name: "Desert", color: [139, 123, 86], move: 1.55, fertility: 0.16, mineral: 0.16, regen: 0.014 } +{ name: "平原", color: [82, 102, 74], move: 1.0, fertility: 0.55, mineral: 0.05, regen: 0.025 }, +{ name: "森林", color: [58, 91, 68], move: 1.3, fertility: 0.62, mineral: 0.08, regen: 0.038 }, +{ name: "山地", color: [104, 105, 101], move: 2.6, fertility: 0.18, mineral: 0.78, regen: 0.012 }, +{ name: "水域", color: [52, 78, 103], move: 7.0, fertility: 0, mineral: 0.02, regen: 0.004 }, +{ name: "砂漠", color: [139, 123, 86], move: 1.55, fertility: 0.16, mineral: 0.16, regen: 0.014 } ]; const WEEKS_PER_MONTH = 4; const MONTHS_PER_YEAR = 12; const WEEKS_PER_YEAR = MONTHS_PER_YEAR * WEEKS_PER_MONTH; const SimConfig = Object.freeze({ +world: Object.freeze({ +initialPopulation: 50000, +defaultSize: 160 +}), population: Object.freeze({ -softCapStart: 0.85, -hardCapScale: 1.35, +populationScale: 10, carryingCapacityBase: 2.4, carryingCapacityFertility: 7.8, carryingCapacityMineral: 1.8, carryingCapacityFarmland: 5.5, -pressurePenaltyBase: 0.2, -pressureReproductionPenalty: 0.16 }), city: Object.freeze({ -maxCities: 300, -agingStartYears: 180, -agingDecayPerYear: 0.002, -agingOverCapAttrition: 0.035, -agingRestoreMinWear: 0.08, -agingRestoreCostPerWear: 70, -agingRestoreBudgetShare: 0.18 +maxCities: 1200, +initialPopulation: 400, +abandonmentPopulation: 200, +populationScale: 10, +foodProductionScale: 10, +postShockRecoveryGrowth: 0.045, +overCapacityAttrition: 0.020, +naturalFoundingMinDistance: 6, +naturalFoundingStartYears: 160, +naturalFoundingIntervalYears: 5, +naturalFoundingReferenceArea: 160 * 160, +naturalFoundingMaxPerCycle: 8, +foundingCompetitionRadius: 9, }), render: Object.freeze({ graphThrottleMs: 1400, @@ -42,7 +49,6 @@ historyWindowYears: 2000, historySamplePaddingYears: 240 }), technology: Object.freeze({ -cityDiffusion: 0.0022, tradeDiffusion: 0.0032, cityInnovation: 0.00045 }), @@ -53,7 +59,47 @@ charismaMin: 0.5, charismaMax: 1.5, charismaAverage: 1.0, leaderTenureMinYears: 22, -leaderTenureMaxYears: 72 +leaderTenureMaxYears: 72, +foundingProtectionYears: 12, +warCapitalDistanceStart: 18, +warCapitalDistanceScale: 42, +warDisconnectedTerritoryFactor: 0.42, +institutionalAgingAnnualIncrease: 0.0015, +institutionalReformThreshold: 0.30, +institutionalReformBaseChance: 0.008, +institutionalReformChanceScale: 0.10, +institutionalReformMaxChance: 0.12, +institutionalReformCooldownYears: 50, +institutionalReformMinChange: -0.50, +institutionalReformMaxChange: 0.30, +treasuryCapPerPopulation: 0.30, +treasuryCityFoundingChance: 0.14, +treasuryCityFoundingCostRatio: 0.35, +treasuryCityPopulationPerCost: 0.18, +treasuryCityReservePerCost: 0.45, +treasuryCityFoundingSearchRadius: 20, +treasuryCitySiteScoreWindow: 6.0 +}), +territory: Object.freeze({ +baseCityReach: 9, +radiusScale: 0.5, +cityPowerWeight: 1.8, +capitalReachBonus: 1.5, +ownershipSwitchMargin: 1.5, +minimumInfluence: 2.4, +fullMaintenanceCityPopulation: 2400, +minimumPopulationSupport: 0.28, +maintenancePressure: 4, +supportSmoothing: 0.18, +smallStateSwitchPenalty: 2.5 +}), +rebellion: Object.freeze({ +participationLoyalty: 0.50, +automaticLoyalty: 0.30, +chanceScale: 0.20, +maxAnnualChance: 0.16, +conquestGraceYears: 20, +treasuryTransferRate: 0.65 }), campaign: Object.freeze({ checkIntervalYears: 3, @@ -64,7 +110,8 @@ maxActiveCampaigns: 12, frontierTargetChance: 0.35, nonStateTargetChance: 0.30, independentCityTargetChance: 0.20, -polityTargetChance: 0.15, +polityTargetChance: 0, +independentCityPeacefulShare: 0.4, baseDurationYears: 8, maxDurationYears: 25, claimRadius: 8, @@ -114,10 +161,14 @@ lowLoyaltyTransitPenalty: 0.012, foreignTransitPenalty: 0.008 }), culture: Object.freeze({ -spreadRadius: 3, -cityWeight: 0.035, -routeWeight: 1.35, -minimumInfluence: 0.18 +minimumInfluence: 0.18, +divergenceRateMultiplier: 0.25, +absorptionPopulationThreshold: 30, +urbanSpreadRadius: 5, +cityBlendRate: 0.045, +routeBlendRate: 0.035, +routeNeighborFactor: 0.35, +cityTradeBlendRate: 0.015 }), route: Object.freeze({ maxRouteLength: 42, @@ -136,17 +187,34 @@ routePheromoneMaintain: 0.12, routeUpkeepPerTile: 0.018, routeWeakThreshold: 8, routeUnsupportedDecay: 3, -routeMaintainedBoost: 10 +routeMaintainedBoost: 10, +manualProtectionYears: 25, +manualProtectedStrength: 32, +manualRouteMaxLength: 120, +desertTraversalCostFactor: 0.68, +desertRouteLengthBonus: 30, +desertAdaptiveMaxRouteLength: 96, +desertPheromoneThresholdFactor: 0.45, +desertConstructionCostFactor: 0.72 }), war: Object.freeze({ +damageMultiplier: 0.65, +tickWeeks: 4, +startChanceMultiplier: 3, +maxActiveWars: 12, +maxStartsPerTick: 4, +minDurationWeeks: 12, +idleEndWeeks: 24, +cooldownWeeks: 24, +decisiveScore: 6, pressureMemoryDecay: 0.88, -cityDamageMinRate: 0.003, -cityDamageMaxRate: 0.08, -captureLossBase: 0.08, -captureLossMax: 0.32, -exhaustionPopulationLossBase: 0.0007, -exhaustionPopulationLossMax: 0.012, -warZoneTileLossRate: 0.006, +cityDamageMinRate: 0.025, +cityDamageMaxRate: 0.30, +captureLossBase: 0.22, +captureLossMax: 0.40, +exhaustionPopulationLossBase: 0.003, +exhaustionPopulationLossMax: 0.03, +warZoneTileLossRate: 0.025, majorSettlementThreshold: 1.25 }), disaster: Object.freeze({ diff --git a/engine.js b/engine.js index 9fa1d51..38170a8 100644 --- a/engine.js +++ b/engine.js @@ -31,7 +31,6 @@ this.tradeRoute = new Uint8Array(this.count); this.farmland = new Float32Array(this.count); this.cityPull = new Float32Array(this.count); this.city = new Int32Array(this.count); -this.pressure = new Float32Array(this.count); this.population = new Float32Array(this.count); this.settledPopulation = new Float32Array(this.count); this.mobilePopulation = new Float32Array(this.count); @@ -42,7 +41,7 @@ this.metallurgyKnowledge = new Float32Array(this.count); this.nomadInfluence = new Float32Array(this.count); this.nomadBand = new Int32Array(this.count); this.territoryOwner = new Int32Array(this.count); -this.polity = new Int32Array(this.count); +this.polity = this.territoryOwner; this.control = new Float32Array(this.count); this.claim = new Float32Array(this.count); this.contested = new Uint8Array(this.count); @@ -54,6 +53,31 @@ this.territoryOwner.fill(-1); this.polity.fill(-1); this.dominantEthnicity.fill(-1); this.generate(); +this.buildLandNeighbors(); +} +buildLandNeighbors() { +// Terrain is fixed after generation. Keep the original dy/dx traversal order. +const starts = new Int32Array(this.count + 1); +const tiles = []; +for (let i = 0; i < this.count; i++) { +starts[i] = tiles.length; +if (this.terrain[i] === Terrain.WATER) continue; +const x = i % this.size; +const y = Math.floor(i / this.size); +for (let dy = -1; dy <= 1; dy++) { +for (let dx = -1; dx <= 1; dx++) { +if (!dx && !dy) continue; +const tx = x + dx; +const ty = y + dy; +if (tx < 0 || ty < 0 || tx >= this.size || ty >= this.size) continue; +const tile = this.idx(tx, ty); +if (this.terrain[tile] !== Terrain.WATER) tiles.push(tile); +} +} +} +starts[this.count] = tiles.length; +this.landNeighborStarts = starts; +this.landNeighbors = Int32Array.from(tiles); } idx(x, y) { return y * this.size + x; @@ -114,7 +138,11 @@ else t = Terrain.PLAINS; } const info = terrainInfo[t]; this.terrain[i] = t; -this.fertility[i] = clamp(info.fertility + humid * 0.16 - Math.abs(temp - 0.58) * 0.08 + this.rng.range(-0.03, 0.03), 0, 1); +// Water does not participate in fertility simulation. Keep it explicitly at zero +// so later systems never spend work interpreting a meaningless fertility value. +this.fertility[i] = t === Terrain.WATER +? 0 +: clamp(info.fertility + humid * 0.16 - Math.abs(temp - 0.58) * 0.08 + this.rng.range(-0.03, 0.03), 0, 1); this.mineral[i] = clamp(info.mineral + minerals * 0.16, 0, 1); this.regen[i] = info.regen * (0.7 + this.fertility[i]); this.move[i] = info.move; @@ -127,20 +155,24 @@ this.enrichWaterMargins(); enrichWaterMargins() { const s = this.size; const nextFertility = new Float32Array(this.fertility); -for (let y = 0; y < s; y++) { -for (let x = 0; x < s; x++) { -const i = this.idx(x, y); -if (this.terrain[i] === Terrain.WATER) continue; -let waterScore = 0; +const offsets = []; for (let dy = -3; dy <= 3; dy++) { for (let dx = -3; dx <= 3; dx++) { const d = Math.abs(dx) + Math.abs(dy); if (!d || d > 3) continue; +offsets.push([dx, dy, (4 - d) / 4]); +} +} +for (let y = 0; y < s; y++) { +for (let x = 0; x < s; x++) { +const i = y * s + x; +if (this.terrain[i] === Terrain.WATER) continue; +let waterScore = 0; +for (const [dx, dy, weight] of offsets) { const tx = x + dx; const ty = y + dy; if (tx < 0 || ty < 0 || tx >= s || ty >= s) continue; -if (this.terrain[this.idx(tx, ty)] === Terrain.WATER) waterScore += (4 - d) / 4; -} +if (this.terrain[ty * s + tx] === Terrain.WATER) waterScore += weight; } if (waterScore <= 0) continue; const boost = Math.min(0.32, waterScore * 0.08); @@ -150,14 +182,16 @@ if (this.terrain[i] === Terrain.DESERT && waterScore > 1.2) this.terrain[i] = Te } for (let i = 0; i < this.count; i++) { const info = terrainInfo[this.terrain[i]]; -this.fertility[i] = nextFertility[i]; -this.regen[i] = info.regen * (0.7 + this.fertility[i]); -this.move[i] = info.move; if (this.terrain[i] === Terrain.WATER) { +this.fertility[i] = 0; +this.regen[i] = info.regen * 0.7; this.resource[i] = 0; } else { +this.fertility[i] = nextFertility[i]; +this.regen[i] = info.regen * (0.7 + this.fertility[i]); this.resource[i] = Math.max(this.resource[i], this.rng.range(5, 20) * (0.45 + this.fertility[i] + this.mineral[i] * 0.25)); } +this.move[i] = info.move; } } smoothNoise(x, y, scale) { @@ -178,26 +212,43 @@ return v - Math.floor(v); computeHumidityFromWater(moistureMap) { const s = this.size; const radius = 10; +const unreachable = radius + 1; +const distance = new Uint8Array(this.count); +distance.fill(unreachable); +for (let i = 0; i < this.count; i++) { +if (this.terrain[i] === Terrain.WATER) distance[i] = 0; +} +// Exact city-block distance transform. The former implementation scanned the +// full radius around every tile; two linear passes produce the same nearest- +// water distance with O(tile count) work. for (let y = 0; y < s; y++) { for (let x = 0; x < s; x++) { -const i = this.idx(x, y); +const i = y * s + x; +if (distance[i] === 0) continue; +let d = distance[i]; +if (x > 0) d = Math.min(d, distance[i - 1] + 1); +if (y > 0) d = Math.min(d, distance[i - s] + 1); +distance[i] = Math.min(unreachable, d); +} +} +for (let y = s - 1; y >= 0; y--) { +for (let x = s - 1; x >= 0; x--) { +const i = y * s + x; +if (distance[i] === 0) continue; +let d = distance[i]; +if (x + 1 < s) d = Math.min(d, distance[i + 1] + 1); +if (y + 1 < s) d = Math.min(d, distance[i + s] + 1); +distance[i] = Math.min(unreachable, d); +} +} +for (let i = 0; i < this.count; i++) { if (this.terrain[i] === Terrain.WATER) { this.humidity[i] = 1; continue; } -let best = 0; -for (let dy = -radius; dy <= radius; dy++) { -for (let dx = -radius; dx <= radius; dx++) { -const d = Math.abs(dx) + Math.abs(dy); -if (!d || d > radius) continue; -const tx = x + dx; -const ty = y + dy; -if (tx < 0 || ty < 0 || tx >= s || ty >= s) continue; -if (this.terrain[this.idx(tx, ty)] === Terrain.WATER) best = Math.max(best, 1 - d / (radius + 1)); -} -} -this.humidity[i] = clamp(best * 0.78 + moistureMap[i] * 0.22, 0, 1); -} +const d = distance[i]; +const waterInfluence = d <= radius ? 1 - d / (radius + 1) : 0; +this.humidity[i] = clamp(waterInfluence * 0.78 + moistureMap[i] * 0.22, 0, 1); } this.smoothField(this.humidity, 1); } @@ -302,7 +353,7 @@ return values[Math.floor(clamp(ratio, 0, 1) * (values.length - 1))]; } } class Simulation { -constructor(size, initialPopulation) { +constructor(size, initialPopulation = SimConfig.world?.initialPopulation ?? 50000) { this.rng = new Rng(Date.now()); this.world = new World(size, this.rng); this.ethnicities = new Map(); @@ -316,10 +367,16 @@ this.nomadBands = []; this.disasters = []; this.disasterHistory = []; this.graphEvents = []; +this.worldHistory = []; this.polityHistory = new Map(); this.deadPolityHistories = []; this.tradeLinks = []; this.activeTradeRouteTiles = new Set(); +this.activePheromoneTiles = new Set(); +this.nextPheromoneTiles = new Set(); +this.pheromoneTouchedScratch = []; +this.manualTradeRoutes = []; +this.manualRouteProtection = new Map(); this.dominantEthnicityCache = new Map(); this.nextEthnicity = 1; this.nextCity = 1; @@ -347,15 +404,16 @@ this.radiusOffsetCache = new Map(); this.scratchFloatA = new Float32Array(this.world.count); this.scratchFloatB = new Float32Array(this.world.count); this.scratchFloatC = new Float32Array(this.world.count); +this.populationCapacityStatic = new Float32Array(this.world.count); +this.populationCapacityDynamicScale = new Float32Array(this.world.count); +this.initializePopulationCapacityCache(); +this.territoryBestSupport = new Float32Array(this.world.count); +this.territoryIncumbentSupport = new Float32Array(this.world.count); this.scratchIntA = new Int32Array(this.world.count); this.scratchIntB = new Int32Array(this.world.count); this.scratchUintA = new Uint8Array(this.world.count); this.visitStamp = new Int32Array(this.world.count); this.nextVisitStamp = 1; -this.cultureInfluence = new Float32Array(64); -this.cultureSeen = new Int32Array(64); -this.cultureSeenIds = []; -this.cultureStamp = 1; this.cityScoreScratch = []; this.pairCandidateScratch = []; this.routeCandidateScratch = []; @@ -369,6 +427,7 @@ this.routeHeapScratch = []; this.seedInitialPopulationFieldDirectly(initialPopulation); this.recomputeTerritories({ allowOwnershipChanges: true, reason: "initial" }); this.updateEthnicStats(); +this.sampleWorldHistory(); } markPopulationTile(tile) { if (tile >= 0 && tile < this.world.count) this.activePopulationTiles.add(tile); @@ -424,23 +483,6 @@ this.nextVisitStamp = 1; } return this.nextVisitStamp++; } -ensureCultureScratch() { -const needed = Math.max(64, this.nextEthnicity + 8); -if (this.cultureInfluence.length >= needed) return; -let size = this.cultureInfluence.length; -while (size < needed) size *= 2; -this.cultureInfluence = new Float32Array(size); -this.cultureSeen = new Int32Array(size); -this.cultureStamp = 1; -} -nextCultureMarker() { -this.ensureCultureScratch(); -if (this.cultureStamp >= 2147483640) { -this.cultureSeen.fill(0); -this.cultureStamp = 1; -} -return this.cultureStamp++; -} topHeapPush(heap, item, limit, scoreKey) { if (limit <= 0) return; if (heap.length < limit) { @@ -491,7 +533,8 @@ climateTemp: climate?.temperature ?? 0.55, climateHumidity: climate?.humidity ?? 0.45, color: hslToRgb((id * 0.61803398875) % 1, 0.55, 0.56), centroidX: 0, -centroidY: 0 +centroidY: 0, +nextDivergenceCheck: this.year + years(this.rng.range(18, 72) / clamp(SimConfig.culture?.divergenceRateMultiplier ?? 0.25, 0.05, 1)) }); return id; } @@ -692,7 +735,7 @@ assimilation: this.rng.range(0.02, 0.18) const population = options.population ?? Math.round(this.rng.range(cfg.minPopulation ?? 80, cfg.maxPopulation ?? 420)); const band = { id: this.nextNomadBand++, -name: `Band ${this.nextNomadBand - 1}`, +name: `遊牧集団${this.nextNomadBand - 1}`, ethnicityId, x: originTile % w.size, y: Math.floor(originTile / w.size), @@ -1085,6 +1128,7 @@ this.nomadRaidCity(band, city, true); const oldPolityId = city.polityId; if (city.polityId !== null) this.removeCityFromPolity(city); this.releaseCityTerritory(city, oldPolityId, 5, "nomadConquest"); +this.protectCityFromRebellion(city); city.loyalty = 0.22; band.prestige = clamp(band.prestige + 0.28, 0, 5); this.addGraphEvent("nomadConquest", this.year, { bandId: band.id, cityId: city.id, outcome: "puppetIndependent" }, 3); @@ -1092,6 +1136,7 @@ this.addGraphEvent("nomadConquest", this.year, { bandId: band.id, cityId: city.i const oldPolityId = city.polityId; if (city.polityId !== null) this.removeCityFromPolity(city); this.releaseCityTerritory(city, oldPolityId, 5, "nomadConquest"); +this.protectCityFromRebellion(city); const settlers = Math.min(band.population * 0.28, Math.max(30, city.population * 0.35)); band.population -= settlers; city.population += settlers; @@ -1182,9 +1227,15 @@ step() { for (const city of this.cities) city.activeVisitors = 0; this.dominantEthnicityCache.clear(); this.rebuildIndexes(); -this.updateFieldPressureFromPopulation(); -if (this.year % 2 === 0) this.updateWorldFields(2); -this.updatePopulationCapacity(); +// World fields are visually and behaviorally slow-moving. Updating them once +// per simulated month halves full-map work while preserving the same annual +// decay/regeneration scale. Annual city processing owns its capacity refresh. +const annualTick = this.year % years(1) === 0; +const fieldTick = this.year % WEEKS_PER_MONTH === 0; +const resourceTick = this.year % 12 === 2; +const pheromoneChanged = fieldTick ? this.updateWorldFields(WEEKS_PER_MONTH, 0) : false; +if (resourceTick) this.regenerateResources(12); +if (!annualTick && pheromoneChanged) this.updatePopulationCapacity(); this.maybeSpawnDisaster(); if (this.year % years(1) === 0) this.maybeSpawnFrontierWave(); if (this.year % years(1) === 0) { @@ -1192,16 +1243,16 @@ this.updateCities(); this.updateNomadBands(); this.consumeTileResources(); this.growTilePopulation(); -this.updatePopulationCapacity(); +this.updatePopulationPressure(); this.diffusePopulation(); -this.updatePopulationCapacity(); +this.updatePopulationPressure(); if (this.year % years(2) === 0) { this.updateTileTechnology(); this.diffuseTileTechnology(); this.cityTechnologyExchange(); } if (this.year % years(3) === 0) this.updateTileAssimilation(); -this.updateRegionalCultures(); +this.spreadCulturesFromCitiesAndTrade(); this.updateNomadInfluence(); if (this.year % years(100) === 0 && typeof console !== "undefined" && console.debug) { const d = this.territoryDebug; @@ -1214,17 +1265,22 @@ if (this.year % years(5) === 0) { this.updateTradeRoutesFieldBased(); } this.updatePolities(); +if (this.year % SimConfig.war.tickWeeks === 0) { +this.maybeStartWars(); +this.updateCampaigns(); +this.updateWars(); +} +const historyTick = this.year % 12 === 0; +if (historyTick) this.updateEthnicStats(); +if (this.year > 0 && annualTick) { +this.absorbSmallEthnicities(); this.updateEthnicStats(); -if (this.year % years(45) === 0) { this.splitDivergentEthnicities(); this.updateEthnicStats(); } +if (historyTick) this.sampleWorldHistory(); this.year++; } -updateFieldPressureFromPopulation() { -const w = this.world; -for (let i = 0; i < w.count; i++) w.pressure[i] = w.population[i] || 0; -} rebuildIndexes() { this.cityById.clear(); for (const city of this.cities) this.cityById.set(city.id, city); @@ -1269,7 +1325,7 @@ w.mobilePopulation.fill(0); w.populationPressure.fill(0); this.tileEthnicMix.clear(); this.activePopulationTiles.clear(); -const founders = Math.max(6, Math.min(18, Math.round(initialPopulation / 650))); +const founders = Math.max(6, Math.min(18, Math.round(initialPopulation / (650 * SimConfig.population.populationScale)))); const desertFounders = Math.max(2, Math.floor(founders * 0.25)); for (let e = 0; e < founders; e++) { const desertFounder = e < desertFounders; @@ -1605,7 +1661,7 @@ for (const tile of tiles) { const population = w.population[tile]; if (population <= 0 || w.terrain[tile] === Terrain.WATER) continue; const pressure = w.populationPressure[tile] || 0; -const demand = population * (0.0045 + Math.max(0, pressure - 1) * 0.0035); +const demand = (population / SimConfig.population.populationScale) * (0.0045 + Math.max(0, pressure - 1) * 0.0035); w.resource[tile] = Math.max(0, w.resource[tile] - demand); } } @@ -1651,69 +1707,81 @@ this.updateCultureTile(tile); } } } -updateRegionalCultures() { +blendEthnicComposition(target, targetTotal, source, rate) { +if (!target || !source?.size || targetTotal <= 0 || rate <= 0) return false; +const sourceTotal = compositionTotal(source); +if (sourceTotal <= 0) return false; +const blendRate = clamp(rate, 0, 0.25); +const ids = new Set([...target.keys(), ...source.keys()]); +for (const id of ids) { +const current = target.get(id) || 0; +const desired = targetTotal * (source.get(id) || 0) / sourceTotal; +const next = current + (desired - current) * blendRate; +if (next > 0.01) target.set(id, next); +else target.delete(id); +} +return true; +} +blendTileEthnicComposition(tile, source, rate) { +const population = this.world.population[tile] || 0; +if (population <= 0.01 || this.world.terrain[tile] === Terrain.WATER || !source?.size) return false; +let target = this.tileEthnicMix.get(tile); +if (!target?.size) { +target = new Map(); +const sourceTotal = compositionTotal(source); +if (sourceTotal <= 0) return false; +for (const [id, count] of source) target.set(id, population * count / sourceTotal); +this.tileEthnicMix.set(tile, target); +this.updateCultureTile(tile); +return true; +} +const targetTotal = compositionTotal(target); +const changed = this.blendEthnicComposition(target, targetTotal, source, rate); +if (changed) this.updateCultureTile(tile); +return changed; +} +spreadCulturesFromCitiesAndTrade() { const w = this.world; -const nextDominant = this.scratchIntA; -const nextDiversity = this.scratchFloatA; -nextDominant.set(w.dominantEthnicity); -nextDiversity.set(w.cultureDiversity); -const radius = SimConfig.culture.spreadRadius; -const offsets = this.getRadiusOffsets(radius); -this.ensureCultureScratch(); -const influence = this.cultureInfluence; -const seen = this.cultureSeen; -for (let y = 0; y < w.size; y++) { -for (let x = 0; x < w.size; x++) { +const cfg = SimConfig.culture || {}; +const urbanRadius = cfg.urbanSpreadRadius ?? 5; +const cityRate = cfg.cityBlendRate ?? 0.045; +for (const city of this.cities) { +if (!city.ethnicityComposition?.size || city.population <= 0) continue; +const populationStrength = clamp(Math.sqrt(city.population / (SimConfig.city.populationScale || 1)) / 18, 0.35, 1.4); +for (const { dx, dy, distance } of this.getRadiusOffsets(urbanRadius)) { +const x = city.x + dx; +const y = city.y + dy; +if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; const tile = w.idx(x, y); -if (w.terrain[tile] === Terrain.WATER) continue; -const stamp = this.nextCultureMarker(); -const seenIds = this.cultureSeenIds; -seenIds.length = 0; -let total = 0; -for (const offset of offsets) { -const distance = offset.distance; -const dx = offset.dx; -const dy = offset.dy; -const tx = x + dx; -const ty = y + dy; -if (tx < 0 || ty < 0 || tx >= w.size || ty >= w.size) continue; -const source = w.idx(tx, ty); -const id = w.dominantEthnicity[source]; -if (id < 0) continue; -const pressureWeight = Math.sqrt(Math.max(0, w.population[source])); -const cityWeight = w.city[source] >= 0 -? Math.sqrt(Math.max(1, this.getCityById(w.city[source])?.population || 1)) * SimConfig.culture.cityWeight -: 0; -const routeWeight = w.tradeRoute[source] ? SimConfig.culture.routeWeight : 1; -const weight = (pressureWeight + cityWeight) * routeWeight / (1 + distance); -if (weight <= 0) continue; -if (seen[id] !== stamp) { -seen[id] = stamp; -influence[id] = weight; -seenIds.push(id); -} else { -influence[id] += weight; -} -total += weight; -} -let bestId = nextDominant[tile]; -let bestWeight = 0; -for (const id of seenIds) { -const weight = influence[id]; -if (weight > bestWeight) { -bestId = id; -bestWeight = weight; +if (w.terrain[tile] === Terrain.WATER || (w.population[tile] || 0) <= 0.01) continue; +const falloff = 1 - distance / (urbanRadius + 1); +const routeBoost = w.tradeRoute[tile] ? 1.35 : 1; +this.blendTileEthnicComposition(tile, city.ethnicityComposition, cityRate * populationStrength * falloff * routeBoost); } } -if (bestWeight >= SimConfig.culture.minimumInfluence) { -nextDominant[tile] = bestId; -nextDiversity[tile] = total > 0 ? clamp(1 - bestWeight / total, 0, 1) : 0; +const routeRate = cfg.routeBlendRate ?? 0.035; +const neighborFactor = cfg.routeNeighborFactor ?? 0.35; +const cityTradeRate = cfg.cityTradeBlendRate ?? 0.015; +for (const link of this.tradeLinks || []) { +const a = this.getCityById(link.from); +const b = this.getCityById(link.to); +if (!a?.ethnicityComposition?.size || !b?.ethnicityComposition?.size) continue; +const aSource = new Map(a.ethnicityComposition); +const bSource = new Map(b.ethnicityComposition); +this.blendEthnicComposition(a.ethnicityComposition, compositionTotal(a.ethnicityComposition), bSource, cityTradeRate * (0.5 + (link.strength || 0))); +this.blendEthnicComposition(b.ethnicityComposition, compositionTotal(b.ethnicityComposition), aSource, cityTradeRate * (0.5 + (link.strength || 0))); +const routeCulture = new Map(); +for (const [id, count] of aSource) routeCulture.set(id, (routeCulture.get(id) || 0) + count / Math.max(1, a.population)); +for (const [id, count] of bSource) routeCulture.set(id, (routeCulture.get(id) || 0) + count / Math.max(1, b.population)); +const localRate = routeRate * clamp(0.6 + (link.strength || 0), 0.6, 1.8); +for (const tile of link.path || []) { +if ((w.population[tile] || 0) > 0.01) this.blendTileEthnicComposition(tile, routeCulture, localRate); +this.forCardinalNeighbors(tile, neighbor => { +if ((w.population[neighbor] || 0) > 0.01) this.blendTileEthnicComposition(neighbor, routeCulture, localRate * neighborFactor); +}); } } } -w.dominantEthnicity.set(nextDominant); -w.cultureDiversity.set(nextDiversity); -} farmabilityAt(tile) { const t = this.world.terrain[tile]; if (t === Terrain.PLAINS) return 0.75; @@ -1721,34 +1789,14 @@ if (t === Terrain.FOREST) return 0.55; if (t === Terrain.DESERT) return 0.25; return 0.0; } -carryingCapacityAt(tile) { -return this.carryingCapacityAtTile(tile); -} -carryingCapacityAtTile(tile) { -const w = this.world; -if (w.terrain[tile] === Terrain.WATER) return 0.35; -const terrainFactor = -w.terrain[tile] === Terrain.MOUNTAIN ? 0.62 : -w.terrain[tile] === Terrain.DESERT ? 0.55 : -w.terrain[tile] === Terrain.FOREST ? 0.92 : -1; -const routeBonus = w.tradeRoute[tile] ? 1.6 : clamp(w.pheromone[tile] / Math.max(1, SimConfig.route.maxPheromone), 0, 1) * 0.8; -const cityBonus = w.city[tile] >= 0 ? 3.5 : w.cityPull[tile] * 2.2; -return Math.max(0.1, ( -SimConfig.population.carryingCapacityBase + -w.fertility[tile] * SimConfig.population.carryingCapacityFertility + -w.mineral[tile] * SimConfig.population.carryingCapacityMineral + -w.farmland[tile] * SimConfig.population.carryingCapacityFarmland + -routeBonus + -cityBonus -) * terrainFactor); -} -updatePopulationCapacity() { +initializePopulationCapacityCache() { const w = this.world; +const { carryingCapacityBase, carryingCapacityFertility, carryingCapacityMineral } = SimConfig.population; +const populationScale = SimConfig.population.populationScale; for (let i = 0; i < w.count; i++) { if (w.terrain[i] === Terrain.WATER) { -w.populationCapacity[i] = 0.35; -w.populationPressure[i] = w.population[i] / 0.35; +this.populationCapacityStatic[i] = 0.35 * populationScale; +this.populationCapacityDynamicScale[i] = 0; continue; } const terrainFactor = @@ -1756,20 +1804,44 @@ w.terrain[i] === Terrain.MOUNTAIN ? 0.62 : w.terrain[i] === Terrain.DESERT ? 0.55 : w.terrain[i] === Terrain.FOREST ? 0.92 : 1; -const routeBonus = w.tradeRoute[i] ? 1.6 : clamp(w.pheromone[i] / Math.max(1, SimConfig.route.maxPheromone), 0, 1) * 0.8; -const cityBonus = w.city[i] >= 0 ? 3.5 : w.cityPull[i] * 2.2; -const capacity = Math.max(0.1, ( -SimConfig.population.carryingCapacityBase + -w.fertility[i] * SimConfig.population.carryingCapacityFertility + -w.mineral[i] * SimConfig.population.carryingCapacityMineral + -w.farmland[i] * SimConfig.population.carryingCapacityFarmland + -routeBonus + -cityBonus -) * terrainFactor); -w.populationCapacity[i] = capacity; +const scale = terrainFactor * populationScale; +this.populationCapacityStatic[i] = ( +carryingCapacityBase + +w.fertility[i] * carryingCapacityFertility + +w.mineral[i] * carryingCapacityMineral +) * scale; +this.populationCapacityDynamicScale[i] = scale; +} +} +updatePopulationPressure() { +const w = this.world; +for (let i = 0; i < w.count; i++) { +const capacity = w.populationCapacity[i]; w.populationPressure[i] = capacity > 0 ? w.population[i] / capacity : 0; } } +updatePopulationCapacity() { +const w = this.world; +const { carryingCapacityFarmland } = SimConfig.population; +const maxPheromone = Math.max(1, SimConfig.route.maxPheromone); +const staticCapacity = this.populationCapacityStatic; +const dynamicScale = this.populationCapacityDynamicScale; +for (let i = 0; i < w.count; i++) { +const scale = dynamicScale[i]; +if (scale === 0) { +w.populationCapacity[i] = staticCapacity[i]; +w.populationPressure[i] = w.population[i] / staticCapacity[i]; +continue; +} +const routeBonus = w.tradeRoute[i] ? 1.6 : Math.min(1, Math.max(0, w.pheromone[i] / maxPheromone)) * 0.8; +const cityBonus = w.city[i] >= 0 ? 3.5 : w.cityPull[i] * 2.2; +const capacity = staticCapacity[i] + ( +w.farmland[i] * carryingCapacityFarmland + routeBonus + cityBonus +) * scale; +w.populationCapacity[i] = capacity; +w.populationPressure[i] = w.population[i] / capacity; +} +} updateTileTechnology() { const w = this.world; const tiles = this.activePopulationSnapshot(); @@ -1863,46 +1935,74 @@ const tempDiff = Math.abs(this.world.temperature[tile] - ethnicity.climateTemp); const humidDiff = Math.abs(this.world.humidity[tile] - ethnicity.climateHumidity); return tempDiff * 0.58 + humidDiff * 0.42; } -updateWorldFields(scale = 1) { +updateWorldFields(scale = 1, resourceScale = scale) { +if (resourceScale > 0) this.regenerateResources(resourceScale); +// Preserve the former biweekly pheromone diffusion semantics while keeping +// pheromone work sparse. Resource regeneration is batched separately by step(). +let remaining = Math.max(0, scale); +let pheromoneChanged = false; +while (remaining > 0) { +const chunk = Math.min(2, remaining); +if (this.updatePheromoneField(chunk)) pheromoneChanged = true; +remaining -= chunk; +} +return pheromoneChanged; +} +regenerateResources(scale = 1) { const w = this.world; -const pheromoneDecay = Math.pow(SimConfig.route.pheromoneDecay, scale); -const diffusion = SimConfig.route.pheromoneDiffusion * scale; -const nextPheromone = diffusion > 0 ? this.scratchFloatC : null; -if (nextPheromone) nextPheromone.set(w.pheromone); for (let i = 0; i < w.count; i++) { w.resource[i] = Math.min(58, w.resource[i] + w.regen[i] * scale * (1 + w.farmland[i] * 1.15)); -const decayed = w.pheromone[i] * pheromoneDecay; -if (nextPheromone) nextPheromone[i] = decayed; -else w.pheromone[i] = Math.min(SimConfig.route.maxPheromone, decayed); } -if (nextPheromone) { -for (let y = 0; y < w.size; y++) { -for (let x = 0; x < w.size; x++) { -const i = w.idx(x, y); -if (w.terrain[i] === Terrain.WATER) { -w.pheromone[i] = Math.min(SimConfig.route.maxPheromone, nextPheromone[i] * 0.85); -continue; } -let neighborSum = 0; -let neighborCount = 0; -for (let dy = -1; dy <= 1; dy++) { -for (let dx = -1; dx <= 1; dx++) { -if (!dx && !dy) continue; -const tx = x + dx; -const ty = y + dy; -if (tx < 0 || ty < 0 || tx >= w.size || ty >= w.size) continue; -const tile = w.idx(tx, ty); +updatePheromoneField(scale = 1) { +const w = this.world; +const active = this.activePheromoneTiles; +if (!active?.size) return false; +const decay = Math.pow(SimConfig.route.pheromoneDecay, scale); +const diffusion = SimConfig.route.pheromoneDiffusion * scale; +const maxPheromone = SimConfig.route.maxPheromone; +const touched = this.pheromoneTouchedScratch; +touched.length = 0; +const marker = this.nextVisitMarker(); +const starts = w.landNeighborStarts; +const neighbors = w.landNeighbors; +const markTouched = tile => { +if (this.visitStamp[tile] === marker) return; +this.visitStamp[tile] = marker; +touched.push(tile); +}; +for (const tile of active) { +if (tile < 0 || tile >= w.count) continue; +markTouched(tile); if (w.terrain[tile] === Terrain.WATER) continue; -neighborSum += nextPheromone[tile]; -neighborCount++; -} -} -const neighborAverage = neighborCount ? neighborSum / neighborCount : nextPheromone[i]; -w.pheromone[i] = Math.min(SimConfig.route.maxPheromone, lerp(nextPheromone[i], neighborAverage, diffusion)); +for (let n = starts[tile]; n < starts[tile + 1]; n++) markTouched(neighbors[n]); } +const decayed = this.scratchFloatC; +for (const tile of touched) decayed[tile] = w.pheromone[tile] * decay; +const nextActive = this.nextPheromoneTiles; +nextActive.clear(); +for (const tile of touched) { +let value; +if (w.terrain[tile] === Terrain.WATER) { +value = Math.min(maxPheromone, decayed[tile] * 0.85); +} else { +let neighborSum = 0; +const begin = starts[tile]; +const end = starts[tile + 1]; +for (let n = begin; n < end; n++) neighborSum += decayed[neighbors[n]]; +const neighborCount = end - begin; +const neighborAverage = neighborCount ? neighborSum / neighborCount : decayed[tile]; +value = Math.min(maxPheromone, lerp(decayed[tile], neighborAverage, diffusion)); } +if (value < 0.0005) value = 0; +w.pheromone[tile] = value; +if (value > 0) nextActive.add(tile); } +this.activePheromoneTiles = nextActive; +this.nextPheromoneTiles = active; +return touched.length > 0; } + updateCities() { const w = this.world; w.city.fill(-1); @@ -1918,7 +2018,8 @@ const settled = w.settledPopulation[tile] || 0; if (settled < 5 && population < 9) continue; const x = tile % w.size; const y = Math.floor(tile / w.size); -if (this.getCitiesNear(x, y, 10).length) continue; +const foundingSpacing = SimConfig.city.naturalFoundingMinDistance ?? 6; +if (this.getCitiesNear(x, y, Math.max(1, foundingSpacing - 1)).length) continue; const cx = clamp(Math.round(x / 4) * 4, 0, w.size - 1); const cy = clamp(Math.round(y / 4) * 4, 0, w.size - 1); const i = w.idx(cx, cy); @@ -1941,17 +2042,29 @@ for (const [id, count] of mix) group.ethnicities.set(id, (group.ethnicities.get( } } let foundedThisTick = 0; -const canFoundCities = this.year >= years(160) && this.year % years(20) === 0; -const foundingLimit = canFoundCities ? (this.year < years(1000) ? 1 : 1 + Math.floor(this.year / years(1200))) : 0; -const candidateEntries = [...candidates].sort((a, b) => { -const scoreA = this.cityFoundingScore(a[0], a[1]); -const scoreB = this.cityFoundingScore(b[0], b[1]); -return scoreB - scoreA; -}); +const foundingStartYears = SimConfig.city.naturalFoundingStartYears ?? 160; +const foundingIntervalYears = Math.max(1, SimConfig.city.naturalFoundingIntervalYears ?? 5); +const canFoundCities = this.year >= years(foundingStartYears) && this.year % years(foundingIntervalYears) === 0; +const foundingLimit = canFoundCities ? this.naturalCityFoundingLimit() : 0; +const scoredCandidates = [...candidates].map(([tile, group]) => ({ +tile, +group, +score: this.cityFoundingScore(tile, group) +})); +const bestFoundingScore = scoredCandidates.reduce((best, entry) => Math.max(best, entry.score), -Infinity); +// Near-equivalent sites should not always resolve to the exact same maximum. +// Keep strong suitability preference, but randomize within the broad top band. +for (const entry of scoredCandidates) { +const nearBest = entry.score >= bestFoundingScore - 4.0; +entry.priority = nearBest ? bestFoundingScore + this.rng.range(0, 4.0) : entry.score; +} +scoredCandidates.sort((a, b) => b.priority - a.priority); +const candidateEntries = scoredCandidates.map(entry => [entry.tile, entry.group]); for (const [i, group] of candidateEntries) { if (group.count < 24) continue; const avgSedentary = clamp(group.sedentary / Math.max(1, group.count), 0, 1); -let city = this.getCitiesNear(i % w.size, Math.floor(i / w.size), 12)[0] || null; +const foundingSpacing = SimConfig.city.naturalFoundingMinDistance ?? 6; +let city = this.getCitiesNear(i % w.size, Math.floor(i / w.size), foundingSpacing)[0] || null; if (!city && canFoundCities && foundedThisTick < foundingLimit && this.cities.length < SimConfig.city.maxCities) { const foundingScore = this.cityFoundingScore(i, group); const foundingChance = clamp((foundingScore - 12) * 0.030, 0.01, 0.38); @@ -1974,7 +2087,7 @@ city.knowledge.farming = Math.max(city.knowledge.farming * 0.998, group.farming city.knowledge.metallurgy = Math.max(city.knowledge.metallurgy * 0.998, group.metallurgy / Math.max(1, group.techCount)); const urbanWeight = clamp((avgSedentary - 0.18) * 1.45, 0.08, 1); for (const [id, count] of group.ethnicities) { -const urbanCount = this.weightedUrbanContribution(count * 0.2, urbanWeight); +const urbanCount = this.weightedUrbanContribution(count * 0.2 * SimConfig.city.populationScale / SimConfig.population.populationScale, urbanWeight); if (urbanCount > 0) city.ethnicityComposition.set(id, (city.ethnicityComposition.get(id) || 0) + urbanCount); } city.strength = city.strength * 0.96 + group.count * 0.05; @@ -1982,8 +2095,8 @@ city.strength = city.strength * 0.96 + group.count * 0.05; } this.absorbUrbanPopulation(); this.rebuildIndexes(); -this.updateFieldPressureFromPopulation(); this.processCityEconomies(); +const removedCities = []; this.cities = this.cities.filter(c => { c.age++; c.strength *= 0.992; @@ -1993,7 +2106,10 @@ if (c.activeVisitors < 2 && foodPerCapita < 0.04) c.strength -= 0.035; else if (c.activeVisitors < 5 && foodPerCapita < 0.02) c.strength -= 0.015; if (c.population < 25 && foodPerCapita < 0.05) c.strength -= 0.018; } -if (c.population <= 0 || c.strength <= 0.06) return false; +if (c.population < (SimConfig.city.abandonmentPopulation ?? 200) || c.strength <= 0.06) { +removedCities.push(c); +return false; +} const radius = c.agriculturalRadius; for (const offset of this.getRadiusOffsets(radius)) { const dx = offset.dx; @@ -2002,23 +2118,37 @@ const x = clamp(c.x + dx, 0, w.size - 1); const y = clamp(c.y + dy, 0, w.size - 1); const d = offset.distance; const tile = w.idx(x, y); -w.city[tile] = c.id; if (w.terrain[tile] !== Terrain.WATER) { w.farmland[tile] = Math.max(w.farmland[tile], (radius - d + 1) / (radius + 1)); w.cityPull[tile] = Math.max(w.cityPull[tile], (radius - d + 1) / (radius + 1)); } } +w.city[w.idx(c.x, c.y)] = c.id; return true; }); +for (const city of removedCities) { +const oldPolityId = city.polityId; +if (oldPolityId !== null) this.removeCityFromPolity(city); +const tile = w.idx(city.x, city.y); +if (w.city[tile] === city.id) w.city[tile] = -1; +if (oldPolityId !== null) this.releaseCityTerritory(city, oldPolityId, 5, "cityAbandoned"); +} this.rebuildIndexes(); this.updatePopulationCapacity(); +if (removedCities.length) this.pruneOrphanTradeRoutes(); +} +naturalCityFoundingLimit() { +const referenceArea = Math.max(1, SimConfig.city.naturalFoundingReferenceArea ?? (160 * 160)); +const maxPerCycle = Math.max(1, SimConfig.city.naturalFoundingMaxPerCycle ?? 8); +return clamp(Math.ceil(this.world.count / referenceArea), 1, maxPerCycle); } cityFoundingScore(tile, group) { const w = this.world; const settledShare = group.count > 0 ? group.sedentary / group.count : 0; const pressure = w.populationPressure[tile] || 0; const route = w.tradeRoute[tile] ? 1.4 : clamp(w.pheromone[tile] / 10, 0, 1.2); -const nearbyPenalty = this.getCitiesNear(tile % w.size, Math.floor(tile / w.size), 18).length * 11; +const spacing = SimConfig.city.naturalFoundingMinDistance ?? 6; +const nearbyPenalty = this.getCitiesNear(tile % w.size, Math.floor(tile / w.size), SimConfig.city.foundingCompetitionRadius ?? spacing + 3).length * 11; return group.count * (0.45 + settledShare) + pressure * 2.2 + w.fertility[tile] * 3.4 + @@ -2077,14 +2207,15 @@ this.removeEthnicPopulationProportionally(tile, take); remaining -= take; } } -createCity(x, y, seedGroup = null) { -const seedPopulation = seedGroup ? Math.max(14, Math.floor(seedGroup.count * 0.42)) : 10; +createCity(x, y, seedGroup = null, options = {}) { +const scale = SimConfig.city.populationScale; +const seedPopulation = Math.max(1, Math.round(options.initialPopulation ?? SimConfig.city.initialPopulation ?? 400)); const seedSedentary = seedGroup ? seedGroup.sedentary / Math.max(1, seedGroup.count) : 0.5; const composition = new Map(); if (seedGroup) { const urbanWeight = clamp((seedSedentary - 0.18) * 1.45, 0.08, 1); for (const [id, count] of seedGroup.ethnicities) { -const urbanCount = this.weightedUrbanContribution(count * 0.42, urbanWeight); +const urbanCount = this.weightedUrbanContribution(count * 0.42 * scale / SimConfig.population.populationScale, urbanWeight); if (urbanCount > 0) composition.set(id, urbanCount); } } @@ -2093,14 +2224,13 @@ id: this.nextCity++, x, y, population: seedPopulation, -storedResources: 34 + (seedGroup?.resources || 0) * 0.55, +storedResources: options.initialResources ?? (34 + (seedGroup?.resources || 0) * 0.55) * scale, ethnicityComposition: composition, pheromoneOutput: 0, agriculturalRadius: 2, tradeLinks: new Set(), activeVisitors: 0, age: 0, -ageWear: 0, peakPopulation: seedPopulation, strength: 3, sedentaryCulture: seedSedentary, @@ -2110,27 +2240,14 @@ polityId: null, loyalty: 0.5, receivedAid: false, tradeValue: 0, -tradeReach: 0 +tradeReach: 0, +rebellionProtectedUntil: 0 }; if (seedGroup) this.drawPopulationFromTilesForCity(city, seedGroup, seedPopulation); this.projectCityPopulationToTiles(city); this.syncTilePopulationCulture(); return city; } -updateCityAging(city) { -city.ageWear ??= 0; -city.peakPopulation = Math.max(city.peakPopulation || 0, city.population || 0); -const cfg = SimConfig.city; -const ageStart = cfg.agingStartYears ?? 180; -if ((city.age || 0) <= ageStart) return; -city.ageWear = clamp(city.ageWear + (cfg.agingDecayPerYear ?? 0.002), 0, 1); -} -cityAgeCapacityFactor(city) { -return clamp(1 - (city?.ageWear || 0), 0, 1); -} -cityAgePopulationLimit(city) { -return this.cityCarryingCapacity(city); -} cityCarryingCapacity(city) { const w = this.world; if (!city) return 1; @@ -2164,8 +2281,7 @@ farmlandSum * 18 + (city.tradeValue || 0) * 45 + (city.knowledge?.farming || 0) * 90 + Math.sqrt(Math.max(0, city.storedResources || 0)) * 3; -capacity *= clamp(1 - (city.ageWear || 0) * 0.45, 0.45, 1.25); -return Math.max(20, capacity); +return Math.max(20, capacity) * SimConfig.city.populationScale; } absorbUrbanPopulation() { // Population is already absorbed into cities when field-founded settlements draw @@ -2176,11 +2292,19 @@ const value = amount * weight; const whole = Math.floor(value); return whole + (this.rng.next() < value - whole ? 1 : 0); } +cityRecoveryGrowthBonus(city) { +if (!city || city.population <= 0) return 0; +const peak = Math.max(city.population, city.peakPopulation || city.population); +if (peak <= 0) return 0; +const recoveryGap = clamp((peak - city.population) / peak, 0, 0.75); +return recoveryGap * (SimConfig.city.postShockRecoveryGrowth ?? 0.045); +} processCityEconomies() { const w = this.world; for (const city of this.cities) { -this.updateCityAging(city); -city.agriculturalRadius = clamp(Math.floor(1 + Math.sqrt(city.population) / 4.5), 2, 14); +city.peakPopulation = Math.max(city.peakPopulation || 0, city.population || 0); +const populationScale = SimConfig.city.populationScale; +city.agriculturalRadius = clamp(Math.floor(1 + Math.sqrt(city.population / populationScale) / 4.5), 2, 14); city.pheromoneOutput = clamp(Math.log2(city.population + 1) * 0.09, 0.15, 1.8); city.knowledge ??= { farming: 0, metallurgy: 0 }; let harvested = 0; @@ -2196,7 +2320,7 @@ if (w.terrain[i] === Terrain.WATER) continue; const pull = (radius - distance + 1) / (radius + 1); const farmingYield = 1 + city.knowledge.farming * 0.85; const metallurgyYield = 1 + city.knowledge.metallurgy * w.mineral[i] * 0.35; -const extraction = Math.min(w.resource[i], (0.07 + w.fertility[i] * 0.18 * farmingYield + w.mineral[i] * 0.045 * metallurgyYield) * pull); +const extraction = Math.min(w.resource[i], (0.07 + w.fertility[i] * 0.18 * farmingYield + w.mineral[i] * 0.045 * metallurgyYield) * pull * SimConfig.city.foodProductionScale); w.resource[i] -= extraction; w.farmland[i] = Math.max(w.farmland[i], pull); this.addPheromone(i, city.pheromoneOutput * pull * 0.09); @@ -2204,9 +2328,9 @@ harvested += extraction; } city.storedResources += harvested; const trade = this.cityTradeProfile(city); -const tradeIncome = trade.value * (0.18 + Math.sqrt(Math.max(0, city.population)) * 0.018); +const tradeIncome = trade.value * (0.18 + Math.sqrt(Math.max(0, city.population / populationScale)) * 0.018) * populationScale; city.storedResources += tradeIncome; -const supportRatio = city.activeVisitors / Math.max(1, city.population); +const supportRatio = (city.activeVisitors / SimConfig.population.populationScale) / Math.max(1, city.population / populationScale); const knowledgeMaintenance = city.population * (city.knowledge.farming * 0.0008 + city.knowledge.metallurgy * 0.0012); const tradeRelief = clamp(trade.value * 0.09, 0, 0.32); const upkeep = (city.population * (0.010 + Math.max(0, 0.025 - supportRatio) * 0.09)) * (1 - tradeRelief) + knowledgeMaintenance; @@ -2225,20 +2349,29 @@ city.tradeValue = 0; city.tradeReach = 0; } const capacity = this.cityCarryingCapacity(city); -if (city.storedResources > city.population * 0.14 && city.population > 0 && city.population < capacity && city.supplyStress < 0.9) { +const recoveryBonus = this.cityRecoveryGrowthBonus(city); +const recoveryMode = recoveryBonus > 0.002; +const growthReserveRatio = recoveryMode ? 0.06 : 0.11; +const growthStressLimit = recoveryMode ? 1.20 : 0.90; +if (city.storedResources > city.population * growthReserveRatio && city.population > 0 && city.population < capacity && city.supplyStress < growthStressLimit) { const prosperity = clamp(city.storedResources / Math.max(1, city.population) - 0.12 + trade.value * 0.012, 0, 0.8); const birthRoom = Math.max(0, Math.floor(capacity - city.population)); -const births = Math.min(birthRoom, Math.max(1, Math.floor(city.population * (0.012 + prosperity * 0.012 + clamp(trade.value, 0, 1.8) * 0.0015)))); +const births = Math.min(birthRoom, Math.max(1, Math.floor(city.population * ( +0.012 + +prosperity * 0.012 + +clamp(trade.value, 0, 1.8) * 0.0015 + +recoveryBonus +)))); city.population += births; city.storedResources -= births * 0.55; addBirthsToComposition(city.ethnicityComposition, births, this.rng); } if (city.population > capacity && city.supplyStress > 0.45) { const overLimit = city.population - capacity; -const ageLoss = Math.min(city.population, Math.max(1, Math.ceil(overLimit * (SimConfig.city.agingOverCapAttrition ?? 0.035)))); -city.population -= ageLoss; -removeFromComposition(city.ethnicityComposition, ageLoss); -city.strength -= Math.min(0.08, ageLoss / Math.max(1, city.population + ageLoss) * 0.18); +const overCapacityLoss = Math.min(city.population, Math.max(1, Math.ceil(overLimit * (SimConfig.city.overCapacityAttrition ?? 0.020)))); +city.population -= overCapacityLoss; +removeFromComposition(city.ethnicityComposition, overCapacityLoss); +city.strength -= Math.min(0.08, overCapacityLoss / Math.max(1, city.population + overCapacityLoss) * 0.18); } if (city.age > 20 && city.activeVisitors < 2 && city.storedResources < city.population * 0.03 && city.population > 0) { const attrition = Math.max(1, Math.ceil(city.population * (city.activeVisitors === 0 ? 0.025 : 0.010))); @@ -2327,7 +2460,7 @@ return (Math.sqrt(city.population) * 1.4 + Math.sqrt(Math.max(0, city.storedReso } setTileOwner(tile, polityId, options = {}) { const w = this.world; -if (tile == null || tile < 0 || tile >= w.count || w.terrain[tile] === Terrain.WATER) return false; +if (tile == null || tile < 0 || tile >= w.count || (w.terrain[tile] === Terrain.WATER && (polityId ?? -1) >= 0)) return false; const owner = polityId ?? -1; if (owner >= 0 && !this.getPolityById(owner)) return false; w.territoryOwner[tile] = owner; @@ -2347,14 +2480,13 @@ return true; } syncVisibleTerritoryOwners() { const w = this.world; -w.polity.set(w.territoryOwner); +if (w.polity !== w.territoryOwner) w.polity.set(w.territoryOwner); } validPolityIds() { return new Set(this.polities.map(polity => polity.id)); } -// Territory ownership is persistent. This pass refreshes control/claim/contest -// visualization from soft influence without moving borders unless explicitly -// requested for initialization/debug repair. +// Territory follows a weighted nearest-city model. Distance is primary, while +// city/state power, loyalty, trade, terrain and culture shift the boundary. clearTerritories() { const w = this.world; this.syncVisibleTerritoryOwners(); @@ -2366,19 +2498,39 @@ recomputeTerritories(options = {}) { const w = this.world; const allowOwnershipChanges = !!options.allowOwnershipChanges; this.clearTerritories(); -if (!this.polities.length || !this.cities.length) return; +if (!this.polities.length || !this.cities.length) { +this.enforceTerritoryConnectivity(); +return; +} const best = this.scratchFloatA; const second = this.scratchFloatB; +const incumbent = this.scratchFloatC; const owner = this.scratchIntB; +const bestSupport = this.territoryBestSupport; +const incumbentSupport = this.territoryIncumbentSupport; best.fill(0); second.fill(0); +incumbent.fill(0); owner.fill(-1); +bestSupport.fill(0); +incumbentSupport.fill(0); for (const polity of this.polities) { const polityCities = this.getPolityCities(polity); if (!polityCities.length) continue; const center = this.getCityById(polity.centerCityId) || polityCities[0]; const maxRange = clamp(Math.ceil(this.polityInfluenceRange(polity, false)), 8, 36); for (const city of polityCities) { +const targetPopulationSupport = clamp( +Math.sqrt(Math.max(0, city.population || 0) / (SimConfig.territory?.fullMaintenanceCityPopulation ?? 2400)), +SimConfig.territory?.minimumPopulationSupport ?? 0.28, +1 +); +if (city.territorySupport == null) city.territorySupport = targetPopulationSupport; +else if (city.territorySupportUpdatedAt !== this.year) { +city.territorySupport = lerp(city.territorySupport, targetPopulationSupport, SimConfig.territory?.supportSmoothing ?? 0.18); +} +city.territorySupportUpdatedAt = this.year; +const populationSupport = city.territorySupport; const cityTile = w.idx(city.x, city.y); const cityEthnicity = this.dominantCityEthnicity(city); const capitalDistance = center ? this.effectiveDistance(center, city) : 0; @@ -2386,46 +2538,97 @@ const capitalFactor = city.id === polity.centerCityId ? 1.28 : clamp(1 - capital const loyaltyFactor = 0.62 + clamp(city.loyalty ?? 0.5, 0, 1) * 0.58; const tradeFactor = 1 + clamp((city.tradeReach || 0) / 60, 0, 0.42) + clamp((city.tradeValue || 0) * 0.10, 0, 0.22); const baseInfluence = Math.max(1, this.cityInfluence(city)) * capitalFactor * loyaltyFactor * tradeFactor; -const radius = clamp(Math.ceil(maxRange * (0.62 + clamp(Math.sqrt(city.population || 1) / 30, 0, 0.45))), 6, maxRange); -for (const { dx, dy, distance: manhattan } of this.getRadiusOffsets(radius)) { +const normalizedInfluence = baseInfluence / Math.sqrt(SimConfig.city.populationScale || 1); +const cityPowerReach = clamp(Math.log1p(normalizedInfluence) * (SimConfig.territory?.cityPowerWeight ?? 1.8), 2, 10); +const capitalReach = city.id === polity.centerCityId ? (SimConfig.territory?.capitalReachBonus ?? 1.5) : 0; +const radiusScale = (SimConfig.territory?.radiusScale ?? 0.5) * populationSupport; +const radius = clamp( +Math.ceil(maxRange * (0.62 + clamp(Math.sqrt(city.population || 1) / 30, 0, 0.45)) * radiusScale), +3, +Math.max(3, Math.ceil(maxRange * radiusScale)) +); +for (const { dx, dy } of this.getRadiusOffsets(Math.ceil(radius * Math.SQRT2))) { +const distance = Math.hypot(dx, dy); +if (distance > radius) continue; const x = city.x + dx; const y = city.y + dy; if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; const tile = w.idx(x, y); const isWater = w.terrain[tile] === Terrain.WATER; if (isWater && tile !== cityTile && !w.tradeRoute[tile] && !this.territoryWaterAnchor(tile)) continue; +if ((w.population[tile] || 0) <= 0 && tile !== cityTile) continue; const routeBoost = w.tradeRoute[tile] ? 1.28 : 1; const terrainDrag = isWater ? 2.35 : w.move[tile] * (w.terrain[tile] === Terrain.MOUNTAIN ? 1.18 : 1); -const effectiveDistance = (manhattan + terrainDrag * 1.4) / routeBoost; -const distanceFalloff = clamp(1 - effectiveDistance / (radius + 4), 0, 1); -if (distanceFalloff <= 0) continue; +const effectiveDistance = (distance + terrainDrag * 1.4) / routeBoost; const localEthnicity = w.dominantEthnicity[tile]; -const ethnicityFactor = cityEthnicity !== null && localEthnicity >= 0 && cityEthnicity !== localEthnicity ? 0.82 : 1.06; -const populationAnchor = clamp(Math.sqrt(Math.max(0, w.population[tile])) / 20, 0, 0.28); -const score = baseInfluence * distanceFalloff * distanceFalloff * routeBoost * ethnicityFactor * (1 + populationAnchor) / (1 + terrainDrag * 0.18); +const ethnicityShift = cityEthnicity !== null && localEthnicity >= 0 && cityEthnicity !== localEthnicity ? -0.65 : 0.35; +const populationAnchor = clamp(Math.sqrt(Math.max(0, w.population[tile])) / 40, 0, 0.7); +const maintainedReach = (SimConfig.territory?.baseCityReach ?? 9) * (0.45 + populationSupport * 0.55); +const score = maintainedReach - effectiveDistance + cityPowerReach * populationSupport + capitalReach + ethnicityShift + populationAnchor; if (score <= 0.8) continue; +if (w.territoryOwner[tile] === polity.id && score > incumbent[tile]) { +incumbent[tile] = score; +incumbentSupport[tile] = populationSupport; +} if (score > best[tile]) { if (owner[tile] !== polity.id) second[tile] = best[tile]; best[tile] = score; owner[tile] = polity.id; +bestSupport[tile] = populationSupport; } else if (owner[tile] !== polity.id && score > second[tile]) { second[tile] = score; } } } } -const threshold = 2.4; +const threshold = SimConfig.territory?.minimumInfluence ?? 2.4; +const rebalanceOwnership = !!options.rebalanceOwnership; +const switchMargin = SimConfig.territory?.ownershipSwitchMargin ?? 1.5; +const activeWarPairs = new Set((this.wars || []) +.filter(war => war.ended === null) +.map(war => `${Math.min(war.aPolityId, war.bPolityId)}:${Math.max(war.aPolityId, war.bPolityId)}`)); for (let i = 0; i < w.count; i++) { const currentOwner = w.territoryOwner[i]; -if (allowOwnershipChanges && currentOwner < 0 && owner[i] >= 0 && best[i] >= threshold) { -this.setTileOwner(i, owner[i], { +const proposedOwner = owner[i]; +const cityHere = w.city[i] >= 0 ? this.getCityById(w.city[i]) : null; +const protectedCityCore = cityHere?.polityId != null && cityHere.polityId !== proposedOwner; +const currentCityCore = cityHere?.polityId === currentOwner; +const atWarAcrossBorder = currentOwner >= 0 && proposedOwner >= 0 && currentOwner !== proposedOwner && +activeWarPairs.has(`${Math.min(currentOwner, proposedOwner)}:${Math.max(currentOwner, proposedOwner)}`); +const currentSupport = incumbentSupport[i] || 0; +const proposedSupport = bestSupport[i] || 0; +const maintenanceThreshold = threshold + (1 - currentSupport) * (SimConfig.territory?.maintenancePressure ?? 4); +const expansionThreshold = threshold + (1 - proposedSupport) * (SimConfig.territory?.maintenancePressure ?? 4); +if ( +allowOwnershipChanges && +currentOwner >= 0 && +currentSupport < 1 && +!currentCityCore && +incumbent[i] < maintenanceThreshold +) { +this.setTileOwner(i, -1); +this.territorialClaims.delete(i); +continue; +} +const shouldSwitchOwner = +rebalanceOwnership && +currentOwner >= 0 && +proposedOwner >= 0 && +proposedOwner !== currentOwner && +!protectedCityCore && +!atWarAcrossBorder && +best[i] >= expansionThreshold && +best[i] >= incumbent[i] + switchMargin + (1 - Math.min(currentSupport, proposedSupport)) * (SimConfig.territory?.smallStateSwitchPenalty ?? 2.5); +if (allowOwnershipChanges && (currentOwner < 0 || shouldSwitchOwner) && proposedOwner >= 0 && best[i] >= expansionThreshold) { +this.setTileOwner(i, proposedOwner, { control: clamp((best[i] - threshold) / 18, 0.12, 1), claim: clamp(best[i] / 22, 0, 1) }); +if (this.territorialClaims.get(i)?.polityId !== proposedOwner) this.territorialClaims.delete(i); continue; } if (currentOwner < 0) { -if (owner[i] >= 0 && best[i] >= threshold) { +if (owner[i] >= 0 && best[i] >= expansionThreshold) { w.claim[i] = clamp(best[i] / 28, 0, 0.45); if (second[i] > best[i] * 0.72) w.contested[i] = 1; } @@ -2443,8 +2646,103 @@ if (owner[i] >= 0 && owner[i] !== currentOwner && best[i] >= threshold * 0.8) w. } this.applyStoredTerritorialClaims(); this.enforceCityTerritoryAnchors(options); +if (allowOwnershipChanges) this.smoothTerritoryBorders(1); +this.pruneUnpopulatedTerritory(); this.enforceTerritoryConnectivity(options); } +pruneUnpopulatedTerritory() { +const w = this.world; +for (let tile = 0; tile < w.count; tile++) { +if (w.territoryOwner[tile] < 0 || (w.population[tile] || 0) > 0) continue; +const city = w.city[tile] >= 0 ? this.getCityById(w.city[tile]) : null; +if (city && city.population > 0) continue; +this.setTileOwner(tile, -1); +this.territorialClaims.delete(tile); +} +} +smoothTerritoryBorders(passes = 2) { +const w = this.world; +const source = this.scratchIntA; +const protectedTiles = this.scratchUintA; +protectedTiles.fill(0); +for (const city of this.cities) { +const tile = w.idx(city.x, city.y); +protectedTiles[tile] = 1; +for (let n = w.landNeighborStarts[tile]; n < w.landNeighborStarts[tile + 1]; n++) { +protectedTiles[w.landNeighbors[n]] = 1; +} +} +for (let pass = 0; pass < passes; pass++) { +source.set(w.territoryOwner); +let changed = 0; +for (let tile = 0; tile < w.count; tile++) { +if (w.terrain[tile] === Terrain.WATER || protectedTiles[tile] || w.tradeRoute[tile]) continue; +const start = w.landNeighborStarts[tile]; +const end = w.landNeighborStarts[tile + 1]; +if (end - start < 6) continue; // Preserve coasts and the edge of the world. +const owner = source[tile]; +let candidate = -1; +let same = 0; +let neutral = 0; +let foreign = false; +for (let n = start; n < end; n++) { +const neighborOwner = source[w.landNeighbors[n]]; +if (neighborOwner < 0) neutral++; +else if (owner >= 0) { +if (neighborOwner === owner) same++; +else foreign = true; +} else if (candidate < 0) { candidate = neighborOwner; same++; } +else if (neighborOwner === candidate) same++; +else foreign = true; +} +const x = tile % w.size; +let cardinal = 0; +const target = owner >= 0 ? owner : candidate; +if (x > 0 && source[tile - 1] === target) cardinal++; +if (x < w.size - 1 && source[tile + 1] === target) cardinal++; +if (tile >= w.size && source[tile - w.size] === target) cardinal++; +if (tile < w.count - w.size && source[tile + w.size] === target) cardinal++; +if (foreign) { +// At a shared border, move only small leaves toward a clear local majority. +// Tiles with two connections to their own country can be bridges: keep them. +if (owner < 0 || cardinal > 1) continue; +let majority = -1; +let votes = 0; +for (let n = start; n < end; n++) { +const id = source[w.landNeighbors[n]]; +if (!votes) { majority = id; votes = 1; } +else votes += id === majority ? 1 : -1; +} +if (majority < 0 || majority === owner) continue; +let count = 0; +let touching = false; +for (let n = start; n < end; n++) { +const neighbor = w.landNeighbors[n]; +if (source[neighbor] !== majority) continue; +count++; +if (neighbor === tile - w.size || neighbor === tile + w.size || +(Math.floor(neighbor / w.size) === Math.floor(tile / w.size) && Math.abs(neighbor - tile) === 1)) touching = true; +} +if (count < 5 || !touching) continue; +this.setTileOwner(tile, majority, { control: 0.22, claim: 0.35, contested: false }); +this.territorialClaims.set(tile, { polityId: majority, control: 0.22, claim: 0.35, reason: "borderSmoothing", year: this.year }); +changed++; +continue; +} +if (owner < 0 && candidate >= 0 && same >= 5 && cardinal >= 2) { +this.setTileOwner(tile, candidate, { control: 0.22, claim: 0.35 }); +changed++; +} else if (owner >= 0 && neutral >= 5 && cardinal <= 1) { +// Trim only leaves; keep narrow bridges and corridors connected. +this.setTileOwner(tile, -1); +this.territorialClaims.delete(tile); +changed++; +} +} +if (!changed) break; +} +this.syncVisibleTerritoryOwners(); +} applyStoredTerritorialClaims() { const w = this.world; const validPolities = this.validPolityIds(); @@ -2477,9 +2775,8 @@ for (const city of this.cities) { if (city.population <= 0) continue; const tile = w.idx(city.x, city.y); if (city.polityId === null) { -if (w.territoryOwner[tile] >= 0) { -w.contested[tile] = 1; -} +this.setTileOwner(tile, -1); +this.territorialClaims.delete(tile); continue; } const polity = this.getPolityById(city.polityId); @@ -2494,9 +2791,13 @@ if (w.terrain[t] === Terrain.WATER) continue; const otherCity = w.city[t] >= 0 ? this.getCityById(w.city[t]) : null; if (otherCity && otherCity.id !== city.id && otherCity.polityId !== city.polityId) continue; const core = dx === 0 && dy === 0; +if (core || (allowOwnershipChanges && w.territoryOwner[t] < 0)) this.setTileOwner(t, polity.id); +if (core && this.territorialClaims.get(t)?.polityId !== polity.id) this.territorialClaims.delete(t); const ownedByCityPolity = w.territoryOwner[t] === polity.id; -if (allowOwnershipChanges && (core || w.territoryOwner[t] < 0)) this.setTileOwner(t, polity.id); -else if (!ownedByCityPolity) w.contested[t] = 1; +if (!ownedByCityPolity) { +if (w.territoryOwner[t] >= 0) w.contested[t] = 1; +continue; +} w.control[t] = Math.max(w.control[t], core ? 0.55 : 0.35); w.claim[t] = Math.max(w.claim[t], core ? 0.62 : 0.40); if (core && (ownedByCityPolity || allowOwnershipChanges)) w.contested[t] = 0; @@ -2506,40 +2807,38 @@ if (core && (ownedByCityPolity || allowOwnershipChanges)) w.contested[t] = 0; } enforceTerritoryConnectivity(options = {}) { const w = this.world; -if (!options.allowOwnershipChanges) { -this.syncVisibleTerritoryOwners(); -return 0; -} +this.enforceCityTerritoryAnchors(); let removed = 0; -for (const polity of this.polities) { -const seeds = this.getPolityCities(polity).map(city => w.idx(city.x, city.y)); -if (!seeds.length) continue; const reachable = this.visitStamp; const marker = this.nextVisitMarker(); -const queue = []; -for (const seed of seeds) { -if (w.territoryOwner[seed] !== polity.id) continue; +const queue = this.scratchIntA; +let tail = 0; +const validPolities = this.validPolityIds(); +for (const city of this.cities) { +if (city.population <= 0 || city.polityId == null || !validPolities.has(city.polityId)) continue; +const seed = w.idx(city.x, city.y); +if (w.terrain[seed] === Terrain.WATER || w.territoryOwner[seed] !== city.polityId || reachable[seed] === marker) continue; reachable[seed] = marker; -queue.push(seed); +queue[tail++] = seed; } -for (let q = 0; q < queue.length; q++) { +// All countries share one traversal: each tile is visited at most once. +for (let q = 0; q < tail; q++) { const tile = queue[q]; +const owner = w.territoryOwner[tile]; this.forCardinalNeighbors(tile, n => { -if (reachable[n] === marker || w.territoryOwner[n] !== polity.id) return; -if (w.terrain[n] === Terrain.WATER && (!w.tradeRoute[n] || !this.territoryWaterAnchor(n))) return; +if (reachable[n] === marker || w.territoryOwner[n] !== owner || w.terrain[n] === Terrain.WATER) return; reachable[n] = marker; -queue.push(n); +queue[tail++] = n; }); } for (let i = 0; i < w.count; i++) { -if (w.territoryOwner[i] !== polity.id || reachable[i] === marker) continue; +if (w.territoryOwner[i] < 0 || reachable[i] === marker) continue; this.setTileOwner(i, -1); -const stored = this.territorialClaims.get(i); -if (stored?.polityId === polity.id) this.territorialClaims.delete(i); +this.territorialClaims.delete(i); removed++; } -} this.territoryDebug.disconnectedTerritoryRemoved += removed; +this.syncVisibleTerritoryOwners(); return removed; } reconcileCityTerritoryOwnership() { @@ -2573,46 +2872,6 @@ if (Math.abs(cx - x) + Math.abs(cy - y) <= radius || campaign.targetTile === til } return false; } -surroundingPolityForCity(city, radius) { -const w = this.world; -const counts = new Map(); -const controls = new Map(); -let total = 0; -for (const { dx, dy } of this.getRadiusOffsets(radius)) { -const x = city.x + dx; -const y = city.y + dy; -if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; -const tile = w.idx(x, y); -const owner = w.polity[tile]; -if (owner < 0) continue; -total++; -counts.set(owner, (counts.get(owner) || 0) + 1); -controls.set(owner, (controls.get(owner) || 0) + (w.control[tile] || 0)); -} -let best = null; -let count = 0; -for (const [id, value] of counts) { -if (value > count) { -best = id; -count = value; -} -} -const polity = best != null ? this.getPolityById(best) : null; -return polity ? { polity, share: count / Math.max(1, total), control: (controls.get(best) || 0) / Math.max(1, count) } : null; -} -clearIndependentCityEnclave(city, radius) { -const w = this.world; -for (const { dx, dy } of this.getRadiusOffsets(radius)) { -const x = city.x + dx; -const y = city.y + dy; -if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; -const tile = w.idx(x, y); -if (w.terrain[tile] === Terrain.WATER) continue; -w.control[tile] = 0; -w.claim[tile] = 0; -w.contested[tile] = 0; -} -} territoryWaterAnchor(tile) { const w = this.world; let anchored = false; @@ -2635,23 +2894,6 @@ return false; }); return border; } -territoryStatsForPolity(polity) { -const w = this.world; -const stats = { tiles: 0, population: 0, coreTiles: 0, contestedTiles: 0, borderTiles: 0 }; -if (!polity) return stats; -for (let i = 0; i < w.count; i++) { -if (w.polity[i] !== polity.id) continue; -stats.tiles++; -stats.population += w.population?.[i] || 0; -if (w.control[i] >= 0.55 && !w.contested[i]) stats.coreTiles++; -if (w.contested[i]) stats.contestedTiles++; -if (this.isBorderTile(i)) stats.borderTiles++; -} -if (stats.population <= 0) { -stats.population = this.getPolityCities(polity).reduce((sum, city) => sum + Math.max(0, city.population || 0), 0); -} -return stats; -} campaignPressureOnTerritories() { const w = this.world; const cfg = SimConfig.campaign || {}; @@ -2681,21 +2923,26 @@ w.claim[tile] = Math.max(w.claim[tile], local); w.contested[tile] = 1; } } -this.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); } } getCityById(id) { const cached = this.cityById?.get(id); if (cached) return cached; const city = this.cities.find(c => c.id === id) || null; -if (city) this.cityById.set(id, city); +if (city) { +this.cityById ??= new Map(); +this.cityById.set(id, city); +} return city; } getPolityById(id) { const cached = this.polityById?.get(id); if (cached) return cached; const polity = this.polities.find(p => p.id === id) || null; -if (polity) this.polityById.set(id, polity); +if (polity) { +this.polityById ??= new Map(); +this.polityById.set(id, polity); +} return polity; } getPolityCities(polity) { @@ -2802,13 +3049,16 @@ cityIds: new Set(), treasury: Math.max(0, centerCity.storedResources * 0.12), color: hslToRgb((id * 0.38196601125) % 1, 0.58, 0.62), founded: this.year, +nextWarAllowedWeek: this.year + years(SimConfig.polity.foundingProtectionYears ?? 12), legitimacy: this.rng.range(0.68, 0.94), cohesion: this.rng.range(0.58, 0.9), charisma: this.rng.range(SimConfig.polity.charismaMin ?? 0.5, SimConfig.polity.charismaMax ?? 1.5), leaderStarted: this.year, leaderTenureYears: this.rng.range(SimConfig.polity.leaderTenureMinYears ?? 24, SimConfig.polity.leaderTenureMaxYears ?? 68), crisis: 0, -lastCrisisYear: this.year +lastCrisisYear: this.year, +institutionalAging: 0, +lastInstitutionalReformYear: this.year }; this.polities.push(polity); this.polityById.set(polity.id, polity); @@ -2818,6 +3068,7 @@ control: 0.72, claim: 0.85, reason: "founding" }); +this.enforcePolityTreasuryCap(polity); this.claimPolityCoreTerritory(polity, centerCity, 4, "founding"); this.ensurePolityHistory(polity); this.samplePolityHistory(polity); @@ -2871,6 +3122,8 @@ cities: cities.length, population, treasury, avgLoyalty, +institutionalAging: clamp(polity.institutionalAging ?? 0, 0, 1), +loyaltyCap: this.polityLoyaltyCap ? this.polityLoyaltyCap(polity) : 1, power: typeof this.polityPower === "function" ? this.polityPower(polity) : fallbackPower }; history.samples.push(sample); @@ -2884,6 +3137,24 @@ while (history.samples.length > maxSamples) history.samples.shift(); samplePolityHistories() { for (const polity of this.polities) this.samplePolityHistory(polity); } +sampleWorldHistory() { +let regionalPopulation = 0; +for (const tile of this.activePopulationTiles) regionalPopulation += Math.max(0, this.world.population[tile] || 0); +const urbanPopulation = this.cities.reduce((sum, city) => sum + Math.max(0, city.population || 0), 0); +const sample = { +year: this.year, +regionalPopulation, +urbanPopulation, +cities: this.cities.length, +polities: this.polities.length, +ethnicities: [...this.ethnicities.values()].filter(ethnicity => (ethnicity.population || 0) > 0).length +}; +const last = this.worldHistory[this.worldHistory.length - 1]; +if (last?.year === this.year) this.worldHistory[this.worldHistory.length - 1] = sample; +else this.worldHistory.push(sample); +const maxSamples = (SimConfig.render.historyWindowYears + SimConfig.render.historySamplePaddingYears) * 4; +while (this.worldHistory.length > maxSamples) this.worldHistory.shift(); +} addPolityEvent(polityId, type, year = this.year, data = {}, importance = 1) { let history = this.polityHistory.get(polityId) || this.deadPolityHistories.find(h => h.id === polityId) || null; if (!history) { @@ -3079,6 +3350,110 @@ this.disasters = this.disasters .slice(-(config?.maxActiveVisuals ?? 12)); while (this.disasterHistory.length > (config?.maxHistory ?? 160)) this.disasterHistory.shift(); } +triggerManualDisasterAt(x, y) { +const w = this.world; +const tx = clamp(Math.floor(x), 0, w.size - 1); +const ty = clamp(Math.floor(y), 0, w.size - 1); +const cfg = SimConfig.disaster || {}; +const radius = this.rng.range(Math.max(5, cfg.minRadius ?? 6), Math.min(24, cfg.maxRadius ?? 34)); +const intensity = this.rng.range(Math.max(0.48, cfg.minIntensity ?? 0.25), Math.min(0.82, cfg.maxIntensity ?? 0.95)); +const beforeId = this.nextDisaster; +this.applyDisaster(tx, ty, radius, intensity); +const record = this.disasterHistory.find(item => item.id === beforeId) || this.disasterHistory[this.disasterHistory.length - 1]; +return { ok: true, record, x: tx, y: ty, radius, intensity }; +} +manualCityEthnicitySeed(tile) { +const w = this.world; +const local = this.tileEthnicMix.get(tile); +if (local?.size) return new Map(local); +const dominant = w.dominantEthnicity[tile]; +if (dominant >= 0) return new Map([[dominant, 1]]); +const tx = tile % w.size; +const ty = Math.floor(tile / w.size); +let nearest = null; +let nearestDistance = Infinity; +for (const [cultureTile, mix] of this.tileEthnicMix) { +if (!mix?.size) continue; +const distance = Math.abs(cultureTile % w.size - tx) + Math.abs(Math.floor(cultureTile / w.size) - ty); +if (distance < nearestDistance) { +nearest = mix; +nearestDistance = distance; +if (distance <= 2) break; +} +} +if (nearest?.size) return new Map(nearest); +let nearestCity = null; +let cityDistance = Infinity; +for (const city of this.cities) { +if (!city.ethnicityComposition?.size) continue; +const distance = Math.abs(city.x - tx) + Math.abs(city.y - ty); +if (distance < cityDistance) { +nearestCity = city; +cityDistance = distance; +} +} +if (nearestCity) return new Map(nearestCity.ethnicityComposition); +const ethnicityId = this.createEthnicity(0, { +temperature: w.temperature[tile], +humidity: w.humidity[tile] +}); +const ethnicity = this.ethnicities.get(ethnicityId); +if (ethnicity) ethnicity.averageTraits = this.randomTraits(); +return new Map([[ethnicityId, 1]]); +} +applyCityEthnicitySeed(city, seed, population) { +city.ethnicityComposition ??= new Map(); +city.ethnicityComposition.clear(); +let total = 0; +for (const count of seed?.values?.() || []) total += Math.max(0, count || 0); +if (total <= 0) return; +let assigned = 0; +const entries = [...seed.entries()]; +for (let index = 0; index < entries.length; index++) { +const [id, count] = entries[index]; +const amount = index === entries.length - 1 +? Math.max(0, population - assigned) +: Math.max(0, Math.round(population * Math.max(0, count || 0) / total)); +if (amount <= 0) continue; +city.ethnicityComposition.set(id, amount); +assigned += amount; +} +} +buildCityAt(x, y) { +const w = this.world; +const tx = clamp(Math.floor(x), 0, w.size - 1); +const ty = clamp(Math.floor(y), 0, w.size - 1); +const tile = w.idx(tx, ty); +// Manual intervention bypasses natural spacing and the automatic-city cap, +// but cities still require land. +if (w.terrain[tile] === Terrain.WATER) return { ok: false, reason: "water", x: tx, y: ty }; +const ethnicitySeed = this.manualCityEthnicitySeed(tile); +const city = this.createCity(tx, ty); +const basePopulation = city.population; +const targetPopulation = Math.max(1, SimConfig.city.initialPopulation ?? 400); +this.applyCityEthnicitySeed(city, ethnicitySeed, targetPopulation); +city.population = targetPopulation; +city.peakPopulation = targetPopulation; +city.storedResources = Math.max(city.storedResources, targetPopulation * 0.20); +city.strength = Math.max(city.strength, 6); +city.activeVisitors = Math.max(city.activeVisitors, 12); +if (targetPopulation > basePopulation) { +city.population = targetPopulation - basePopulation; +this.projectCityPopulationToTiles(city); +city.population = targetPopulation; +} +this.cities.push(city); +this.rebuildIndexes(); +w.city[tile] = city.id; +this.assignNewCityToTerritoryOwner(city, tile, { explicit: true }); +if (city.polityId !== null) { +const polity = this.getPolityById(city.polityId); +if (polity) this.claimPolityCoreTerritory(polity, city, 3, "manualCity"); +} +this.updatePopulationCapacity(); +this.syncTilePopulationCulture(); +return { ok: true, city }; +} markPolityEnded(polity, reason = "dissolved") { if (!polity) return; const history = this.ensurePolityHistory(polity); @@ -3090,7 +3465,7 @@ history.fate = reason; history.centerCityId = polity.centerCityId ?? history.centerCityId; this.polityHistory.delete(polity.id); this.deadPolityHistories.push(history); -while (this.deadPolityHistories.length > 80) this.deadPolityHistories.shift(); +while (this.deadPolityHistories.length > 20) this.deadPolityHistories.shift(); } getAllPolityHistories() { return [...this.deadPolityHistories, ...this.polityHistory.values()] @@ -3129,6 +3504,8 @@ war.ended === null && } startWar(a, b) { if (!a || !b || a.id === b.id) return null; +if (this.year < (a.nextWarAllowedWeek ?? 0) || this.year < (b.nextWarAllowedWeek ?? 0)) return null; +if (this.wars.filter(war => war.ended === null).length >= SimConfig.war.maxActiveWars) return null; if (this.getWarBetween(a.id, b.id)) return null; if (this.isPolityAtWar(a.id) || !this.canBeWarTarget(b.id)) return null; const id = this.nextWar++; @@ -3140,7 +3517,7 @@ bPolityId: b.id, goal, started: this.year, lastActionYear: this.year, -intensity: this.rng.range(0.45, 1.05), +intensity: this.rng.range(0.9, 1.4), exhaustionA: 0, exhaustionB: 0, scoreA: 0, @@ -3152,6 +3529,8 @@ lastFrontAdvanceYear: new Map(), ended: null }; this.wars.push(war); +this.addPolityEvent(a.id, "war", this.year, { outcome: "started", targetPolityId: b.id }, 2); +this.addPolityEvent(b.id, "war", this.year, { outcome: "started", targetPolityId: a.id }, 2); a.crisis = clamp((a.crisis || 0) + 0.04, 0, 1.5); b.crisis = clamp((b.crisis || 0) + 0.04, 0, 1.5); return war; @@ -3175,6 +3554,16 @@ endWar(war) { if (!war || war.ended !== null) return; this.applyWarSettlement(war); war.ended = this.year; +for (const [id, other] of [[war.aPolityId, war.bPolityId], [war.bPolityId, war.aPolityId]]) { +const polity = this.getPolityById(id); +if (polity) polity.nextWarAllowedWeek = Math.max(polity.nextWarAllowedWeek || 0, this.year + SimConfig.war.cooldownWeeks); +this.addPolityEvent(id, "war", this.year, { outcome: "ended", targetPolityId: other }, 2); +} +for (const campaign of this.campaigns) { +if (campaign.status === "active" && campaign.type === "border_war" && +((campaign.attackerPolityId === war.aPolityId && campaign.defenderPolityId === war.bPolityId) || +(campaign.attackerPolityId === war.bPolityId && campaign.defenderPolityId === war.aPolityId))) campaign.status = "ceased"; +} } totalPolityPopulation(polity) { return this.getPolityCities(polity) @@ -3258,6 +3647,128 @@ if (distance < best) best = distance; } return best; } +polityTreasuryCap(polity) { +if (!polity) return 0; +const perPopulation = Math.max(0, SimConfig.polity?.treasuryCapPerPopulation ?? 0.30); +return Math.max(0, this.totalPolityPopulation(polity) * perPopulation); +} +enforcePolityTreasuryCap(polity) { +if (!polity) return 0; +const cap = this.polityTreasuryCap(polity); +polity.treasury = clamp(polity.treasury || 0, 0, cap); +return cap; +} +enforcePolityTreasuryCaps() { +for (const polity of this.polities) this.enforcePolityTreasuryCap(polity); +} +treasuryCityInvestmentProfile(cost) { +const cfg = SimConfig.polity || {}; +const safeCost = Math.max(0, cost || 0); +const basePopulation = Math.max(1, SimConfig.city.initialPopulation ?? 400); +const populationPerCost = Math.max(0, cfg.treasuryCityPopulationPerCost ?? 0.18); +const reservePerCost = Math.max(0, cfg.treasuryCityReservePerCost ?? 0.45); +const population = Math.max(basePopulation, Math.round(basePopulation + safeCost * populationPerCost)); +const resources = +34 * SimConfig.city.populationScale + +safeCost * reservePerCost + +Math.max(0, population - basePopulation) * 0.22; +return { population, resources }; +} +findTreasuryCityFoundingSite(polity) { +if (!polity) return -1; +const w = this.world; +const cities = this.getPolityCities(polity); +if (!cities.length) return -1; +const spacing = Math.max(1, SimConfig.city.naturalFoundingMinDistance ?? 6); +const radius = Math.max(spacing + 1, SimConfig.polity?.treasuryCityFoundingSearchRadius ?? 20); +const candidates = []; +const visited = new Set(); +for (const source of cities) { +for (const { dx, dy, distance } of this.getRadiusOffsets(radius, false)) { +if (distance < spacing) continue; +const x = source.x + dx; +const y = source.y + dy; +if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; +const tile = w.idx(x, y); +if (visited.has(tile)) continue; +visited.add(tile); +if (w.terrain[tile] === Terrain.WATER || w.city[tile] >= 0) continue; +if (w.territoryOwner[tile] !== polity.id) continue; +if (this.getCitiesNear(x, y, spacing - 1).length) continue; +const route = w.tradeRoute[tile] ? 1.25 : clamp((w.pheromone[tile] || 0) / 12, 0, 0.8); +const score = +(w.fertility[tile] || 0) * 3.2 + +clamp((w.resource[tile] || 0) / 20, 0, 2.5) + +(w.populationPressure[tile] || 0) * 1.6 + +(w.farmland[tile] || 0) * 1.4 + +(w.control[tile] || 0) * 1.2 + +route - +(w.move[tile] || 1) * 0.75; +candidates.push({ tile, score }); +} +} +if (!candidates.length) return -1; +candidates.sort((a, b) => b.score - a.score); +const bestScore = candidates[0].score; +const scoreWindow = Math.max(0.2, SimConfig.polity?.treasuryCitySiteScoreWindow ?? 6.0); +const eligible = candidates.filter(candidate => candidate.score >= bestScore - scoreWindow); +const floor = bestScore - scoreWindow; +let totalWeight = 0; +for (const candidate of eligible) { +candidate.weight = Math.pow(Math.max(0.20, candidate.score - floor + 0.20), 1.10); +totalWeight += candidate.weight; +} +let roll = this.rng.next() * totalWeight; +for (const candidate of eligible) { +roll -= candidate.weight; +if (roll <= 0) return candidate.tile; +} +return eligible[eligible.length - 1]?.tile ?? candidates[0].tile; +} +maybeBuildTreasuryCities() { +const cfg = SimConfig.polity || {}; +const chance = clamp(cfg.treasuryCityFoundingChance ?? 0.14, 0, 1); +const costRatio = clamp(cfg.treasuryCityFoundingCostRatio ?? 0.35, 0, 1); +if (chance <= 0 || costRatio <= 0 || this.cities.length >= SimConfig.city.maxCities) return 0; +let founded = 0; +for (const polity of [...this.polities]) { +if (this.cities.length >= SimConfig.city.maxCities) break; +const cap = this.polityTreasuryCap(polity); +if (cap <= 0 || (polity.treasury || 0) + 1e-6 < cap) continue; +if (this.rng.next() >= chance) continue; +const tile = this.findTreasuryCityFoundingSite(polity); +if (tile < 0) continue; +const cost = Math.min(polity.treasury || 0, cap * costRatio); +if (cost <= 0) continue; +const x = tile % this.world.size; +const y = Math.floor(tile / this.world.size); +const ethnicitySeed = this.manualCityEthnicitySeed(tile); +const investment = this.treasuryCityInvestmentProfile(cost); +const city = this.createCity(x, y, null, { +initialPopulation: investment.population, +initialResources: investment.resources +}); +this.applyCityEthnicitySeed(city, ethnicitySeed, city.population); +city.strength = Math.max(city.strength, 4.5); +city.activeVisitors = Math.max(city.activeVisitors, 6); +this.cities.push(city); +this.cityById.set(city.id, city); +const bucketKey = this.cityBucketKey(city.x, city.y); +if (!this.cityBuckets.has(bucketKey)) this.cityBuckets.set(bucketKey, []); +this.cityBuckets.get(bucketKey).push(city); +this.world.city[tile] = city.id; +this.addCityToPolity(city, polity, 0.72); +this.claimPolityCoreTerritory(polity, city, 3, "treasuryCity"); +polity.treasury = Math.max(0, (polity.treasury || 0) - cost); +founded++; +} +if (founded) { +this.rebuildIndexes(); +this.updatePopulationCapacity(); +this.syncTilePopulationCulture(); +} +return founded; +} polityAge(polity) { return (this.year - (polity?.founded ?? this.year)) / WEEKS_PER_YEAR; } @@ -3267,6 +3778,51 @@ if (age < 80) return 0; const x = (age - 80) / 420; return clamp(1 - Math.exp(-x), 0, 1.35); } +polityInstitutionalAging(polity) { +return clamp(polity?.institutionalAging ?? 0, 0, 1); +} +polityLoyaltyCap(polity) { +return clamp(1 - this.polityInstitutionalAging(polity), 0, 1); +} +updateInstitutionalAging() { +const cfg = SimConfig.polity || {}; +const annualIncrease = Math.max(0, cfg.institutionalAgingAnnualIncrease ?? 0.0015); +for (const polity of this.polities) { +polity.institutionalAging = this.polityInstitutionalAging(polity); +if (this.year <= (polity.founded ?? this.year)) continue; +polity.institutionalAging = clamp(polity.institutionalAging + annualIncrease, 0, 1); +} +} +maybeTriggerInstitutionalReforms() { +const cfg = SimConfig.polity || {}; +const threshold = clamp(cfg.institutionalReformThreshold ?? 0.30, 0, 1); +const cooldown = years(Math.max(0, cfg.institutionalReformCooldownYears ?? 50)); +for (const polity of this.polities) { +const before = this.polityInstitutionalAging(polity); +if (before <= threshold) continue; +if (this.year - (polity.lastInstitutionalReformYear ?? polity.founded ?? 0) < cooldown) continue; +const chance = clamp( +(cfg.institutionalReformBaseChance ?? 0.008) + before * (cfg.institutionalReformChanceScale ?? 0.10), +0, +cfg.institutionalReformMaxChance ?? 0.12 +); +if (this.rng.next() >= chance) continue; +const changeRate = this.rng.range( +cfg.institutionalReformMinChange ?? -0.50, +cfg.institutionalReformMaxChange ?? 0.30 +); +const after = clamp(before * (1 + changeRate), 0, 1); +polity.institutionalAging = after; +polity.lastInstitutionalReformYear = this.year; +this.addPolityEvent(polity.id, "institutionalReform", this.year, { +before, +after, +changeRate, +loyaltyCapBefore: clamp(1 - before, 0, 1), +loyaltyCapAfter: clamp(1 - after, 0, 1) +}, 3); +} +} polityOverextension(polity) { const cities = this.getPolityCities(polity); const center = this.getCityById(polity.centerCityId); @@ -3365,60 +3921,6 @@ this.createPolity(city); formed++; } } -expandPolities() { -return; -for (const polity of this.polities) { -const center = this.getCityById(polity.centerCityId); -if (!center) continue; -const centerInfluence = this.cityInfluence(center); -let absorbed = 0; -for (const city of this.cities) { -if (absorbed >= 2) break; -if (city.polityId !== null || city.id === center.id) continue; -const connection = this.polityConnectionToCity(polity, city); -if (!connection.connected) continue; -const distance = connection.distance; -const targetInfluence = this.cityInfluence(city); -if (centerInfluence <= targetInfluence * 0.9) continue; -const dominanceScore = -(centerInfluence / (targetInfluence + 1)) * -(1 / (1 + distance * 0.08)) * -(this.hasDirectTradeConnection(connection.source, city) ? 1.5 : 1.0); -if (dominanceScore > 0.62 && this.rng.next() < 0.24) { -this.addCityToPolity(city, polity, 0.62); -absorbed++; -} -} -} -} -absorbIndependentCities() { -return; -if (this.year % years(5) !== 0) return; -for (const polity of this.polities) { -const cities = this.getPolityCities(polity); -if (!cities.length) continue; -const power = this.polityPower(polity); -const range = this.polityInfluenceRange(polity, false); -let absorbed = 0; -const candidates = this.cities -.filter(city => city.polityId === null && city.population > 0) -.map(city => ({ city, connection: this.polityConnectionToCity(polity, city) })) -.filter(x => x.connection.connected && x.connection.distance <= range) -.sort((a, b) => a.connection.distance - b.connection.distance); -for (const { city, connection } of candidates) { -if (absorbed >= 1) break; -const distance = connection.distance; -const cityInfluence = this.cityInfluence ? this.cityInfluence(city) : Math.sqrt(city.population || 1); -const proximity = 1 / (1 + distance * 0.07); -const pressure = (power / Math.max(1, cityInfluence)) * proximity; -if (pressure > 0.75 && this.rng.next() < clamp(pressure * 0.055, 0.01, 0.22)) { -this.addCityToPolity(city, polity, 0.42); -city.population = Math.max(1, Math.floor(city.population * this.rng.range(0.95, 0.99))); -absorbed++; -} -} -} -} // Phase 1B: campaigns are discrete targeted events. Influence/control can show // continuous territory, but new holdings come from these active campaign objects. maybeStartCampaigns() { @@ -3500,7 +4002,7 @@ const w = this.world; if (w.polity[tile] >= 0 || w.city[tile] >= 0 || w.terrain[tile] === Terrain.WATER) return null; const expansion = this.isValidExpansionTarget(polity, tile, { maxNeutralPath: 7, requireUnowned: true }); if (!expansion) return null; -const population = w.population?.[tile] || w.pressure[tile] || 0; +const population = w.population?.[tile] || 0; const ethnicity = w.dominantEthnicity[tile]; if (population < 2 && ethnicity < 0) return null; const diversity = w.cultureDiversity[tile] || 0; @@ -3697,19 +4199,24 @@ return best; } startCampaign(polity, target) { const cfg = SimConfig.campaign || {}; +if (target.type === "border_war") { +const defender = this.getPolityById(target.defenderPolityId); +if (!defender || (!this.getWarBetween(polity.id, defender.id) && !this.startWar(polity, defender))) return null; +} const duration = years(Math.min(cfg.maxDurationYears ?? 25, (cfg.baseDurationYears ?? 8) + this.rng.int(Math.max(1, (cfg.maxDurationYears ?? 25) - (cfg.baseDurationYears ?? 8) + 1)))); const targetTile = target.targetTile ?? (target.targetCityId ? this.cityTile(this.getCityById(target.targetCityId)) : null); if (targetTile == null) return null; const campaign = { id: this.nextCampaign++, type: target.type, +annexationMode: target.type === "independent_city_annexation" ? this.independentAnnexationMode() : null, attackerPolityId: polity.id, defenderPolityId: target.defenderPolityId ?? null, targetCityId: target.targetCityId ?? null, targetTile, targetEthnicity: target.targetEthnicity ?? null, started: this.year, -expires: this.year + duration, +expires: target.type === "border_war" ? Infinity : this.year + duration, progress: 0, strength: 0, resistance: 0, @@ -3729,13 +4236,18 @@ this.addPolityEvent(polity.id, "expansion", this.year, this.campaignEventData(ca this.addPolityEvent(polity.id, "campaign", this.year, this.campaignEventData(campaign, "started"), 1); return campaign; } +independentAnnexationMode() { +const peacefulShare = SimConfig.campaign?.independentCityPeacefulShare ?? 0.4; +return this.rng.next() < peacefulShare ? "peaceful" : "military"; +} cityTile(city) { return city ? this.world.idx(city.x, city.y) : null; } updateCampaigns() { -if (this.year % years(1) !== 0) return; for (const campaign of this.campaigns) { if (campaign.status !== "active") continue; +const borderWar = campaign.type === "border_war"; +if (this.year % (borderWar ? SimConfig.war.tickWeeks : years(1)) !== 0) continue; const attacker = this.getPolityById(campaign.attackerPolityId); if (!attacker) { campaign.status = "failed"; @@ -3746,7 +4258,7 @@ const resistance = this.campaignResistance(campaign, attacker); campaign.strength = force; campaign.resistance = resistance; const momentum = (force - resistance) / Math.max(1, force + resistance); -campaign.progress = clamp(campaign.progress + 0.09 + momentum * 0.18 + this.rng.range(-0.08, 0.08), -0.35, 1.25); +campaign.progress = clamp(campaign.progress + (borderWar ? 0.25 + momentum * 0.4 : 0.09 + momentum * 0.18) + this.rng.range(-0.08, 0.08), -0.35, 1.25); attacker.treasury = Math.max(0, (attacker.treasury || 0) - Math.max(0.05, force * 0.018)); if (campaign.progress >= 1) this.resolveCampaignSuccess(campaign); else if (campaign.progress <= -0.28) this.resolveCampaignFailure(campaign); @@ -3778,7 +4290,7 @@ const targetCity = this.getCityById(campaign.targetCityId); const defender = campaign.defenderPolityId != null ? this.getPolityById(campaign.defenderPolityId) : null; const connection = this.nearestPolityTileConnection(attacker, tile); const terrain = w.move[tile] * (w.terrain[tile] === Terrain.MOUNTAIN ? 1.45 : 1); -const population = targetCity?.population || w.population[tile] || w.pressure[tile] || 0; +const population = targetCity?.population || w.population[tile] || 0; const defenderPower = defender ? this.polityPower(defender) * 0.55 : 0; const attackerEthnicity = this.dominantCityEthnicity(connection.source); const localEthnicity = targetCity ? this.dominantCityEthnicity(targetCity) : w.dominantEthnicity[tile]; @@ -3801,18 +4313,25 @@ const cityTile = city ? this.world.idx(city.x, city.y) : null; const cityTileOwner = cityTile != null ? this.world.territoryOwner[cityTile] : -1; if (city && city.polityId === null && (cityTileOwner < 0 || cityTileOwner === attacker.id)) { const similarity = this.campaignEthnicSimilarity(attacker, campaign); +const peaceful = campaign.annexationMode === "peaceful"; +const resistanceRatio = campaign.resistance / Math.max(1, campaign.strength + campaign.resistance); +if (!peaceful) { +this.applyCityWarDamage(city, clamp(0.025 + resistanceRatio * 0.06, 0.025, 0.10), "independentAnnexation"); +} this.transferCityToPolity(city, attacker, { -loyalty: clamp(0.28 + similarity * 0.34 - campaign.resistance / Math.max(1, campaign.strength + campaign.resistance) * 0.14, 0.16, 0.68), -control: 0.48, -claim: 0.62, -reason: "annexation" +loyalty: peaceful +? clamp(0.58 + similarity * 0.22, 0.58, 0.82) +: clamp(0.20 + similarity * 0.22 - resistanceRatio * 0.12, 0.12, 0.48), +control: peaceful ? 0.58 : 0.46, +claim: peaceful ? 0.68 : 0.62, +reason: peaceful ? "peacefulAnnexation" : "militaryAnnexation" }); -campaign.affectedTiles = this.applyCampaignTerritory(attacker, cityTile, 5, 0.42, { +campaign.affectedTiles = this.applyCampaignTerritory(attacker, cityTile, 5, peaceful ? 0.48 : 0.42, { allowForeignTakeover: false, -reason: "annexation" +reason: peaceful ? "peacefulAnnexation" : "militaryAnnexation" }) || []; } -this.addPolityEvent(attacker.id, "annexation", this.year, this.campaignEventData(campaign, "succeeded"), 2); +this.addPolityEvent(attacker.id, "annexation", this.year, this.campaignEventData(campaign, campaign.annexationMode || "military"), 2); } else if (campaign.type === "border_war") { const defender = this.getPolityById(campaign.defenderPolityId); const city = this.getCityById(campaign.targetCityId); @@ -3864,12 +4383,8 @@ this.addPolityEvent(attacker.id, "colonization", this.year, this.campaignEventDa this.recordCampaign(attacker, campaign, campaign.status); this.syncTilePopulationCulture(); this.recomputeTerritories({ allowOwnershipChanges: false, reason: "campaign" }); -this.applyStoredTerritorialClaims(); -this.enforceCityTerritoryAnchors({ allowOwnershipChanges: false }); -this.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); this.reconcileCityTerritoryOwnership(); this.campaignPressureOnTerritories(); -this.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); } resolveCampaignFailure(campaign, reason = "failed") { campaign.status = reason; @@ -3890,8 +4405,11 @@ const defender = campaign.defenderPolityId != null ? this.getPolityById(campaign if (defender) this.addWarScore(war, defender.id, 0.45 + clamp(campaign.resistance / Math.max(1, campaign.strength), 0, 1.2)); } this.addPolityEvent(attacker.id, "failedCampaign", this.year, this.campaignEventData(campaign, reason), 1); +const peacefulAnnexation = campaign.type === "independent_city_annexation" && campaign.annexationMode === "peaceful"; +if (!peacefulAnnexation) { this.applyPolityWarExhaustionPopulationLoss(attacker, 0.45, clamp(campaign.resistance / Math.max(1, campaign.strength), 0.4, 1.4)); this.applyWarZoneTileDamage(campaign.targetTile, SimConfig.war.warZoneTileLossRate ?? 0.006); +} this.recordCampaign(attacker, campaign, campaign.status); } campaignEthnicSimilarity(polity, campaign) { @@ -3911,7 +4429,12 @@ if (!toPolity && !clearing) return changed; for (const tile of tiles) { if (tile == null || tile < 0 || tile >= w.count || w.terrain[tile] === Terrain.WATER) continue; const owner = w.territoryOwner[tile]; -if (fromPolityId != null && owner !== fromPolityId) continue; +if ( +fromPolityId != null && +owner !== fromPolityId && +owner !== toPolityId && +!(options.allowNeutralWithFrom && owner < 0) +) continue; if (!clearing && owner >= 0 && owner !== toPolityId && !options.allowForeignTakeover) continue; if (owner === toPolityId || (clearing && owner < 0)) continue; this.setTileOwner(tile, toPolityId, { @@ -3950,7 +4473,9 @@ claimPolityCoreTerritory(polity, city, radius = 4, reason = "founding") { if (!polity || !city) return []; const w = this.world; const tiles = []; -for (const { dx, dy, distance } of this.getRadiusOffsets(radius)) { +for (const { dx, dy } of this.getRadiusOffsets(Math.ceil(radius * Math.SQRT2))) { +const distance = Math.hypot(dx, dy); +if (distance > radius) continue; const x = city.x + dx; const y = city.y + dy; if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; @@ -3969,6 +4494,16 @@ claim: 0.58, reason }); } +isConquestTransferReason(reason) { +return reason === "warCapture" || reason === "borderWar" || reason === "militaryAnnexation" || reason === "settlement" || reason === "nomadConquest"; +} +protectCityFromRebellion(city, graceYears = SimConfig.rebellion?.conquestGraceYears ?? 20) { +if (!city) return; +city.rebellionProtectedUntil = Math.max(city.rebellionProtectedUntil || 0, this.year + years(Math.max(0, graceYears))); +} +isCityRebellionProtected(city) { +return !!city && (city.rebellionProtectedUntil || 0) > this.year; +} transferCityToPolity(city, toPolity, options = {}) { if (!city || !toPolity) return false; const fromPolityId = city.polityId; @@ -3981,6 +4516,7 @@ control: options.control ?? 0.58, claim: options.claim ?? 0.70, reason: options.reason ?? "cityTransfer" }); +if (this.isConquestTransferReason(options.reason)) this.protectCityFromRebellion(city, options.rebellionProtectionYears); return true; } releaseCityTerritory(city, fromPolityId, radius = 4, reason = "fragmentation") { @@ -4085,7 +4621,7 @@ return false; } const visited = this.visitStamp; const marker = this.nextVisitMarker(); -const queue = seeds.map(tile => ({ tile, distance: Math.abs((tile % w.size) - cx) + Math.abs(Math.floor(tile / w.size) - cy) })); +const queue = seeds.map(tile => ({ tile, distance: Math.hypot((tile % w.size) - cx, Math.floor(tile / w.size) - cy) })); for (const seed of seeds) visited[seed] = marker; const candidates = []; const maxTiles = options.maxTiles ?? Infinity; @@ -4099,7 +4635,7 @@ const owner = w.territoryOwner[tile]; const canTake = owner === polity.id || (allowForeignTakeover -? (fromPolityId == null ? owner < 0 || owner !== polity.id : owner === fromPolityId) +? (fromPolityId == null ? owner < 0 || owner !== polity.id : owner < 0 || owner === fromPolityId) : owner < 0); if (!canTake) { if (owner >= 0 && owner !== polity.id) w.contested[tile] = 1; @@ -4110,7 +4646,7 @@ candidates.push({ tile, distance, local }); if (candidates.length >= maxTiles) break; this.forCardinalNeighbors(tile, (n, tx, ty) => { if (visited[n] === marker) return; -const nd = Math.abs(tx - cx) + Math.abs(ty - cy); +const nd = Math.hypot(tx - cx, ty - cy); if (nd > radius || w.terrain[n] === Terrain.WATER) return; const neighborOwner = w.territoryOwner[n]; if (neighborOwner >= 0 && neighborOwner !== polity.id && !allowForeignTakeover) { @@ -4131,6 +4667,7 @@ polity.id, ordered.map(entry => entry.tile), { allowForeignTakeover, +allowNeutralWithFrom: allowForeignTakeover && fromPolityId != null, control: Math.max(0.18, strength * 0.65), claim: Math.max(0.22, strength), contested: false, @@ -4209,6 +4746,7 @@ campaignEventData(campaign, outcome) { return { campaignId: campaign.id, campaignType: campaign.type, +annexationMode: campaign.annexationMode ?? null, outcome, targetCityId: campaign.targetCityId ?? null, targetPolityId: campaign.defenderPolityId ?? null, @@ -4249,20 +4787,21 @@ const regionalEthnicity = this.world.dominantEthnicity[targetTile]; const sourceEthnicity = this.dominantCityEthnicity(source) || (regionalEthnicity >= 0 ? regionalEthnicity : 1); composition.set(sourceEthnicity, isFrontier ? 12 : 18); } -const seedPopulation = Math.max(12, Math.round(compositionTotal(composition) * (isFrontier ? 1.2 : 1.6))); +const populationScale = SimConfig.city.populationScale; +const seedPopulation = Math.max(12, Math.round(compositionTotal(composition) * (isFrontier ? 1.2 : 1.6))) * populationScale; +for (const [id, count] of composition) composition.set(id, count * populationScale); const city = { id: this.nextCity++, x: target.x ?? targetTile % w.size, y: target.y ?? Math.floor(targetTile / w.size), population: seedPopulation, -storedResources: 18 + (w.resource[targetTile] || 0) * 0.25, +storedResources: (18 + (w.resource[targetTile] || 0) * 0.25) * populationScale, ethnicityComposition: composition, pheromoneOutput: 0, agriculturalRadius: 2, tradeLinks: new Set(), activeVisitors: 0, age: 0, -ageWear: 0, peakPopulation: seedPopulation, strength: isFrontier ? 1.8 : 2.4, sedentaryCulture: isFrontier ? 0.42 : 0.55, @@ -4272,7 +4811,8 @@ polityId: null, loyalty: isFrontier ? 0.52 : 0.32, receivedAid: false, tradeValue: 0, -tradeReach: 0 +tradeReach: 0, +rebellionProtectedUntil: 0 }; this.cities.push(city); this.cityById.set(city.id, city); @@ -4293,8 +4833,13 @@ this.syncTilePopulationCulture(); return city; } maybeStartWars() { -if (this.year % years(1) !== 0) return; +if (this.year % SimConfig.war.tickWeeks !== 0) return; +let actions = 0; +let warSlots = SimConfig.war.maxActiveWars - this.wars.filter(war => war.ended === null).length; +const maxActions = SimConfig.war.maxStartsPerTick; for (const a of this.polities) { +if (actions >= maxActions) break; +if (this.year < (a.nextWarAllowedWeek ?? 0)) continue; if (this.isPolityAtWar(a.id)) continue; const aPower = this.polityPower(a); if (aPower <= 0) continue; @@ -4302,6 +4847,7 @@ let started = false; for (const b of this.polities) { if (started) break; if (a.id === b.id) continue; +if (this.year < (b.nextWarAllowedWeek ?? 0)) continue; if (!this.canBeWarTarget(b.id)) continue; if (this.getWarBetween(a.id, b.id)) continue; const distance = this.polityDistance(a, b); @@ -4352,9 +4898,12 @@ generalInstability + lowLoyaltyPressure * 0.018 + weakSideLowLoyalty * 0.028 + opportunisticPressure; -if (this.rng.next() < clamp(chance, 0, 0.12)) { -this.startWar(a, b); -started = true; +if (this.rng.next() < clamp(chance * SimConfig.war.startChanceMultiplier, 0, 0.35)) { +if (warSlots > 0) { +started = !!this.startWar(a, b); +if (started) warSlots--; +} +if (started) actions++; } } } @@ -4368,7 +4917,8 @@ const sizePressure = clamp((aCities + bCities - 3) / 8, 0, 1); return proximity * (0.35 + sizePressure * 0.65); } updateWars() { -if (this.year % years(2) !== 0) return; +if (this.year % SimConfig.war.tickWeeks !== 0) return; +this.warLogisticsCache = new Map(); for (const war of this.wars) { if (war.ended !== null) continue; const a = this.getPolityById(war.aPolityId); @@ -4395,19 +4945,20 @@ defender, selected.city, selected.connection.distance, attackerPower, -defenderPower +defenderPower, +selected.connection.logisticsFactor ); const key = `${attacker.id}:${selected.city.id}`; -const memory = (war.cityPressureById?.get(key) || 0) * (SimConfig.war.pressureMemoryDecay ?? 0.88) + pressure * (war.intensity || 0.75); +const memory = (war.cityPressureById?.get(key) || 0) * (SimConfig.war.pressureMemoryDecay ?? 0.88) + pressure * (war.intensity || 0.75) * 1.6; war.cityPressureById?.set(key, memory); const captureThreshold = war.goal === "collapse_exploitation" ? 1.55 : war.goal === "city_conquest" ? 1.75 : war.goal === "capital_pressure" ? 1.85 : 2.15; -const chance = clamp((memory - captureThreshold + pressure * 0.35) * 0.16, 0.01, 0.58); +const chance = clamp((memory - captureThreshold * 0.65 + pressure * 0.35) * 0.45, 0.05, 0.85); const damageRate = clamp( -(SimConfig.war.cityDamageMinRate ?? 0.003) + pressure * 0.010 + memory * 0.006, +(SimConfig.war.cityDamageMinRate ?? 0.003) + pressure * 0.030 + memory * 0.018, SimConfig.war.cityDamageMinRate ?? 0.003, SimConfig.war.cityDamageMaxRate ?? 0.08 ); -if (memory > captureThreshold && pressure > 0.72 && this.rng.next() < chance) { +if (memory > captureThreshold * 0.65 && pressure > 0.55 && this.rng.next() < chance) { this.captureCityInWar(selected.city, attacker, defender, war, pressure); } else { this.applyCityWarDamage(selected.city, damageRate, "warPressure"); @@ -4418,7 +4969,7 @@ const lastAdvance = war.lastFrontAdvanceYear instanceof Map ? (war.lastFrontAdva const canAdvanceFront = memory > 1.05 && pressure > 0.58 && -this.year - lastAdvance > years(4); +this.year - lastAdvance >= SimConfig.war.tickWeeks; if (canAdvanceFront && this.rng.next() < clamp((memory - 0.9) * 0.10 + (pressure - 0.55) * 0.22, 0.02, 0.34)) { const border = this.nearestBorderCampaignTile(attacker, defender); if (border?.tile != null && Number.isFinite(border.distance)) { @@ -4463,6 +5014,7 @@ const routeAccess = this.hasDirectTradeConnection(connection.source, city) || th const cityValue = Math.sqrt(city.population || 1) * 0.10 + (city.tradeValue || 0) * 0.55 + (capital ? 0.9 : 0); const powerAdvantage = clamp(attackerPower / Math.max(1, defenderPower) - 1, -0.4, 2.4); const deepPenalty = Math.max(0, connection.distance - SimConfig.polity.logisticsDistance) * (war.goal === "capital_pressure" ? 0.010 : 0.018); +const logisticsPenalty = (1 - connection.logisticsFactor) * 2.2; const weakState = defenderInstability * 0.55 + (1 - defenderCohesion) * 0.35 + (1 - defenderLegitimacy) * 0.28; const goalBonus = war.goal === "punitive_raid" ? (city.storedResources || 0) * 0.004 : @@ -4470,7 +5022,7 @@ war.goal === "border_claim" ? Math.max(0, 18 - connection.distance) * 0.035 : war.goal === "collapse_exploitation" ? weakState * 0.9 + lowLoyalty * 0.45 : war.goal === "capital_pressure" && capital ? 1.15 : 0.35; -const score = cityValue + lowLoyalty * 0.85 + routeAccess + memory * 0.45 + powerAdvantage * 0.45 + weakState + goalBonus - connection.distance * 0.018 - deepPenalty + (probe ? 0 : this.rng.range(-0.08, 0.10)); +const score = cityValue + lowLoyalty * 0.85 + routeAccess + memory * 0.45 + powerAdvantage * 0.45 + weakState + goalBonus - connection.distance * 0.018 - deepPenalty - logisticsPenalty + (probe ? 0 : this.rng.range(-0.08, 0.10)); if (score > bestScore) { bestScore = score; best = { city, connection, score }; @@ -4490,18 +5042,71 @@ return clamp(base + clamp((ratio - 1) * 12, 0, 18) + routeReach + cohesion + wea warConnectionToCity(polity, city) { let source = null; let distance = Infinity; +let logisticsFactor = 0; +let campaignCost = Infinity; for (const c of this.getPolityCities(polity)) { if (c.id === city.id) continue; let d = this.effectiveDistance(c, city); if (this.hasDirectTradeConnection(c, city)) d *= 0.72; -if (d < distance) { +const logistics = this.warLogisticsFactor(polity, c, city); +const cost = d / Math.max(0.28, logistics); +if (cost < campaignCost) { source = c; distance = d; +logisticsFactor = logistics; +campaignCost = cost; } } -return { source, distance, connected: !!source }; +return { source, distance, connected: !!source, logisticsFactor, campaignCost }; } -warAbsorptionPressure(attacker, defender, city, distance, attackerPower, defenderPower) { +warLogisticsFactor(polity, sourceCity, targetCity) { +if (!polity || !sourceCity || !targetCity) return 0.25; +const capital = this.getCityById(polity.centerCityId) || sourceCity; +const capitalDistance = this.effectiveDistance(capital, targetCity); +const distanceStart = SimConfig.polity.warCapitalDistanceStart ?? 18; +const distanceScale = SimConfig.polity.warCapitalDistanceScale ?? 42; +let factor = 1 / (1 + Math.max(0, capitalDistance - distanceStart) / Math.max(1, distanceScale)); +const connected = sourceCity.id === capital.id || this.territoryRouteConnected(polity.id, capital, sourceCity); +if (!connected) factor *= SimConfig.polity.warDisconnectedTerritoryFactor ?? 0.42; +if (sourceCity.id !== capital.id && this.hasDirectTradeConnection(capital, sourceCity)) factor *= 1.08; +return clamp(factor, 0.18, 1); +} +territoryRouteConnected(polityId, fromCity, toCity) { +if (!fromCity || !toCity) return false; +if (fromCity.id === toCity.id) return true; +const key = `${polityId}:${fromCity.id}:${toCity.id}`; +if (this.warLogisticsCache?.has(key)) return this.warLogisticsCache.get(key); +const w = this.world; +const start = w.idx(fromCity.x, fromCity.y); +const goal = w.idx(toCity.x, toCity.y); +if (w.territoryOwner[start] !== polityId || w.territoryOwner[goal] !== polityId) { +this.warLogisticsCache?.set(key, false); +return false; +} +const visited = this.visitStamp; +const marker = this.nextVisitMarker(); +const queue = this.scratchIntA; +let head = 0; +let tail = 0; +queue[tail++] = start; +visited[start] = marker; +let connected = false; +while (head < tail) { +const tile = queue[head++]; +if (tile === goal) { +connected = true; +break; +} +this.forCardinalNeighbors(tile, neighbor => { +if (visited[neighbor] === marker || w.territoryOwner[neighbor] !== polityId || w.terrain[neighbor] === Terrain.WATER) return; +visited[neighbor] = marker; +queue[tail++] = neighbor; +}); +} +this.warLogisticsCache?.set(key, connected); +return connected; +} +warAbsorptionPressure(attacker, defender, city, distance, attackerPower, defenderPower, logisticsFactor = 1) { const powerRatio = attackerPower / Math.max(1, defenderPower); const proximity = 1 / (1 + distance * 0.055); const defenderInstability = this.polityInstability ? this.polityInstability(defender) : 0; @@ -4522,6 +5127,7 @@ proximity * techAdvantage * ethnicityFactor * tradeFactor * +clamp(logisticsFactor, 0.18, 1) * (1 + defenderInstability * 0.32) * (1 + defenderAge * 0.18) * (1 + defenderOverextension * 0.14) * @@ -4576,8 +5182,8 @@ a.treasury = Math.max(0, (a.treasury || 0) - costA); b.treasury = Math.max(0, (b.treasury || 0) - costB); a.crisis = clamp((a.crisis || 0) + 0.004 * intensity, 0, 1.5); b.crisis = clamp((b.crisis || 0) + 0.004 * intensity, 0, 1.5); -war.exhaustionA = clamp((war.exhaustionA || 0) + 0.006 * intensity, 0, 1); -war.exhaustionB = clamp((war.exhaustionB || 0) + 0.006 * intensity, 0, 1); +war.exhaustionA = clamp((war.exhaustionA || 0) + 0.08 * intensity, 0, 1); +war.exhaustionB = clamp((war.exhaustionB || 0) + 0.08 * intensity, 0, 1); this.applyPolityWarExhaustionPopulationLoss(a, war.exhaustionA || 0, intensity); this.applyPolityWarExhaustionPopulationLoss(b, war.exhaustionB || 0, intensity); } @@ -4591,15 +5197,15 @@ return; const age = this.year - war.started; const noActionFor = this.year - war.lastActionYear; const exhaustion = Math.max(war.exhaustionA || 0, war.exhaustionB || 0); -if (age > years(90)) { +if (!this.getPolityCities(a).length || !this.getPolityCities(b).length) { this.endWar(war); return; } -if (age > years(10) && noActionFor > years(18)) { +if (age >= SimConfig.war.minDurationWeeks && noActionFor >= SimConfig.war.idleEndWeeks) { this.endWar(war); return; } -if (exhaustion > 0.85 && this.rng.next() < 0.35) { +if (age >= SimConfig.war.minDurationWeeks && (exhaustion >= 0.8 || Math.abs((war.scoreA || 0) - (war.scoreB || 0)) >= SimConfig.war.decisiveScore)) { this.endWar(war); } } @@ -4610,16 +5216,20 @@ else if (war.bPolityId === polityId) war.scoreB = (war.scoreB || 0) + amount; } applyCityWarDamage(city, rate, reason = "war") { if (!city || city.population <= 1 || rate <= 0) return 0; -const loss = Math.min(city.population - 1, Math.max(1, Math.floor(city.population * clamp(rate, 0, SimConfig.war.cityDamageMaxRate ?? 0.08)))); +const damageMultiplier = SimConfig.war.damageMultiplier ?? 1; +const maxRate = reason === "capture" ? SimConfig.war.captureLossMax : SimConfig.war.cityDamageMaxRate; +const appliedRate = clamp(rate, 0, maxRate) * damageMultiplier; +const loss = Math.min(city.population - 1, Math.max(1, Math.floor(city.population * appliedRate))); if (loss <= 0) return 0; city.population = Math.max(1, city.population - loss); if (city.ethnicityComposition) removeFromComposition(city.ethnicityComposition, loss); city.storedResources = Math.max(0, (city.storedResources || 0) - loss * (reason === "capture" ? 0.38 : 0.16)); -city.loyalty = clamp((city.loyalty ?? 0.5) - rate * (reason === "capture" ? 1.8 : 0.9), 0, 1); +city.loyalty = clamp((city.loyalty ?? 0.5) - appliedRate * (reason === "capture" ? 1.8 : 0.9), 0, 1); city.lastWarDamageYear = this.year; this.recordWarDeaths(loss, reason === "capture" ? 0.45 : 0.65); return loss; } + applyPolityWarExhaustionPopulationLoss(polity, exhaustion, intensity) { if (!polity || exhaustion <= 0.04) return 0; const cities = this.getPolityCities(polity); @@ -4649,6 +5259,7 @@ return total; applyWarZoneTileDamage(tile, rate) { const w = this.world; if (tile == null || tile < 0 || tile >= w.count || rate <= 0) return 0; +const damageMultiplier = SimConfig.war.damageMultiplier ?? 1; let removed = 0; for (const { dx, dy, distance } of this.getRadiusOffsets(2)) { const x = tile % w.size + dx; @@ -4656,7 +5267,7 @@ const y = Math.floor(tile / w.size) + dy; if (x < 0 || y < 0 || x >= w.size || y >= w.size) continue; const t = w.idx(x, y); if (w.terrain[t] === Terrain.WATER || w.population[t] <= 0) continue; -const localRate = rate * (1 - distance / 4); +const localRate = rate * damageMultiplier * (1 - distance / 4); const amount = w.population[t] * localRate; if (amount <= 0.03) continue; removed += this.removeEthnicPopulationProportionally(t, amount) || 0; @@ -4665,6 +5276,7 @@ w.resource[t] = Math.max(0, w.resource[t] - amount * 0.02); this.recordWarDeaths(removed, 0.8); return removed; } + recordWarDeaths(amount, civilianShare = 0.5) { if (amount <= 0) return; this.deaths += Math.max(0, Math.floor(amount * clamp(civilianShare, 0, 1))); @@ -4762,6 +5374,7 @@ city.receivedAid = true; city.loyalty = clamp(city.loyalty + 0.05, 0, 1); } } +this.enforcePolityTreasuryCap(polity); } } erodePolityLegitimacy() { @@ -4836,7 +5449,8 @@ updateCityLoyalty() { for (const polity of this.polities) { const center = this.getCityById(polity.centerCityId); if (!center) continue; -center.loyalty = 1; +const loyaltyCap = this.polityLoyaltyCap(polity); +center.loyalty = loyaltyCap; const instability = this.polityInstability(polity); const agePressure = this.polityAgePressure(polity); const overextension = this.polityOverextension(polity); @@ -4862,46 +5476,93 @@ delta -= overextension * clamp(distance / 48, 0, 1) * 0.014; delta -= logisticsStress * clamp(distance / 42, 0.25, 1) * 0.018; if ((polity.legitimacy ?? 0.7) < 0.25) delta -= 0.020; if ((polity.crisis || 0) > 0.6) delta -= 0.014; -city.loyalty = clamp(city.loyalty + delta, 0, 1); +city.loyalty = clamp(city.loyalty + delta, 0, loyaltyCap); } } } splitUnloyalCities() { -for (const polity of this.polities) { +const cfg = SimConfig.rebellion || {}; +const participationLoyalty = cfg.participationLoyalty ?? 0.50; +const automaticLoyalty = cfg.automaticLoyalty ?? 0.30; +for (const polity of [...this.polities]) { +const originalCities = this.getPolityCities(polity); +const preRebellionPopulation = originalCities.reduce((sum, city) => sum + Math.max(0, city.population || 0), 0); +const members = originalCities +.filter(city => city.id !== polity.centerCityId && city.polityId === polity.id) +.filter(city => !this.isCityRebellionProtected(city)) +.filter(city => (city.loyalty ?? 0.5) < participationLoyalty); +if (!members.length) continue; +const lowestLoyalty = Math.min(...members.map(city => city.loyalty ?? 0.5)); +const automatic = lowestLoyalty < automaticLoyalty; +if (!automatic) { const instability = this.polityInstability(polity); const agePressure = this.polityAgePressure(polity); -const threshold = clamp(0.14 + instability * 0.05 + agePressure * 0.03, 0.14, 0.28); -const rebellions = []; -for (const city of this.getPolityCities(polity)) { -if (city.id === polity.centerCityId || city.loyalty >= threshold) continue; -const chance = -(threshold - city.loyalty) * 0.28 + -instability * 0.012 + -agePressure * 0.010; -if (this.rng.next() < chance) { -const rebellionLoyalty = city.loyalty ?? 0; -const oldPolityId = city.polityId; +const averageLoyalty = members.reduce((sum, city) => sum + (city.loyalty ?? 0.5), 0) / members.length; +const chance = clamp( +(participationLoyalty - averageLoyalty) * (cfg.chanceScale ?? 0.20) + +instability * 0.018 + +agePressure * 0.012, +0, +cfg.maxAnnualChance ?? 0.16 +); +if (this.rng.next() >= chance) continue; +} +// Once a rebellion begins, every non-capital city below 50% loyalty joins +// simultaneously, regardless of distance from the first rebel city. +const trigger = members.reduce((lowest, city) => +(city.loyalty ?? 0.5) < (lowest.loyalty ?? 0.5) ? city : lowest, members[0]); +const rebellionData = members.map(city => ({ cityId: city.id, population: city.population || 0, loyalty: city.loyalty ?? 0 })); +const oldPolityId = polity.id; +this.removeCityFromPolity(trigger); +this.releaseCityTerritory(trigger, oldPolityId, 5, "rebellion"); +const rebelPolity = this.createPolity(trigger); +trigger.loyalty = 1; +for (const city of members) { +if (city.id === trigger.id) continue; +const loyalty = city.loyalty ?? 0.3; this.removeCityFromPolity(city); this.releaseCityTerritory(city, oldPolityId, 5, "rebellion"); -rebellions.push({ -cityId: city.id, -population: city.population || 0, -loyalty: rebellionLoyalty +this.transferCityToPolity(city, rebelPolity, { +loyalty: clamp(0.52 + (participationLoyalty - loyalty) * 0.38, 0.46, 0.72), +control: 0.48, +claim: 0.62, +reason: "rebellion" }); +this.claimPolityCoreTerritory(rebelPolity, city, 3, "rebellion"); } -} -if (rebellions.length >= 3) { -const population = rebellions.reduce((sum, rebellion) => sum + (rebellion.population || 0), 0); -const avgLoyalty = rebellions.reduce((sum, rebellion) => sum + (rebellion.loyalty || 0), 0) / rebellions.length; -this.addPolityEvent(polity.id, "rebellion", this.year, { -cityIds: rebellions.map(rebellion => rebellion.cityId), -cityCount: rebellions.length, +const population = rebellionData.reduce((sum, rebellion) => sum + rebellion.population, 0); +const avgLoyalty = rebellionData.reduce((sum, rebellion) => sum + rebellion.loyalty, 0) / rebellionData.length; +const rebelPopulationShare = preRebellionPopulation > 0 ? clamp(population / preRebellionPopulation, 0, 1) : 0; +const transferRate = clamp(cfg.treasuryTransferRate ?? 0.65, 0, 1); +const treasuryTransferred = Math.min( +Math.max(0, polity.treasury || 0), +Math.max(0, polity.treasury || 0) * rebelPopulationShare * transferRate +); +polity.treasury = Math.max(0, (polity.treasury || 0) - treasuryTransferred); +rebelPolity.treasury = Math.max(0, (rebelPolity.treasury || 0) + treasuryTransferred); +this.enforcePolityTreasuryCap(polity); +this.enforcePolityTreasuryCap(rebelPolity); +const eventData = { +cityIds: rebellionData.map(rebellion => rebellion.cityId), +cityCount: rebellionData.length, population, -loyalty: avgLoyalty +loyalty: avgLoyalty, +automatic, +treasuryTransferred, +newPolityId: rebelPolity.id +}; +this.addPolityEvent(polity.id, "rebellion", this.year, eventData, 3); +this.addPolityEvent(rebelPolity.id, "rebellion", this.year, { +cityIds: eventData.cityIds, +cityCount: eventData.cityCount, +population, +automatic, +treasuryTransferred, +formerPolityId: polity.id }, 3); } } -} + enforcePolityContinuity(polity) { const center = this.getCityById(polity.centerCityId); const cities = this.getPolityCities(polity); @@ -4972,7 +5633,7 @@ if (!center || center.population <= 0) { const oldCenterCityId = polity.centerCityId; center = cities.reduce((best, city) => this.cityInfluence(city) > this.cityInfluence(best) ? city : best, cities[0]); polity.centerCityId = center.id; -center.loyalty = 1; +center.loyalty = this.polityLoyaltyCap ? this.polityLoyaltyCap(polity) : 1; if (oldCenterCityId !== center.id) { this.addPolityEvent(polity.id, "capitalShift", this.year, { oldCenterCityId, @@ -5035,23 +5696,24 @@ this.cleanupPolities(); this.foundPolities(); if (this.reinforcePolityTradeRoutes) this.reinforcePolityTradeRoutes(); this.collectAndRedistributeResources(); +if (this.maybeBuildTreasuryCities) this.maybeBuildTreasuryCities(); this.detectPolityFamines(); if (this.erodePolityLegitimacy) this.erodePolityLegitimacy(); +if (this.updateInstitutionalAging) this.updateInstitutionalAging(); +if (this.maybeTriggerInstitutionalReforms) this.maybeTriggerInstitutionalReforms(); if (this.triggerPolityCrises) this.triggerPolityCrises(); if (this.applyOldStateStress) this.applyOldStateStress(); if (this.updatePolityLeaders) this.updatePolityLeaders(); this.updateCityLoyalty(); this.maybeStartCampaigns(); -this.updateCampaigns(); -this.updateWars(); this.splitUnloyalCities(); +this.enforcePolityTreasuryCaps(); this.cleanupPolities(); if (this.samplePolityHistories) this.samplePolityHistories(); this.syncTilePopulationCulture(); -this.recomputeTerritories({ allowOwnershipChanges: false, reason: "normal" }); +this.recomputeTerritories({ allowOwnershipChanges: true, rebalanceOwnership: true, reason: "normal" }); this.reconcileCityTerritoryOwnership(); this.campaignPressureOnTerritories(); -this.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); } reinforcePolityTradeRoutes() { for (const polity of this.polities) { @@ -5087,6 +5749,28 @@ if (!city) return 1; const capitalBonus = city.polityId !== null && this.getPolityById(city.polityId)?.centerCityId === city.id ? 1 : 0; return clamp((city.population > 180 ? 4 : city.population > 90 ? 3 : 2) + capitalBonus, 2, 5); } +desertCorridorShare(cityA, cityB, samples = 12) { +if (!cityA || !cityB) return 0; +const w = this.world; +let desert = 0; +let land = 0; +for (let step = 0; step <= samples; step++) { +const t = step / samples; +const x = clamp(Math.round(lerp(cityA.x, cityB.x, t)), 0, w.size - 1); +const y = clamp(Math.round(lerp(cityA.y, cityB.y, t)), 0, w.size - 1); +const terrain = w.terrain[w.idx(x, y)]; +if (terrain === Terrain.WATER) continue; +land++; +if (terrain === Terrain.DESERT) desert++; +} +return land > 0 ? desert / land : 0; +} +routeDesertShare(path) { +if (!path?.length) return 0; +let desert = 0; +for (const tile of path) if (this.world.terrain[tile] === Terrain.DESERT) desert++; +return desert / path.length; +} effectiveRouteLengthLimit(cityA = null, cityB = null, ownerPolity = null) { const cfg = SimConfig.route; const base = cfg.maxRouteLength ?? 42; @@ -5100,6 +5784,11 @@ const samePolity = cityA.polityId !== null && cityA.polityId === cityB.polityId; const capital = ownerPolity && (ownerPolity.centerCityId === cityA.id || ownerPolity.centerCityId === cityB.id) ? 1 : 0; const org = ownerPolity ? clamp((ownerPolity.cohesion ?? 0.6) * 0.7 + (ownerPolity.legitimacy ?? 0.7) * 0.3, 0, 1.2) : 0; const treasury = ownerPolity ? clamp(Math.sqrt(Math.max(0, ownerPolity.treasury || 0)) / 18, 0, 1.1) : 0; +const desertShare = this.desertCorridorShare(cityA, cityB); +const desertBonus = desertShare * (cfg.desertRouteLengthBonus ?? 30); +const normalMax = cfg.adaptiveMaxRouteLength ?? 72; +const desertMax = cfg.desertAdaptiveMaxRouteLength ?? normalMax; +const upperLimit = lerp(normalMax, desertMax, desertShare); return Math.floor(clamp( base + clamp(Math.sqrt(avgPopulation) * 0.55, 0, 10) + @@ -5107,9 +5796,10 @@ avgKnowledge * 12 + (samePolity ? 7 : 0) + capital * 6 + org * 5 + -treasury * 4, +treasury * 4 + +desertBonus, base, -cfg.adaptiveMaxRouteLength ?? 72 +upperLimit )); } cityHasRouteTilesNear(city, radius = SimConfig.route.isolatedRouteRadius ?? 4) { @@ -5194,12 +5884,97 @@ return this.distanceBetweenCities(city, a) + polityBiasA - (this.distanceBetween for (const candidate of others.slice(0, 8)) add(candidate); return result; } +createManualTradeRoute(cityAId, cityBId) { +const cityA = this.getCityById(cityAId); +const cityB = this.getCityById(cityBId); +if (!cityA || !cityB) return { ok: false, reason: "missingCity" }; +if (cityA.id === cityB.id) return { ok: false, reason: "sameCity" }; +const cfg = SimConfig.route || {}; +const direct = this.distanceBetweenCities(cityA, cityB); +const maxLength = cfg.manualRouteMaxLength ?? 120; +if (direct > maxLength) return { ok: false, reason: "tooFar", maxLength }; +const ownerPolityId = cityA.polityId !== null && cityA.polityId === cityB.polityId ? cityA.polityId : null; +const ownerPolity = ownerPolityId !== null ? this.getPolityById(ownerPolityId) : null; +const naturalLimit = this.effectiveRouteLengthLimit(cityA, cityB, ownerPolity); +const limit = Math.min(maxLength, Math.max(naturalLimit, Math.ceil(direct + 24))); +const path = this.findTerrainRoute(cityA.x, cityA.y, cityB.x, cityB.y, limit, cityA, cityB, ownerPolity); +if (!this.isValidRoutePath(path, cityB.x, cityB.y, limit)) return { ok: false, reason: "noPath" }; +const protectionYears = cfg.manualProtectionYears ?? 25; +const protectedUntil = this.year + years(protectionYears); +const strength = Math.max(0.35, this.routeStrengthForPath(path)); +this.manualTradeRoutes ??= []; +this.manualTradeRoutes = this.manualTradeRoutes.filter(route => +!((route.from === cityA.id && route.to === cityB.id) || (route.from === cityB.id && route.to === cityA.id))); +const record = { from: cityA.id, to: cityB.id, path: [...path], strength, created: this.year, protectedUntil }; +this.manualTradeRoutes.push(record); +this.manualRouteProtection ??= new Map(); +for (const tile of path) { +if (this.world.terrain[tile] === Terrain.WATER) continue; +this.manualRouteProtection.set(tile, Math.max(this.manualRouteProtection.get(tile) || 0, protectedUntil)); +this.world.tradeRoute[tile] = Math.max(this.world.tradeRoute[tile], cfg.manualProtectedStrength ?? 32); +this.activeTradeRouteTiles.add(tile); +this.addPheromone(tile, cfg.newRoutePheromoneSeed ?? 2.5); +} +const existingLink = this.tradeLinks.some(link => { +const endpoints = this.tradeLinkEndpointIds(link); +return endpoints && endpoints.includes(cityA.id) && endpoints.includes(cityB.id); +}); +cityA.tradeLinks.add(cityB.id); +cityB.tradeLinks.add(cityA.id); +if (!existingLink) { +this.tradeLinks.push({ from: cityA.id, to: cityB.id, strength, path: [...path], ownerPolityId, manual: true, protectedUntil }); +} +return { ok: true, path, protectionYears, protectedUntil }; +} +cleanupManualTradeRouteProtection() { +this.manualTradeRoutes ??= []; +this.manualRouteProtection ??= new Map(); +const active = []; +this.manualRouteProtection.clear(); +for (const route of this.manualTradeRoutes) { +if (!route || route.protectedUntil <= this.year) continue; +const a = this.getCityById(route.from); +const b = this.getCityById(route.to); +if (!a || !b || !route.path?.length) continue; +active.push(route); +for (const tile of route.path) { +if (tile < 0 || tile >= this.world.count || this.world.terrain[tile] === Terrain.WATER) continue; +this.manualRouteProtection.set(tile, Math.max(this.manualRouteProtection.get(tile) || 0, route.protectedUntil)); +} +} +this.manualTradeRoutes = active; +} +isManualRouteTileProtected(tile) { +return (this.manualRouteProtection?.get(tile) || 0) > this.year; +} +restoreProtectedManualRoutes(supportedRoutes) { +const cfg = SimConfig.route || {}; +for (const route of this.manualTradeRoutes || []) { +if (route.protectedUntil <= this.year) continue; +const cityA = this.getCityById(route.from); +const cityB = this.getCityById(route.to); +if (!cityA || !cityB) continue; +cityA.tradeLinks.add(cityB.id); +cityB.tradeLinks.add(cityA.id); +const ownerPolityId = cityA.polityId !== null && cityA.polityId === cityB.polityId ? cityA.polityId : null; +const exists = this.tradeLinks.some(link => +(link.from === cityA.id && link.to === cityB.id) || (link.from === cityB.id && link.to === cityA.id)); +if (!exists) this.tradeLinks.push({ ...route, ownerPolityId, manual: true }); +for (const tile of route.path) { +if (tile < 0 || tile >= this.world.count || this.world.terrain[tile] === Terrain.WATER) continue; +if (supportedRoutes) supportedRoutes.add(tile); +this.world.tradeRoute[tile] = Math.max(this.world.tradeRoute[tile], cfg.manualProtectedStrength ?? 32); +this.activeTradeRouteTiles.add(tile); +} +} +} updateTradeRoutes(fieldBased = false) { const w = this.world; +this.cleanupManualTradeRouteProtection(); for (let i = 0; i < w.count; i++) { const invalidTerrain = w.terrain[i] === Terrain.WATER; if (invalidTerrain) w.tradeRoute[i] = 0; -else if (w.tradeRoute[i] > 0 && this.year % years(4) === 0) { +else if (w.tradeRoute[i] > 0 && this.year % years(4) === 0 && !this.isManualRouteTileProtected(i)) { const pheromoneSupport = clamp(w.pheromone[i] / SimConfig.route.maxPheromone, 0, 1); const decay = pheromoneSupport >= SimConfig.route.routePheromoneMaintain ? 1 : SimConfig.route.routeUnsupportedDecay; w.tradeRoute[i] = Math.max(0, w.tradeRoute[i] - decay); @@ -5208,6 +5983,9 @@ if (w.tradeRoute[i] < SimConfig.route.routeWeakThreshold) w.tradeRoute[i] = 0; } this.tradeLinks = []; for (const city of this.cities) city.tradeLinks.clear(); +const supportedRoutes = this.supportedRouteScratch; +supportedRoutes.clear(); +this.restoreProtectedManualRoutes(supportedRoutes); const maxPairsToRoute = clamp(this.cities.length * 7, 80, 1400); const pairHeap = this.pairCandidateScratch; pairHeap.length = 0; @@ -5248,14 +6026,15 @@ if (!this.isValidRoutePath(path, c2.x, c2.y, limit)) continue; const strength = this.routeStrengthForPath(path); const pheromoneSupport = this.routePheromoneSupport(path); if (strength < 0.08) continue; -if (!fieldBased && ownerPolityId === null && pheromoneSupport < SimConfig.route.routePheromoneBuild) continue; +const desertShare = this.routeDesertShare(path); +const desertThresholdFactor = SimConfig.route.desertPheromoneThresholdFactor ?? 0.45; +const buildThreshold = SimConfig.route.routePheromoneBuild * (1 - desertShare * (1 - desertThresholdFactor)); +if (!fieldBased && ownerPolityId === null && pheromoneSupport < buildThreshold) continue; if (!this.canPayRouteConstructionCost(c1, c2, path, ownerPolity)) continue; const tradeScore = strength * (1 + distanceFactor * 0.7 + pheromoneSupport * 0.75 + (ownerPolityId !== null ? 0.28 : 0)) * marketScale; this.topHeapPush(candidates, { c1, c2, strength, path, tradeScore, pheromoneSupport, ownerPolityId }, routeCandidateLimit, "tradeScore"); } this.heapToDescending(candidates, "tradeScore"); -const supportedRoutes = this.supportedRouteScratch; -supportedRoutes.clear(); for (const candidate of candidates) { if (this.tradeLinks.length >= maxLinks) break; const { c1, c2, strength, path, pheromoneSupport, ownerPolityId } = candidate; @@ -5278,9 +6057,7 @@ this.applyRouteConnectionBenefits(c1, c2, strength, pheromoneSupport, upkeepPaid this.bootstrapIsolatedCityRoutes(supportedRoutes); for (let i = 0; i < w.count; i++) { if (w.tradeRoute[i] && !supportedRoutes.has(i)) { -const pheromoneSupport = clamp(w.pheromone[i] / SimConfig.route.maxPheromone, 0, 1); -w.tradeRoute[i] = Math.max(0, w.tradeRoute[i] - (pheromoneSupport >= SimConfig.route.routePheromoneMaintain ? 2 : SimConfig.route.routeUnsupportedDecay)); -if (w.tradeRoute[i] < SimConfig.route.routeWeakThreshold) w.tradeRoute[i] = 0; +w.tradeRoute[i] = 0; } } this.activeTradeRouteTiles.clear(); @@ -5289,6 +6066,59 @@ if (w.tradeRoute[i]) this.activeTradeRouteTiles.add(i); } this.diffuseCityKnowledgeThroughTrade(); } +pruneOrphanTradeRoutes() { +const w = this.world; +this.cleanupManualTradeRouteProtection(); +const validLinks = []; +const validTiles = new Set(); +for (const link of this.tradeLinks || []) { +if (link.manual && link.protectedUntil != null && link.protectedUntil <= this.year) continue; +const a = this.getCityById(link.from); +const b = this.getCityById(link.to); +const path = link.path || []; +if (!a || !b || !path.length) continue; +const first = path[0]; +const last = path[path.length - 1]; +const endpointDistance = (tile, city) => Math.abs(tile % w.size - city.x) + Math.abs(Math.floor(tile / w.size) - city.y); +const aligned = +(endpointDistance(first, a) <= 1 && endpointDistance(last, b) <= 1) || +(endpointDistance(first, b) <= 1 && endpointDistance(last, a) <= 1); +if (!aligned) continue; +validLinks.push(link); +for (const tile of path) validTiles.add(tile); +} +// Protected user-created routes remain valid even if a normal route refresh has +// not run since they were created. Once protection expires they are omitted and +// can disappear under the ordinary route rules. +for (const route of this.manualTradeRoutes || []) { +if (route.protectedUntil <= this.year) continue; +const a = this.getCityById(route.from); +const b = this.getCityById(route.to); +if (!a || !b || !route.path?.length) continue; +const already = validLinks.some(link => { +const endpoints = this.tradeLinkEndpointIds(link); +return endpoints && endpoints.includes(a.id) && endpoints.includes(b.id); +}); +if (!already) validLinks.push({ ...route, manual: true }); +for (const tile of route.path) if (w.terrain[tile] !== Terrain.WATER) validTiles.add(tile); +} +this.tradeLinks = validLinks; +for (const city of this.cities) { +city.tradeLinks ??= new Set(); +city.tradeLinks.clear(); +} +for (const link of validLinks) { +const a = this.getCityById(link.from); +const b = this.getCityById(link.to); +if (!a || !b) continue; +a.tradeLinks.add(b.id); +b.tradeLinks.add(a.id); +} +for (let tile = 0; tile < w.count; tile++) if (w.tradeRoute[tile] && !validTiles.has(tile)) w.tradeRoute[tile] = 0; +this.activeTradeRouteTiles.clear(); +for (const tile of validTiles) if (w.tradeRoute[tile]) this.activeTradeRouteTiles.add(tile); +} + registerTradeLink(cityA, cityB, strength, path, supportedRoutes = null, routeBoost = 18, pheromoneBoost = 0, ownerPolityId = null) { cityA.tradeLinks.add(cityB.id); cityB.tradeLinks.add(cityA.id); @@ -5412,7 +6242,8 @@ const w = this.world; const routeRelief = w.tradeRoute[tile] ? 0.58 : 1; const pheromoneRelief = 1 - clamp(w.pheromone[tile] / SimConfig.route.maxPheromone, 0, 0.32); const mountain = w.terrain[tile] === Terrain.MOUNTAIN ? 1.2 : 0; -return Math.max(0.45, (w.move[tile] + mountain) * routeRelief * pheromoneRelief); +const desertFactor = w.terrain[tile] === Terrain.DESERT ? (SimConfig.route.desertTraversalCostFactor ?? 0.68) : 1; +return Math.max(0.45, (w.move[tile] * desertFactor + mountain) * routeRelief * pheromoneRelief); } routeStrengthForPath(path) { const w = this.world; @@ -5423,7 +6254,7 @@ let terrainEase = 0; for (const i of path) { route += w.tradeRoute[i] > 0 ? 1 : 0; pheromone += clamp(w.pheromone[i] / 9, 0, 1); -terrainEase += 1 / Math.max(1, w.move[i]); +terrainEase += 1 / Math.max(0.75, this.routeTileCost(i)); } return route / path.length * 0.45 + pheromone / path.length * 0.35 + terrainEase / path.length * 0.2; } @@ -5516,7 +6347,8 @@ routePathDifficulty(path) { if (!path.length) return 1; let difficulty = 0; for (const tile of path) { -const move = this.world.move[tile] || 1; +let move = this.world.move[tile] || 1; +if (this.world.terrain[tile] === Terrain.DESERT) move *= SimConfig.route.desertTraversalCostFactor ?? 0.68; const hard = move > 1.8 ? 0.35 : 0; const existing = this.world.tradeRoute[tile] ? -0.25 : 0; difficulty += Math.max(0.45, move + hard + existing); @@ -5527,7 +6359,10 @@ routeConstructionCost(path, polityBacked = false, options = {}) { let weakTiles = 0; for (const tile of path) if (this.world.tradeRoute[tile] < 24) weakTiles++; const difficulty = this.routePathDifficulty(path); -const base = weakTiles * (polityBacked ? 0.16 : 0.12) * clamp(difficulty / 1.35, 0.75, 2.1); +const desertShare = this.routeDesertShare(path); +const desertFactor = SimConfig.route.desertConstructionCostFactor ?? 0.72; +const terrainConstructionFactor = 1 - desertShare * (1 - desertFactor); +const base = weakTiles * (polityBacked ? 0.16 : 0.12) * clamp(difficulty / 1.35, 0.75, 2.1) * terrainConstructionFactor; return options.bootstrap ? base * 0.62 : base; } canPayRouteConstructionCost(cityA, cityB, path, polity = null, options = {}) { @@ -5567,6 +6402,7 @@ return paid; addPheromone(tile, amount) { if (tile < 0 || tile >= this.world.count || amount <= 0) return; this.world.pheromone[tile] = Math.min(SimConfig.route.maxPheromone, this.world.pheromone[tile] + amount); +if (this.world.pheromone[tile] > 0) this.activePheromoneTiles?.add(tile); } depositRoutePheromone(path, amount) { for (const i of path) { @@ -5620,11 +6456,94 @@ e.diversity /= e.population; e.averageTraits ??= this.randomTraits(); } } +absorptionTargetForEthnicity(ethnicityId) { +const ethnicity = this.ethnicities.get(ethnicityId); +if (!ethnicity) return null; +const scores = new Map(); +const addScore = (id, amount) => { +if (id == null || id === ethnicityId || amount <= 0 || !this.ethnicities.has(id)) return; +scores.set(id, (scores.get(id) || 0) + amount); +}; +for (const [tile, mix] of this.tileEthnicMix) { +const local = mix.get(ethnicityId) || 0; +if (local <= 0) continue; +for (const [id, count] of mix) addScore(id, count * 1.5); +const begin = this.world.landNeighborStarts?.[tile] ?? 0; +const end = this.world.landNeighborStarts?.[tile + 1] ?? begin; +for (let index = begin; index < end; index++) { +const neighborMix = this.tileEthnicMix.get(this.world.landNeighbors[index]); +if (!neighborMix) continue; +for (const [id, count] of neighborMix) addScore(id, count); +} +} +for (const city of this.cities) { +const local = city.ethnicityComposition?.get(ethnicityId) || 0; +if (local <= 0) continue; +for (const [id, count] of city.ethnicityComposition) addScore(id, count * 1.25); +} +let bestId = null; +let bestScore = -Infinity; +for (const [id, score] of scores) { +if (score > bestScore) { bestId = id; bestScore = score; } +} +if (bestId !== null) return bestId; +const parent = ethnicity.parent; +if (parent != null && parent !== ethnicityId && this.ethnicities.has(parent)) return parent; +let nearest = null; +let nearestDistance = Infinity; +for (const candidate of this.ethnicities.values()) { +if (candidate.id === ethnicityId || (candidate.population || 0) <= 0) continue; +const distance = Math.hypot((candidate.centroidX || 0) - (ethnicity.centroidX || 0), (candidate.centroidY || 0) - (ethnicity.centroidY || 0)); +if (distance < nearestDistance) { nearest = candidate.id; nearestDistance = distance; } +} +return nearest; +} +absorbEthnicityInto(ethnicityId, targetId) { +if (ethnicityId === targetId || !this.ethnicities.has(ethnicityId) || !this.ethnicities.has(targetId)) return false; +for (const [tile, mix] of this.tileEthnicMix) { +const amount = mix.get(ethnicityId) || 0; +if (amount <= 0) continue; +mix.delete(ethnicityId); +mix.set(targetId, (mix.get(targetId) || 0) + amount); +this.updateCultureTile(tile); +} +for (const city of this.cities) { +const amount = city.ethnicityComposition?.get(ethnicityId) || 0; +if (amount <= 0) continue; +city.ethnicityComposition.delete(ethnicityId); +city.ethnicityComposition.set(targetId, (city.ethnicityComposition.get(targetId) || 0) + amount); +} +for (const band of this.nomadBands || []) if (band.ethnicityId === ethnicityId) band.ethnicityId = targetId; +for (const ethnicity of this.ethnicities.values()) if (ethnicity.parent === ethnicityId) ethnicity.parent = targetId; +this.ethnicities.delete(ethnicityId); +return true; +} +absorbSmallEthnicities() { +const threshold = Math.max(0, SimConfig.culture?.absorptionPopulationThreshold ?? 30); +if (threshold <= 0 || this.ethnicities.size <= 1) return 0; +let absorbed = 0; +const candidates = [...this.ethnicities.values()] +.filter(ethnicity => (ethnicity.population || 0) > 0 && (ethnicity.population || 0) < threshold) +.sort((a, b) => (a.population || 0) - (b.population || 0)); +for (const ethnicity of candidates) { +if (!this.ethnicities.has(ethnicity.id)) continue; +const target = this.absorptionTargetForEthnicity(ethnicity.id); +if (target == null) continue; +if (this.absorbEthnicityInto(ethnicity.id, target)) absorbed++; +} +return absorbed; +} splitDivergentEthnicities() { this.splitDivergentFieldEthnicities(); } splitDivergentFieldEthnicities() { +let formed = 0; +const divergenceSpeed = clamp(SimConfig.culture?.divergenceRateMultiplier ?? 0.25, 0.05, 1); +const divergenceChance = 0.32; for (const e of [...this.ethnicities.values()]) { +if (formed >= 1) break; +if (this.year < (e.nextDivergenceCheck ?? 0)) continue; +e.nextDivergenceCheck = this.year + years(this.rng.range(24, 90) / divergenceSpeed); if (e.population < 120 || e.diversity < 0.24) continue; const candidates = []; let population = 0; @@ -5637,7 +6556,7 @@ const x = tile % this.world.size; const y = Math.floor(tile / this.world.size); const spatial = Math.hypot(x - e.centroidX, y - e.centroidY) > this.world.size * 0.11; const climate = this.climateMismatch(e.id, tile) > 0.20; -if ((spatial || climate || this.world.cultureDiversity[tile] > 0.38) && this.rng.next() < 0.32) { +if ((spatial || climate || this.world.cultureDiversity[tile] > 0.38) && this.rng.next() < divergenceChance) { candidates.push({ tile, count }); population += count; tempSum += this.world.temperature[tile] * count; @@ -5661,6 +6580,7 @@ mix.set(e.id, Math.max(0, count - split)); mix.set(newId, (mix.get(newId) || 0) + split); this.updateCultureTile(tile); } +formed++; } } } diff --git a/index.html b/index.html index 59edc15..52c9302 100644 --- a/index.html +++ b/index.html @@ -1,125 +1,160 @@ - + - Emergent Civilization Simulation + 文明シミュレータ
    -
    + +
    +

    世界を再生成

    + +

    再生成すると現在の世界は破棄されます。

    +
    + + +
    +
    +
    + diff --git a/render.js b/render.js index 105ccbe..f2accf2 100644 --- a/render.js +++ b/render.js @@ -1,3 +1,47 @@ +const displayTerms = { + "roaming": "移動中", + "grazing": "放牧中", + "leaving": "離脱中", + "settling": "定住中", + "trading": "交易中", + "raiding": "襲撃中", + "invading": "侵攻中", + "confederating": "連合形成中", + "frontier_colonization": "辺境開拓", + "nonstate_subjugation": "非国家地域の征服", + "independent_city_annexation": "独立都市の併合", + "border_war": "国境戦争", + "frontier": "辺境", + "nonstate": "非国家地域", + "independentCity": "独立都市", + "polity": "国家", + "started": "開始", + "ended": "終結", + "ceased": "停戦", + "defending": "防衛", + "succeeded": "成功", + "failed": "失敗", + "peaceful": "平和的併合", + "military": "戦争による併合", + "expired": "期限切れ", + "active": "進行中", + "puppetIndependent": "傀儡都市化", + "nomadicDynasty": "遊牧王朝の成立", + "capturedCity": "都市占領", + "lostCity": "都市喪失", + "settlementGain": "講和による領土獲得", + "settlementLoss": "講和による領土喪失", + "settlementPressure": "講和圧力", + "dissolved": "解体", + "collapsed": "崩壊", + "conquest": "征服", + "war": "戦争", + "event": "発生", + "target": "対象", + "campaign": "遠征", + "non-state": "非国家地域" +}; +function displayTerm(value) { return displayTerms[value] || "状況変化"; } function render() { const start = performance.now(); const w = sim.world; @@ -9,7 +53,6 @@ renderImageSize = size; const image = renderImage; const data = image.data; const mode = els.viewMode.value; -const cityPolityColor = new Map(); const polityColors = new Map(); if (mode === "polities") { for (const polity of sim.polities) { @@ -18,16 +61,6 @@ color: polity.color, isGraphHover: graphState.hoverPolityId === polity.id }); } -for (const city of sim.cities) { -if (city.polityId === null) continue; -const polity = cityPolity(city); -if (!polity) continue; -const isGraphHover = graphState.hoverPolityId === polity.id; -cityPolityColor.set(city.id, { -color: polity.color, -isGraphHover -}); -} } for (let i = 0; i < w.count; i++) { let color; @@ -55,12 +88,12 @@ const city = sim.getCityById(w.city[i]); if (city) color = mix(color, cityMajorityColor(city), 0.72); } } else if (mode === "pressure") { -const pressure = w.populationPressure?.[i] ?? (w.pressure[i] / 12); +const pressure = w.populationPressure[i] || 0; const v = clamp(pressure, 0, 1.6) / 1.6; color = mix(terrainInfo[w.terrain[i]].color, [210, 73, 67], v); } else if (mode === "polities") { color = terrainInfo[w.terrain[i]].color; -const territory = w.polity?.[i] ?? -1; +const territory = w.territoryOwner[i]; if (territory >= 0) { const polityColor = polityColors.get(territory); if (polityColor) { @@ -71,13 +104,6 @@ if (sim.isBorderTile?.(i)) color = mix(color, [232, 225, 185], 0.22); if (graphState.hoverPolityId !== null && !polityColor.isGraphHover) color = mix(color, [16, 18, 19], 0.30); } } -if (w.city[i] >= 0) { -const polityColor = cityPolityColor.get(w.city[i]); -if (polityColor) { -color = mix(color, polityColor.color, polityColor.isGraphHover ? 0.82 : 0.5); -if (graphState.hoverPolityId !== null && !polityColor.isGraphHover) color = mix(color, [16, 18, 19], 0.28); -} -} } else if (mode === "technology") { const farming = w.farmingKnowledge?.[i] || 0; const metallurgy = w.metallurgyKnowledge?.[i] || 0; @@ -106,7 +132,7 @@ drawCampaigns(); drawPopulationAndCities(mode); drawGraphPolityHighlight(); maybeRenderStateGraph(); -els.frameCost.textContent = `${Math.round(performance.now() - start)}ms`; +if (els.frameCost) els.frameCost.textContent = `${Math.round(performance.now() - start)}ミリ秒`; } function renderDisasters() { if (!sim?.disasters?.length) return; @@ -184,6 +210,7 @@ const w = sim.world; ctx.save(); for (const campaign of sim.campaigns) { if (campaign.status !== "active" || campaign.targetTile == null) continue; +if (campaign.type !== "border_war") continue; const x = campaign.targetTile % w.size; const y = Math.floor(campaign.targetTile / w.size); const age = Math.max(0, sim.year - campaign.started) / Math.max(1, campaign.expires - campaign.started); @@ -246,25 +273,13 @@ ctx.restore(); } function drawPopulationAndCities(mode) { ctx.save(); -if (mode !== "ethnicity") { -for (const city of sim.cities) { -const radius = cityRenderRadius(city); -const color = cityDisplayColor(city, mode); -ctx.fillStyle = rgba(color, 0.72); -ctx.globalAlpha = 0.88; -fillSquare(ctx, city.x, city.y, radius); -} -} ctx.globalAlpha = 1; -if (mode === "technology") { -// Tile-level technology is rendered in the base pass. -} else if (mode === "ethnicity") { -// Ethnicity view is driven by tile-level population/culture fields. -} else { +if (mode !== "technology" && mode !== "ethnicity") { const w = sim.world; ctx.fillStyle = "rgba(238, 236, 207, 0.16)"; -for (let tile = 0; tile < w.count; tile++) { -const pop = w.population?.[tile] || 0; +const populatedTiles = sim.activePopulationTiles || []; +for (const tile of populatedTiles) { +const pop = (w.population?.[tile] || 0) / (SimConfig.population.populationScale || 1); if (pop < 6) continue; const alpha = clamp(Math.log1p(pop) / Math.log(160), 0.04, 0.18); ctx.fillStyle = `rgba(238, 236, 207, ${alpha})`; @@ -272,15 +287,14 @@ ctx.fillRect(tile % w.size, Math.floor(tile / w.size), 1, 1); } } for (const city of sim.cities) { -if (mode === "ethnicity") { const radius = cityRenderRadius(city); const color = cityDisplayColor(city, mode); -ctx.globalAlpha = 0.90; -ctx.fillStyle = rgba(color, 0.78); -fillSquare(ctx, city.x, city.y, radius); ctx.globalAlpha = 1; -} -const color = cityDisplayColor(city, mode); +ctx.fillStyle = rgb(color); +fillSquare(ctx, city.x, city.y, radius); +ctx.strokeStyle = "#111315"; +ctx.lineWidth = 1; +ctx.strokeRect(city.x - radius + 0.5, city.y - radius + 0.5, radius * 2, radius * 2); ctx.fillStyle = rgb(color, 55); ctx.fillRect(city.x, city.y, 1, 1); } @@ -308,7 +322,19 @@ ctx.fillRect(city.x - radius + 1, city.y - radius + 1, Math.max(1, radius * 2 - ctx.restore(); } function cityRenderRadius(city) { -return clamp(Math.floor(Math.sqrt(city.population) / 12), 1, 7); +const population = Math.max(0, city?.population || 0); +if (population >= 10000) return 4; +if (population >= 5000) return 3; +if (population >= 1000) return 2; +return 1; +} +function cityAtDisplayTile(x, y) { +for (let index = sim.cities.length - 1; index >= 0; index--) { +const city = sim.cities[index]; +const radius = cityRenderRadius(city); +if (Math.abs(city.x - x) <= radius && Math.abs(city.y - y) <= radius) return city; +} +return null; } function cityMajorityColor(city) { const id = dominantComposition(city.ethnicityComposition); @@ -325,12 +351,6 @@ return [218, 205, 154]; } return cityMajorityColor(city); } -function techLevel(holder, key) { -return holder?.tech?.[key] || 0; -} -function knowledgeLevel(city, key) { -return city?.knowledge?.[key] || 0; -} function showTooltip(event) { const rect = els.canvas.getBoundingClientRect(); const simRect = els.sim.getBoundingClientRect(); @@ -363,80 +383,64 @@ return; } const w = sim.world; const i = w.idx(x, y); -const city = w.city[i] >= 0 ? sim.getCityById(w.city[i]) : null; +const city = cityAtDisplayTile(x, y); +if (w.terrain[i] === Terrain.WATER && w.city[i] < 0) { +hideTooltip(); +return; +} const terrain = terrainInfo[w.terrain[i]]; -const waterInfluence = waterInfluenceAt(w, x, y).toFixed(2); -const cityEthnicity = city ? dominantComposition(city.ethnicityComposition) : null; const polity = cityPolity(city); -const territoryId = w.polity?.[i] ?? -1; -const territoryPolity = territoryId >= 0 ? sim.getPolityById(territoryId) : null; -const ethnicMix = sim.tileEthnicMix?.get(i); -const tileDominantEthnicity = ethnicMix?.size ? dominantComposition(ethnicMix) : w.dominantEthnicity[i]; -const regionalEthnicity = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? `E${tileDominantEthnicity}` : "-"; -const regionalLineage = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? sim.ethnicities.get(tileDominantEthnicity) : null; -const mismatch = tileDominantEthnicity != null && tileDominantEthnicity >= 0 ? sim.climateMismatch(tileDominantEthnicity, i) : 0; -const tilePopulation = w.population?.[i] || 0; -const nearbyCampaigns = activeCampaignsNear(i); -const nearbyNomad = activeNomadNear(i); -els.tooltip.innerHTML = ` - ${city ? `City #${city.id}` : terrain.name} - ${tooltipSection("Tile", [ - tooltipRow("Position", `${x}, ${y}`), - tooltipRow("Terrain", terrain.name), - tooltipRow("Resources", w.resource[i].toFixed(1)), - tooltipRow("Fertility", w.fertility[i].toFixed(2)), - tooltipRow("Minerals", w.mineral[i].toFixed(2)), - tooltipRow("Temp / humid", `${w.temperature[i].toFixed(2)} / ${w.humidity[i].toFixed(2)}`), - tooltipRow("Water", waterInfluence), - tooltipRow("Pressure", (w.populationPressure?.[i] ?? 0).toFixed(2)), - tooltipRow("Capacity", (w.populationCapacity?.[i] ?? 0).toFixed(1)), - tooltipRow("Pheromone", w.pheromone[i].toFixed(1)), - tooltipRow("Route", w.tradeRoute[i], w.tradeRoute[i]) - ])} - ${tooltipSection("Territory", [ - tooltipRow("Territory", territoryPolity ? `#${territoryPolity.id}` : "Unclaimed"), - tooltipRow("Control", `${Math.round((w.control?.[i] || 0) * 100)}%`), - tooltipRow("Contested", w.contested?.[i] ? "yes" : "no"), - tooltipRow("Campaign", nearbyCampaigns, nearbyCampaigns), - tooltipRow("Dominant ethnicity", regionalEthnicity), - tooltipRow("Tile population", tilePopulation >= 10 ? Math.round(tilePopulation).toLocaleString() : tilePopulation.toFixed(1)) - ])} - ${tooltipSection("Nomads", [ - tooltipRow("Band", nearbyNomad ? `${nearbyNomad.name} #${nearbyNomad.id}` : "", nearbyNomad), - tooltipRow("Mode", nearbyNomad?.mode, nearbyNomad), - tooltipRow("Population", nearbyNomad ? Math.round(nearbyNomad.population).toLocaleString() : "", nearbyNomad), - tooltipRow("Ethnicity", nearbyNomad ? `E${nearbyNomad.ethnicityId}` : "", nearbyNomad), - tooltipRow("Cohesion", nearbyNomad?.cohesion.toFixed(2), nearbyNomad), - tooltipRow("Prestige", nearbyNomad?.prestige.toFixed(2), nearbyNomad), - tooltipRow("Resources", nearbyNomad?.resources.toFixed(1), nearbyNomad), - tooltipRow("Herds", nearbyNomad?.herds.toFixed(1), nearbyNomad) - ])} - ${tooltipSection("City & State", [ - tooltipRow("Population", city?.population.toLocaleString(), city), - tooltipRow("Food stock", city?.storedResources.toFixed(1), city), - tooltipRow("Supply stress", (city?.supplyStress || 0).toFixed(2), city), - tooltipRow("Trade", city ? `${city.tradeLinks.size} links, ${(city.tradeValue || 0).toFixed(2)} value` : "", city), - tooltipRow("Knowledge", city ? `${knowledgeLevel(city, "farming").toFixed(2)} farm / ${knowledgeLevel(city, "metallurgy").toFixed(2)} metal` : "", city), - tooltipRow("City majority", `E${cityEthnicity}`, cityEthnicity), - city ? cityEthnicityPie(city) : "", - tooltipRow("State", polity ? `#${polity.id}` : "Independent", city), - tooltipRow("Loyalty", city?.loyalty.toFixed(2), city), - tooltipRow("Charisma", clamp(polity?.charisma ?? 1, 0.5, 1.5).toFixed(2), polity), - tooltipRow("Leader tenure", polity ? `${Math.floor((sim.year - (polity.leaderStarted ?? polity.founded ?? sim.year)) / WEEKS_PER_YEAR)}y` : "", polity), - tooltipRow("Treasury", polity?.treasury.toFixed(1), polity), - tooltipRow("Capital", polity && city ? polity.centerCityId === city.id ? "yes" : "no" : "", polity) - ])} - ${tooltipSection("Culture", [ - tooltipRow("Local culture", `${regionalEthnicity} / ${w.cultureDiversity[i].toFixed(2)}`), - tooltipRow("Lineage pop", regionalLineage?.population?.toLocaleString(), regionalLineage), - tooltipRow("Climate pref", regionalLineage ? `${regionalLineage.climateTemp.toFixed(2)} / ${regionalLineage.climateHumidity.toFixed(2)}` : "", regionalLineage), - tooltipRow("Climate mismatch", mismatch.toFixed(2), regionalLineage), - tooltipRow("Settled pop", (w.settledPopulation?.[i] || 0).toFixed(1), tilePopulation > 0), - tooltipRow("Mobile pop", (w.mobilePopulation?.[i] || 0).toFixed(1), tilePopulation > 0), - tooltipRow("Farming", (w.farmingKnowledge?.[i] || 0).toFixed(3)), - tooltipRow("Metallurgy", (w.metallurgyKnowledge?.[i] || 0).toFixed(3)) - ])} - `; +const territoryPolity = sim.getPolityById(w.territoryOwner[i]); +const displayPolity = polity || territoryPolity; +const mode = els.viewMode.value; +const ethnicity = w.dominantEthnicity[i]; +const population = w.population[i] || 0; +const rows = [ +tooltipRow("場所", `${terrain.name}(${x}, ${y})`), +tooltipRow("所属", polity ? `国家${polity.id}${polity.centerCityId === city.id ? "・首都" : ""}` : city ? "独立都市" : territoryPolity ? `国家${territoryPolity.id}` : "国家未所属") +]; +let citySection = ""; +if (city) { +const cityRows = [ +tooltipRow("都市人口", city.population > 0 ? Math.round(city.population).toLocaleString() : "希薄"), +tooltipRow("食料備蓄", city.storedResources.toFixed(1)), +polity ? tooltipRow("忠誠度", `${Math.round((city.loyalty ?? 0.5) * 100)}%`) : "" +]; +citySection = `

    都市データ

    ${cityRows.filter(Boolean).join("")}${cityEthnicityPie(city)}
    `; +} else { +rows.push(tooltipRow("地域人口", population > 0 ? Math.round(population).toLocaleString() : "希薄")); +if (mode === "resources" || mode === "terrain") { +rows.push(tooltipRow("資源", w.resource[i].toFixed(1))); +rows.push(tooltipRow("肥沃度", `${Math.round(w.fertility[i] * 100)}%`)); +} +} +if (mode === "pressure") rows.push(tooltipRow("人口圧力", `${Math.round(w.populationPressure[i] * 100)}%(収容力比)`)); +if (mode === "ethnicity" && ethnicity >= 0) rows.push(tooltipRow("主な民族", `民族${ethnicity}`)); +if (mode === "technology") rows.push(tooltipRow("農業 / 冶金", `${Math.round(w.farmingKnowledge[i] * 100)}% / ${Math.round(w.metallurgyKnowledge[i] * 100)}%`)); +if (mode === "pheromone") rows.push(tooltipRow("交通量", w.pheromone[i].toFixed(1))); +const campaign = activeCampaignsNear(i); +if (campaign) rows.push(tooltipRow("遠征", campaign)); +else if (w.contested[i]) rows.push(tooltipRow("状態", "係争地")); +const band = activeNomadNear(i); +if (band) rows.push(tooltipRow("遊牧集団", `集団${band.id}・${displayTerm(band.mode)}`)); +let politySection = ""; +if (displayPolity) { +const polityCities = sim.getPolityCities(displayPolity); +const polityPopulation = sim.totalPolityPopulation(displayPolity); +const institutionalAging = sim.polityInstitutionalAging ? sim.polityInstitutionalAging(displayPolity) : clamp(displayPolity.institutionalAging ?? 0, 0, 1); +const loyaltyCap = sim.polityLoyaltyCap ? sim.polityLoyaltyCap(displayPolity) : clamp(1 - institutionalAging, 0, 1); +politySection = tooltipSection("国家データ", [ +tooltipRow("国家", `国家${displayPolity.id}`), +tooltipRow("国力", sim.polityPower(displayPolity).toFixed(1)), +tooltipRow("人口", Math.round(polityPopulation).toLocaleString()), +tooltipRow("都市数", polityCities.length.toLocaleString()), +tooltipRow("国庫", Math.max(0, displayPolity.treasury || 0).toFixed(1)), +tooltipRow("正統性 / 結束", `${Math.round((displayPolity.legitimacy ?? 0) * 100)}% / ${Math.round((displayPolity.cohesion ?? 0) * 100)}%`), +tooltipRow("制度老朽化", `${Math.round(institutionalAging * 100)}%`), +tooltipRow("忠誠度上限", `${Math.round(loyaltyCap * 100)}%`) +]); +} +els.tooltip.innerHTML = `${city ? `都市${city.id}` : terrain.name}${rows.join("")}${citySection}${politySection}`; els.tooltip.hidden = false; const margin = 8; const width = els.tooltip.offsetWidth; @@ -470,7 +474,7 @@ return `rgb(${color.join(",")}) ${start.toFixed(2)}% ${end.toFixed(2)}%`; const labels = slices.map(([id, count]) => { const ethnicity = id ? sim.ethnicities.get(id) : null; const color = ethnicity?.color || [122, 130, 126]; -const label = id ? `E${id}` : "Other"; +const label = id ? `民族${id}` : "その他"; return `${label} ${Math.round(count / total * 100)}%`; }).join(""); return ` @@ -497,9 +501,9 @@ const cy = Math.floor(campaign.targetTile / w.size); const nearTarget = Math.abs(cx - x) + Math.abs(cy - y) <= 3; const nearFront = campaign.affectedTiles?.includes(tile); if (!nearTarget && !nearFront) continue; -labels.push(`${campaign.type.replaceAll("_", " ")} ${Math.round(clamp(campaign.progress, 0, 1) * 100)}%`); +labels.push(`${displayTerm(campaign.type)} ${Math.round(clamp(campaign.progress, 0, 1) * 100)}%`); } -return labels.slice(0, 2).join("; "); +return labels.slice(0, 2).join("、"); } function activeNomadNear(tile) { if (!sim?.nomadBands?.length) return null; @@ -519,68 +523,24 @@ bestDistance = distance; } return best; } -function waterInfluenceAt(world, x, y) { -let score = 0; -for (let dy = -3; dy <= 3; dy++) { -for (let dx = -3; dx <= 3; dx++) { -const d = Math.abs(dx) + Math.abs(dy); -if (!d || d > 3) continue; -const tx = x + dx; -const ty = y + dy; -if (tx < 0 || ty < 0 || tx >= world.size || ty >= world.size) continue; -if (world.terrain[world.idx(tx, ty)] === Terrain.WATER) score += (4 - d) / 4; -} -} -return score; -} function updateStats(force = false) { const now = performance.now(); if (!force && now - lastStatsAt < SimConfig.render.statsThrottleMs) return; lastStatsAt = now; const livingEthnicities = [...sim.ethnicities.values()].filter(e => e.population > 0); -const urbanPopulation = sim.cities.reduce((sum, c) => sum + c.population, 0); -let farmingTotal = 0; -let metallurgyTotal = 0; -let farmingHolders = 0; -let metallurgyHolders = 0; -for (let i = 0; i < sim.world.count; i++) { -const pop = sim.world.population?.[i] || 0; -if (pop <= 0) continue; -farmingTotal += (sim.world.farmingKnowledge?.[i] || 0) * pop; -metallurgyTotal += (sim.world.metallurgyKnowledge?.[i] || 0) * pop; -if ((sim.world.farmingKnowledge?.[i] || 0) > 0.02) farmingHolders++; -if ((sim.world.metallurgyKnowledge?.[i] || 0) > 0.02) metallurgyHolders++; -} -const fieldPopulation = sim.world.population -? Array.from(sim.world.population).reduce((sum, value) => sum + value, 0) -: 0; -const knowledgeDenominator = Math.max(1, fieldPopulation); -const stats = { -year: formatSimDate(sim.year), -activeGroups: Math.round(fieldPopulation).toLocaleString(), -urbanPopulation: Math.floor(urbanPopulation).toLocaleString(), -ethnicities: livingEthnicities.length.toLocaleString(), -cities: sim.cities.length.toLocaleString(), -polities: sim.polities.length.toLocaleString(), -wars: sim.wars.length.toLocaleString(), -routes: sim.tradeLinks.length.toLocaleString(), -farmingKnowledge: `${(farmingTotal / knowledgeDenominator).toFixed(4)} (${farmingHolders})`, -metallurgyKnowledge: `${(metallurgyTotal / knowledgeDenominator).toFixed(4)} (${metallurgyHolders})`, -deaths: sim.deaths.toLocaleString() -}; -for (const [id, value] of Object.entries(stats)) { -if (els[id]) els[id].textContent = value; -} +if (els.currentDate) els.currentDate.textContent = formatSimDate(sim.year); const top = livingEthnicities.sort((a, b) => b.population - a.population).slice(0, 9); -els.ethnicityList.innerHTML = top.map(e => ( +if (els.ethnicityList) els.ethnicityList.innerHTML = top.map(e => ( `
  • ` + -`E${e.id} pop ${e.population.toLocaleString()} div ${e.diversity.toFixed(2)} parent ${e.parent || "-"}
  • ` +`民族${e.id} 人口 ${Math.round(e.population).toLocaleString()}
    多様性 ${Math.round(e.diversity * 100)}% 親系統 ${e.parent ? `民族${e.parent}` : "なし"}` )).join(""); maybeRenderStateGraph(); } function setLegend() { const mode = els.viewMode.value; -els.legend.innerHTML = (legendByMode[mode] || legendByMode.resources)(); +const content = (legendByMode[mode] || legendByMode.resources)(); +els.legend.innerHTML = content; +els.legend.hidden = !content; } function maybeRenderStateGraph() { const now = performance.now(); @@ -626,10 +586,18 @@ if (!rect.width) return; const historyWindowSpan = years(SimConfig.render.historyWindowYears); const historyWindowEnd = sim.year; const historyWindowStart = Math.max(0, historyWindowEnd - historyWindowSpan); +renderWorldTrendGraph(historyWindowStart, historyWindowEnd); graphState.filter = els.historyFilter?.value || graphState.filter; graphState.sort = els.historySort?.value || graphState.sort; graphState.metric = els.historyMetric?.value || graphState.metric; -const histories = sim.getAllPolityHistories() +const allHistories = sim.getAllPolityHistories(); +const recentEndedIds = new Set(allHistories +.filter(history => !(history.active && history.ended === null)) +.sort((a, b) => (b.ended ?? 0) - (a.ended ?? 0)) +.slice(0, 20) +.map(history => history.id)); +const histories = allHistories +.filter(history => (history.active && history.ended === null) || recentEndedIds.has(history.id)) .filter(history => (history.ended ?? sim.year) >= historyWindowStart) .map(history => ({ ...history, @@ -682,11 +650,11 @@ const activeRows = selected.filter(item => item.history.active && item.history.e const pastRows = selected.filter(item => !(item.history.active && item.history.ended === null)); const displayRows = []; if (graphState.showActive && graphState.filter !== "ended" && activeRows.length) { -displayRows.push({ type: "group", label: `Living ${activeRows.length}` }); +displayRows.push({ type: "group", label: `存続中 ${activeRows.length}` }); for (const item of activeRows) displayRows.push({ type: "state", item }); } if (graphState.showPast && graphState.filter !== "active" && pastRows.length) { -displayRows.push({ type: "group", label: `Past ${pastRows.length}` }); +displayRows.push({ type: "group", label: `滅亡済み ${pastRows.length}` }); for (const item of pastRows) displayRows.push({ type: "state", item }); } const logicalHeight = paddingTop + @@ -715,7 +683,8 @@ graphState.markers = []; graphState.scale = null; g.fillStyle = "#7f8984"; g.font = "12px ui-sans-serif, system-ui, sans-serif"; -g.fillText("No state history yet", 16, 28); +g.fillText("国家の歴史はまだありません", 16, 28); +setEventLegend(); return; } let minYear = historyWindowStart; @@ -786,17 +755,20 @@ g.textAlign = "center"; g.fillText(formatGraphYear((minYear + maxYear) / 2), paddingLeft + plotWidth / 2, h - 5); g.textAlign = "right"; g.fillText(formatGraphYear(maxYear), w - paddingRight, h - 5); -const topEvents = (sim.graphEvents || []) +const topEvents = graphState.showEventIcons ? (sim.graphEvents || []) .filter(event => event.importance >= 2) .filter(event => event.year >= minYear && event.year <= maxYear) -.filter(event => graphEventTypes[event.type]); +.filter(event => event.type !== "war" || event.data?.outcome === "started") +.filter(event => graphEventTypes[event.type]) : []; const topCollisions = new Map(); for (const event of topEvents) { -const x = yearToX(event.year); -const bucket = Math.round(x / 7); +const rawX = yearToX(event.year); +const bucket = Math.round(rawX / 18); const count = topCollisions.get(bucket) || 0; topCollisions.set(bucket, count + 1); -const y = Math.max(7, paddingTop * 0.5 + ([-3, 0, 3][count % 3])); +const point = spreadGraphMarker(rawX, paddingTop * 0.5, count, paddingLeft, w - paddingRight); +const x = point.x; +const y = point.y; const r = event.importance >= 4 ? 5 : event.importance >= 3 ? 4 : 3; const graphEvent = graphEventTypes[event.type]; g.fillStyle = graphEvent.color; @@ -821,7 +793,7 @@ const history = row.history; g.textAlign = "left"; g.fillStyle = "#a8b1aa"; g.font = "9px ui-sans-serif, system-ui, sans-serif"; -g.fillText(`S${history.id}`, 4, row.y + 3); +g.fillText(`国${history.id}`, 4, row.y + 3); const inactiveMultiplier = history.active ? 1 : 0.65; const strokeSegment = (fromYear, toYear, metricValue, cities, alphaScale = 1) => { if (toYear <= fromYear) return; @@ -869,17 +841,20 @@ strokeSegment(history.visibleFounded, history.ended ?? sim.year, graphSampleValu }); rows.forEach(row => { if (row.type !== "state") return; -const events = (row.history.events || []) +const events = graphState.showEventIcons ? (row.history.events || []) .filter(event => event.importance >= 2) .filter(event => event.year >= minYear && event.year <= maxYear) -.filter(event => graphEventTypes[event.type]); +.filter(event => event.type !== "war" || event.data?.outcome === "started") +.filter(event => graphEventTypes[event.type]) : []; const collisions = new Map(); for (const event of events) { -const x = yearToX(event.year); -const bucket = Math.round(x / 7); +const rawX = yearToX(event.year); +const bucket = Math.round(rawX / 18); const count = collisions.get(bucket) || 0; collisions.set(bucket, count + 1); -const y = row.y + ([-4, 0, 4][count % 3]); +const point = spreadGraphMarker(rawX, row.y, count, paddingLeft, w - paddingRight); +const x = point.x; +const y = point.y; const r = event.importance >= 4 ? 5 : event.importance >= 3 ? 4 : 3; const graphEvent = graphEventTypes[event.type]; g.fillStyle = graphEvent.color; @@ -887,6 +862,113 @@ graphEvent.draw(g, x, y, r); graphState.markers.push({ row, event, x, y, radius: r + 3 }); } }); +setEventLegend(); +} +function renderWorldTrendGraph(minYear, maxYear) { +const canvas = els.worldTrendGraph; +if (!canvas || !sim) return; +const rect = canvas.getBoundingClientRect(); +if (!rect.width) return; +const dpr = window.devicePixelRatio || 1; +const logicalHeight = 176; +const width = Math.max(1, Math.floor(rect.width * dpr)); +const height = Math.max(1, Math.floor(logicalHeight * dpr)); +if (canvas.width !== width || canvas.height !== height) { +canvas.width = width; +canvas.height = height; +} +const g = canvas.getContext("2d"); +g.setTransform(dpr, 0, 0, dpr, 0, 0); +const w = rect.width; +g.clearRect(0, 0, w, logicalHeight); +g.fillStyle = "#101315"; +g.fillRect(0, 0, w, logicalHeight); +const samples = (sim.worldHistory || []).filter(sample => sample.year >= minYear && sample.year <= maxYear); +if (!samples.length) { +g.fillStyle = "#7f8984"; +g.font = "11px ui-sans-serif, system-ui, sans-serif"; +g.fillText("推移データはまだありません", 8, 20); +return; +} +const left = 7; +const right = 7; +const plotWidth = Math.max(1, w - left - right); +const span = Math.max(1, maxYear - minYear); +const xAt = sample => left + ((sample.year - minYear) / span) * plotWidth; +const regional = samples.map(sample => Math.max(0, sample.regionalPopulation || 0)); +const urban = samples.map(sample => Math.max(0, sample.urbanPopulation || 0)); +const populationMaximum = Math.max(1, ...regional.map((value, index) => value + urban[index])); +const populationTop = 22; +const populationBaseline = 91; +const populationHeight = populationBaseline - populationTop; +g.strokeStyle = "rgba(168, 177, 170, 0.13)"; +g.lineWidth = 1; +strokeLine(g, left, populationBaseline, w - right, populationBaseline); +const populationY = value => populationBaseline - value / populationMaximum * populationHeight; +g.beginPath(); +g.moveTo(xAt(samples[0]), populationBaseline); +for (let index = 0; index < samples.length; index++) g.lineTo(xAt(samples[index]), populationY(regional[index])); +g.lineTo(xAt(samples[samples.length - 1]), populationBaseline); +g.closePath(); +g.fillStyle = "rgba(117, 181, 126, 0.42)"; +g.fill(); +g.beginPath(); +g.moveTo(xAt(samples[0]), populationY(regional[0])); +for (let index = 0; index < samples.length; index++) g.lineTo(xAt(samples[index]), populationY(regional[index] + urban[index])); +for (let index = samples.length - 1; index >= 0; index--) g.lineTo(xAt(samples[index]), populationY(regional[index])); +g.closePath(); +g.fillStyle = "rgba(227, 198, 116, 0.58)"; +g.fill(); +g.fillStyle = "#9bc89b"; +g.font = "10px ui-sans-serif, system-ui, sans-serif"; +g.textAlign = "left"; +g.fillText(`地域人口 ${Math.round(regional.at(-1)).toLocaleString()}`, 7, 12); +g.fillStyle = "#e3c674"; +g.fillText(`都市人口 ${Math.round(urban.at(-1)).toLocaleString()}`, Math.max(112, w * 0.5), 12); +const countMetrics = [ +{ key: "cities", label: "都市", color: "#77b9d6" }, +{ key: "polities", label: "国家", color: "#d58b84" }, +{ key: "ethnicities", label: "民族", color: "#b49bd6" } +]; +const countTop = 112; +const countBaseline = 169; +const countHeight = countBaseline - countTop; +const countMaximum = Math.max(1, ...countMetrics.flatMap(metric => samples.map(sample => Math.max(0, sample[metric.key] || 0)))); +strokeLine(g, left, countBaseline, w - right, countBaseline); +for (let metricIndex = 0; metricIndex < countMetrics.length; metricIndex++) { +const metric = countMetrics[metricIndex]; +const values = samples.map(sample => Math.max(0, sample[metric.key] || 0)); +g.fillStyle = metric.color; +g.fillText(`${metric.label} ${Math.round(values.at(-1)).toLocaleString()}`, 7 + metricIndex * Math.max(78, (w - 14) / 3), 105); +g.beginPath(); +for (let index = 0; index < samples.length; index++) { +const x = xAt(samples[index]); +const y = countBaseline - values[index] / countMaximum * countHeight; +if (index === 0) g.moveTo(x, y); +else g.lineTo(x, y); +} +g.strokeStyle = metric.color; +g.lineWidth = 1.6; +g.stroke(); +const lastX = xAt(samples.at(-1)); +const lastY = countBaseline - values.at(-1) / countMaximum * countHeight; +g.beginPath(); +g.arc(lastX, lastY, 2, 0, Math.PI * 2); +g.fillStyle = metric.color; +g.fill(); +} +g.textAlign = "left"; +} +function spreadGraphMarker(x, baseY, count, minX, maxX) { +const xOffsets = [0, -8, 8, -16, 16, -24, 24]; +const yOffsets = [0, -6, 6]; +const positionsPerBand = xOffsets.length * yOffsets.length; +const band = Math.floor(count / positionsPerBand); +const position = count % positionsPerBand; +const xOffset = xOffsets[Math.floor(position / yOffsets.length)]; +const yOffset = yOffsets[position % yOffsets.length]; +const bandOffset = band ? (band * 3) * (x < (minX + maxX) * 0.5 ? 1 : -1) : 0; +return { x: clamp(x + xOffset + bandOffset, minX, maxX), y: baseY + yOffset }; } function drawGraphCircle(g, x, y, r) { g.beginPath(); @@ -910,143 +992,82 @@ function drawGraphTriangleDown(g, x, y, r) { drawGraphPolygon(g, [[x, y + r], [x + r, y - r], [x - r, y - r]]); } const graphEventTypes = { -capitalShift: { -label: "capital shift", -color: "rgba(227, 179, 65, 0.95)", -draw: drawGraphDiamond, -summary: data => `capital #${data.oldCenterCityId ?? "-"} to #${data.newCenterCityId ?? "-"}` -}, -disaster: { -label: "major disaster", -color: "rgba(211, 95, 84, 0.95)", -draw: drawGraphCircle, -summary: data => `lost ${Math.round((data.lossRate || 0) * 100)}%, ${Math.round(data.populationLoss || 0).toLocaleString()} people, ${data.affectedCities || 0} cities` -}, -famine: { -label: "famine", -color: "rgba(227, 128, 65, 0.90)", -draw: drawGraphTriangleDown, -summary: data => `poor cities ${Math.round((data.poorRate || 0) * 100)}%, food ${Number(data.avgPerCapitaFood || 0).toFixed(3)}/cap` -}, -rebellion: { -label: "rebellion", -color: "rgba(236, 126, 111, 0.95)", -draw: drawGraphTriangleUp, -summary: data => data.cityCount > 1 -? `${data.cityCount} cities, pop ${Math.round(data.population || 0).toLocaleString()}, loyalty ${Number(data.loyalty || 0).toFixed(2)}` -: `city #${data.cityId ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}, loyalty ${Number(data.loyalty || 0).toFixed(2)}` -}, -newEthnicity: { -label: "new ethnicity", -color: "rgba(105, 181, 120, 0.95)", -draw: drawGraphDiamond, -summary: data => `E${data.ethnicity ?? "-"}, ${Math.round(data.population || 0).toLocaleString()} frontier population` -}, -campaign: { -label: "campaign", -color: "rgba(232, 205, 116, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `${data.outcome || "event"} ${data.campaignType || data.targetType || "target"}` -}, -expansion: { -label: "expansion", -color: "rgba(210, 194, 104, 0.95)", -draw: drawGraphDiamond, -summary: data => `${data.outcome || "event"} ${data.campaignType || "frontier"}, tile ${data.targetTile ?? "-"}` -}, -colonization: { -label: "colonization", -color: "rgba(232, 205, 116, 0.95)", -draw: drawGraphDiamond, -summary: data => `${data.campaignType || "frontier"}, progress ${Math.round((data.progress || 0) * 100)}%` -}, -subjugation: { -label: "subjugation", -color: "rgba(196, 122, 77, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `${data.campaignType || "non-state"}, tile ${data.targetTile ?? "-"}` -}, -annexation: { -label: "annexation", -color: "rgba(227, 179, 65, 0.95)", -draw: drawGraphDiamond, -summary: data => `city #${data.targetCityId ?? "-"}` -}, -failedCampaign: { -label: "failed campaign", -color: "rgba(151, 110, 91, 0.95)", -draw: drawGraphTriangleDown, -summary: data => `${data.outcome || "failed"} ${data.campaignType || "campaign"}` -}, -borderWar: { -label: "border war", -color: "rgba(236, 126, 111, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `${data.outcome || "war"} vs S${data.targetPolityId ?? "-"}` -}, -nomadBand: { -label: "nomad band", -color: "rgba(210, 184, 104, 0.95)", -draw: drawGraphDiamond, -summary: data => `band #${data.bandId ?? "-"}, E${data.ethnicity ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}` -}, -nomadTrade: { -label: "nomad trade", -color: "rgba(216, 177, 86, 0.95)", -draw: drawGraphCircle, -summary: data => `band #${data.bandId ?? "-"} with city #${data.cityId ?? "-"}` -}, -nomadRaid: { -label: "nomad raid", -color: "rgba(232, 101, 76, 0.95)", -draw: drawGraphTriangleDown, -summary: data => `band #${data.bandId ?? "-"} raided city #${data.cityId ?? "-"}` -}, -nomadConquest: { -label: "nomad conquest", -color: "rgba(202, 87, 78, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `band #${data.bandId ?? "-"}, city #${data.cityId ?? "-"}, ${data.outcome || "conquest"}` -}, -nomadConfederation: { -label: "nomad confederation", -color: "rgba(191, 162, 91, 0.95)", -draw: drawGraphDiamond, -summary: data => `band #${data.bandId ?? "-"}, pop ${Math.round(data.population || 0).toLocaleString()}` -}, -nomadSplit: { -label: "nomad split", -color: "rgba(151, 130, 91, 0.95)", -draw: drawGraphTriangleDown, -summary: data => `band #${data.bandId ?? "-"} split #${data.newBandId ?? "-"}` -}, -nomadMerge: { -label: "nomad merge", -color: "rgba(170, 145, 91, 0.95)", -draw: drawGraphDiamond, -summary: data => `band #${data.mergedBandId ?? "-"} joined #${data.bandId ?? "-"}` -}, -sedentarization: { -label: "sedentarization", -color: "rgba(202, 169, 102, 0.95)", -draw: drawGraphCircle, -summary: data => `band #${data.bandId ?? "-"} settled ${Math.round(data.population || 0).toLocaleString()} in city #${data.cityId ?? "-"}` -}, -war: { -label: "war", -color: "rgba(202, 87, 78, 0.95)", -draw: drawGraphTriangleUp, -summary: data => `${data.outcome || "war"} ${data.campaignType || ""}` -}, -collapse: { -label: "collapse", -color: "rgba(130, 136, 139, 0.95)", -draw: drawGraphTriangleDown, -summary: data => data.reason || "state ended" -} +capitalShift: { label: "遷都", color: "rgba(227, 179, 65, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("capitalShift", data) }, +disaster: { label: "大災害", color: "rgba(211, 95, 84, 0.95)", draw: drawGraphCircle, summary: data => summarizeEvent("disaster", data) }, +famine: { label: "飢饉", color: "rgba(227, 128, 65, 0.90)", draw: drawGraphTriangleDown, summary: data => summarizeEvent("famine", data) }, +rebellion: { label: "反乱", color: "rgba(236, 126, 111, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("rebellion", data) }, +institutionalReform: { label: "制度改革", color: "rgba(111, 173, 206, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("institutionalReform", data) }, +newEthnicity: { label: "新しい民族", color: "rgba(105, 181, 120, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("newEthnicity", data) }, +campaign: { label: "遠征", color: "rgba(232, 205, 116, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("campaign", data) }, +expansion: { label: "領土拡大", color: "rgba(210, 194, 104, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("expansion", data) }, +colonization: { label: "開拓", color: "rgba(232, 205, 116, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("colonization", data) }, +subjugation: { label: "征服", color: "rgba(196, 122, 77, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("subjugation", data) }, +annexation: { label: "都市の併合", color: "rgba(227, 179, 65, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("annexation", data) }, +failedCampaign: { label: "遠征失敗", color: "rgba(151, 110, 91, 0.95)", draw: drawGraphTriangleDown, summary: data => summarizeEvent("failedCampaign", data) }, +borderWar: { label: "国境戦争", color: "rgba(236, 126, 111, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("borderWar", data) }, +nomadBand: { label: "遊牧集団の誕生", color: "rgba(210, 184, 104, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("nomadBand", data) }, +nomadTrade: { label: "遊牧集団との交易", color: "rgba(216, 177, 86, 0.95)", draw: drawGraphCircle, summary: data => summarizeEvent("nomadTrade", data) }, +nomadRaid: { label: "遊牧集団の襲撃", color: "rgba(232, 101, 76, 0.95)", draw: drawGraphTriangleDown, summary: data => summarizeEvent("nomadRaid", data) }, +nomadConquest: { label: "遊牧集団の征服", color: "rgba(202, 87, 78, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("nomadConquest", data) }, +nomadConfederation: { label: "遊牧連合", color: "rgba(191, 162, 91, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("nomadConfederation", data) }, +nomadSplit: { label: "遊牧集団の分裂", color: "rgba(151, 130, 91, 0.95)", draw: drawGraphTriangleDown, summary: data => summarizeEvent("nomadSplit", data) }, +nomadMerge: { label: "遊牧集団の合流", color: "rgba(170, 145, 91, 0.95)", draw: drawGraphDiamond, summary: data => summarizeEvent("nomadMerge", data) }, +sedentarization: { label: "遊牧集団の定住", color: "rgba(202, 169, 102, 0.95)", draw: drawGraphCircle, summary: data => summarizeEvent("sedentarization", data) }, +war: { label: "戦争", color: "rgba(202, 87, 78, 0.95)", draw: drawGraphTriangleUp, summary: data => summarizeEvent("war", data) }, +collapse: { label: "国家の崩壊", color: "rgba(130, 136, 139, 0.95)", draw: drawGraphTriangleDown, summary: data => summarizeEvent("collapse", data) } }; +function summarizeEvent(type, data) { +if (type === "capitalShift") return `都市${data.oldCenterCityId ?? "-"} → 都市${data.newCenterCityId ?? "-"}`; +if (type === "disaster") return `人口損失 ${Math.round((data.lossRate || 0) * 100)}%・死者 ${Math.round(data.populationLoss || 0).toLocaleString()}人`; +if (type === "famine") return `食料不足の都市 ${Math.round((data.poorRate || 0) * 100)}%`; +if (type === "institutionalReform") { +const before = Math.round((data.before || 0) * 100); +const after = Math.round((data.after || 0) * 100); +const change = Math.round((data.changeRate || 0) * 100); +return `制度老朽化 ${before}% → ${after}%(${change >= 0 ? "+" : ""}${change}%)`; +} +const details = []; +if (data.outcome || data.reason) details.push(displayTerm(data.outcome || data.reason)); +if (data.campaignType) details.push(displayTerm(data.campaignType)); +if (data.bandId != null) details.push(`遊牧集団${data.bandId}`); +if (data.cityId != null || data.targetCityId != null) details.push(`都市${data.cityId ?? data.targetCityId}`); +if (data.targetPolityId != null) details.push(`相手国${data.targetPolityId}`); +if (data.ethnicity != null) details.push(`民族${data.ethnicity}`); +if (data.population != null) details.push(`人口 ${Math.round(data.population).toLocaleString()}`); +if (data.cityCount != null) details.push(`${data.cityCount}都市`); +if (data.newBandId != null) details.push(`新集団${data.newBandId}`); +if (data.mergedBandId != null) details.push(`合流元${data.mergedBandId}`); +if (data.progress != null) details.push(`進捗 ${Math.round(data.progress * 100)}%`); +return details.join("・"); +} +function setEventLegend() { +if (!els.eventLegend) return; +if (!graphState.showEventIcons) { +els.eventLegend.setAttribute("data-event-types", "hidden"); +els.eventLegend.innerHTML = '

    出来事アイコンは非表示です。

    '; +return; +} +const types = [...new Set(graphState.markers.map(marker => marker.event.type))] +.filter(type => graphEventTypes[type]); +const key = types.join(","); +if (els.eventLegend.getAttribute("data-event-types") === key) return; +els.eventLegend.setAttribute("data-event-types", key); +if (!types.length) { +els.eventLegend.innerHTML = '

    現在、歴史グラフに出来事の記号は表示されていません。

    '; +return; +} +els.eventLegend.innerHTML = types.map(type => +`${graphEventTypes[type].label}` +).join(""); +for (const canvas of els.eventLegend.querySelectorAll("canvas")) { +const event = graphEventTypes[canvas.getAttribute("data-event-type")]; +const g = canvas.getContext("2d"); +g.fillStyle = event.color; +event.draw(g, 10, 10, 5); +} +} function graphEventLabel(event) { -return graphEventTypes[event.type]?.label || event.type; +return graphEventTypes[event.type]?.label || "出来事"; } function graphEventSummary(event) { return graphEventTypes[event.type]?.summary(event.data || {}) || ""; @@ -1054,7 +1075,7 @@ return graphEventTypes[event.type]?.summary(event.data || {}) || ""; function showStateGraphMarkerTooltip(marker, pointerX, pointerY) { if (!els.stateGraphTooltip) return; const title = marker.row -? `S${marker.row.history.id} ${graphEventLabel(marker.event)}` +? `国家${marker.row.history.id} ${graphEventLabel(marker.event)}` : graphEventLabel(marker.event); els.stateGraphTooltip.innerHTML = ` ${title} @@ -1090,8 +1111,8 @@ if (!running) render(); } return; } -const status = nearestMarker.row.history.active && nearestMarker.row.history.ended === null ? "living" : "past"; -els.stateGraphInfo.textContent = `S${nearestMarker.row.history.id} ${status} ${formatGraphYear(nearestMarker.event.year)} ${graphEventLabel(nearestMarker.event)}`; +const status = nearestMarker.row.history.active && nearestMarker.row.history.ended === null ? "存続中" : "滅亡済み"; +els.stateGraphInfo.textContent = `国家${nearestMarker.row.history.id} ${status} ${formatGraphYear(nearestMarker.event.year)} ${graphEventLabel(nearestMarker.event)}`; showStateGraphMarkerTooltip(nearestMarker, x, y); if (graphState.hoverPolityId !== nearestMarker.row.history.id) { graphState.hoverPolityId = nearestMarker.row.history.id; @@ -1104,7 +1125,7 @@ const row = graphState.rows .filter(item => item.distance <= item.candidate.height * 0.5); const nearestRow = bestBy(row, item => -item.distance)?.candidate; if (!nearestRow) { -els.stateGraphInfo.textContent = "Hover a row for details"; +els.stateGraphInfo.textContent = ""; hideStateGraphMarkerTooltip(); if (graphState.hoverPolityId !== null) { graphState.hoverPolityId = null; @@ -1127,16 +1148,13 @@ power: nearestRow.peakPower }]; const sample = bestBy(samples, candidate => -Math.abs((candidate.year ?? year) - year)); const metricValue = graphSampleValue(sample, graphState.metric); -const status = nearestRow.history.active && nearestRow.history.ended === null ? "living" : "past"; +const status = nearestRow.history.active && nearestRow.history.ended === null ? "存続中" : "滅亡済み"; els.stateGraphInfo.textContent = -`S${nearestRow.history.id} ${status} ${formatGraphYear(sample.year ?? year)} ` + -`${graphState.metric} ${formatGraphValue(metricValue, graphState.metric)} ` + -`pop ${Math.round(sample.population || 0).toLocaleString()} ` + -`cities ${Math.round(sample.cities || 0).toLocaleString()} ` + -`loyalty ${formatGraphValue(sample.avgLoyalty ?? 0.5, "loyalty")}`; +`国家${nearestRow.history.id} ${status} ${formatGraphYear(sample.year ?? year)} ` + +`${({power: "国力", population: "人口", cities: "都市数", loyalty: "忠誠度"})[graphState.metric]} ${formatGraphValue(metricValue, graphState.metric)}`; } function clearStateGraphInfo() { -if (els.stateGraphInfo) els.stateGraphInfo.textContent = "Hover a row for details"; +if (els.stateGraphInfo) els.stateGraphInfo.textContent = ""; hideStateGraphMarkerTooltip(); if (graphState.hoverPolityId !== null) { graphState.hoverPolityId = null; @@ -1144,12 +1162,12 @@ if (!running) render(); } } function formatGraphYear(week) { -return `${Math.floor(week / WEEKS_PER_YEAR).toLocaleString()}y`; +return `${Math.floor(week / WEEKS_PER_YEAR).toLocaleString()}年`; } function formatSimDate(week) { const year = Math.floor(week / WEEKS_PER_YEAR); const weekOfYear = week % WEEKS_PER_YEAR; const monthOfYear = Math.floor(weekOfYear / WEEKS_PER_MONTH) + 1; const weekOfMonth = weekOfYear % WEEKS_PER_MONTH + 1; -return `${year.toLocaleString()}y ${monthOfYear}m ${weekOfMonth}w`; +return `${year.toLocaleString()}年 ${monthOfYear}月 第${weekOfMonth}週`; } diff --git a/styles.css b/styles.css index 4ca31d4..f159287 100644 --- a/styles.css +++ b/styles.css @@ -26,7 +26,7 @@ body { body { background: var(--bg); color: var(--text); - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Yu Gothic", "Meiryo", sans-serif; } button, @@ -64,6 +64,28 @@ select { background: #16191b; } +.current-date { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 10px; + padding: 9px 11px; + border: 1px solid var(--line); + border-radius: 7px; + background: #101315; +} + +.current-date span { + color: var(--muted); + font-size: 11px; +} + +.current-date strong { + color: var(--text); + font-size: 14px; + font-variant-numeric: tabular-nums; +} + .history-panel { display: flex; flex-direction: column; @@ -113,7 +135,7 @@ select { } .history-group-controls { - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(3, minmax(0, 1fr)); } .history-group-controls button[aria-pressed="false"] { @@ -130,6 +152,29 @@ select { image-rendering: auto; } +.world-trend-wrap { + flex: none; + margin-bottom: 8px; + border: 1px solid var(--line); + border-radius: 6px; + overflow: hidden; + background: #101315; +} + +.world-trend-wrap h3 { + margin: 0; + padding: 6px 8px 2px; + color: var(--muted); + font-size: 11px; + font-weight: 600; +} + +#worldTrendGraph { + display: block; + width: 100%; + height: 176px; +} + .state-graph-scroll { position: relative; flex: 1; @@ -192,6 +237,23 @@ select { line-height: 1.35; } +.return-link { + display: inline-block; + margin-top: 8px; + padding: 5px 9px; + border: 1px solid #3d464b; + border-radius: 6px; + background: var(--panel-2); + color: var(--text); + font-size: 11px; + text-decoration: none; +} + +.return-link:hover { + border-color: #59656b; + color: var(--accent); +} + .panel { padding: 12px; border: 1px solid var(--line); @@ -206,6 +268,49 @@ select { margin-bottom: 12px; } +.row-two { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.intervention-tools { + margin-top: 12px; + padding-top: 11px; + border-top: 1px solid var(--line); +} + +.control-heading { + display: block; + margin-bottom: 7px; + color: var(--muted); + font-size: 12px; +} + +.tool-row { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 6px; +} + +.tool-row button { + min-width: 0; + padding: 0 6px; + font-size: 11px; +} + +.tool-row button[aria-pressed="true"] { + border-color: #8b7840; + background: #4b4023; + color: #fff0b1; +} + +.intervention-status { + min-height: 2.6em; + margin: 7px 0 0; + color: var(--muted); + font-size: 10px; + line-height: 1.3; +} + button, select { min-height: 34px; @@ -306,6 +411,14 @@ select { vertical-align: -1px; } +.fps-counter { + margin-top: 8px; + color: var(--muted); + font-size: 10px; + font-variant-numeric: tabular-nums; + text-align: right; +} + .sim { position: relative; display: grid; @@ -345,6 +458,10 @@ canvas#world { font-size: 11px; } +.legend[hidden] { + display: none; +} + .legend span { display: inline-flex; align-items: center; @@ -371,10 +488,42 @@ canvas#world { color: var(--text); font-size: 11px; line-height: 1.35; - pointer-events: auto; + pointer-events: none; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28); } +.map-guide summary { + cursor: pointer; + font-size: 14px; + font-weight: 700; +} +.map-guide h3 { + margin: 14px 0 6px; + font-size: 12px; +} +.map-guide p, +.guide-list { + margin: 6px 0; + color: var(--muted); + font-size: 11px; + line-height: 1.65; +} +.guide-list div { margin-bottom: 8px; } +.guide-list dt { color: var(--text); font-weight: 700; } +.guide-list dd { margin: 2px 0 0; } +.guide-list .guide-gold { color: #ffd75a; } +.guide-list .guide-red { color: #ec7e6f; } +.event-legend { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 5px 8px; + font-size: 11px; + color: var(--muted); +} +.event-legend span { display: flex; align-items: baseline; gap: 5px; } +.event-legend canvas { width: 20px; height: 20px; flex: 0 0 20px; } +.event-legend .event-legend-empty { grid-column: 1 / -1; } + .tooltip strong { display: block; margin-bottom: 6px; @@ -458,6 +607,51 @@ canvas#world { border-radius: 2px; } +.regenerate-dialog { + width: min(380px, calc(100vw - 32px)); + padding: 0; + border: 1px solid #465158; + border-radius: 9px; + background: var(--panel); + color: var(--text); + box-shadow: 0 18px 60px rgba(0, 0, 0, 0.48); +} + +.regenerate-dialog::backdrop { + background: rgba(0, 0, 0, 0.62); +} + +.regenerate-form { + display: grid; + gap: 13px; + padding: 18px; +} + +.regenerate-form h2 { + margin: 0; + font-size: 17px; +} + +.regenerate-form label { + display: grid; + gap: 6px; + color: var(--muted); + font-size: 12px; +} + +.regenerate-form p { + margin: 0; + color: var(--muted); + font-size: 11px; + line-height: 1.5; +} + +.dialog-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + @media (max-width: 1100px) { body { overflow: auto; diff --git a/tests/modifications.test.cjs b/tests/modifications.test.cjs new file mode 100644 index 0000000..6367f08 --- /dev/null +++ b/tests/modifications.test.cjs @@ -0,0 +1,600 @@ +const { test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); +const vm = require('node:vm'); + +const root = path.join(__dirname, '..'); +const read = name => fs.readFileSync(path.join(root, name), 'utf8'); +const context = vm.createContext({ console, Date, performance }); +vm.runInContext( + read('config.js') + read('utils.js') + read('engine.js') + + ';globalThis.WorldClass = World;globalThis.SimulationClass = Simulation;globalThis.Settings = SimConfig;', + context +); + +function findConnectedLandPair(sim, minDistance = 6, maxDistance = 20) { + const w = sim.world; + const start = w.terrain.findIndex(t => t !== 3); + assert.ok(start >= 0, 'land tile required'); + const queue = [start]; + const seen = new Set([start]); + while (queue.length) { + const tile = queue.shift(); + const distance = Math.abs(tile % w.size - start % w.size) + Math.abs(Math.floor(tile / w.size) - Math.floor(start / w.size)); + if (distance >= minDistance && distance <= maxDistance) return [start, tile]; + const begin = w.landNeighborStarts[tile]; + const end = w.landNeighborStarts[tile + 1]; + for (let i = begin; i < end; i++) { + const next = w.landNeighbors[i]; + if (!seen.has(next)) { seen.add(next); queue.push(next); } + } + } + throw new Error('connected land pair not found'); +} + +test('UIから1週進行と初期人口スライダーを削除し、再生成ダイアログと介入ボタンを備える', () => { + const html = read('index.html'); + assert.equal(html.includes('id="stepOnce"'), false); + assert.equal(html.includes('id="agentCount"'), false); + assert.ok(html.includes('id="regenerateDialog"')); + assert.ok(html.includes('id="worldSize"')); + assert.ok(html.includes('id="triggerDisaster"')); + assert.ok(html.includes('id="buildCity"')); + assert.ok(html.includes('id="connectCities"')); +}); + +test('水域の肥沃度は常に0として生成する', () => { + const sim = new context.SimulationClass(32, 1000); + let water = 0; + for (let i = 0; i < sim.world.count; i++) { + if (sim.world.terrain[i] !== 3) continue; + water++; + assert.equal(sim.world.fertility[i], 0); + } + assert.ok(water > 0); +}); + +test('忠誠度30%未満で反乱が自動発火し、50%未満の都市が全て同時参加する', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, centerCityId: 1 }; + const cities = [ + { id: 1, polityId: 1, loyalty: 1, population: 1000 }, + { id: 2, polityId: 1, loyalty: 0.29, population: 600 }, + { id: 3, polityId: 1, loyalty: 0.49, population: 500 }, + { id: 4, polityId: 1, loyalty: 0.50, population: 400 }, + { id: 5, polityId: 1, loyalty: 0.72, population: 300 } + ]; + const events = []; + Object.assign(sim, { + polities: [polity], cities, year: 100, rng: { next: () => 0.999 }, + getPolityCities: p => cities.filter(city => city.polityId === p.id), + polityInstability: () => 0, + polityAgePressure: () => 0, + removeCityFromPolity: city => { city.polityId = null; }, + releaseCityTerritory: () => {}, + createPolity: trigger => { const rebel = { id: 2, centerCityId: trigger.id }; trigger.polityId = 2; return rebel; }, + transferCityToPolity: (city, rebel, options) => { city.polityId = rebel.id; city.loyalty = options.loyalty; return true; }, + claimPolityCoreTerritory: () => [], + addPolityEvent: (id, type, year, data) => events.push({ id, type, year, data }) + }); + sim.splitUnloyalCities(); + assert.equal(cities[1].polityId, 2); + assert.equal(cities[2].polityId, 2); + assert.equal(cities[3].polityId, 1); + assert.equal(cities[4].polityId, 1); + assert.equal(events[0].data.automatic, true); + assert.deepEqual([...events[0].data.cityIds].sort((a, b) => a - b), [2, 3]); +}); + +test('ユーザー建設都市は即時存続でき、手動交易路は保護期間終了後に通常管理へ戻る', () => { + const sim = new context.SimulationClass(32, 1000); + const [aTile, bTile] = findConnectedLandPair(sim); + const a = sim.buildCityAt(aTile % 32, Math.floor(aTile / 32)); + const b = sim.buildCityAt(bTile % 32, Math.floor(bTile / 32)); + assert.equal(a.ok, true); + assert.equal(b.ok, true); + assert.ok(a.city.population > 100); + assert.ok(b.city.population > 100); + const route = sim.createManualTradeRoute(a.city.id, b.city.id); + assert.equal(route.ok, true); + assert.equal(sim.manualTradeRoutes.length, 1); + assert.ok(route.path.some(tile => sim.isManualRouteTileProtected(tile))); + sim.year = route.protectedUntil; + sim.cleanupManualTradeRouteProtection(); + assert.equal(sim.manualTradeRoutes.length, 0); + assert.equal(route.path.some(tile => sim.isManualRouteTileProtected(tile)), false); +}); + +test('戦争人口損害は旧値の約65%に軽減される', () => { + const sim = Object.create(context.SimulationClass.prototype); + Object.assign(sim, { year: 0, deaths: 0 }); + sim.recordWarDeaths = () => {}; + const city = { population: 1000, storedResources: 500, loyalty: 1, ethnicityComposition: new Map() }; + const loss = sim.applyCityWarDamage(city, 0.10, 'war'); + assert.equal(loss, 65); + assert.equal(city.population, 935); +}); + +test('手動災害は指定地点で即時に履歴へ記録される', () => { + const sim = new context.SimulationClass(24, 800); + const before = sim.disasterHistory.length; + const result = sim.triggerManualDisasterAt(12, 12); + assert.equal(result.ok, true); + assert.equal(sim.disasterHistory.length, before + 1); + assert.equal(result.record.x, 12); + assert.equal(result.record.y, 12); +}); + + +test('介入は成功後も選択状態を維持し、連続実行できるUI実装になっている', () => { + const boot = read('boot.js'); + assert.equal(boot.includes('interventionMode = null;\nels.triggerDisaster?.setAttribute("aria-pressed", "false")'), false); + assert.equal(boot.includes('interventionMode = null;\nels.buildCity?.setAttribute("aria-pressed", "false")'), false); + assert.equal(boot.includes('interventionMode = null;\nels.connectCities?.setAttribute("aria-pressed", "false")'), false); + assert.ok(boot.includes('続けて地点をクリックできます。')); + assert.ok(boot.includes('続けて建設地点をクリックできます。')); + assert.ok(boot.includes('続けて1つ目の都市をクリックできます。')); +}); + +test('ヘルプを整理し、交易路保護期間の案内文を表示しない', () => { + const html = read('index.html'); + const boot = read('boot.js'); + assert.ok(html.includes('ヘルプ')); + assert.ok(html.includes('連続実行できます')); + assert.equal(html.includes('ヘルプ:地図・記号の見方'), false); + assert.equal(boot.includes('交易路は${result.protectionYears}年間保護され、その後は自然消滅する可能性があります。'), false); +}); + +test('砂漠横断の交易路は距離上限・通行コスト・建設コストで過度に不利にならない', () => { + const sim = new context.SimulationClass(32, 1000); + const y = 16; + const path = []; + for (let x = 4; x <= 27; x++) { + const tile = sim.world.idx(x, y); + sim.world.terrain[tile] = 4; + sim.world.move[tile] = 1.55; + sim.world.tradeRoute[tile] = 0; + sim.world.pheromone[tile] = 0; + path.push(tile); + } + const a = { id: 9001, x: 4, y, population: 80, polityId: null, knowledge: { farming: 0, metallurgy: 0 } }; + const b = { id: 9002, x: 27, y, population: 80, polityId: null, knowledge: { farming: 0, metallurgy: 0 } }; + const desertShare = sim.desertCorridorShare(a, b); + const desertLimit = sim.effectiveRouteLengthLimit(a, b, null); + const desertCost = sim.routeConstructionCost(path, false); + const desertTileCost = sim.routeTileCost(path[Math.floor(path.length / 2)]); + assert.ok(desertShare > 0.8); + assert.ok(desertTileCost < 1.2, `desert tile route cost=${desertTileCost}`); + + for (const tile of path) { + sim.world.terrain[tile] = 0; + sim.world.move[tile] = 1.0; + } + const plainLimit = sim.effectiveRouteLengthLimit(a, b, null); + const plainCost = sim.routeConstructionCost(path, false); + assert.ok(desertLimit > plainLimit, `desert=${desertLimit}, plain=${plainLimit}`); + assert.ok(desertCost < plainCost, `desert=${desertCost}, plain=${plainCost}`); +}); + +test('ユーザー建設都市には必ず民族構成が設定される', () => { + const sim = new context.SimulationClass(32, 1000); + let tile = -1; + for (let i = 0; i < sim.world.count; i++) { + if (sim.world.terrain[i] === 3) continue; + const x = i % sim.world.size; + const y = Math.floor(i / sim.world.size); + if (!sim.getCitiesNear(x, y, 4).length) { tile = i; break; } + } + assert.ok(tile >= 0, 'buildable land tile required'); + const result = sim.buildCityAt(tile % sim.world.size, Math.floor(tile / sim.world.size)); + assert.equal(result.ok, true); + assert.equal(typeof result.city.ethnicityComposition?.size, 'number'); + assert.ok(result.city.ethnicityComposition.size > 0); + const total = [...result.city.ethnicityComposition.values()].reduce((sum, value) => sum + value, 0); + assert.equal(total, result.city.population); +}); + +test('征服された都市は20年間反乱から保護され、期間終了後は通常判定へ戻る', () => { + const sim = Object.create(context.SimulationClass.prototype); + const city = { id: 2, x: 1, y: 1, polityId: 1, loyalty: 0.22, population: 500, rebellionProtectedUntil: 0 }; + const oldPolity = { id: 1, centerCityId: 1, cityIds: new Set([1, 2]) }; + const newPolity = { id: 2, centerCityId: 3, cityIds: new Set([3]) }; + Object.assign(sim, { + year: 100, + world: { idx: () => 0 }, + polities: [oldPolity, newPolity], + cities: [city], + removeCityFromPolity: target => { oldPolity.cityIds.delete(target.id); target.polityId = null; }, + addCityToPolity: (target, polity, loyalty) => { target.polityId = polity.id; target.loyalty = loyalty; polity.cityIds.add(target.id); }, + transferTerritoryTiles: () => [] + }); + sim.transferCityToPolity(city, newPolity, { loyalty: 0.22, reason: 'warCapture', allowForeignTakeover: true }); + assert.equal(city.rebellionProtectedUntil, 100 + 20 * 48); + assert.equal(sim.isCityRebellionProtected(city), true); + sim.year = city.rebellionProtectedUntil - 1; + assert.equal(sim.isCityRebellionProtected(city), true); + sim.year = city.rebellionProtectedUntil; + assert.equal(sim.isCityRebellionProtected(city), false); +}); + +test('反乱発生時も征服保護中の低忠誠都市は反乱に参加しない', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, centerCityId: 1 }; + const cities = [ + { id: 1, polityId: 1, loyalty: 1, population: 1000, rebellionProtectedUntil: 0 }, + { id: 2, polityId: 1, loyalty: 0.20, population: 600, rebellionProtectedUntil: 0 }, + { id: 3, polityId: 1, loyalty: 0.18, population: 500, rebellionProtectedUntil: 1000 } + ]; + Object.assign(sim, { + polities: [polity], cities, year: 100, rng: { next: () => 0.999 }, + getPolityCities: p => cities.filter(city => city.polityId === p.id), + polityInstability: () => 0, + polityAgePressure: () => 0, + removeCityFromPolity: city => { city.polityId = null; }, + releaseCityTerritory: () => {}, + createPolity: trigger => { const rebel = { id: 2, centerCityId: trigger.id }; trigger.polityId = 2; return rebel; }, + transferCityToPolity: (city, rebel, options) => { city.polityId = rebel.id; city.loyalty = options.loyalty; return true; }, + claimPolityCoreTerritory: () => [], + addPolityEvent: () => {} + }); + sim.splitUnloyalCities(); + assert.equal(cities[1].polityId, 2); + assert.equal(cities[2].polityId, 1); +}); + +test('制度老朽化は毎年増加し、その分だけ忠誠度上限を低下させる', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, founded: 0, institutionalAging: 0.25 }; + Object.assign(sim, { year: 48 * 100, polities: [polity] }); + const before = polity.institutionalAging; + sim.updateInstitutionalAging(); + assert.ok(polity.institutionalAging > before); + assert.equal(Number(sim.polityLoyaltyCap(polity).toFixed(4)), Number((1 - polity.institutionalAging).toFixed(4))); + + const center = { id: 1, polityId: 1, loyalty: 1, population: 1000, storedResources: 100 }; + const city = { id: 2, polityId: 1, loyalty: 1, population: 500, storedResources: 100, supplyStress: 0 }; + polity.centerCityId = 1; + Object.assign(sim, { + cities: [center, city], + getCityById: id => id === 1 ? center : id === 2 ? city : null, + getPolityCities: () => [center, city], + polityInstability: () => 0, + polityAgePressure: () => 0, + polityOverextension: () => 0, + polityLogisticsStress: () => 0, + sameDominantEthnicity: () => true, + effectiveDistance: () => 1, + hasDirectTradeConnection: () => true, + tradeAccessLoyaltyPenalty: () => 0 + }); + sim.updateCityLoyalty(); + const cap = sim.polityLoyaltyCap(polity); + assert.equal(center.loyalty, cap); + assert.ok(city.loyalty <= cap); +}); + +test('制度改革は老朽化30%を超えてから発生し、-50%から+30%の相対変動を履歴へ記録する', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 7, founded: 0, institutionalAging: 0.30, lastInstitutionalReformYear: 0 }; + const events = []; + Object.assign(sim, { + year: 48 * 100, + polities: [polity], + rng: { next: () => 0, range: (min, max) => min }, + addPolityEvent: (id, type, year, data, importance) => events.push({ id, type, year, data, importance }) + }); + assert.equal(context.Settings.polity.institutionalReformThreshold, 0.30); + sim.maybeTriggerInstitutionalReforms(); + assert.equal(events.length, 0); + assert.equal(polity.institutionalAging, 0.30); + + polity.institutionalAging = 0.31; + sim.maybeTriggerInstitutionalReforms(); + assert.equal(Number(polity.institutionalAging.toFixed(3)), 0.155); + assert.equal(events.length, 1); + assert.equal(events[0].type, 'institutionalReform'); + assert.equal(events[0].importance, 3); + assert.equal(events[0].data.changeRate, -0.5); + assert.equal(events[0].data.before, 0.31); + assert.equal(events[0].data.after, 0.155); + assert.equal(context.Settings.polity.institutionalReformCooldownYears, 50); + + polity.institutionalAging = 0.31; + sim.year = 48 * 149; + sim.maybeTriggerInstitutionalReforms(); + assert.equal(events.length, 1, '前回改革から50年未満では再改革しない'); + sim.year = 48 * 150; + sim.maybeTriggerInstitutionalReforms(); + assert.equal(events.length, 2, '50年経過後は再改革できる'); +}); + +test('国庫が上限に達した国家は確率判定で国庫を消費して都市を建設する', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, cityIds: new Set([1]), treasury: 99 }; + const world = { size: 16, city: new Int32Array(256).fill(-1) }; + const cityById = new Map(); + const cityBuckets = new Map(); + let nextCity = 2; + Object.assign(sim, { + polities: [polity], cities: [{ id: 1, x: 2, y: 2, polityId: 1, population: 1000 }], + world, cityById, cityBuckets, year: 48 * 200, rng: { next: () => 0 }, + polityTreasuryCap: () => 100, + findTreasuryCityFoundingSite: () => 5 + 5 * 16, + manualCityEthnicitySeed: () => new Map([[1, 1]]), + createCity: (x, y, _seed, options = {}) => ({ id: nextCity++, x, y, population: options.initialPopulation ?? 400, storedResources: options.initialResources ?? 340, ethnicityComposition: new Map(), polityId: null, loyalty: 0.5 }), + applyCityEthnicitySeed: (city, seed, population) => { city.ethnicityComposition = new Map([[1, population]]); }, + cityBucketKey: () => 0, + addCityToPolity: (city, state, loyalty) => { city.polityId = state.id; city.loyalty = loyalty; state.cityIds.add(city.id); }, + claimPolityCoreTerritory: () => {}, + rebuildIndexes: () => {}, updatePopulationCapacity: () => {}, syncTilePopulationCulture: () => {} + }); + assert.equal(context.Settings.polity.treasuryCityFoundingChance, 0.14); + assert.equal(context.Settings.polity.treasuryCityFoundingCostRatio, 0.35); + assert.equal(sim.maybeBuildTreasuryCities(), 0); + assert.equal(sim.cities.length, 1); + + polity.treasury = 100; + assert.equal(sim.maybeBuildTreasuryCities(), 1); + assert.equal(sim.cities.length, 2); + assert.equal(polity.treasury, 65); + assert.ok(sim.cities[1].population > 400); + assert.ok(sim.cities[1].storedResources > 340); + assert.equal(sim.cities[1].polityId, 1); + assert.equal(sim.cities[1].ethnicityComposition.get(1), sim.cities[1].population); +}); + +test('国家興亡グラフに制度改革イベントと老朽化変動を表示する', () => { + const render = read('render.js'); + assert.ok(render.includes('institutionalReform: { label: "制度改革"')); + assert.ok(render.includes('制度老朽化 ${before}% → ${after}%')); +}); + +test('ヘルプに主要パラメータの簡単な説明を表示する', () => { + const html = read('index.html'); + assert.ok(html.includes('

    主なパラメータ

    ')); + for (const label of ['人口 / 人口圧力', '資源 / 肥沃度', '農業 / 冶金', '交通量', '忠誠度', '国庫', '正統性 / 結束', '制度老朽化', '国力']) { + assert.ok(html.includes(`
    ${label}
    `), `${label} の説明が必要`); + } +}); + +test('国庫上限は国家人口に比例し、超過分を保持しない', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, cityIds: new Set([1, 2]), treasury: 999 }; + const cities = [ + { id: 1, polityId: 1, population: 1200 }, + { id: 2, polityId: 1, population: 800 } + ]; + Object.assign(sim, { + cities, + getPolityCities: () => cities + }); + assert.equal(context.Settings.polity.treasuryCapPerPopulation, 0.30); + assert.equal(sim.polityTreasuryCap(polity), 600); + sim.enforcePolityTreasuryCap(polity); + assert.equal(polity.treasury, 600); + cities[1].population = 300; + assert.equal(sim.polityTreasuryCap(polity), 450); + sim.enforcePolityTreasuryCap(polity); + assert.equal(polity.treasury, 450); +}); + +test('反乱時は反乱人口比に応じて国庫の一部が反乱国へ移る', () => { + const sim = Object.create(context.SimulationClass.prototype); + const polity = { id: 1, centerCityId: 1, cityIds: new Set([1, 2]), treasury: 300 }; + const rebelPolity = { id: 2, centerCityId: 2, cityIds: new Set([2]), treasury: 0 }; + const cities = [ + { id: 1, polityId: 1, loyalty: 1, population: 1000, storedResources: 0, rebellionProtectedUntil: 0 }, + { id: 2, polityId: 1, loyalty: 0.20, population: 1000, storedResources: 0, rebellionProtectedUntil: 0 } + ]; + const events = []; + Object.assign(sim, { + polities: [polity], cities, year: 100, + rng: { next: () => 0.999 }, + getPolityCities: p => cities.filter(city => city.polityId === p.id), + polityInstability: () => 0, + polityAgePressure: () => 0, + removeCityFromPolity: city => { city.polityId = null; polity.cityIds.delete(city.id); }, + releaseCityTerritory: () => {}, + createPolity: trigger => { trigger.polityId = 2; return rebelPolity; }, + transferCityToPolity: (city, rebel, options) => { city.polityId = rebel.id; rebel.cityIds.add(city.id); city.loyalty = options.loyalty; return true; }, + claimPolityCoreTerritory: () => [], + addPolityEvent: (id, type, year, data) => events.push({ id, type, year, data }) + }); + assert.equal(context.Settings.rebellion.treasuryTransferRate, 0.65); + sim.splitUnloyalCities(); + const expected = 300 * 0.5 * 0.65; + assert.equal(Number(rebelPolity.treasury.toFixed(3)), Number(expected.toFixed(3))); + assert.equal(Number(polity.treasury.toFixed(3)), Number((300 - expected).toFixed(3))); + assert.equal(Number(events[0].data.treasuryTransferred.toFixed(3)), Number(expected.toFixed(3))); +}); + +test('自然都市上限を大幅増加し、手動都市は近接・上限制限を無視するが水域には建設できない', () => { + assert.equal(context.Settings.city.maxCities, 1200); + assert.equal(context.Settings.city.naturalFoundingMinDistance, 6); + assert.equal(context.Settings.city.foundingCompetitionRadius, 9); + const sim = new context.SimulationClass(32, 1000); + const water = sim.world.terrain.findIndex(tile => tile === 3); + assert.ok(water >= 0, 'water tile required'); + const wx = water % sim.world.size; + const wy = Math.floor(water / sim.world.size); + const rejected = sim.buildCityAt(wx, wy); + assert.equal(rejected.ok, false); + assert.equal(rejected.reason, 'water'); + + let land = -1; + for (let i = 0; i < sim.world.count; i++) { + if (sim.world.terrain[i] !== 3) { land = i; break; } + } + assert.ok(land >= 0, 'land tile required'); + const x = land % sim.world.size; + const y = Math.floor(land / sim.world.size); + const first = sim.buildCityAt(x, y); + assert.equal(first.ok, true); + let adjacent = -1; + for (const [dx, dy] of [[1,0],[-1,0],[0,1],[0,-1]]) { + const nx = x + dx, ny = y + dy; + if (nx < 0 || ny < 0 || nx >= sim.world.size || ny >= sim.world.size) continue; + if (sim.world.terrain[sim.world.idx(nx, ny)] !== 3) { adjacent = sim.world.idx(nx, ny); break; } + } + if (adjacent >= 0) { + const second = sim.buildCityAt(adjacent % sim.world.size, Math.floor(adjacent / sim.world.size)); + assert.equal(second.ok, true); + assert.ok(Math.abs(second.city.x - first.city.x) + Math.abs(second.city.y - first.city.y) <= 1); + } +}); + +test('交通量拡散は疎更新対象を追跡し、空の世界では全域拡散を行わない', () => { + const sim = new context.SimulationClass(32, 1000); + assert.equal(sim.activePheromoneTiles.size, 0); + const tile = sim.world.terrain.findIndex(t => t !== 3); + assert.ok(tile >= 0); + sim.addPheromone(tile, 4); + assert.ok(sim.activePheromoneTiles.has(tile)); + const before = sim.world.pheromone[tile]; + sim.updatePheromoneField(2); + assert.ok(sim.world.pheromone[tile] < before); + assert.ok(sim.activePheromoneTiles.size > 0); +}); + +test('国家興亡グラフに出来事アイコン表示切替を備え、国庫は一重表示にする', () => { + const html = read('index.html'); + const boot = read('boot.js'); + const render = read('render.js'); + assert.ok(html.includes('id="toggleEventIcons"')); + assert.ok(boot.includes('graphState.showEventIcons = !graphState.showEventIcons')); + assert.ok(render.includes('graphState.showEventIcons ? (sim.graphEvents || [])')); + assert.ok(render.includes('tooltipRow("国庫", Math.max(0, displayPolity.treasury || 0).toFixed(1))')); + assert.equal(render.includes('tooltipRow("国庫", `${Math.max(0, displayPolity.treasury || 0).toFixed(1)} /'), false); +}); + +test('自然都市の創設流量は5年周期でマップ面積に応じて増える', () => { + assert.equal(context.Settings.city.naturalFoundingStartYears, 160); + assert.equal(context.Settings.city.naturalFoundingIntervalYears, 5); + const sim = Object.create(context.SimulationClass.prototype); + sim.world = { count: 160 * 160 }; + assert.equal(sim.naturalCityFoundingLimit(), 1); + sim.world = { count: 220 * 220 }; + assert.equal(sim.naturalCityFoundingLimit(), 2); + sim.world = { count: 280 * 280 }; + assert.equal(sim.naturalCityFoundingLimit(), 4); +}); + +test('都市は人口400で成立し、200未満で消滅する', () => { + assert.equal(context.Settings.city.initialPopulation, 400); + assert.equal(context.Settings.city.abandonmentPopulation, 200); + const sim = new context.SimulationClass(32, 1000); + const land = sim.world.terrain.findIndex(tile => tile !== 3); + assert.ok(land >= 0, 'land tile required'); + const result = sim.buildCityAt(land % sim.world.size, Math.floor(land / sim.world.size)); + assert.equal(result.ok, true); + assert.equal(result.city.population, 400); + + result.city.population = 199; + result.city.strength = 3; + result.city.storedResources = 100; + result.city.activeVisitors = 10; + sim.processCityEconomies = () => {}; + sim.updateCities(); + assert.equal(sim.cities.some(city => city.id === result.city.id), false); + + const simAtThreshold = new context.SimulationClass(32, 1000); + const secondLand = simAtThreshold.world.terrain.findIndex(tile => tile !== 3); + const thresholdCity = simAtThreshold.buildCityAt(secondLand % simAtThreshold.world.size, Math.floor(secondLand / simAtThreshold.world.size)); + thresholdCity.city.population = 200; + thresholdCity.city.strength = 3; + thresholdCity.city.storedResources = 100; + thresholdCity.city.activeVisitors = 10; + simAtThreshold.processCityEconomies = () => {}; + simAtThreshold.updateCities(); + assert.equal(simAtThreshold.cities.some(city => city.id === thresholdCity.city.id), true); +}); + +test('民族分化の時間スケールを1/4にし、極小民族は隣接民族へ吸収する', () => { + assert.equal(context.Settings.culture.divergenceRateMultiplier, 0.25); + assert.equal(context.Settings.culture.absorptionPopulationThreshold, 30); + const sim = new context.SimulationClass(24, 500); + sim.ethnicities.clear(); + sim.tileEthnicMix.clear(); + sim.cities = []; + sim.nomadBands = []; + sim.nextEthnicity = 1; + sim.year = 0; + sim.rng = { next: () => 0.5, range: (min, max) => (min + max) / 2 }; + const targetId = sim.createEthnicity(null, { temperature: 0.5, humidity: 0.5 }); + const lowId = sim.createEthnicity(targetId, { temperature: 0.5, humidity: 0.5 }); + const expectedMinDelay = 18 / 0.25 * 48; + assert.ok(sim.ethnicities.get(lowId).nextDivergenceCheck >= expectedMinDelay); + + const [lowTile, targetTile] = findConnectedLandPair(sim, 1, 1); + sim.tileEthnicMix.set(lowTile, new Map([[lowId, 10]])); + sim.tileEthnicMix.set(targetTile, new Map([[targetId, 100]])); + sim.world.population[lowTile] = 10; + sim.world.population[targetTile] = 100; + sim.updateCultureTile(lowTile); + sim.updateCultureTile(targetTile); + sim.updateEthnicStats(); + assert.ok(sim.ethnicities.get(lowId).population < context.Settings.culture.absorptionPopulationThreshold); + assert.equal(sim.absorbSmallEthnicities(), 1); + assert.equal(sim.ethnicities.has(lowId), false); + assert.equal(sim.tileEthnicMix.get(lowTile).get(targetId), 10); + assert.equal(sim.tileEthnicMix.get(lowTile).has(lowId), false); +}); + +test('再生成ダイアログから初期人口固定の説明を削除する', () => { + const html = read('index.html'); + assert.equal(html.includes('初期人口は標準値'), false); +}); + + +test('国家の都市建設投資は消費額が大きいほど初期人口と初期備蓄を増やす', () => { + const sim = Object.create(context.SimulationClass.prototype); + const low = sim.treasuryCityInvestmentProfile(100); + const mid = sim.treasuryCityInvestmentProfile(500); + const high = sim.treasuryCityInvestmentProfile(2000); + assert.ok(low.population >= context.Settings.city.initialPopulation); + assert.ok(low.population < mid.population && mid.population < high.population); + assert.ok(low.resources < mid.resources && mid.resources < high.resources); +}); + +test('国家の都市建設候補は広い適地全体から加重抽選され、特定地点へ固定されない', () => { + const sim = Object.create(context.SimulationClass.prototype); + const size = 40; + const count = size * size; + const fillFloat = value => { const array = new Float32Array(count); array.fill(value); return array; }; + const world = { + size, count, + terrain: new Uint8Array(count), + city: new Int32Array(count).fill(-1), + territoryOwner: new Int32Array(count).fill(1), + fertility: fillFloat(0.6), resource: fillFloat(20), populationPressure: fillFloat(0.5), + farmland: fillFloat(0.2), control: fillFloat(0.7), pheromone: fillFloat(0), move: fillFloat(1), + tradeRoute: new Uint8Array(count), + idx: (x, y) => y * size + x + }; + let state = 123456789; + Object.assign(sim, { + world, + radiusOffsetCache: new Map(), + getPolityCities: () => [{ x: 20, y: 20 }], + getCitiesNear: () => [], + rng: { next: () => { state = (1664525 * state + 1013904223) >>> 0; return state / 4294967296; } } + }); + const picks = Array.from({ length: 20 }, () => sim.findTreasuryCityFoundingSite({ id: 1 })); + assert.ok(new Set(picks).size >= 12, '同等適地から十分に分散して選ばれる必要がある'); +}); + +test('都市老朽化を削除し、人口回復は人口減少幅に応じて働く', () => { + const engineSource = read('engine.js'); + assert.equal('agingStartYears' in context.Settings.city, false); + assert.equal('agingDecayPerYear' in context.Settings.city, false); + assert.equal('agingCapacityPenaltyMax' in context.Settings.city, false); + assert.equal(engineSource.includes('updateCityAging'), false); + assert.equal(engineSource.includes('ageWear'), false); + + const sim = Object.create(context.SimulationClass.prototype); + const stable = sim.cityRecoveryGrowthBonus({ population: 1000, peakPopulation: 1000 }); + const damaged = sim.cityRecoveryGrowthBonus({ population: 500, peakPopulation: 1000 }); + assert.equal(stable, 0); + assert.ok(damaged > stable); +}); diff --git a/tests/simulation.test.cjs b/tests/simulation.test.cjs new file mode 100644 index 0000000..3c9d2b6 --- /dev/null +++ b/tests/simulation.test.cjs @@ -0,0 +1,478 @@ +const { test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); +const vm = require('node:vm'); +const root = path.join(__dirname, '..'); +const read = name => fs.readFileSync(path.join(root, name), 'utf8'); +const engine = vm.createContext({ console, Date, performance }); +vm.runInContext(read('config.js') + read('utils.js') + read('engine.js') + + ';globalThis.WorldClass = World;globalThis.SimulationClass = Simulation;globalThis.SimSettings = SimConfig;', engine); + +function fixture() { + const w = Object.create(engine.WorldClass.prototype); + Object.assign(w, { size: 16, count: 256, terrain: new Uint8Array(256), + territoryOwner: new Int32Array(256).fill(-1), polity: new Int32Array(256).fill(-1), + city: new Int32Array(256).fill(-1), tradeRoute: new Uint8Array(256), + control: new Float32Array(256), claim: new Float32Array(256), contested: new Uint8Array(256) }); + w.buildLandNeighbors(); + const sim = Object.create(engine.SimulationClass.prototype); + Object.assign(sim, { world: w, scratchIntA: new Int32Array(256), scratchUintA: new Uint8Array(256), + cities: [], polities: [{ id: 1 }, { id: 2 }], polityById: new Map(), territorialClaims: new Map(), radiusOffsetCache: new Map(), + visitStamp: new Int32Array(256), nextVisitStamp: 1, territoryDebug: { disconnectedTerritoryRemoved: 0 } }); + sim.getPolityById = id => sim.polities.find(p => p.id === id); + const set = (x, y, owner = 1) => { w.territoryOwner[w.idx(x, y)] = owner; w.polity[w.idx(x, y)] = owner; }; + const rect = (x1, y1, x2, y2) => { for (let y = y1; y <= y2; y++) for (let x = x1; x <= x2; x++) set(x, y); }; + return { sim, w, set, rect }; +} + +test('国境の小さな穴・凹み・突起を整える', () => { + const { sim, w, set, rect } = fixture(); + rect(3, 3, 11, 11); + set(7, 7, -1); set(3, 7, -1); set(12, 7); + sim.smoothTerritoryBorders(); + assert.equal(w.polity[w.idx(7, 7)], 1); + assert.equal(w.polity[w.idx(3, 7)], 1); + assert.equal(w.polity[w.idx(12, 7)], -1); + assert.deepEqual(w.polity, w.territoryOwner); +}); + +test('細い連絡路・都市・交易路を保護する', () => { + const { sim, w, set, rect } = fixture(); + rect(2, 4, 5, 7); rect(10, 4, 13, 7); + for (let x = 6; x <= 9; x++) set(x, 5); + set(3, 8); sim.cities.push({ x: 3, y: 8 }); + set(12, 8); w.tradeRoute[w.idx(12, 8)] = 100; + sim.smoothTerritoryBorders(); + for (let x = 6; x <= 9; x++) assert.equal(w.polity[w.idx(x, 5)], 1); + assert.equal(w.polity[w.idx(3, 8)], 1); + assert.equal(w.polity[w.idx(12, 8)], 1); +}); + +test('外国の都市と海岸を保護する', () => { + const { sim, w, set, rect } = fixture(); + rect(3, 3, 11, 11); + set(7, 7, -1); set(6, 7, 2); + sim.cities.push({ x: 6, y: 7 }); + w.terrain[w.idx(12, 8)] = 3; + w.buildLandNeighbors(); + const original = w.terrain.slice(); + sim.smoothTerritoryBorders(); + assert.equal(w.polity[w.idx(6, 7)], 2); + assert.equal(w.polity[w.idx(7, 7)], -1); + assert.deepEqual(w.terrain, original); +}); + +test('国家同士の境界でも小さな突起を整える', () => { + const { sim, w, set, rect } = fixture(); + rect(2, 2, 13, 13); + for (let y = 2; y <= 13; y++) for (let x = 9; x <= 13; x++) set(x, y, 2); + set(8, 7, 2); + sim.smoothTerritoryBorders(); + assert.equal(w.polity[w.idx(8, 7)], 1); + assert.equal(w.polity[w.idx(9, 7)], 2); + assert.equal(sim.territorialClaims.get(w.idx(8, 7)).polityId, 1); +}); + +test('通常更新でも都市に接続されていない領土と保存済みの主張を除去する', () => { + const { sim, w, rect } = fixture(); + rect(2, 2, 5, 5); rect(10, 10, 12, 12); + sim.cities = [{ id: 1, x: 3, y: 3, population: 1000, polityId: 1 }]; + sim.territorialClaims.set(w.idx(11, 11), { polityId: 1, claim: 0.8 }); + sim.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); + assert.equal(w.polity[w.idx(3, 3)], 1); + assert.equal(w.polity[w.idx(11, 11)], -1); + assert.equal(w.control[w.idx(11, 11)], 0); + assert.equal(sim.territorialClaims.has(w.idx(11, 11)), false); + assert.deepEqual(w.polity, w.territoryOwner); +}); + +test('都市の国家切り替え後は中心の所属を修正し、旧国家の残存領土を除去する', () => { + const { sim, w, rect } = fixture(); + rect(2, 2, 5, 5); rect(10, 10, 12, 12); + const left = { id: 1, x: 3, y: 3, population: 1000, polityId: 1 }; + const captured = { id: 2, x: 11, y: 11, population: 1000, polityId: 1 }; + sim.cities = [left, captured]; + sim.polities[0].cityIds = new Set([1, 2]); sim.polities[1].cityIds = new Set(); + sim.territorialClaims.set(w.idx(11, 11), { polityId: 1, claim: 0.8 }); + sim.addCityToPolity(captured, sim.polities[1]); + sim.enforceTerritoryConnectivity({ allowOwnershipChanges: false }); + assert.equal(w.polity[w.idx(11, 11)], 2); + assert.equal(w.polity[w.idx(10, 10)], -1); + assert.equal(w.polity[w.idx(3, 3)], 1); + assert.equal(sim.territorialClaims.has(w.idx(11, 11)), false); + captured.polityId = null; + sim.enforceTerritoryConnectivity(); + assert.equal(w.polity[w.idx(11, 11)], -1); +}); + +test('独立都市併合の平和・武力分岐をNode回帰試験で一元管理する', () => { + const selector = Object.create(engine.SimulationClass.prototype); + selector.rng = { next: () => 0.399999 }; + assert.equal(selector.independentAnnexationMode(), 'peaceful'); + selector.rng.next = () => 0.4; + assert.equal(selector.independentAnnexationMode(), 'military'); + + const run = (cityPolityId, annexationMode) => { + const sim = Object.create(engine.SimulationClass.prototype); + const attacker = { id: 1 }; + const city = { id: 7, x: 2, y: 3, polityId: cityPolityId, population: 1000 }; + Object.assign(sim, { + world: { size: 10, territoryOwner: new Int32Array(100), idx: (x, y) => y * 10 + x }, + year: 0, damageCalls: 0, transferCalls: 0 + }); + sim.world.territoryOwner.fill(-1); + sim.getPolityById = id => id === 1 ? attacker : null; + sim.getCityById = id => id === 7 ? city : null; + sim.campaignEthnicSimilarity = () => 0.5; + sim.applyCityWarDamage = () => { sim.damageCalls++; }; + sim.transferCityToPolity = () => { sim.transferCalls++; city.polityId = attacker.id; }; + sim.applyCampaignTerritory = () => []; + sim.addPolityEvent = () => {}; + sim.recordCampaign = () => {}; + sim.syncTilePopulationCulture = () => {}; + sim.recomputeTerritories = () => {}; + sim.reconcileCityTerritoryOwnership = () => {}; + sim.campaignPressureOnTerritories = () => {}; + sim.resolveCampaignSuccess({ + id: 1, type: 'independent_city_annexation', annexationMode, attackerPolityId: 1, + targetCityId: 7, targetTile: 32, progress: 1, strength: 100, resistance: 50 + }); + return sim; + }; + + const peaceful = run(null, 'peaceful'); + assert.equal(peaceful.transferCalls, 1); + assert.equal(peaceful.damageCalls, 0); + const military = run(null, 'military'); + assert.equal(military.transferCalls, 1); + assert.equal(military.damageCalls, 1); + const owned = run(2, 'peaceful'); + assert.equal(owned.transferCalls, 0); +}); + +function warFixture() { + const { sim } = fixture(); + Object.assign(sim, { wars: [], campaigns: [], nextWar: 1, year: 4, deaths: 0, + rng: { range: () => 1, next: () => 0.99 }, + cities: [{ id: 1, polityId: 1, population: 1000, storedResources: 500, loyalty: 1 }, + { id: 2, polityId: 2, population: 1000, storedResources: 500, loyalty: 1 }] }); + sim.getPolityCities = polity => sim.cities.filter(city => city.polityId === polity.id); + sim.chooseWarGoal = () => 'border_claim'; + sim.addPolityEvent = () => {}; + sim.applyWarSettlement = () => {}; + return sim; +} + +test('new polities receive a founding truce before they can enter a war', () => { + const { sim } = fixture(); + Object.assign(sim, { + year: 96, nextPolity: 3, rng: { range: (min, max) => (min + max) / 2 }, + polities: [], polityById: new Map() + }); + sim.transferCityToPolity = () => true; + sim.claimPolityCoreTerritory = () => []; + sim.ensurePolityHistory = () => ({}); + sim.samplePolityHistory = () => {}; + const polity = sim.createPolity({ id: 7, storedResources: 100 }); + assert.equal(polity.nextWarAllowedWeek, 96 + engine.SimSettings.polity.foundingProtectionYears * 48); + + const warSim = warFixture(); + warSim.polities[0].nextWarAllowedWeek = warSim.year + 1; + assert.equal(warSim.startWar(warSim.polities[0], warSim.polities[1]), null); +}); + +test('captured city claims can absorb adjacent neutralized former territory', () => { + const { sim, w, set } = fixture(); + const center = w.idx(8, 8); + const former = w.idx(9, 8); + const neutral = w.idx(8, 9); + set(8, 8, 1); set(9, 8, 2); set(8, 9, -1); + sim.cities = [{ id: 9, x: 8, y: 8, polityId: 1 }]; + w.city[center] = 9; + sim.getCityById = id => sim.cities.find(city => city.id === id) || null; + sim.recomputeTerritories = () => {}; + sim.markContestedFront = () => {}; + const originalTransfer = sim.transferTerritoryTiles.bind(sim); + let optionsSeen = null; + sim.transferTerritoryTiles = (from, to, tiles, options) => { + optionsSeen = options; + return originalTransfer(from, to, tiles, options); + }; + const changed = sim.applyCampaignTerritory(sim.polities[0], center, 2, 0.8, { + allowForeignTakeover: true, fromPolityId: 2, reason: 'war' + }); + assert.equal(optionsSeen.allowNeutralWithFrom, true); + assert.ok(changed.includes(former)); + assert.ok(changed.includes(neutral)); + assert.equal(w.territoryOwner[former], 1); + assert.equal(w.territoryOwner[neutral], 1); +}); + +test('戦争は年境界以外でも4週ごとに損害を与える', () => { + const sim = warFixture(); + sim.startWar(sim.polities[0], sim.polities[1]); + sim.applyWarPressure = (war, attacker, defender) => sim.applyCityWarDamage(sim.getPolityCities(defender)[0], 0.1); + sim.applyWarExhaustion = () => {}; + sim.recordWarDeaths = loss => { sim.deaths += loss; }; + sim.updateWars(); + assert.equal(sim.cities[0].population, 935); + assert.equal(sim.cities[1].population, 935); + assert.equal(sim.deaths, 130); + sim.year = 5; sim.updateWars(); + assert.equal(sim.deaths, 130); +}); + +test('国家間の戦争開始判定も4週ごとに実行する', () => { + const sim = warFixture(); + sim.rng.next = () => 0; + sim.polityPower = () => 100; + sim.polityDistance = () => 10; + sim.polityInstability = sim.polityAgePressure = sim.polityOverextension = () => 0; + sim.averagePolityLoyalty = () => 1; + sim.maybeStartWars(); + assert.equal(sim.wars.length, 1); + assert.equal(sim.wars[0].started, 4); +}); + +test('戦争は経過年数だけでは終結せず、戦闘停止後に終結して再戦間隔を空ける', () => { + const sim = warFixture(); + const war = sim.startWar(sim.polities[0], sim.polities[1]); + sim.campaigns.push({ type: 'border_war', status: 'active', attackerPolityId: 1, defenderPolityId: 2 }); + sim.year = war.started + 100 * 48; + war.lastActionYear = sim.year; + sim.maybeEndWar(war); + assert.equal(war.ended, null); + war.lastActionYear = sim.year - engine.SimSettings.war.idleEndWeeks; + sim.maybeEndWar(war); + assert.equal(war.ended, sim.year); + assert.equal(sim.campaigns[0].status, 'ceased'); + assert.equal(sim.startWar(sim.polities[0], sim.polities[1]), null); + sim.year += engine.SimSettings.war.cooldownWeeks; + assert.ok(sim.startWar(sim.polities[0], sim.polities[1])); +}); + +test('首都から遠く領域接続もない戦場では攻撃補給が不利になる', () => { + const sim = warFixture(); + const capital = Object.assign(sim.cities[0], { x: 2, y: 2, tradeLinks: new Set() }); + const source = { id: 3, polityId: 1, x: 5, y: 2, population: 500, storedResources: 100, tradeLinks: new Set() }; + const closeTarget = Object.assign(sim.cities[1], { x: 7, y: 2, tradeLinks: new Set() }); + const farTarget = { id: 4, polityId: 2, x: 15, y: 15, population: 500, storedResources: 100, tradeLinks: new Set() }; + sim.cities.push(source, farTarget); + sim.polities[0].centerCityId = capital.id; + for (let x = 2; x <= 5; x++) sim.world.territoryOwner[sim.world.idx(x, 2)] = 1; + sim.warLogisticsCache = new Map(); + const connected = sim.warLogisticsFactor(sim.polities[0], source, closeTarget); + sim.world.territoryOwner[sim.world.idx(4, 2)] = -1; + sim.warLogisticsCache = new Map(); + const disconnected = sim.warLogisticsFactor(sim.polities[0], source, closeTarget); + const distant = sim.warLogisticsFactor(sim.polities[0], capital, farTarget); + assert.ok(connected > disconnected * 2); + assert.ok(connected > distant); +}); + +test('明確な戦果や疲弊でも短期間で戦争を終結する', () => { + for (const reason of ['score', 'exhaustion']) { + const sim = warFixture(); + const war = sim.startWar(sim.polities[0], sim.polities[1]); + sim.year = war.started + engine.SimSettings.war.minDurationWeeks; + if (reason === 'score') war.scoreA = engine.SimSettings.war.decisiveScore; + else war.exhaustionA = 0.8; + sim.maybeEndWar(war); + assert.equal(war.ended, sim.year); + } +}); + +test('地域人口と収容力を10倍にしても人口圧力と食料需要は維持する', () => { + const models = [1, 10].map(scale => { + const fixedDate = class extends Date { static now() { return 42; } }; + const context = vm.createContext({ console, Date: fixedDate, performance }); + const config = read('config.js').replace(/(population: Object.freeze\(\{\s*populationScale: )10/, `$1${scale}`); + vm.runInContext(config + read('utils.js') + read('engine.js') + ';globalThis.Model = Simulation', context); + return new context.Model(32, 5000 * scale); + }); + assert.equal(models[1].world.polity, models[1].world.territoryOwner); + for (let tile = 0; tile < models[0].world.count; tile++) { + assert.ok(Math.abs(models[1].world.population[tile] - models[0].world.population[tile] * 10) < 0.01); + assert.ok(Math.abs(models[1].world.populationCapacity[tile] - models[0].world.populationCapacity[tile] * 10) < 0.001); + assert.ok(Math.abs(models[1].world.populationPressure[tile] - models[0].world.populationPressure[tile]) < 0.001); + } + for (const sim of models) sim.consumeTileResources(); + for (let tile = 0; tile < models[0].world.count; tile++) { + assert.ok(Math.abs(models[1].world.resource[tile] - models[0].world.resource[tile]) < 0.001); + } +}); + +test('領土の中心部は円形の距離で広がる', () => { + const { sim, w } = fixture(); + sim.transferTerritoryTiles = (from, to, tiles) => tiles; + const tiles = sim.claimPolityCoreTerritory({ id: 1 }, { x: 7, y: 7 }, 4); + assert.ok(tiles.includes(w.idx(10, 9))); // 菱形の範囲外だが円の範囲内。 + assert.ok(!tiles.includes(w.idx(10, 10))); +}); + +test('通常のシミュレーションを複数年進めても人口と領土が正常', () => { + const sim = new engine.SimulationClass(32, 6000); + for (let week = 0; week < 480; week++) sim.step(); + assert.equal(sim.year, 480); + assert.deepEqual(sim.world.polity, sim.world.territoryOwner); + const countries = new Set(sim.polities.map(p => p.id)); + for (let tile = 0; tile < sim.world.count; tile++) { + assert.ok(Number.isFinite(sim.world.population[tile])); + assert.ok(sim.world.population[tile] >= 0); + assert.ok(sim.world.polity[tile] === -1 || countries.has(sim.world.polity[tile])); + } +}); + +test('農業圏は都市として登録せず、中心の一タイルだけ登録する', () => { + const sim = new engine.SimulationClass(32, 6000); + const city = sim.createCity(16, 16); + city.population = 200; + sim.cities.push(city); + sim.rebuildIndexes(); + sim.updateCities(); + assert.equal(sim.cities.length, 1); + assert.equal(sim.world.city[sim.world.idx(16, 16)], city.id); + assert.equal([...sim.world.city].filter(id => id >= 0).length, 1); + assert.equal(sim.world.city[sim.world.idx(17, 16)], -1); +}); + +test('全レイヤー・統計・歴史・ツールチップを日本語で描画できる', () => { + const texts = []; + const rectangles = []; + const outlines = []; + const circles = []; + const drawing = new Proxy({ + createImageData: (w, h) => ({ data: new Uint8ClampedArray(w * h * 4) }), + createRadialGradient: () => ({ addColorStop() {} }), + fillText: text => texts.push(text), + fillRect: (...args) => rectangles.push(args), + strokeRect: (...args) => outlines.push(args), + arc: (...args) => circles.push(args) + }, { get: (target, key) => key in target ? target[key] : () => {} }); + const elements = {}; + const element = id => elements[id] ??= { value: '', style: {}, hidden: true, + innerHTML: '', textContent: '', offsetWidth: 200, offsetHeight: 180, + getContext: () => drawing, getBoundingClientRect: () => ({ left: 0, top: 0, width: 300, height: 300 }), + addEventListener() {}, attributes: {}, + getAttribute(name) { return this.attributes[name] ?? null; }, + setAttribute(name, value) { this.attributes[name] = value; }, + querySelectorAll(selector) { + if (selector !== 'canvas') return []; + return [...this.innerHTML.matchAll(/data-event-type="([^"]+)"/g)].map(match => ({ + getAttribute: () => match[1], getContext: () => drawing + })); + } }; + element('viewMode').value = 'polities'; + const ui = vm.createContext({ console, Date, performance, window: { devicePixelRatio: 1 }, + document: { getElementById: element, querySelector: () => element('sim') } }); + vm.runInContext(['config.js', 'utils.js', 'app-state.js', 'engine.js', 'render.js'].map(read).join('\n'), ui); + vm.runInContext('sim = new Simulation(16, 500);', ui); + assert.equal(vm.runInContext('cityRenderRadius({ population: 200 })', ui), 1); + assert.equal(vm.runInContext('cityRenderRadius({ population: 999 })', ui), 1); + assert.equal(vm.runInContext('cityRenderRadius({ population: 1000 })', ui), 2); + assert.equal(vm.runInContext('cityRenderRadius({ population: 4999 })', ui), 2); + assert.equal(vm.runInContext('cityRenderRadius({ population: 5000 })', ui), 3); + assert.equal(vm.runInContext('cityRenderRadius({ population: 9999 })', ui), 3); + assert.equal(vm.runInContext('cityRenderRadius({ population: 10000 })', ui), 4); + vm.runInContext('sim.world.terrain[sim.world.idx(8, 8)] = Terrain.PLAINS; sim.world.terrain[sim.world.idx(9, 8)] = Terrain.PLAINS; sim.world.buildLandNeighbors();', ui); + // 描画済みの凡例とレイヤー連動の簡潔なツールチップを確認。 + for (const mode of ['polities', 'terrain', 'resources', 'ethnicity', 'pressure', 'technology', 'pheromone']) { + element('viewMode').value = mode; + vm.runInContext('render(); setLegend(); hoverState = { x: 8, y: 8, left: 20, top: 20, width: 300, height: 300 }; renderTooltip();', ui); + assert.ok(!/[A-Za-z]{2,}/.test(element('tooltip').innerHTML.replace(/<[^>]*>/g, ''))); + assert.ok((element('tooltip').innerHTML.match(//g) || []).length <= 8); + } + vm.runInContext('setEventLegend(); updateStats(true);', ui); + assert.equal((element('eventLegend').innerHTML.match(//g) || []).length, 0); + assert.ok(element('eventLegend').innerHTML.includes('記号は表示されていません')); + assert.ok(!/Pheromone|Routes|States|pop |parent /.test(element('eventLegend').innerHTML + element('ethnicityList').innerHTML)); + assert.equal(vm.runInContext('formatSimDate(49)', ui), '1年 1月 第2週'); + const summaries = vm.runInContext('Object.entries(graphEventTypes).map(([type, item]) => item.label + item.summary({ outcome: "started", campaignType: "border_war", population: 100, cityId: 1 }))', ui); + for (const summary of summaries) assert.ok(!/[A-Za-z]/.test(summary), summary); + vm.runInContext('renderStateGraph();', ui); + assert.ok(texts.includes('国家の歴史はまだありません')); + vm.runInContext(` + const capital = { id: 1, x: 8, y: 8, population: 1000, storedResources: 40, + loyalty: 0.8, polityId: 1, ethnicityComposition: new Map([[1, 1000]]) }; + const country = { id: 1, color: [100, 180, 120], centerCityId: 1, cityIds: new Set([1]) }; + sim.cities = [capital]; sim.polities = [country]; sim.rebuildIndexes(); + sim.world.city[sim.world.idx(8, 8)] = 1; + sim.world.polity[sim.world.idx(8, 8)] = 1; + sim.year = years(2); + const event = { type: "capitalShift", year: years(1), importance: 3, + data: { oldCenterCityId: 2, newCenterCityId: 1 } }; + sim.polityHistory.set(1, { id: 1, color: country.color, active: true, + founded: 0, ended: null, events: [event], samples: [ + { year: 0, population: 500, cities: 1, avgLoyalty: 0.8, power: 40 }, + { year: years(2), population: 1000, cities: 1, avgLoyalty: 0.8, power: 60 } + ] }); + sim.graphEvents = [event]; + renderStateGraph(); render(); renderTooltip(); + showStateGraphMarkerTooltip(graphState.markers[0], 100, 10); + `, ui); + assert.ok(element('tooltip').innerHTML.includes('首都')); + assert.ok(element('tooltip').innerHTML.includes('都市データ')); + assert.ok(element('tooltip').innerHTML.includes('民族1 100%')); + assert.ok(element('tooltip').innerHTML.includes('制度老朽化')); + assert.ok(element('tooltip').innerHTML.includes('忠誠度上限')); + assert.equal((element('tooltip').innerHTML.match(/国庫<\/b>/g) || []).length, 1); + assert.ok(!/国庫<\/b>[^<]*\//.test(element('tooltip').innerHTML)); + assert.ok(element('tooltip').innerHTML.indexOf('都市データ') < element('tooltip').innerHTML.indexOf('国家データ')); + assert.ok(element('stateGraphTooltip').innerHTML.includes('遷都')); + assert.ok(texts.includes('存続中 1')); + assert.ok(texts.includes('国1')); + // The whole rendered city icon opens the city tooltip, while water still suppresses it. + vm.runInContext('hoverState = { x: 9, y: 8, left: 20, top: 20, width: 300, height: 300 }; renderTooltip()', ui); + assert.ok(element('tooltip').innerHTML.includes('都市1')); + vm.runInContext('sim.world.terrain[sim.world.idx(9, 8)] = Terrain.WATER; renderTooltip()', ui); + assert.equal(element('tooltip').hidden, true); + vm.runInContext('sim.world.terrain[sim.world.idx(9, 8)] = Terrain.PLAINS; hoverState = { x: 8, y: 8, left: 20, top: 20, width: 300, height: 300 }; renderTooltip()', ui); + assert.equal(element('tooltip').hidden, false); + rectangles.length = 0; outlines.length = 0; + vm.runInContext('sim.world.population.fill(0); sim.activePopulationTiles.clear(); sim.world.population[sim.world.idx(7, 8)] = 100; sim.activePopulationTiles.add(sim.world.idx(7, 8)); drawPopulationAndCities("polities")', ui); + assert.equal(rectangles.length, 3); // population tile, city body, and city center + assert.equal(outlines.length, 1); + vm.runInContext(` + const crowded = Array.from({ length: 9 }, (_, index) => ({ + type: "war", year: years(1), importance: 2, + data: { opponentPolityId: 2, outcome: index % 2 ? "ended" : "started" } + })); + sim.polityHistory.get(1).events = crowded; + sim.graphEvents = []; + renderStateGraph(); + `, ui); + const markerPositions = vm.runInContext('graphState.markers.filter(marker => marker.row).map(marker => `${marker.x},${marker.y}`)', ui); + assert.equal(markerPositions.length, 5); + assert.equal(new Set(markerPositions).size, markerPositions.length); + vm.runInContext('graphState.showEventIcons = false; renderStateGraph(); setEventLegend();', ui); + assert.equal(vm.runInContext('graphState.markers.length', ui), 0); + assert.ok(element('eventLegend').innerHTML.includes('非表示')); + vm.runInContext('graphState.showEventIcons = true; renderStateGraph();', ui); + vm.runInContext('sim.campaigns = [{ type: "frontier_colonization", status: "active", targetTile: 10, started: 0, expires: 200, progress: 0.5 }]', ui); + circles.length = 0; + vm.runInContext('drawCampaigns()', ui); + assert.equal(circles.length, 0); + vm.runInContext('sim.campaigns[0].type = "border_war"; drawCampaigns()', ui); + assert.equal(circles.length, 1); + // 凡例には現在のグラフで描かれた種類だけを載せ、地図の記号と混同しない。 + assert.equal((element('eventLegend').innerHTML.match(//g) || []).length, 1); + assert.ok(element('eventLegend').innerHTML.includes('data-event-type="war"')); + assert.ok(!element('eventLegend').innerHTML.includes('遊牧集団')); + assert.ok(!/[●◆▲▼]/.test(element('eventLegend').innerHTML)); + element('historyFilter').value = 'ended'; + vm.runInContext('renderStateGraph()', ui); + assert.ok(element('eventLegend').innerHTML.includes('記号は表示されていません')); + element('historyFilter').value = 'all'; + vm.runInContext('sim.polityHistory.get(1).events = []; sim.graphEvents = [{ type: "nomadTrade", year: years(1), importance: 1 }]; renderStateGraph();', ui); + assert.ok(!element('eventLegend').innerHTML.includes('遊牧集団との交易')); + const html = read('index.html'); + assert.ok(html.includes('lang="ja"')); + assert.ok(html.includes('')); + assert.ok(!/[A-Za-z]/.test(html.replace(/<[^>]*>/g, '').replace(/FPS/g, ''))); + assert.ok(/