diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 107281b..bb23c61 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -1,4 +1,5 @@ @import "photoswipe/dist/photoswipe.css"; +@import "mapbox-gl/dist/mapbox-gl.css"; @tailwind base; @tailwind components; @@ -41,4 +42,20 @@ .animate-spin { animation: spin 1s linear infinite; transform-origin: center center; +} + +@layer components { + .mapboxgl-ctrl-logo, + .mapboxgl-ctrl-attrib { + @apply hidden !important; /* 隐藏版权信息 */ + } + + .mapboxgl-ctrl-zoom-in, + .mapboxgl-ctrl-zoom-out { + @apply bg-base-200 text-base-content hover:bg-base-300 p-2; + } + + .mapboxgl-marker path { + @apply fill-current text-primary; + } } \ No newline at end of file diff --git a/app/controllers/cities_controller.rb b/app/controllers/cities_controller.rb index 05a6c71..aaf3976 100644 --- a/app/controllers/cities_controller.rb +++ b/app/controllers/cities_controller.rb @@ -35,6 +35,7 @@ class CitiesController < ApplicationController def show @city = City.friendly.find(params[:id]) + @arts = @city.weather_arts.order(weather_date: :desc).includes([ :image_attachment ]) ahoy.track "View City", { city_id: @city.id, name: @city.name, diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 61604f3..afb6930 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -8,9 +8,12 @@ import PhotoSwipeLightBoxController from "./photo_swipe_lightbox_controller" import FlashMessageController from "./flash_controller" import SearchController from "./search_controller" import PageLoadTimeController from "./page_load_time_controller" +import MapController from "./map_controller" application.register("hello", HelloController) application.register("photo-swipe-lightbox", PhotoSwipeLightBoxController) application.register("flash", FlashMessageController) application.register("search", SearchController) application.register("page-load-time", PageLoadTimeController) +application.register("map", MapController) + diff --git a/app/javascript/controllers/map_controller.js b/app/javascript/controllers/map_controller.js new file mode 100644 index 0000000..cca4004 --- /dev/null +++ b/app/javascript/controllers/map_controller.js @@ -0,0 +1,72 @@ +import { Controller } from "@hotwired/stimulus" +import mapboxgl from 'mapbox-gl' +import 'mapbox-gl/dist/mapbox-gl.css'; + +export default class extends Controller { + static values = { + latitude: Number, + longitude: Number, + zoom: { type: Number, default: 6 }, + weatherArt: Object, + weatherArtUrl: String, + token: String + } + + connect() { + mapboxgl.accessToken = this.tokenValue + + this.map = new mapboxgl.Map({ + container: this.element, + style: 'mapbox://styles/mapbox/satellite-streets-v12', + // projection: 'globe', // 启用 3D 地球模式 + center: [this.longitudeValue, this.latitudeValue], + zoom: this.zoomValue + }); + + this.map.on('style.load', () => { + // 设置地球效果 + this.map.setFog({ + 'color': 'rgb(186, 210, 235)', + 'high-color': 'rgb(36, 92, 223)', + 'horizon-blend': 0.02 + }); + }); + + // 添加标记 + // const marker = new mapboxgl.Marker({ + // color: "#FF6B6B", + // scale: 1.2 + // }) + // .setLngLat([this.longitudeValue, this.latitudeValue]) + // .addTo(this.map); + + const marker = new mapboxgl.Marker() + .setLngLat([this.longitudeValue, this.latitudeValue]) + .addTo(this.map); + // marker.getElement().addEventListener('click', () => { + // this.showPopup(); + // }); + + // 默认弹出窗口 + // this.showPopup(); + + // 添加缩放控件 + this.map.addControl(new mapboxgl.NavigationControl()); + } + + showPopup() { + console.log("weatherArtValue: ", this.weatherArtValue) + const popupContent = ` +
+ ${this.weatherArtValue.description} +

${this.weatherArtValue.description}

+ 查看详情 +
+ `; + + const popup = new mapboxgl.Popup() + .setLngLat([this.longitudeValue, this.latitudeValue]) + .setHTML(popupContent) + .addTo(this.map); + } +} \ No newline at end of file diff --git a/app/models/city.rb b/app/models/city.rb index 4d7f95b..18fb0a7 100644 --- a/app/models/city.rb +++ b/app/models/city.rb @@ -107,6 +107,34 @@ class City < ApplicationRecord ) } + # 定义 latest_weather_art 关联 + has_one :latest_weather_art, -> { order(weather_date: :desc) }, + class_name: "WeatherArt" + + # 包含最新天气艺术的 scope + scope :with_latest_weather_art, -> { + includes(:latest_weather_art) + } + + # 只获取有最新天气艺术的城市 + scope :has_weather_art, -> { + joins(:weather_arts).distinct + } + + # 按最新天气更新时间排序 + scope :order_by_latest_weather, -> { + joins(:weather_arts) + .group("cities.id") + .order("MAX(weather_arts.weather_date) DESC") + } + + # 获取最近24小时内更新过天气的城市 + scope :recently_updated, -> { + joins(:weather_arts) + .where("weather_arts.weather_date > ?", 24.hours.ago) + .distinct + } + def to_s name @@ -185,5 +213,36 @@ class City < ApplicationRecord self.id) .count end + end + + def formatted_current_time(type = :date, use_local_timezone = true) + # 获取时区 + timezone_info = self.country&.timezones.present? ? + eval(self.country.timezones).first : + { "zoneName" => "UTC", "gmtOffsetName" => "UTC+00:00" } + + # 设置时区对象 + time_zone = ActiveSupport::TimeZone[timezone_info["zoneName"]] || + ActiveSupport::TimeZone["UTC"] + time = Time.current + + case type + when :date + # 格式化日期 + time.strftime("%B %d, %Y") + when :time + use_local_timezone ? + "#{time.in_time_zone(time_zone).strftime('%H:%M')} #{timezone_info['gmtOffsetName']}" : + "#{time.utc.strftime('%H:%M')} UTC" + when :all + # 返回日期 + 时间 + UTC 信息 + date = time.strftime("%B %d, %Y") + time = use_local_timezone ? + updated_at.in_time_zone(time_zone).strftime("%H:%M") + " #{timezone_info['gmtOffsetName']}" : + updated_at.utc.strftime("%H:%M") + " UTC" + "#{date} #{time}" + else + "Unknown #{type}" end + end end diff --git a/app/models/weather_art.rb b/app/models/weather_art.rb index f624037..01b3422 100644 --- a/app/models/weather_art.rb +++ b/app/models/weather_art.rb @@ -68,6 +68,35 @@ class WeatherArt < ApplicationRecord end end + def formatted_time(type = :date, use_local_timezone = false) + # 获取时区 + timezone_info = self.city&.country&.timezones.present? ? + eval(self.city.country.timezones).first : + { "zoneName" => "UTC", "gmtOffsetName" => "UTC+00:00" } + + # 设置时区对象 + time_zone = ActiveSupport::TimeZone[timezone_info["zoneName"]] || + ActiveSupport::TimeZone["UTC"] + + case type + when :date + # 格式化日期 + self&.weather_date&.strftime("%B %d, %Y") + when :time + # 获取时间 + time = updated_at + + if use_local_timezone + # 使用本地时区 + local_time = time.in_time_zone(time_zone) + "#{local_time.strftime('%H:%M')} #{timezone_info['gmtOffsetName']}" + else + # 使用 UTC + "#{time.utc.strftime('%H:%M')} UTC" + end + end + end + def image_url image.attached? ? image.blob : nil end diff --git a/app/views/arts/index.html.erb b/app/views/arts/index.html.erb index 42a55b1..5499093 100644 --- a/app/views/arts/index.html.erb +++ b/app/views/arts/index.html.erb @@ -28,7 +28,7 @@
Latest from <%= featured_art.city.name %>, <%= featured_art.city.country.name %> - <%= featured_art.weather_date.strftime("%B %d, %Y") %> + <%= featured_art.formatted_time(:date) %>
<% end %> @@ -139,7 +139,7 @@ <%= art.city.name %>

- <%= art.weather_date.strftime("%B %d, %Y") %> + <%= art.formatted_time(:date, true) %>

diff --git a/app/views/cities/_city.html.erb b/app/views/cities/_city.html.erb index 438d472..06e2753 100644 --- a/app/views/cities/_city.html.erb +++ b/app/views/cities/_city.html.erb @@ -51,7 +51,7 @@ - <%= city.latest_weather_art.weather_date.strftime("%b %d, %Y") %> + <%= city.latest_weather_art.formatted_time(:date) %>
diff --git a/app/views/cities/_map.html.erb b/app/views/cities/_map.html.erb new file mode 100644 index 0000000..2f5b375 --- /dev/null +++ b/app/views/cities/_map.html.erb @@ -0,0 +1,16 @@ + +
+
+ +
+
+
\ No newline at end of file diff --git a/app/views/cities/_stat_card.html.erb b/app/views/cities/_stat_card.html.erb new file mode 100644 index 0000000..f62f32e --- /dev/null +++ b/app/views/cities/_stat_card.html.erb @@ -0,0 +1,13 @@ + +
+
+ <%= weather_stat_icon(stat[:icon]) %> +
<%= stat[:title] %>
+
+
+
+ <%= stat[:value] %> +
+
+
<%= stat[:desc] %>
+
diff --git a/app/views/cities/index.html.erb b/app/views/cities/index.html.erb index 3706f00..b5aae1c 100644 --- a/app/views/cities/index.html.erb +++ b/app/views/cities/index.html.erb @@ -29,7 +29,7 @@ <%= featured_art.city.name %>, <%= featured_art.city.country.name %> - <%= featured_art.weather_date.strftime("%B %d, %Y") %> + <%= featured_art.formatted_time(:date) %> <% end %> <%= render 'cities/search_city' %> diff --git a/app/views/cities/show.html.erb b/app/views/cities/show.html.erb index bd87b53..02db839 100644 --- a/app/views/cities/show.html.erb +++ b/app/views/cities/show.html.erb @@ -1,19 +1,18 @@ -
- - <% if @city.latest_weather_art&.image&.attached? %> -
- <%= image_tag @city.latest_weather_art.webp_image.processed, - class: "absolute w-full h-full object-cover scale-110 filter blur-2xl opacity-25" %> -
-
- <% end %> +
+ +
+ + <% if @city.latest_weather_art&.image&.attached? %> +
+ <%= image_tag @city.latest_weather_art.webp_image.processed, + class: "w-full h-full object-cover object-center" %> +
+
+ <% end %> - -
- -
+
<%= link_to cities_path, - class: "btn btn-ghost btn-lg gap-2 bg-base-100/50 backdrop-blur-sm hover:bg-base-100/70 transition-all duration-300" do %> + class: "inline-flex items-center btn btn-ghost gap-2 " do %> @@ -21,131 +20,77 @@ <% end %>
- -
-
-

- +
+
+ +
+

<%= @city.localized_name %> - -

+

-
-
- <%= "#{@city&.country&.emoji + " " || ""}#{@city&.country&.name}" %>, <%= @city.region %> +
+
+ <%= "#{@city&.country&.emoji + " " || ""}#{@city&.country&.name}" %> +
+
+ <%= @city&.state&.name %> +
-
- <%= @city.timezone.present? ? Time.current.in_time_zone(@city.timezone).strftime("%Y-%m-%d %H:%M") : "Timezone undefined" %> + + +
+ <%= render partial: 'cities/stat_card', collection: [ + { + icon: 'temperature', + title: 'Latest Weather', + value: "#{@city.latest_weather_art&.temperature}°C", + desc: @city.latest_weather_art&.description + }, + { + icon: 'location', + title: 'Coordinates', + value: "#{@city.latitude}°N, #{@city.longitude}°E", + desc: 'Geographical Location' + }, + { + icon: 'history', + title: 'Records', + value: @city.weather_arts.count, + desc: 'Total Weather Arts' + } + ], as: :stat %>
+ + <%= render 'cities/map', city: @city %> + + <%= render 'cities/admin_panel' %>
- - -
-
-
- <%= weather_stat_icon("temperature") %> -
Latest Weather
-
-
<%= @city.latest_weather_art&.temperature %>°C
-
<%= @city.latest_weather_art&.description %>
-
- -
-
- <%= weather_stat_icon("location") %> -
Coordinates
-
-
- <%= @city.latitude %>°N, - <%= @city.longitude %>°E -
-
Geographical Location
-
- -
-
- <%= weather_stat_icon("history") %> -
Records
-
-
<%= @city.weather_arts.count %>
-
Total Weather Arts
-
-
- - <%= render 'cities/admin_panel' %>
+
- -
+ +
+
-

- Weather Art History -

-
+

Weather Art History

+
- Last Updated: - - <%= time_ago_in_words(@city.last_weather_fetch) if @city.last_weather_fetch %> - + Last Updated: <%= time_ago_in_words(@city.last_weather_fetch) if @city.last_weather_fetch %>
- <% @city.weather_arts.order(weather_date: :desc).each do |art| %> -
-
- <% if art.image.attached? %> - <%= image_tag art.preview_image.processed, - class: "w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" %> -
-
-
<%= art.temperature %>°C
-
-
<%= art.created_at.strftime("%H:%M") %>
-
<%= art.weather_date.strftime("%B %d, %Y") %>
-
-
-
- <% end %> -
- -
-

- <%= weather_description_icon(art.description) %> - <%= art.description %> -

- -
-
- <%= weather_stat_icon("humidity") %> - Humidity: <%= art.humidity %>% -
-
- <%= weather_stat_icon("wind") %> - Wind: <%= art.wind_scale %> -
-
- - <%= link_to city_weather_art_path(@city, art), - class: "btn btn-primary btn-block" do %> - View Details - - - - <% end %> -
-
- <% end %> + <%= render partial: 'weather_arts/card', collection: @arts, as: :weather_art %>
-
\ No newline at end of file +
diff --git a/app/views/home/_arts.html.erb b/app/views/home/_arts.html.erb index bf432bb..bb127f0 100644 --- a/app/views/home/_arts.html.erb +++ b/app/views/home/_arts.html.erb @@ -11,7 +11,7 @@

<%= art.city.name %>

- <%= art.weather_date.strftime("%B %d, %Y") %> + <%= art.formatted_time(:date) %>

diff --git a/app/views/weather_arts/_card.html.erb b/app/views/weather_arts/_card.html.erb new file mode 100644 index 0000000..bead5f5 --- /dev/null +++ b/app/views/weather_arts/_card.html.erb @@ -0,0 +1,44 @@ + +
+
+ <% if weather_art.image.attached? %> + <%= image_tag weather_art.preview_image.processed, + class: "w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" %> +
+
+
<%= weather_art.temperature %>°C
+
+
<%= weather_art.formatted_time(:date) %>
+
<%= weather_art.formatted_time(:time, true) %>
+
+
+
+ <% end %> +
+ +
+

+ <%= weather_description_icon(weather_art.description) %> + <%= weather_art.description %> +

+ +
+
+ <%= weather_stat_icon("humidity") %> + Humidity: <%= weather_art.humidity %>% +
+
+ <%= weather_stat_icon("wind") %> + Wind: <%= weather_art.wind_scale %> +
+
+ + <%= link_to city_weather_art_path(weather_art.city, weather_art), + class: "btn btn-primary btn-block" do %> + View Details + + + + <% end %> +
+
\ No newline at end of file diff --git a/app/views/weather_arts/show.html.erb b/app/views/weather_arts/show.html.erb index dd85448..7e6547f 100644 --- a/app/views/weather_arts/show.html.erb +++ b/app/views/weather_arts/show.html.erb @@ -52,10 +52,10 @@
- <%= @weather_art.weather_date.strftime("%B %d, %Y") %> + <%= @weather_art.formatted_time(:date) %>
- <%= @weather_art.created_at.strftime("%H:%M") %> + <%= @weather_art.formatted_time(:time, true) %>
diff --git a/app/workers/batch_generate_weather_arts_worker.rb b/app/workers/batch_generate_weather_arts_worker.rb index 2d29c0e..8a285a6 100644 --- a/app/workers/batch_generate_weather_arts_worker.rb +++ b/app/workers/batch_generate_weather_arts_worker.rb @@ -2,8 +2,8 @@ class BatchGenerateWeatherArtsWorker include Sidekiq::Worker GENERATION_INTERVAL = 36.hours - MAX_DURATION = 50.minutes - SLEEP_DURATION = 120.seconds + MAX_DURATION = 5.minutes + SLEEP_DURATION = 10.seconds DAILY_GENERATION_LIMIT = 50 # 每日生成图片上限 def perform(*args) @@ -11,10 +11,26 @@ class BatchGenerateWeatherArtsWorker remaining_slots = calculate_remaining_slots return if remaining_slots <= 0 - # 获取符合条件的城市并处理 cities_to_process = select_cities(remaining_slots)&.shuffle print_cities_list(cities_to_process, start_time) - process_cities(cities_to_process, start_time) + + skipped_cities = [] + processed_cities = [] + + cities_to_process.each do |city| + if within_sunrise_time?(city) + Rails.logger.info "Generating weather art for #{city.name} (time: [#{city.formatted_current_time(:all)}])" + GenerateWeatherArtWorker.perform_async(city.id) + processed_cities << city.name + else + Rails.logger.info "Skipping #{city.name} (time: [#{city.formatted_current_time(:all)}]) due to local time not being within sunrise hours." + skipped_cities << city.name + end + sleep SLEEP_DURATION + break if Time.current - start_time > MAX_DURATION + end + + print_summary(processed_cities, skipped_cities) end private @@ -32,16 +48,36 @@ class BatchGenerateWeatherArtsWorker Rails.logger.info "Generate city task start at: #{start_time}" Rails.logger.info "Generate city list: " Rails.logger.info "======================================" - Rails.logger.info "ID\tRegion\tCountry\tState\tName" + Rails.logger.info "ID\tRegion\tCountry\tState\tName\tLocalTime" cities.each do |city| - Rails.logger.info "#{city.id}\t#{city&.country&.region&.name}\t#{city&.country&.name}\t#{city&.state&.name}\t#{city&.name}" + Rails.logger.info "#{city.id}\t#{city.country&.region&.name}\t#{city.country&.name}\t#{city.state&.name}\t#{city.name}\t#{city.formatted_current_time(:all)}" end end + def within_sunrise_time?(city) + local_time = get_local_time(city) + Rails.logger.debug "#{city.name} now hour: #{local_time.hour}" + local_time.hour >= 8 && local_time.hour <= 18 + end + + def get_local_time(city) + return Time.current unless city + timezone_info = eval(city.country.timezones).first + return Time.current unless timezone_info + + timezone = ActiveSupport::TimeZone[timezone_info["zoneName"]] || + ActiveSupport::TimeZone["UTC"] + Time.current.in_time_zone(timezone) + end + + def print_summary(processed_cities, skipped_cities) + Rails.logger.info "Processed cities: #{processed_cities.join(', ')}" + Rails.logger.info "Skipped cities: #{skipped_cities.join(', ')}" + end + def select_cities(limit) cutoff_time = Time.current - GENERATION_INTERVAL - # 基础查询:排除最近生成过的城市 base_query = City .joins("LEFT JOIN ( SELECT city_id, MAX(created_at) as last_generation_time @@ -50,7 +86,6 @@ class BatchGenerateWeatherArtsWorker ) latest_arts ON cities.id = latest_arts.city_id") .where("latest_arts.last_generation_time IS NULL OR latest_arts.last_generation_time < ?", cutoff_time) - # 优先选择活跃城市 active_cities = base_query .where(active: true) .order(:priority) @@ -60,7 +95,6 @@ class BatchGenerateWeatherArtsWorker remaining_slots = limit - active_cities.size if remaining_slots > 0 - # 如果还有剩余名额,从其他城市中随机选择 other_cities = base_query .where.not(id: active_cities.map(&:id)) .order("RANDOM()") @@ -72,14 +106,4 @@ class BatchGenerateWeatherArtsWorker active_cities end end - - def process_cities(cities, start_time) - cities.each do |city| - break if Time.current - start_time > MAX_DURATION - - Rails.logger.info "Generating weather art for #{city.name}" - GenerateWeatherArtWorker.perform_async(city.id) - sleep SLEEP_DURATION - end - end end diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index 7f598a1..b1ee349 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -mNiwLK27M1vAWefYLzYIiQO0jBJqqZ1Yo0T1YOcldA3YrQo+AVm1vImv7Nbc96N3OK4f782Q3lNp4mTPl0zUFjiWy2QN/VdBMN9B2uxcUXJIASCJMwDlrc+e2evD6dqUb/hTj0q2Hi/uMVuRBI1O/bDvxxBQma/4MyPgwm6uwnP2g1yLfiBkgveU72yc4tHHmzXwEoxtJa3VkVKus+QWwCyWe/ZKvoDF2RplQm7RYVXgsbNhSdTVfoGvH9ExKRZvKjzrXutLtXe4YpHiiLSisCQBLYqF/XptG86U/uFldtCcbcB6XX2psyrQxHmhdxHnucMSx35rvh4XrjPMNKDpCiYuvJepjaJzgPDRkxjf4txIUHnIs3p6lVto+b92vq2OGKAq/nUwTpAB46WVz4CNCI0Z+QHkbSZ05a6cHAkzBY1Z4uiwu7gM6AFN/jYOdDo6GzxrP6h/Msp3wmOgKiM8Ts1kysXNdJ6E8X8GHPNKfHLnyVnoVrJbY1GGv6oXu4WkIxAK5v6Mi10J0Sd6QQJuZYv2SKNCjXUtxrm4NFWd9DY3BMvF3TSDRU17riruPyJHCYKSqCQHobblC7Sr1lwcN3+CfOJqGXR66D0OH6DNiHwobxsyVSHzSePl5bVi9a44V+GtzDJ0fZQYOpVnzWOsMj++K89dz2qtruB7BSOQe9YAXGk+dk//XqUebz4fqYUiW79aj4M1DyFquapbcn+WpzmXFGuVORM2ZuQjUr0Glev8JMq95R4JIZkMDwm5/q7YUbqEb25yMdhs5c48vmCIy3itliieWN9kYZO6pqIsP73KXms2Xi5nJ+FcaFQ9T24zs/S9JcA1a2KUl6n8kYBcVYBdNBvE+9ab+eJ3RUp3YMOErmMHAtTsUXQCZLmXpRheaaOkupS/XB+M+jYgYLI6+sv86ISZsYz472iT9UMCn5F/X8lNIwDClPoJP2kafLDq6hMlo76Oa/aVj+miy7tJIWFgVvMJ3VwPf526MMZgNShF6tZ+Z7PA0pr+9WuoZSyQ0Ai9lql/Tk+r2ZUPT6Z28qjGr9ln2jbb509ETwhSxnHjINskNyLmfFWUcELy+BEmOSn9GQgay0PoFkUrYpidpXD9Tw2IpEpklyIGhr4HFHv4bQ5uBWjPrIGm3R8fjATA0xB+Wg9SDPSHd+QclAzcL6Po8UlLIZfROjReg7ZJn5+8x0rf7UidNXTfy+JM0GmUR9aUh110RKE0u1WjdhhzdVDiQH2m58CZf3TsP3z4o8SLWfXAftqU8p3sBXPOV+L5RyWrUMzvWmDFzL0RmP854fOILsq76QoI4PULPHD7AIGaCHxuM+qmNQvYhFBMDCaHEeLP4ARX2NmUxMCT40T7bWEFbrAJ14Kd8L/EAjYVsGrBTWGZSvB3aZcZnP3cy4kC9XWvfAksstm9dPSqbxH7d8POb5KJBhSnfm5UWczc24s/6TC9UON921Shz3e9tk7bbBSBNIA/pHWmoZ8vFS3Cegihnt9TnALlWDBrGm7arYr3oQJHqkQ4KPEh36EwZDw/+YDaXLhN2yR8hL7nGPsewcwKdYEU4bGjTpI6xtjs0hBgwuMwTNWUsEm+bijt2feTxzJgUyT9ywW7aSsDfZi88J06LMJfpeAUIjhTjB9Coohk33lrpmsrD5Hb3RaObELlrpG6RkCHlmTxMTjTonS9ni+7dXUYJFYYvtLuyFmhSxEEk7bCrCMVkOWN5tTs0y0J22bxT/FrGLn/GKKlK/FVAeoGN8ZvEOCmIizEQ8k6wgAbuLDaTxV1irLLOeaY3JtjwVxBQHfNuCgxKXxd0zcUqv7D/sgMC0zafcqshG8VaXfGvFexWVEnZjPiZ6aHzeNMhdTPsf9D0p8R3PFgcvC2rSLYNbj2MXnvGqkrtQCre0CiNVxflVvOHbJjugdp5LqAjf6bssCsrZKifaRTPeg=--B6BEVJN27qT5bDUL--B4LzjOJ7SlzEKibq4VSVmg== \ No newline at end of file +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--JNyAqrs+Fsmpu043--vwHHQzq3PsM/qcTSemHHAg== \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 415bcf5..5389bbd 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -79,4 +79,6 @@ Rails.application.configure do # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. # config.generators.apply_rubocop_autocorrect_after_generate! + + config.serve_static_assets = true end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 4873244..270956e 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,3 +5,8 @@ Rails.application.config.assets.version = "1.0" # Add additional assets to the asset load path. # Rails.application.config.assets.paths << Emoji.images_path +# Rails.application.config.assets.paths << Rails.root.join("app/assets/builds") +# Rails.application.config.assets.paths << Rails.root.join("node_modules") +# Rails.application.config.assets.precompile += %w( *.png *.jpg *.jpeg *.gif ) +# Rails.application.config.assets.paths << Rails.root.join("app/assets/builds") +# Rails.application.config.assets.precompile += %w( *.png *.jpg *.jpeg *.gif ) diff --git a/config/sidekiq_scheduler.yml b/config/sidekiq_scheduler.yml index 6963062..8914b3f 100644 --- a/config/sidekiq_scheduler.yml +++ b/config/sidekiq_scheduler.yml @@ -1,5 +1,5 @@ batch_generate_weather: - cron: '0 8,18 * * *' + cron: '0 */1 * * *' class: BatchGenerateWeatherArtsWorker description: "Batch Generate weather arts" enabled: true diff --git a/package.json b/package.json index 8b11caf..0644ede 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "autoprefixer": "^10.4.20", "jquery": "^3.7.1", "jquery-ui": "^1.14.1", + "mapbox-gl": "^3.10.0", + "ol": "^10.4.0", "photoswipe": "^5.4.4", "postcss": "^8.5.1", "sass": "^1.83.4", diff --git a/public/marker-icon.svg b/public/marker-icon.svg new file mode 100644 index 0000000..f8b3554 --- /dev/null +++ b/public/marker-icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 29ceef2..4a97adb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -213,6 +213,43 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@mapbox/jsonlint-lines-primitives@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234" + integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ== + +"@mapbox/mapbox-gl-supported@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz#bebd3d5da3c1fd988011bb79718a39f63f5e16ac" + integrity sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg== + +"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" + integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== + +"@mapbox/tiny-sdf@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz#9a1d33e5018093e88f6a4df2343e886056287282" + integrity sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA== + +"@mapbox/unitbezier@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01" + integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw== + +"@mapbox/vector-tile@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666" + integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== + dependencies: + "@mapbox/point-geometry" "~0.1.0" + +"@mapbox/whoots-js@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" + integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -323,6 +360,11 @@ "@parcel/watcher-win32-ia32" "2.5.0" "@parcel/watcher-win32-x64" "2.5.0" +"@petamoriken/float16@^3.4.7": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@petamoriken/float16/-/float16-3.9.1.tgz#f1239d6721f25c1bf921dde0d7d678efef9c1de2" + integrity sha512-j+ejhYwY6PeB+v1kn7lZFACUIG97u90WxMuGosILFsl9d4Ovi0sjk0GlPfoEcx+FzvXZDAfioD+NGnnPamXgMA== + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" @@ -333,6 +375,49 @@ resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.2.201.tgz" integrity sha512-wsTdWoZ5EfG5k3t7ORdyQF0ZmDEgN4aVPCanHAiNEwCROqibSZMXXmCbH7IDJUVri4FOeAVwwbPINI7HVHPKBw== +"@types/geojson-vt@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/geojson-vt/-/geojson-vt-3.2.5.tgz#b6c356874991d9ab4207533476dfbcdb21e38408" + integrity sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g== + dependencies: + "@types/geojson" "*" + +"@types/geojson@*", "@types/geojson@^7946.0.16": + version "7946.0.16" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" + integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== + +"@types/mapbox__point-geometry@*", "@types/mapbox__point-geometry@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz#0ef017b75eedce02ff6243b4189210e2e6d5e56d" + integrity sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA== + +"@types/mapbox__vector-tile@^1.3.4": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz#ad757441ef1d34628d9e098afd9c91423c1f8734" + integrity sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg== + dependencies: + "@types/geojson" "*" + "@types/mapbox__point-geometry" "*" + "@types/pbf" "*" + +"@types/pbf@*", "@types/pbf@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.5.tgz#a9495a58d8c75be4ffe9a0bd749a307715c07404" + integrity sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA== + +"@types/rbush@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/rbush/-/rbush-4.0.0.tgz#b327bf54952e9c924ea6702c36904c2ce1d47f35" + integrity sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ== + +"@types/supercluster@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/supercluster/-/supercluster-7.1.3.tgz#1a1bc2401b09174d9c9e44124931ec7874a72b27" + integrity sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA== + dependencies: + "@types/geojson" "*" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -429,6 +514,11 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001688: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz" integrity sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A== +cheap-ruler@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cheap-ruler/-/cheap-ruler-4.0.0.tgz#bdc984de7e0e3f748bdfd2dbe23ec6b9dc820a09" + integrity sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw== + chokidar@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" @@ -458,11 +548,36 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-2.0.0.tgz#03ff6b1b5aec9bb3cf1ed82400c2790dfcd01d2d" + integrity sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-parse@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/color-parse/-/color-parse-2.0.2.tgz#37b46930424924060988edf25b24e6ffb4a1dc3f" + integrity sha512-eCtOz5w5ttWIUcaKLiktF+DxZO1R9KLNY/xhbV6CkhM7sR3GhVghmt6X6yOnzeaM24po+Z9/S1apbXMwA3Iepw== + dependencies: + color-name "^2.0.0" + +color-rgba@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color-rgba/-/color-rgba-3.0.0.tgz#77090bdcdb2951c1735e20099ddd50401675375b" + integrity sha512-PPwZYkEY3M2THEHHV6Y95sGUie77S7X8v+h1r6LSAPF3/LL2xJ8duUXSrkic31Nzc4odPwHgUbiX/XuTYzQHQg== + dependencies: + color-parse "^2.0.0" + color-space "^2.0.0" + +color-space@^2.0.0, color-space@^2.0.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/color-space/-/color-space-2.3.1.tgz#1c13ca8ee017585807e65c76de3870cdc7c4fdfb" + integrity sha512-5DJdKYwoDji3ik/i0xSn+SiwXsfwr+1FEcCMUz2GS5speGCfGSbBMOLd84SDUBOuX8y4CvdFJmOBBJuC4wp7sQ== + commander@^4.0.0: version "4.1.1" resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" @@ -485,6 +600,11 @@ css-selector-tokenizer@^0.8: cssesc "^3.0.0" fastparse "^1.1.2" +csscolorparser@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" + integrity sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" @@ -520,6 +640,11 @@ dlv@^1.1.3: resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== +earcut@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-3.0.1.tgz#f60b3f671c5657cca9d3e131c5527c5dde00ef38" + integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" @@ -629,6 +754,30 @@ function-bind@^1.1.2: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +geojson-vt@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-4.0.2.tgz#1162f6c7d61a0ba305b1030621e6e111f847828a" + integrity sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A== + +geotiff@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/geotiff/-/geotiff-2.1.3.tgz#993f40f2aa6aa65fb1e0451d86dd22ca8e66910c" + integrity sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA== + dependencies: + "@petamoriken/float16" "^3.4.7" + lerc "^3.0.0" + pako "^2.0.4" + parse-headers "^2.0.2" + quick-lru "^6.1.1" + web-worker "^1.2.0" + xml-utils "^1.0.2" + zstddec "^0.1.0" + +gl-matrix@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" + integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -655,6 +804,11 @@ glob@^10.3.10: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" +grid-index@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" + integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== + hasown@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -662,6 +816,11 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" +ieee754@^1.1.12: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + immutable@^5.0.2: version "5.0.3" resolved "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz" @@ -739,6 +898,16 @@ jquery-ujs@^1.2.2: resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz" integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== +kdbush@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + +lerc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lerc/-/lerc-3.0.0.tgz#36f36fbd4ba46f0abf4833799fff2e7d6865f5cb" + integrity sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww== + lilconfig@^3.0.0, lilconfig@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz" @@ -754,6 +923,40 @@ lru-cache@^10.2.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +mapbox-gl@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-3.10.0.tgz#9104a4e2f75fe2cf2a8ba015397be59f5179ba8c" + integrity sha512-YnQxjlthuv/tidcxGYU2C8nRDVXMlAHa3qFhuOJeX4AfRP72OMRBf9ApL+M+k5VWcAXi2fcNOUVgphknjLumjA== + dependencies: + "@mapbox/jsonlint-lines-primitives" "^2.0.2" + "@mapbox/mapbox-gl-supported" "^3.0.0" + "@mapbox/point-geometry" "^0.1.0" + "@mapbox/tiny-sdf" "^2.0.6" + "@mapbox/unitbezier" "^0.0.1" + "@mapbox/vector-tile" "^1.3.1" + "@mapbox/whoots-js" "^3.1.0" + "@types/geojson" "^7946.0.16" + "@types/geojson-vt" "^3.2.5" + "@types/mapbox__point-geometry" "^0.1.4" + "@types/mapbox__vector-tile" "^1.3.4" + "@types/pbf" "^3.0.5" + "@types/supercluster" "^7.1.3" + cheap-ruler "^4.0.0" + csscolorparser "~1.0.3" + earcut "^3.0.0" + geojson-vt "^4.0.2" + gl-matrix "^3.4.3" + grid-index "^1.1.0" + kdbush "^4.0.2" + murmurhash-js "^1.0.0" + pbf "^3.2.1" + potpack "^2.0.0" + quickselect "^3.0.0" + serialize-to-js "^3.1.2" + supercluster "^8.0.1" + tinyqueue "^3.0.0" + vt-pbf "^3.1.3" + merge2@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" @@ -779,6 +982,11 @@ minimatch@^9.0.4: resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +murmurhash-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" + integrity sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw== + mz@^2.7.0: version "2.7.0" resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" @@ -823,11 +1031,34 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== +ol@^10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ol/-/ol-10.4.0.tgz#b073dd2b08c3cc31fece1c904a6711e0d289d6e4" + integrity sha512-gv3voS4wgej1WVvdCz2ZIBq3lPWy8agaf0094E79piz8IGQzHiOWPs2in1pdoPmuTNvcqGqyUFG3IbxNE6n08g== + dependencies: + "@types/rbush" "4.0.0" + color-rgba "^3.0.0" + color-space "^2.0.1" + earcut "^3.0.0" + geotiff "^2.1.3" + pbf "4.0.1" + rbush "^4.0.0" + package-json-from-dist@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz" integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== +pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +parse-headers@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" @@ -846,6 +1077,21 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +pbf@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-4.0.1.tgz#ad9015e022b235dcdbe05fc468a9acadf483f0d4" + integrity sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA== + dependencies: + resolve-protobuf-schema "^2.1.0" + +pbf@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.3.0.tgz#1790f3d99118333cc7f498de816028a346ef367f" + integrity sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q== + dependencies: + ieee754 "^1.1.12" + resolve-protobuf-schema "^2.1.0" + photoswipe@^5.4.4: version "5.4.4" resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.4.4.tgz#e045dc036453493188d5c8665b0e8f1000ac4d6e" @@ -924,11 +1170,38 @@ postcss@^8.4.47, postcss@^8.5.1: picocolors "^1.1.1" source-map-js "^1.2.1" +potpack@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/potpack/-/potpack-2.0.0.tgz#61f4dd2dc4b3d5e996e3698c0ec9426d0e169104" + integrity sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw== + +protocol-buffers-schema@^3.3.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03" + integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-6.1.2.tgz#e9a90524108629be35287d0b864e7ad6ceb3659e" + integrity sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ== + +quickselect@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-3.0.0.tgz#a37fc953867d56f095a20ac71c6d27063d2de603" + integrity sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g== + +rbush@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/rbush/-/rbush-4.0.1.tgz#1f55afa64a978f71bf9e9a99bc14ff84f3cb0d6d" + integrity sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ== + dependencies: + quickselect "^3.0.0" + read-cache@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" @@ -948,6 +1221,13 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +resolve-protobuf-schema@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758" + integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== + dependencies: + protocol-buffers-schema "^3.3.1" + resolve@^1.1.7, resolve@^1.22.8: version "1.22.10" resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz" @@ -980,6 +1260,11 @@ sass@^1.83.4: optionalDependencies: "@parcel/watcher" "^2.4.1" +serialize-to-js@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-3.1.2.tgz#844b8a1c2d72412f68ea30da55090b3fc8e95790" + integrity sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -1063,6 +1348,13 @@ sucrase@^3.35.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" +supercluster@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-8.0.1.tgz#9946ba123538e9e9ab15de472531f604e7372df5" + integrity sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ== + dependencies: + kdbush "^4.0.2" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" @@ -1110,6 +1402,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +tinyqueue@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-3.0.0.tgz#101ea761ccc81f979e29200929e78f1556e3661e" + integrity sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -1135,6 +1432,20 @@ util-deprecate@^1.0.2: resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +vt-pbf@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" + integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.2.1" + +web-worker@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.5.0.tgz#71b2b0fbcc4293e8f0aa4f6b8a3ffebff733dcc5" + integrity sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw== + which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -1160,7 +1471,17 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" +xml-utils@^1.0.2: + version "1.10.1" + resolved "https://registry.yarnpkg.com/xml-utils/-/xml-utils-1.10.1.tgz#fa0c9b38545760532d4cf89003f90c3b24e7200f" + integrity sha512-Dn6vJ1Z9v1tepSjvnCpwk5QqwIPcEFKdgnjqfYOABv1ngSofuAhtlugcUC3ehS1OHdgDWSG6C5mvj+Qm15udTQ== + yaml@^2.3.4: version "2.7.0" resolved "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz" integrity sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA== + +zstddec@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.1.0.tgz#7050f3f0e0c3978562d0c566b3e5a427d2bad7ec" + integrity sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==