const DAYS = [{"id": "d14", "date": "14 giugno", "title": "Tokyo moderna", "city": "Tokyo", "base": "Asakusa", "summary": "Arrivo, Meiji Jingu, Shibuya e Shinjuku.", "budget_jpy": [18000, 28000], "hint": "Non correte: primo highlight Meiji Jingu.", "weather_city": "Tokyo, Japan", "timeline": [["08:50", "Narita", "Arrivo", "Narita International Airport"], ["10:30", "Asakusa", "Check-in", "AMANEK Asakusa Sakurabashi"], ["15:00", "Meiji Jingu", "Passeggiata", "Meiji Jingu"], ["18:00", "Shibuya", "Crossing", "Shibuya Crossing"], ["19:45", "Shinjuku", "Cena", "Omoide Yokocho"]], "lunch": {"area": "Asakusa", "places": [{"name": "Yoshikami", "query": "Yoshikami Asakusa Tokyo"}, {"name": "Daikokuya Tempura", "query": "Daikokuya Tempura Asakusa Tokyo"}, {"name": "Opzione pranzo 3 · Asakusa", "query": "lunch Asakusa Tokyo Japan"}, {"name": "Opzione pranzo 4 · Asakusa", "query": "lunch Asakusa Tokyo Japan"}, {"name": "Opzione pranzo 5 · Asakusa", "query": "lunch Asakusa Tokyo Japan"}]}, "dinner": {"area": "Shinjuku", "places": [{"name": "Kamo to Negi", "query": "Kamo to Negi Shinjuku Tokyo"}, {"name": "Tsunahachi", "query": "Tsunahachi Shinjuku Tokyo"}, {"name": "Opzione cena 3 · Shinjuku", "query": "dinner Shinjuku Tokyo Japan"}, {"name": "Opzione cena 4 · Shinjuku", "query": "dinner Shinjuku Tokyo Japan"}, {"name": "Opzione cena 5 · Shinjuku", "query": "dinner Shinjuku Tokyo Japan"}]}, "onsen": [{"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Mikokuyu (sento)", "query": "Mikokuyu Sumida Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}, {"id": "d15", "date": "15 giugno", "title": "Tokyo tradizionale", "city": "Tokyo", "base": "Asakusa", "summary": "Senso-ji, Skytree, Ueno e Akihabara.", "budget_jpy": [16000, 30000], "hint": "Entrate presto a Senso-ji.", "weather_city": "Tokyo, Japan", "timeline": [["09:00", "Senso-ji", "Tempio e Nakamise", "Senso-ji"], ["11:00", "Tokyo Skytree", "Vista", "Tokyo Skytree"], ["14:40", "Ueno Park", "Passeggiata", "Ueno Park"], ["17:30", "Akihabara", "Anime ed elettronica", "Akihabara Station"]], "lunch": {"area": "Asakusa / Solamachi", "places": [{"name": "Sushi Zanmai Asakusa", "query": "Sushi Zanmai Asakusa Tokyo"}, {"name": "Tokyo Solamachi food hall", "query": "Tokyo Solamachi Tokyo"}, {"name": "Opzione pranzo 3 · Asakusa / Solamachi", "query": "lunch Asakusa / Solamachi Tokyo Japan"}, {"name": "Opzione pranzo 4 · Asakusa / Solamachi", "query": "lunch Asakusa / Solamachi Tokyo Japan"}, {"name": "Opzione pranzo 5 · Asakusa / Solamachi", "query": "lunch Asakusa / Solamachi Tokyo Japan"}]}, "dinner": {"area": "Akihabara / Asakusa", "places": [{"name": "Gyukatsu Motomura Akihabara", "query": "Gyukatsu Motomura Akihabara Tokyo"}, {"name": "Izakaya vicino ad Asakusa", "query": "Izakaya Asakusa Tokyo"}, {"name": "Opzione cena 3 · Akihabara / Asakusa", "query": "dinner Akihabara / Asakusa Tokyo Japan"}, {"name": "Opzione cena 4 · Akihabara / Asakusa", "query": "dinner Akihabara / Asakusa Tokyo Japan"}, {"name": "Opzione cena 5 · Akihabara / Asakusa", "query": "dinner Akihabara / Asakusa Tokyo Japan"}]}, "onsen": [{"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Daikokuyu (Asakusa area)", "query": "Daikokuyu Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}, {"id": "d16", "date": "16 giugno", "title": "teamLab + Tsukiji + Odaiba", "city": "Tokyo", "base": "Asakusa", "summary": "Arte immersiva, mercato, giardini e waterfront.", "budget_jpy": [22000, 36000], "hint": "teamLab va vissuto con calma.", "weather_city": "Tokyo, Japan", "timeline": [["09:30", "teamLab Planets", "Ingresso prenotato", "teamLab Planets TOKYO"], ["12:30", "Tsukiji", "Pranzo seafood", "Tsukiji Outer Market"], ["14:30", "Hama-rikyu", "Giardini", "Hama-rikyu Gardens"], ["16:40", "Odaiba", "Passeggiata", "The Gundam Base Tokyo"]], "lunch": {"area": "Tsukiji", "places": [{"name": "Sushizanmai Tsukiji", "query": "Sushizanmai Tsukiji Tokyo"}, {"name": "Tsukiji Itadori Bekkan", "query": "Tsukiji Itadori Bekkan Tokyo"}, {"name": "Opzione pranzo 3 · Tsukiji", "query": "lunch Tsukiji Tokyo Japan"}, {"name": "Opzione pranzo 4 · Tsukiji", "query": "lunch Tsukiji Tokyo Japan"}, {"name": "Opzione pranzo 5 · Tsukiji", "query": "lunch Tsukiji Tokyo Japan"}]}, "dinner": {"area": "Odaiba / Asakusa", "places": [{"name": "Bills Odaiba", "query": "Bills Odaiba Tokyo"}, {"name": "Ramen rientro Asakusa", "query": "Ramen Asakusa Tokyo"}, {"name": "Opzione cena 3 · Odaiba / Asakusa", "query": "dinner Odaiba / Asakusa Tokyo Japan"}, {"name": "Opzione cena 4 · Odaiba / Asakusa", "query": "dinner Odaiba / Asakusa Tokyo Japan"}, {"name": "Opzione cena 5 · Odaiba / Asakusa", "query": "dinner Odaiba / Asakusa Tokyo Japan"}]}, "onsen": [{"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Daikokuyu (Asakusa area)", "query": "Daikokuyu Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}, {"id": "d17", "date": "17 giugno", "title": "Kamakura", "city": "Kamakura", "base": "Asakusa", "summary": "Grande Buddha, Hasedera, centro storico e spiaggia.", "budget_jpy": [18000, 30000], "hint": "Non riempite troppo la giornata.", "weather_city": "Kamakura, Japan", "timeline": [["07:45", "Kamakura", "Partenza presto", "Kamakura Station"], ["10:00", "Kotoku-in", "Grande Buddha", "Kotoku-in"], ["11:00", "Hasedera", "Tempio e giardini", "Hasedera Temple"], ["14:00", "Komachi-dori", "Passeggiata", "Komachi-dori Street"], ["15:30", "Yuigahama", "Relax", "Yuigahama Beach"]], "lunch": {"area": "Kamakura", "places": [{"name": "Matsubara-an Komachi", "query": "Matsubara-an Komachi Kamakura"}, {"name": "Shirasu-don Komachi-dori", "query": "Shirasu don Komachi dori Kamakura"}, {"name": "Opzione pranzo 3 · Kamakura", "query": "lunch Kamakura Kamakura Japan"}, {"name": "Opzione pranzo 4 · Kamakura", "query": "lunch Kamakura Kamakura Japan"}, {"name": "Opzione pranzo 5 · Kamakura", "query": "lunch Kamakura Kamakura Japan"}]}, "dinner": {"area": "Asakusa", "places": [{"name": "Cena semplice Asakusa", "query": "Restaurant Asakusa Tokyo"}, {"name": "Soba Asakusa", "query": "Soba Asakusa Tokyo"}, {"name": "Opzione cena 3 · Asakusa", "query": "dinner Asakusa Kamakura Japan"}, {"name": "Opzione cena 4 · Asakusa", "query": "dinner Asakusa Kamakura Japan"}, {"name": "Opzione cena 5 · Asakusa", "query": "dinner Asakusa Kamakura Japan"}]}, "onsen": [{"name": "Inamuragasaki Onsen", "query": "Inamuragasaki Onsen Kamakura"}, {"name": "Enoshima Island Spa", "query": "Enoshima Island Spa"}, {"name": "Tattoo friendly bath near Kamakura", "query": "tattoo friendly bath Kamakura"}], "love_hotels": [{"name": "Love hotel in zona", "query": "love hotel Kamakura Japan"}, {"name": "Adult only hotel in zona", "query": "adult only hotel Kamakura Japan"}, {"name": "Short stay hotel in zona", "query": "short stay hotel Kamakura Japan"}]}, {"id": "d18", "date": "18 giugno", "title": "Tokyo → Kanazawa", "city": "Kanazawa", "base": "Kanazawa", "summary": "Shinkansen, Omicho Market e quartiere samurai.", "budget_jpy": [38000, 55000], "hint": "Mercato + quartiere samurai bastano.", "weather_city": "Kanazawa, Japan", "timeline": [["08:30", "Kanazawa", "Shinkansen", "Kanazawa Station"], ["12:15", "Omicho Market", "Pranzo", "Omicho Market"], ["14:30", "Nagamachi", "Passeggiata quartiere samurai", "Nagamachi Samurai District"], ["19:30", "Katamachi", "Cena", "Katamachi"]], "lunch": {"area": "Omicho Market", "places": [{"name": "Mori Mori Sushi", "query": "Mori Mori Sushi Omicho Kanazawa"}, {"name": "Iki-Iki Tei", "query": "Iki-Iki Tei Omicho Kanazawa"}, {"name": "Opzione pranzo 3 · Omicho Market", "query": "lunch Omicho Market Kanazawa Japan"}, {"name": "Opzione pranzo 4 · Omicho Market", "query": "lunch Omicho Market Kanazawa Japan"}, {"name": "Opzione pranzo 5 · Omicho Market", "query": "lunch Omicho Market Kanazawa Japan"}]}, "dinner": {"area": "Katamachi", "places": [{"name": "Izakaya Katamachi", "query": "Izakaya Katamachi Kanazawa"}, {"name": "Sushi di Kanazawa", "query": "Sushi Katamachi Kanazawa"}, {"name": "Opzione cena 3 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}, {"name": "Opzione cena 4 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}, {"name": "Opzione cena 5 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}]}, "onsen": [{"name": "Kashikiri / private bath Kanazawa", "query": "private onsen Kanazawa"}, {"name": "Ryokan private bath Kanazawa", "query": "ryokan private bath Kanazawa"}, {"name": "Tattoo friendly sento Kanazawa", "query": "tattoo friendly sento Kanazawa"}], "love_hotels": [{"name": "Love hotel in zona", "query": "love hotel Kanazawa Japan"}, {"name": "Adult only hotel in zona", "query": "adult only hotel Kanazawa Japan"}, {"name": "Short stay hotel in zona", "query": "short stay hotel Kanazawa Japan"}]}, {"id": "d19", "date": "19 giugno", "title": "Kanazawa classica", "city": "Kanazawa", "base": "Kanazawa", "summary": "Kenroku-en, castello e Higashi Chaya.", "budget_jpy": [18000, 35000], "hint": "Kenroku-en va fatto lentamente.", "weather_city": "Kanazawa, Japan", "timeline": [["09:15", "Kenroku-en", "Visita", "Kenroku-en"], ["11:30", "Kanazawa Castle", "Passaggio dal giardino al castello", "Kanazawa Castle"], ["13:10", "Higashi Chaya", "Passeggiata e tè", "Higashi Chaya District"], ["18:30", "Centro", "Cena", "Katamachi"]], "lunch": {"area": "Centro / Higashi Chaya", "places": [{"name": "Soba in centro", "query": "Soba Kanazawa city center"}, {"name": "Omicho Market bis", "query": "Omicho Market Kanazawa"}, {"name": "Opzione pranzo 3 · Centro / Higashi Chaya", "query": "lunch Centro / Higashi Chaya Kanazawa Japan"}, {"name": "Opzione pranzo 4 · Centro / Higashi Chaya", "query": "lunch Centro / Higashi Chaya Kanazawa Japan"}, {"name": "Opzione pranzo 5 · Centro / Higashi Chaya", "query": "lunch Centro / Higashi Chaya Kanazawa Japan"}]}, "dinner": {"area": "Katamachi", "places": [{"name": "Izakaya Katamachi", "query": "Izakaya Katamachi Kanazawa"}, {"name": "Sushi di Kanazawa", "query": "Sushi Kanazawa Katamachi"}, {"name": "Opzione cena 3 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}, {"name": "Opzione cena 4 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}, {"name": "Opzione cena 5 · Katamachi", "query": "dinner Katamachi Kanazawa Japan"}]}, "onsen": [{"name": "Kashikiri / private bath Kanazawa", "query": "private onsen Kanazawa"}, {"name": "Ryokan private bath Kanazawa", "query": "ryokan private bath Kanazawa"}, {"name": "Tattoo friendly sento Kanazawa", "query": "tattoo friendly sento Kanazawa"}], "love_hotels": [{"name": "Love hotel in zona", "query": "love hotel Kanazawa Japan"}, {"name": "Adult only hotel in zona", "query": "adult only hotel Kanazawa Japan"}, {"name": "Short stay hotel in zona", "query": "short stay hotel Kanazawa Japan"}]}, {"id": "d20", "date": "20 giugno", "title": "Shirakawa-go + Kyoto", "city": "Kyoto", "base": "Kyoto", "summary": "Villaggio UNESCO e trasferimento a Kyoto.", "budget_jpy": [35000, 50000], "hint": "Fate il viewpoint e poi rilassatevi.", "weather_city": "Kyoto, Japan", "timeline": [["08:10", "Shirakawa-go", "Bus espresso", "Shirakawa-go Bus Terminal"], ["09:35", "Shirakawa-go", "Villaggio + viewpoint", "Shirakawa-go"], ["16:00", "Kyoto", "Trasferimento", "Kyoto Station"], ["18:30", "Kyoto", "Check-in", "M's Plus Shijo Omiya"]], "lunch": {"area": "Shirakawa-go", "places": [{"name": "Irori", "query": "Irori Shirakawa-go"}, {"name": "Soba nel villaggio", "query": "Soba Shirakawa-go"}, {"name": "Opzione pranzo 3 · Shirakawa-go", "query": "lunch Shirakawa-go Kyoto Japan"}, {"name": "Opzione pranzo 4 · Shirakawa-go", "query": "lunch Shirakawa-go Kyoto Japan"}, {"name": "Opzione pranzo 5 · Shirakawa-go", "query": "lunch Shirakawa-go Kyoto Japan"}]}, "dinner": {"area": "Kyoto hotel area", "places": [{"name": "Ramen vicino all’hotel", "query": "Ramen Shijo Omiya Kyoto"}, {"name": "Izakaya vicino all’hotel", "query": "Izakaya Shijo Omiya Kyoto"}, {"name": "Opzione cena 3 · Kyoto hotel area", "query": "dinner Kyoto hotel area Kyoto Japan"}, {"name": "Opzione cena 4 · Kyoto hotel area", "query": "dinner Kyoto hotel area Kyoto Japan"}, {"name": "Opzione cena 5 · Kyoto hotel area", "query": "dinner Kyoto hotel area Kyoto Japan"}]}, "onsen": [{"name": "Arashiyama Onsen Kadensho", "query": "Arashiyama Onsen Kadensho Kyoto"}, {"name": "Hanaikada", "query": "Hanaikada Arashiyama Kyoto"}, {"name": "Fufu no Yu", "query": "Fufu no Yu Kyoto"}], "love_hotels": [{"name": "Hotel In The Green", "query": "Hotel In The Green Kyoto"}, {"name": "Hotel Chronos - Adult Only", "query": "Hotel Chronos Kyoto"}, {"name": "Hotel & Spa Lotus", "query": "Hotel & Spa Lotus Kyoto"}]}, {"id": "d21", "date": "21 giugno", "title": "Arashiyama + Kinkaku-ji", "city": "Kyoto", "base": "Kyoto", "summary": "Bamboo grove, Tenryu-ji, onsen e Kinkaku-ji.", "budget_jpy": [18000, 34000], "hint": "Bamboo grove presto, poi rallentate.", "weather_city": "Kyoto, Japan", "timeline": [["08:30", "Arashiyama", "Randen", "Arashiyama Bamboo Grove"], ["09:50", "Tenryu-ji", "Tempio e giardini", "Tenryu-ji"], ["13:15", "Fufu-no-yu", "Onsen", "Fufu-no-yu"], ["16:45", "Kinkaku-ji", "Visita", "Kinkaku-ji"]], "lunch": {"area": "Arashiyama", "places": [{"name": "Saga Tofu Ine", "query": "Saga Tofu Ine Arashiyama Kyoto"}, {"name": "Arashiyama Yoshimura", "query": "Arashiyama Yoshimura Kyoto"}, {"name": "Opzione pranzo 3 · Arashiyama", "query": "lunch Arashiyama Kyoto Japan"}, {"name": "Opzione pranzo 4 · Arashiyama", "query": "lunch Arashiyama Kyoto Japan"}, {"name": "Opzione pranzo 5 · Arashiyama", "query": "lunch Arashiyama Kyoto Japan"}]}, "dinner": {"area": "Centro Kyoto", "places": [{"name": "Ramen in centro", "query": "Ramen central Kyoto"}, {"name": "Izakaya centro Kyoto", "query": "Izakaya central Kyoto"}, {"name": "Opzione cena 3 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}, {"name": "Opzione cena 4 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}, {"name": "Opzione cena 5 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}]}, "onsen": [{"name": "Arashiyama Onsen Kadensho", "query": "Arashiyama Onsen Kadensho Kyoto"}, {"name": "Hanaikada", "query": "Hanaikada Arashiyama Kyoto"}, {"name": "Fufu no Yu", "query": "Fufu no Yu Kyoto"}], "love_hotels": [{"name": "Hotel In The Green", "query": "Hotel In The Green Kyoto"}, {"name": "Hotel Chronos - Adult Only", "query": "Hotel Chronos Kyoto"}, {"name": "Hotel & Spa Lotus", "query": "Hotel & Spa Lotus Kyoto"}]}, {"id": "d22", "date": "22 giugno", "title": "Nara + Fushimi Inari + Gion", "city": "Kyoto", "base": "Kyoto", "summary": "Nara, Grande Buddha, torii rossi e Gion.", "budget_jpy": [20000, 38000], "hint": "Salite un po’ a Fushimi Inari.", "weather_city": "Kyoto, Japan", "timeline": [["09:00", "Nara", "Trasferimento", "Nara Park"], ["10:50", "Todai-ji", "Grande Buddha", "Todai-ji"], ["15:30", "Fushimi Inari", "Torii rossi", "Fushimi Inari Taisha"], ["19:00", "Gion/Pontocho", "Cena e passeggiata", "Gion Kyoto"]], "lunch": {"area": "Nara", "places": [{"name": "Set lunch vicino al parco", "query": "Lunch Nara Park"}, {"name": "Soba a Nara", "query": "Soba Nara Park"}, {"name": "Opzione pranzo 3 · Nara", "query": "lunch Nara Kyoto Japan"}, {"name": "Opzione pranzo 4 · Nara", "query": "lunch Nara Kyoto Japan"}, {"name": "Opzione pranzo 5 · Nara", "query": "lunch Nara Kyoto Japan"}]}, "dinner": {"area": "Gion / Pontocho", "places": [{"name": "Cena speciale Gion", "query": "Restaurant Gion Kyoto"}, {"name": "Cena Pontocho", "query": "Restaurant Pontocho Kyoto"}, {"name": "Opzione cena 3 · Gion / Pontocho", "query": "dinner Gion / Pontocho Kyoto Japan"}, {"name": "Opzione cena 4 · Gion / Pontocho", "query": "dinner Gion / Pontocho Kyoto Japan"}, {"name": "Opzione cena 5 · Gion / Pontocho", "query": "dinner Gion / Pontocho Kyoto Japan"}]}, "onsen": [{"name": "Arashiyama Onsen Kadensho", "query": "Arashiyama Onsen Kadensho Kyoto"}, {"name": "Hanaikada", "query": "Hanaikada Arashiyama Kyoto"}, {"name": "Fufu no Yu", "query": "Fufu no Yu Kyoto"}], "love_hotels": [{"name": "Hotel In The Green", "query": "Hotel In The Green Kyoto"}, {"name": "Hotel Chronos - Adult Only", "query": "Hotel Chronos Kyoto"}, {"name": "Hotel & Spa Lotus", "query": "Hotel & Spa Lotus Kyoto"}]}, {"id": "d23", "date": "23 giugno", "title": "Kyoto storica + Nishiki + Otagi", "city": "Kyoto", "base": "Kyoto", "summary": "Castello, mercato e tempio laterale pieno di carattere.", "budget_jpy": [18000, 35000], "hint": "Otagi è il vero jolly.", "weather_city": "Kyoto, Japan", "timeline": [["09:00", "Nijo Castle", "Ingresso presto", "Nijo Castle"], ["12:00", "Nishiki Market", "Pranzo diffuso", "Nishiki Market"], ["15:00", "Otagi Nenbutsu-ji", "Visita del tempio", "Otagi Nenbutsu-ji"], ["19:30", "Centro", "Cena", "Shijo Kyoto"]], "lunch": {"area": "Nishiki Market", "places": [{"name": "Assaggi a Nishiki", "query": "Nishiki Market Kyoto"}, {"name": "Pranzo diffuso Nishiki", "query": "Nishiki Market lunch Kyoto"}, {"name": "Opzione pranzo 3 · Nishiki Market", "query": "lunch Nishiki Market Kyoto Japan"}, {"name": "Opzione pranzo 4 · Nishiki Market", "query": "lunch Nishiki Market Kyoto Japan"}, {"name": "Opzione pranzo 5 · Nishiki Market", "query": "lunch Nishiki Market Kyoto Japan"}]}, "dinner": {"area": "Centro Kyoto", "places": [{"name": "Kurakura", "query": "Kurakura Kyoto"}, {"name": "Piccolo izakaya centro", "query": "Izakaya central Kyoto"}, {"name": "Opzione cena 3 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}, {"name": "Opzione cena 4 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}, {"name": "Opzione cena 5 · Centro Kyoto", "query": "dinner Centro Kyoto Kyoto Japan"}]}, "onsen": [{"name": "Arashiyama Onsen Kadensho", "query": "Arashiyama Onsen Kadensho Kyoto"}, {"name": "Hanaikada", "query": "Hanaikada Arashiyama Kyoto"}, {"name": "Fufu no Yu", "query": "Fufu no Yu Kyoto"}], "love_hotels": [{"name": "Hotel In The Green", "query": "Hotel In The Green Kyoto"}, {"name": "Hotel Chronos - Adult Only", "query": "Hotel Chronos Kyoto"}, {"name": "Hotel & Spa Lotus", "query": "Hotel & Spa Lotus Kyoto"}]}, {"id": "d24", "date": "24 giugno", "title": "Kobe + Osaka", "city": "Osaka", "base": "Kyoto", "summary": "Kobe beef, castello e neon.", "budget_jpy": [30000, 65000], "hint": "Il momento simbolico è il pranzo a Kobe.", "weather_city": "Osaka, Japan", "timeline": [["09:30", "Kobe", "JR Special Rapid", "Kitanocho Kobe"], ["12:30", "Kobe", "Pranzo Kobe beef", "Sannomiya Kobe"], ["16:00", "Osaka Castle", "Passeggiata", "Osaka Castle"], ["18:30", "Dotonbori", "Cena e street food", "Dotonbori"]], "lunch": {"area": "Kobe", "places": [{"name": "Steakland Kobe", "query": "Steakland Kobe"}, {"name": "Mouriya", "query": "Mouriya Kobe"}, {"name": "Opzione pranzo 3 · Kobe", "query": "lunch Kobe Osaka Japan"}, {"name": "Opzione pranzo 4 · Kobe", "query": "lunch Kobe Osaka Japan"}, {"name": "Opzione pranzo 5 · Kobe", "query": "lunch Kobe Osaka Japan"}]}, "dinner": {"area": "Dotonbori", "places": [{"name": "Akaoni Takoyaki", "query": "Akaoni Dotonbori Osaka"}, {"name": "Ajinoya Honten", "query": "Ajinoya Honten Osaka"}, {"name": "Opzione cena 3 · Dotonbori", "query": "dinner Dotonbori Osaka Japan"}, {"name": "Opzione cena 4 · Dotonbori", "query": "dinner Dotonbori Osaka Japan"}, {"name": "Opzione cena 5 · Dotonbori", "query": "dinner Dotonbori Osaka Japan"}]}, "onsen": [{"name": "Solaniwa Onsen", "query": "Solaniwa Onsen Osaka"}, {"name": "Spa World", "query": "Spa World Osaka"}, {"name": "Naniwa no Yu", "query": "Naniwa no Yu Osaka"}], "love_hotels": [{"name": "Hotel Salle de bain", "query": "Hotel Salle de bain Osaka"}, {"name": "Hotel Lotus Umeda", "query": "Hotel Lotus Umeda Osaka"}, {"name": "HOTEL FIVE plus", "query": "HOTEL FIVE plus Osaka"}]}, {"id": "d25", "date": "25 giugno", "title": "Kyoto → Tokyo + Shibuya Sky", "city": "Tokyo", "base": "Asakusa", "summary": "Rientro morbido e grande tramonto finale su Tokyo.", "budget_jpy": [32000, 55000], "hint": "Shibuya Sky è il cuore della giornata.", "weather_city": "Tokyo, Japan", "timeline": [["10:00", "Tokyo", "Shinkansen", "Tokyo Station"], ["12:30", "Asakusa", "Transfer hotel", "AMANEK Asakusa Sakurabashi"], ["17:30", "Shibuya Sky", "Ingresso al tramonto", "SHIBUYA SKY"], ["19:15", "Shibuya", "Cena", "Shibuya Crossing"]], "lunch": {"area": "Asakusa / Tokyo Station", "places": [{"name": "Lunch veloce Tokyo Station", "query": "Tokyo Station lunch"}, {"name": "Lunch veloce Asakusa", "query": "Lunch Asakusa Tokyo"}, {"name": "Opzione pranzo 3 · Asakusa / Tokyo Station", "query": "lunch Asakusa / Tokyo Station Tokyo Japan"}, {"name": "Opzione pranzo 4 · Asakusa / Tokyo Station", "query": "lunch Asakusa / Tokyo Station Tokyo Japan"}, {"name": "Opzione pranzo 5 · Asakusa / Tokyo Station", "query": "lunch Asakusa / Tokyo Station Tokyo Japan"}]}, "dinner": {"area": "Shibuya", "places": [{"name": "Bistrot a Shibuya", "query": "Bistro Shibuya Tokyo"}, {"name": "Sushi easy Shibuya", "query": "Sushi Shibuya Tokyo"}, {"name": "Opzione cena 3 · Shibuya", "query": "dinner Shibuya Tokyo Japan"}, {"name": "Opzione cena 4 · Shibuya", "query": "dinner Shibuya Tokyo Japan"}, {"name": "Opzione cena 5 · Shibuya", "query": "dinner Shibuya Tokyo Japan"}]}, "onsen": [{"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Mikokuyu (sento)", "query": "Mikokuyu Sumida Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}, {"id": "d26", "date": "26 giugno", "title": "Nikko", "city": "Nikko", "base": "Asakusa", "summary": "Santuari nel bosco e passeggiata a Kanmangafuchi.", "budget_jpy": [22000, 38000], "hint": "Toshogu e Kanmangafuchi bastano.", "weather_city": "Nikko, Japan", "timeline": [["08:30", "Tobu Nikko", "Treno", "Tobu Asakusa Station"], ["11:00", "Nikko Toshogu", "Visita principale", "Nikko Toshogu"], ["14:45", "Kanmangafuchi", "Passeggiata", "Kanmangafuchi Abyss"], ["16:20", "Rientro", "Verso Asakusa", "AMANEK Asakusa Sakurabashi"]], "lunch": {"area": "Nikko", "places": [{"name": "Hippari Dako", "query": "Hippari Dako Nikko"}, {"name": "Yuba lunch Nikko", "query": "Yuba Nikko"}, {"name": "Opzione pranzo 3 · Nikko", "query": "lunch Nikko Nikko Japan"}, {"name": "Opzione pranzo 4 · Nikko", "query": "lunch Nikko Nikko Japan"}, {"name": "Opzione pranzo 5 · Nikko", "query": "lunch Nikko Nikko Japan"}]}, "dinner": {"area": "Asakusa", "places": [{"name": "Cena tranquilla Asakusa", "query": "Restaurant Asakusa Tokyo"}, {"name": "Soba Asakusa", "query": "Soba Asakusa Tokyo"}, {"name": "Opzione cena 3 · Asakusa", "query": "dinner Asakusa Nikko Japan"}, {"name": "Opzione cena 4 · Asakusa", "query": "dinner Asakusa Nikko Japan"}, {"name": "Opzione cena 5 · Asakusa", "query": "dinner Asakusa Nikko Japan"}]}, "onsen": [{"name": "Nikko Station Hotel Classic onsen", "query": "Nikko Station Hotel Classic onsen"}, {"name": "Tattoo friendly private bath Nikko", "query": "private bath Nikko"}, {"name": "Onsen near Tobu Nikko", "query": "onsen Tobu Nikko"}], "love_hotels": [{"name": "Love hotel in zona", "query": "love hotel Nikko Japan"}, {"name": "Adult only hotel in zona", "query": "adult only hotel Nikko Japan"}, {"name": "Short stay hotel in zona", "query": "short stay hotel Nikko Japan"}]}, {"id": "d27", "date": "27 giugno", "title": "Yanaka + ultimo giorno", "city": "Tokyo", "base": "Asakusa", "summary": "Tokyo bassa, ultimi acquisti e cena finale.", "budget_jpy": [20000, 45000], "hint": "Tenete energia per la cena d’addio.", "weather_city": "Tokyo, Japan", "timeline": [["10:00", "Yanaka Ginza", "Passeggiata lenta", "Yanaka Ginza"], ["12:00", "Pranzo", "Yanaka / Ueno / Asakusa", "Yanaka Ginza"], ["16:00", "Asakusa", "Ultimi acquisti", "Senso-ji"], ["19:30", "Cena finale", "Teppanyaki o sushi", "Asakusa"]], "lunch": {"area": "Yanaka / Ueno", "places": [{"name": "Lunch informale Yanaka", "query": "Lunch Yanaka Tokyo"}, {"name": "Opzione semplice Ueno", "query": "Lunch Ueno Tokyo"}, {"name": "Opzione pranzo 3 · Yanaka / Ueno", "query": "lunch Yanaka / Ueno Tokyo Japan"}, {"name": "Opzione pranzo 4 · Yanaka / Ueno", "query": "lunch Yanaka / Ueno Tokyo Japan"}, {"name": "Opzione pranzo 5 · Yanaka / Ueno", "query": "lunch Yanaka / Ueno Tokyo Japan"}]}, "dinner": {"area": "Asakusa", "places": [{"name": "Teppanyaki finale", "query": "Teppanyaki Asakusa Tokyo"}, {"name": "Sushi finale", "query": "Sushi Asakusa Tokyo"}, {"name": "Opzione cena 3 · Asakusa", "query": "dinner Asakusa Tokyo Japan"}, {"name": "Opzione cena 4 · Asakusa", "query": "dinner Asakusa Tokyo Japan"}, {"name": "Opzione cena 5 · Asakusa", "query": "dinner Asakusa Tokyo Japan"}]}, "onsen": [{"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Daikokuyu (Asakusa area)", "query": "Daikokuyu Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}, {"id": "d28", "date": "28 giugno", "title": "Rientro", "city": "Tokyo", "base": "Narita / volo", "summary": "Uscita semplice e senza stress.", "budget_jpy": [3000, 8000], "hint": "La prossima tappa è arrivare bene in aeroporto.", "weather_city": "Tokyo, Japan", "timeline": [["07:15", "Check-out", "Partenza con anticipo", "AMANEK Asakusa Sakurabashi"], ["07:30", "Narita", "Transfer aeroporto", "Narita International Airport"], ["09:00", "Narita", "Check-in e controlli", "Narita International Airport"], ["11:10", "Volo", "Partenza", "Narita International Airport"]], "lunch": {"area": "Aeroporto / volo", "places": [{"name": "Snack aeroporto", "query": "Narita Airport restaurants"}, {"name": "Food court Narita", "query": "Narita Airport food court"}, {"name": "Opzione pranzo 3 · Aeroporto / volo", "query": "lunch Aeroporto / volo Tokyo Japan"}, {"name": "Opzione pranzo 4 · Aeroporto / volo", "query": "lunch Aeroporto / volo Tokyo Japan"}, {"name": "Opzione pranzo 5 · Aeroporto / volo", "query": "lunch Aeroporto / volo Tokyo Japan"}]}, "dinner": {"area": "Volo / rientro", "places": [{"name": "Pasto in volo", "query": "Narita International Airport"}, {"name": "Opzione cena 2 · Volo / rientro", "query": "dinner Volo / rientro Tokyo Japan"}, {"name": "Opzione cena 3 · Volo / rientro", "query": "dinner Volo / rientro Tokyo Japan"}, {"name": "Opzione cena 4 · Volo / rientro", "query": "dinner Volo / rientro Tokyo Japan"}, {"name": "Opzione cena 5 · Volo / rientro", "query": "dinner Volo / rientro Tokyo Japan"}]}, "onsen": [{"name": "Asakusa ROX Matsuri-yu", "query": "Asakusa ROX Matsuri-yu Tokyo"}, {"name": "Thermae-Yu Shinjuku", "query": "Thermae-Yu Shinjuku Tokyo"}, {"name": "Daikokuyu (Asakusa area)", "query": "Daikokuyu Tokyo"}], "love_hotels": [{"name": "Bali An Resort Shinjuku Forest", "query": "Hotel Bali An Resort Shinjuku Forest Tokyo"}, {"name": "HOTEL & SPA AN Shinjuku Kabukicho", "query": "HOTEL & SPA AN Shinjuku Kabukicho Tokyo"}, {"name": "HOTEL & SPA J-MEX Shinjuku", "query": "HOTEL & SPA J-MEX Shinjuku Tokyo"}]}]; const HOTELS = [{"city": "Tokyo", "name": "AMANEK Asakusa Sakurabashi", "dates": "14–18 giugno · 25–28 giugno", "query": "AMANEK Asakusa Sakurabashi Tokyo"}, {"city": "Kanazawa", "name": "Ryokan a Kanazawa", "dates": "18–20 giugno", "query": "ryokan Kanazawa station"}, {"city": "Kyoto", "name": "M's Hotel Plus Shijo Omiya", "dates": "20–25 giugno", "query": "M's Hotel Plus Shijo Omiya Kyoto"}]; const EURJPY = 182.85; const LAST_DAY_KEY='jp-trip-last-day-webapp-v27'; const LEGACY_TODO_KEY='jp-trip-todo-stable'; const LEGACY_COSTS_KEY='jp-trip-costs-stable'; const DB_NAME='jp-trip-db-v27'; const STORE='kv'; let dbPromise=null; function openDB(){ if(dbPromise) return dbPromise; dbPromise = new Promise((resolve,reject)=>{ const req = indexedDB.open(DB_NAME,1); req.onupgradeneeded = ()=>{ const db = req.result; if(!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE); }; req.onsuccess = ()=> resolve(req.result); req.onerror = ()=> reject(req.error); }); return dbPromise; } async function idbGet(key, fallback){ try{ const db = await openDB(); return await new Promise((resolve,reject)=>{ const tx = db.transaction(STORE,'readonly'); const req = tx.objectStore(STORE).get(key); req.onsuccess = ()=> resolve(req.result === undefined ? fallback : req.result); req.onerror = ()=> reject(req.error); }); }catch{ return fallback; } } async function idbSet(key, value){ try{ const db = await openDB(); return await new Promise((resolve,reject)=>{ const tx = db.transaction(STORE,'readwrite'); tx.objectStore(STORE).put(value,key); tx.oncomplete = ()=> resolve(true); tx.onerror = ()=> reject(tx.error); }); }catch{ return false; } } function mapsLink(q){ return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}`; } function jpyToEur(jpy){ return jpy / EURJPY; } function eurToJpy(eur){ return eur * EURJPY; } function formatJpy(n){ return '¥' + Number(n||0).toLocaleString('it-IT', {maximumFractionDigits:0}); } function formatEur(n){ return new Intl.NumberFormat('it-IT', {style:'currency', currency:'EUR'}).format(n||0); } const todaySelect=document.getElementById('todaySelect'),todayTop=document.getElementById('todayTop'),daysList=document.getElementById('daysList'),cityFilter=document.getElementById('cityFilter'); async function fetchWeather(city) { try { const g = await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1&language=it&format=json`); const gj = await g.json(); if(!gj.results || !gj.results.length) return null; const r = gj.results[0]; const w = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${r.latitude}&longitude=${r.longitude}¤t=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m&timezone=auto`); const wj = await w.json(); return {name:r.name, current:wj.current}; } catch(e) { return null; } } function weatherText(code) { const map = {0:'Sereno',1:'Poco nuvoloso',2:'Parzialmente nuvoloso',3:'Coperto',45:'Nebbia',48:'Nebbia intensa',51:'Pioviggine leggera',53:'Pioviggine',55:'Pioviggine intensa',61:'Pioggia leggera',63:'Pioggia',65:'Pioggia intensa',71:'Neve leggera',73:'Neve',75:'Neve intensa',80:'Rovesci leggeri',81:'Rovesci',82:'Rovesci forti',95:'Temporale',96:'Temporale con grandine',99:'Temporale forte'}; return map[code] || 'Meteo variabile'; } function populateSelects(){ todaySelect.innerHTML=DAYS.map(d=>``).join(''); const cities=[...new Set(DAYS.map(d=>d.city))].sort(); cityFilter.innerHTML=''+cities.map(c=>``).join(''); const last=localStorage.getItem(LAST_DAY_KEY); if(last&&DAYS.find(d=>d.id===last))todaySelect.value=last; } async function renderToday(){ const id=todaySelect.value||DAYS[0].id; localStorage.setItem(LAST_DAY_KEY,id); const day=DAYS.find(d=>d.id===id)||DAYS[0]; const stop=day.timeline[0]; const allStops=day.timeline.map(t=>`
${t[0]}
${t[1]}
${t[2]}
Maps
`).join(''); const lunch=day.lunch.places.slice(0,5).map(p=>`
  • ${p.name}
  • `).join(''); const dinner=day.dinner.places.slice(0,5).map(p=>`
  • ${p.name}
  • `).join(''); const onsen=day.onsen.map(p=>`
  • ${p.name}
  • `).join(''); const love=day.love_hotels.map(p=>`
  • ${p.name}
  • `).join(''); todayTop.innerHTML=`
    Dove siete
    ${day.city} · ${day.base}
    Meteo
    Caricamento...
    ${stop?stop[0]:'—'}
    ${stop?stop[1]:'Nessuna tappa'}
    ${stop?stop[2]:''}

    Tappe di oggi

    ${allStops}

    Pranzo · zona ${day.lunch.area}

    Cena · zona ${day.dinner.area}

    Onsen · tattoo friendly / private

    Love hotel in zona

    `; const weather=await fetchWeather(day.weather_city); const wc=document.getElementById('weatherCard'); if(wc){ if(weather&&weather.current){ wc.innerHTML=`
    Meteo · ${weather.name}
    ${weatherText(weather.current.weather_code)}
    Umidità ${weather.current.relative_humidity_2m}% · Vento ${weather.current.wind_speed_10m} km/h
    ${Math.round(weather.current.temperature_2m)}°
    `; } else { wc.innerHTML='
    Meteo
    Non disponibile
    '; } } } function renderDays(){ const q=document.getElementById('searchInput').value.trim().toLowerCase(); const city=cityFilter.value; const items=DAYS.filter(d=>(!q||JSON.stringify(d).toLowerCase().includes(q))&&(!city||d.city===city)); daysList.innerHTML=items.map(d=>`

    ${d.date} · ${d.title}

    ${d.city} · ${d.summary}
    `).join(''); document.querySelectorAll('.open-day').forEach(b=>b.onclick=()=>{todaySelect.value=b.dataset.id;renderToday();location.hash='#oggi';}); } function renderHotels(){ const host=document.getElementById('hotelList'); host.innerHTML=HOTELS.map(h=>`

    ${h.name}

    ${h.city} · ${h.dates}
    Maps
    `).join(''); } async function migrateLegacyData(){ const legacyTodo = localStorage.getItem(LEGACY_TODO_KEY); const legacyCosts = localStorage.getItem(LEGACY_COSTS_KEY); const existingTodo = await idbGet('todoData', null); const existingCosts = await idbGet('costData', null); if(legacyTodo && existingTodo === null){ try{ await idbSet('todoData', JSON.parse(legacyTodo)); }catch{} } if(legacyCosts && existingCosts === null){ try{ await idbSet('costData', JSON.parse(legacyCosts)); }catch{} } } async function renderTodo(){ const defaultTodo = ['Passaporti controllati','Assicurazione viaggio attiva','Prenotazioni hotel verificate','Biglietti aerei salvati','eSIM / SIM dati attivata','Carte e contanti pronti','Power bank carico','Adattatore prese in valigia','Prenotazioni teamLab / Shibuya Sky','Bagaglio e documenti finali']; let state = await idbGet('todoData', null); if(state === null){ state = defaultTodo.map(t=>({text:t,done:false})); await idbSet('todoData', state); } const host=document.getElementById('todoList'); host.innerHTML=state.map((item,i)=>``).join(''); host.querySelectorAll('input[type=checkbox]').forEach(cb=>cb.onchange=async ()=>{ const s = await idbGet('todoData', []); s[Number(cb.dataset.i)].done = cb.checked; await idbSet('todoData', s); }); } async function renderCosts(){ const costs = await idbGet('costData', []); const host=document.getElementById('costList'); host.innerHTML=costs.length?costs.map((c,i)=>`
    ${c.desc}
    ${formatJpy(c.jpy)} · ${formatEur(c.eur)}
    `).join(''):'
    Nessuna spesa inserita.
    '; const totalJpy=costs.reduce((a,c)=>a+Number(c.jpy||0),0); const totalEur=costs.reduce((a,c)=>a+Number(c.eur||0),0); document.getElementById('totalJpy').textContent=formatJpy(totalJpy); document.getElementById('totalEur').textContent=formatEur(totalEur); host.querySelectorAll('.del-cost').forEach(b=>b.onclick=async ()=>{ const s = await idbGet('costData', []); s.splice(Number(b.dataset.i),1); await idbSet('costData', s); renderCosts(); }); } todaySelect.onchange=renderToday; document.getElementById('prevDay').onclick=()=>{const idx=DAYS.findIndex(d=>d.id===todaySelect.value);if(idx>0)todaySelect.value=DAYS[idx-1].id;renderToday();}; document.getElementById('nextDay').onclick=()=>{const idx=DAYS.findIndex(d=>d.id===todaySelect.value);if(idx{ const desc=document.getElementById('costDesc').value.trim(); const jpyRaw=document.getElementById('costJpy').value; const eurRaw=document.getElementById('costEur').value; const jpyVal=Number(jpyRaw); const eurVal=Number(eurRaw); if(!desc) return; let jpy=0, eur=0; if(jpyVal>0){ jpy=jpyVal; eur=jpyToEur(jpyVal); } else if(eurVal>0){ eur=eurVal; jpy=eurToJpy(eurVal); } else { return; } const s=await idbGet('costData',[]); s.unshift({desc,jpy,eur}); await idbSet('costData',s); document.getElementById('costDesc').value=''; document.getElementById('costJpy').value=''; document.getElementById('costEur').value=''; renderCosts(); }; document.getElementById('clearCostsBtn').onclick=async ()=>{await idbSet('costData',[]);renderCosts();}; (async function init(){ populateSelects(); await migrateLegacyData(); renderToday(); renderDays(); renderHotels(); await renderTodo(); await renderCosts(); })();