"use strict"; const APP_VERSION = "39.18.18"; const CACHE_NAME = `tarinai-colony-${APP_VERSION}`; const v = `v=${APP_VERSION}`; // Static runtime list synchronized with app_manifest.json for this release. const coreScriptNames = [ "version", "event_bus", "domain_ids", "registry_base", "disease_registry", "sound_pack", "deterministic_helpers", "item_tool_metadata", "item_tool_definitions", "item_visual_definitions", "item_food_definitions", "item_effect_definitions", "item_registry", "data", "ground_types", "input_mode_manager", "math", "geometry_helpers", "collision_footprint_system", "physics_helpers", "placement_preview_system", "pin_attachment_system", "physics_shape_editor_system", "mechanical_system", "mechanical_shape_bridge", "constraint_system", "physics_world_system", "physics_projection_system", "circuit_board_system", "signal_system", "assets", "audio", "perf_profiler", "display_helpers", "render", "sim_core", "tarinai_seed_factory", "structures", "item_type_catalog", "items", "item_type_initializers", "item_lifecycle_support", "item_update_policy", "fire_runtime_system", "robot_cleaner_system", "item_dynamic_tool_system", "item_dynamic_ball_system", "item_dynamic_duplicator_system", "item_dynamic_pin_system", "item_dynamic_zunchi_system", "item_environment_hazard_system", "item_dynamic_system", "item_lifecycle_decay_system", "item_lifecycle_growth_system", "item_lifecycle_step_frame", "item_lifecycle_step_decay", "item_lifecycle_step_dynamic", "item_lifecycle_step_growth", "update_step_pipeline_runner", "item_lifecycle_pipeline", "item_runtime", "structure_lifecycle", "memorial_bell_system", "item_render_helpers", "item_render_runtime", "burn_motion_util", "ants", "health", "tarinai", "tarinai_action_spec", "tarinai_behavior_state", "tarinai_identity_social", "tarinai_action_state", "tarinai_disease_nest", "tarinai_item_effects", "tarinai_needs_core", "tarinai_behavior_text", "tarinai_forced_behavior", "tarinai_nest_sleep_system", "tarinai_item_targeting", "tarinai_consumable_behavior", "tarinai_social_action_runtime", "tarinai_building_behavior", "seesaw_system", "tarinai_action_definitions", "tarinai_needs_items", "tarinai_food_prototype_mixin", "tarinai_direct_feeding_system", "tarinai_need_planner_system", "tarinai_item_interaction_context", "tarinai_food_interaction_system", "tarinai_contact_item_system", "tarinai_item_interaction_system", "tarinai_sunbath_system", "tarinai_cursor_care_system", "tarinai_local_environment_system", "tarinai_social_move_life", "tarinai_update_step_frame", "tarinai_update_step_ai", "tarinai_update_step_environment", "tarinai_update_step_movement", "tarinai_update_step_health", "tarinai_update_pipeline", "tarinai_runtime", "tarinai_render", "world", "world_view", "family_graph", "world_reset_presets", "world_family_social", "impact_core_system", "impact_response_system", "collision_response_system", "world_combat_effects", "world_environment", "world_temperature_system", "world_pathfinding_system", "world_grass_placement_system", "world_spatial_budget", "world_ants_system", "weather_system", "item_update_scheduler", "simulation_runtime_helpers", "tarinai_update_policy", "simulation_environment_system", "simulation_item_ant_system", "simulation_effects_system", "simulation_creature_system", "simulation_maintenance_system", "simulation_ambient_system", "simulation_systems", "system_order", "simulation", "colony_situation_system", "world_update", "world_tool_actions", "world_placement_log", "world_event_effects", "command_dispatcher", "text_catalog", "ui", "game_dialogs", "achievement_catalog", "achievements", "ui_helpers", "ui_log", "ui_selected", "save_schema", "snapshot_system", "restore_coordinator", "history_system", "save_codec", "save_storage", "save_system", "ui_tooltips", "ui_layout_dialogs", "ui_ground", "ui_tools", "ui_input_shared", "ui_pointer_action_system", "ui_input_touch", "ui_input_mouse", "ui_bind", "ui_charts", "ui_family_data", "ui_family_async", "ui_family_layout", "ui_family_paths", "ui_family_render", "main", "debug_tools" ]; const mediaAssetNames = [ "assets/objects/ant_queen.webp", "assets/objects/ant_worker.webp", "assets/objects/genkotsu.webp", "assets/objects/oshibyo.webp", "assets/objects/oshibyo_stuck.webp", "assets/objects/plushie_bear.png", "assets/objects/pushpin.webp", "assets/objects/pushpin_stuck.webp", "assets/objects/zunchi.webp", "assets/objects/zunchi_02.webp", "assets/sounds/achievement_unlock.mp3", "assets/sounds/acquired_stress_001.wav", "assets/sounds/acquired_stress_002.wav", "assets/sounds/acquired_stress_003.wav", "assets/sounds/acquired_stress_004.wav", "assets/sounds/acquired_stress_005.wav", "assets/sounds/acquired_stress_006.wav", "assets/sounds/bicycle_bell.mp3", "assets/sounds/firecracker_explosion.mp3", "assets/sounds/major_damage_01.wav", "assets/sounds/major_damage_02.wav", "assets/sounds/major_damage_03.wav", "assets/sounds/major_damage_04.wav", "assets/sounds/shoot_bolt_action.mp3", "assets/sounds/shoot_pistol.mp3", "assets/sounds/voice_001_hau.wav", "assets/sounds/voice_002_flee.wav", "assets/sounds/voice_003_po.wav", "assets/sounds/voice_004_eat.wav", "assets/sounds/voice_005_stress.wav", "assets/sounds/voice_006_sleep.wav", "assets/sounds/voice_007_sunbath_pokapoka.wav", "assets/sounds/voice_008_temperature_buruburu.wav", "assets/sounds/voice_009_temperature_achui.wav", "assets/sounds/intimidate_alt_001.wav", "assets/sounds/ochibi_sleep_002.wav", "assets/sounds/ochibi_sleep_003.wav", "assets/sounds/ochibi_fight_hit_004.wav", "assets/sounds/ochibi_panic_005.wav", "assets/sounds/ochibi_electric_006.wav", "assets/sounds/ochibi_hot_007.wav", "assets/sounds/ochibi_stress_008.wav", "assets/sprites/tarinai_01_smile.webp", "assets/sprites/tarinai_02_angry.webp", "assets/sprites/tarinai_03_teary.webp", "assets/sprites/tarinai_04_jito.webp", "assets/sprites/tarinai_05_drool.webp", "assets/sprites/tarinai_06_cry.webp", "assets/sprites/tarinai_07_sleep.webp", "assets/sprites/tarinai_08_pokan.webp", "assets/sprites/tarinai_09_stretch.webp", "assets/sprites/tarinai_10_hurt.webp", "assets/sprites/tarinai_11_weak.webp", "assets/sprites/tarinai_12_back.webp", "assets/sprites/tarinai_13_flee.webp", "assets/sprites/tarinai_14_zunda_eat.webp", "assets/sprites/tarinai_15_hurt2.webp", "assets/sprites/tarinai_16_normal_smirk.webp", "assets/sprites/tarinai_17_normal_tongue.webp", "assets/sprites/tarinai_18_fear.webp", "assets/sprites/tarinai_19_flee_fear2.webp", "assets/sprites/tarinai_20_sleep2.webp", "assets/sprites/tarinai_21_normal_happy.webp", "assets/sprites/tarinai_22_fear_blue.webp", "assets/sprites/tarinai_23_fear_cry.webp", "assets/sprites/tarinai_24_stress_dizzy.webp", "assets/sprites/tarinai_25_stress_sweat.webp", "assets/sprites/tarinai_26_intimidate.webp", "assets/sprites/tarinai_27_birth_ritual.webp", "assets/sprites/tarinai_28_zunchi_slave.webp", "assets/sprites/tarinai_29_hungry_70.webp", "assets/sprites/tarinai_30_zunchi_slave_alt.webp", "assets/sprites/tarinai_31_sunbath_01.webp", "assets/sprites/tarinai_32_sunbath_02.webp", "assets/sprites/tarinai_33_sunbath_03.webp", "assets/sprites/tarinai_34_hot_01.webp", "assets/sprites/tarinai_35_hot_02.webp", "assets/sprites/tarinai_36_hot_03.webp", "assets/sprites/tarinai_37_cold_01.webp", "assets/sprites/tarinai_38_cold_02.webp", "assets/sprites/tarinai_39_cold_03.webp", "assets/sprites/tarinai_40_intimidate_alt.webp", "assets/sprites/tarinai_acquired_overlay.png", "assets/ui/apple-touch-icon.png", "assets/ui/ecology_hp_stress.webp", "assets/ui/favicon.png", "assets/ui/tool_acquired_tarinai.webp", "assets/ui/tool_ammo.webp", "assets/ui/tool_ant_nest.webp", "assets/ui/tool_ball.webp", "assets/ui/tool_bed.webp", "assets/ui/tool_delete.webp", "assets/ui/tool_duplicator.webp", "assets/ui/tool_dwarf_drug.webp", "assets/ui/tool_fence_h.webp", "assets/ui/tool_fence_v.webp", "assets/ui/tool_fight_mochi.webp", "assets/ui/tool_firecracker.webp", "assets/ui/tool_genkotsu.webp", "assets/ui/tool_giant_drug.webp", "assets/ui/tool_grass.webp", "assets/ui/tool_laxative.webp", "assets/ui/tool_love_mochi.webp", "assets/ui/tool_mercury.webp", "assets/ui/tool_mystery_drug.webp", "assets/ui/tool_nest_box.webp", "assets/ui/tool_new.webp", "assets/ui/tool_niteropu.webp", "assets/ui/tool_observe.webp", "assets/ui/tool_oshibyo.webp", "assets/ui/tool_protein.webp", "assets/ui/tool_pushpin.webp", "assets/ui/tool_shoot.png", "assets/ui/tool_signboard.webp", "assets/ui/tool_sleep_drug.webp", "assets/ui/tool_stone.webp", "assets/ui/tool_sweet.webp", "assets/ui/tool_zunchi.webp", "assets/ui/tool_zunda_juice.webp" ]; const CORE_ASSETS = [ "./", "./index.html", `./css/base.css?${v}`, `./css/layout.css?${v}`, `./css/panel.css?${v}`, `./css/components.css?${v}`, `./css/mobile.css?${v}`, ...coreScriptNames.map(name => `./js/${name}.js?${v}`), "./app_manifest.json", "./manifest.webmanifest", "./favicon.ico", "./assets/ui/pwa-icon-192.png", "./assets/ui/pwa-icon-512.png", ...mediaAssetNames.map(name => `./${name}`), ]; self.addEventListener("install", event => { event.waitUntil((async () => { const cache = await caches.open(CACHE_NAME); await cache.addAll(CORE_ASSETS); await self.skipWaiting(); })()); }); self.addEventListener("activate", event => { event.waitUntil((async () => { const keys = await caches.keys(); await Promise.all(keys .filter(key => key.startsWith("tarinai-colony-") && key !== CACHE_NAME) .map(key => caches.delete(key))); await self.clients.claim(); })()); }); function isStaticAsset(request) { return /\.(?:js|css|json|webmanifest|ico|webp|png|jpg|jpeg|gif|svg|mp3|wav|woff2?)$/i.test(new URL(request.url).pathname); } function cacheableResponse(response) { return response && response.status === 200 && response.type !== "opaque"; } function putCacheSafely(request, response) { if (!cacheableResponse(response)) return Promise.resolve(false); return caches.open(CACHE_NAME).then(cache => cache.put(request, response.clone())).then(() => true).catch(() => false); } self.addEventListener("fetch", event => { const request = event.request; if (request.method !== "GET") return; const url = new URL(request.url); // PWA-04 intentionally remains unchanged: cross-origin Google Fonts are not cached. if (url.origin !== self.location.origin || /service-worker\.js$/i.test(url.pathname)) return; if (request.mode === "navigate" || /index\.html$/i.test(url.pathname)) { const networkResponse = fetch(request); const cacheWrite = networkResponse.then(response => putCacheSafely(request, response)).catch(() => false); event.waitUntil(cacheWrite.then(() => undefined)); event.respondWith(networkResponse.catch(() => caches.match(request).then(cached => cached || caches.match("./index.html")))); return; } if (isStaticAsset(request)) { const responsePromise = caches.match(request).then(async cached => { if (cached) return cached; // Media are precached at their canonical URL. JS/CSS query versions must not // resolve to an older cached file, otherwise UI fixes can remain stale. const isCodeAsset = /\.(?:js|css)$/i.test(url.pathname); if (!isCodeAsset) { const canonical = await caches.match(request, { ignoreSearch: true }); if (canonical) return canonical; } const response = await fetch(request); await putCacheSafely(request, response); return response; }); event.waitUntil(responsePromise.then(() => undefined, () => undefined)); event.respondWith(responsePromise); } });