diff --git a/backend/src/main/resources/static/login.png b/backend/src/main/resources/static/login.png new file mode 100644 index 0000000..329b27b Binary files /dev/null and b/backend/src/main/resources/static/login.png differ diff --git a/backend/target/classes/application.yml b/backend/target/classes/application.yml new file mode 100644 index 0000000..393865a --- /dev/null +++ b/backend/target/classes/application.yml @@ -0,0 +1,52 @@ +server: + port: 8011 +spring: + application: + name: guardia-mall + datasource: + url: ${DB_URL:jdbc:postgresql://localhost:5432/mall_db} + username: ${DB_USER:mall_user} + password: ${DB_PASS:mall_pass2026} + driver-class-name: org.postgresql.Driver + servlet: + multipart: + max-file-size: 20MB + max-request-size: 20MB +mybatis: + mapper-locations: classpath:mapper/*.xml + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl +springdoc: + api-docs: + path: /api/mall/docs + swagger-ui: + path: /api/mall/swagger +mall: + # 외부 게이트웨이 어댑터 선택 — 기본 mock(개발/데모 외부호출 0). 운영 시 환경변수로 오버라이드. + payment: + provider: ${MALL_PAYMENT_PROVIDER:mock} # mock | stripe + tax: + provider: ${MALL_TAX_PROVIDER:mock} # mock | taxjar | avalara + address: + provider: ${MALL_ADDRESS_PROVIDER:mock} # mock | google | smarty + sms: + provider: ${MALL_SMS_PROVIDER:mock} # mock | twilio + email: + provider: ${MALL_EMAIL_PROVIDER:mock} # mock | sendgrid +guardia: + itsm-url: ${ITSM_URL:http://localhost:9001} + erp-url: ${ERP_URL:http://localhost:8003} + crm-url: ${CRM_URL:http://localhost:8004} + ocr-url: ${OCR_URL:http://localhost:8005} + ollama-url: ${OLLAMA_URL:http://localhost:11434} + ollama-text-model: ${OLLAMA_TEXT_MODEL:llama3} + crypto: + secret: ${CRYPTO_SECRET:guardia-mall-aes-256-gcm-master-key-2026-zioinfo} + jwt: + secret: ${JWT_SECRET:guardia-mall-jwt-secret-2026-minimum-256bit-key-zioinfo} + expiration: 86400000 +logging: + level: + com.zioinfo.mall: DEBUG + org.mybatis: WARN diff --git a/backend/target/classes/com/zioinfo/mall/MallApplication.class b/backend/target/classes/com/zioinfo/mall/MallApplication.class new file mode 100644 index 0000000..08a7796 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/MallApplication.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController$ActiveRequest.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController$ActiveRequest.class new file mode 100644 index 0000000..7f5bd84 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController$ActiveRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController$CreateUserRequest.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController$CreateUserRequest.class new file mode 100644 index 0000000..02dfa2e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController$CreateUserRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController$PasswordRequest.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController$PasswordRequest.class new file mode 100644 index 0000000..75fa422 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController$PasswordRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController$RoleRequest.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController$RoleRequest.class new file mode 100644 index 0000000..8447689 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController$RoleRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController$SettingRequest.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController$SettingRequest.class new file mode 100644 index 0000000..677a528 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController$SettingRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminController.class b/backend/target/classes/com/zioinfo/mall/admin/AdminController.class new file mode 100644 index 0000000..9d99e25 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AdminUserService.class b/backend/target/classes/com/zioinfo/mall/admin/AdminUserService.class new file mode 100644 index 0000000..a08fcd9 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AdminUserService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/AuditService.class b/backend/target/classes/com/zioinfo/mall/admin/AuditService.class new file mode 100644 index 0000000..aa33e39 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/AuditService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/SettingService.class b/backend/target/classes/com/zioinfo/mall/admin/SettingService.class new file mode 100644 index 0000000..527ad52 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/SettingService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/dto/AuditLog.class b/backend/target/classes/com/zioinfo/mall/admin/dto/AuditLog.class new file mode 100644 index 0000000..ca36757 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/dto/AuditLog.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/dto/MallSetting.class b/backend/target/classes/com/zioinfo/mall/admin/dto/MallSetting.class new file mode 100644 index 0000000..3647874 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/dto/MallSetting.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/dto/UserDto.class b/backend/target/classes/com/zioinfo/mall/admin/dto/UserDto.class new file mode 100644 index 0000000..cbc843d Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/dto/UserDto.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/mapper/AdminUserMapper.class b/backend/target/classes/com/zioinfo/mall/admin/mapper/AdminUserMapper.class new file mode 100644 index 0000000..57901aa Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/mapper/AdminUserMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/mapper/AuditLogMapper.class b/backend/target/classes/com/zioinfo/mall/admin/mapper/AuditLogMapper.class new file mode 100644 index 0000000..864d7e0 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/mapper/AuditLogMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/admin/mapper/SettingMapper.class b/backend/target/classes/com/zioinfo/mall/admin/mapper/SettingMapper.class new file mode 100644 index 0000000..d1bf15b Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/admin/mapper/SettingMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/ai/MallAiController.class b/backend/target/classes/com/zioinfo/mall/ai/MallAiController.class new file mode 100644 index 0000000..d4a0877 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/ai/MallAiController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/ai/MallAiService.class b/backend/target/classes/com/zioinfo/mall/ai/MallAiService.class new file mode 100644 index 0000000..6f3d508 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/ai/MallAiService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/ai/OllamaClient.class b/backend/target/classes/com/zioinfo/mall/ai/OllamaClient.class new file mode 100644 index 0000000..7b708ab Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/ai/OllamaClient.class differ diff --git a/backend/target/classes/com/zioinfo/mall/analytics/AnalyticsController.class b/backend/target/classes/com/zioinfo/mall/analytics/AnalyticsController.class new file mode 100644 index 0000000..83d3cda Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/analytics/AnalyticsController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/analytics/mapper/AnalyticsMapper.class b/backend/target/classes/com/zioinfo/mall/analytics/mapper/AnalyticsMapper.class new file mode 100644 index 0000000..fb37c91 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/analytics/mapper/AnalyticsMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/AuthController$LoginRequest.class b/backend/target/classes/com/zioinfo/mall/auth/AuthController$LoginRequest.class new file mode 100644 index 0000000..b072e8b Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/AuthController$LoginRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/AuthController$RegisterRequest.class b/backend/target/classes/com/zioinfo/mall/auth/AuthController$RegisterRequest.class new file mode 100644 index 0000000..186e997 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/AuthController$RegisterRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/AuthController.class b/backend/target/classes/com/zioinfo/mall/auth/AuthController.class new file mode 100644 index 0000000..912badd Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/AuthController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/AuthService.class b/backend/target/classes/com/zioinfo/mall/auth/AuthService.class new file mode 100644 index 0000000..395026e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/AuthService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/JwtFilter.class b/backend/target/classes/com/zioinfo/mall/auth/JwtFilter.class new file mode 100644 index 0000000..ea007ec Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/JwtFilter.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/JwtUtil.class b/backend/target/classes/com/zioinfo/mall/auth/JwtUtil.class new file mode 100644 index 0000000..356c565 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/JwtUtil.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/MallUser.class b/backend/target/classes/com/zioinfo/mall/auth/MallUser.class new file mode 100644 index 0000000..119c501 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/MallUser.class differ diff --git a/backend/target/classes/com/zioinfo/mall/auth/mapper/UserMapper.class b/backend/target/classes/com/zioinfo/mall/auth/mapper/UserMapper.class new file mode 100644 index 0000000..7b36fa9 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/auth/mapper/UserMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cart/CartController.class b/backend/target/classes/com/zioinfo/mall/cart/CartController.class new file mode 100644 index 0000000..08884e9 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cart/CartController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cart/MallCartItem.class b/backend/target/classes/com/zioinfo/mall/cart/MallCartItem.class new file mode 100644 index 0000000..4353c91 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cart/MallCartItem.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cart/mapper/CartMapper.class b/backend/target/classes/com/zioinfo/mall/cart/mapper/CartMapper.class new file mode 100644 index 0000000..693f8ff Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cart/mapper/CartMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/category/CategoryController.class b/backend/target/classes/com/zioinfo/mall/category/CategoryController.class new file mode 100644 index 0000000..2cf7884 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/category/CategoryController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/category/MallCategory.class b/backend/target/classes/com/zioinfo/mall/category/MallCategory.class new file mode 100644 index 0000000..9e662d3 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/category/MallCategory.class differ diff --git a/backend/target/classes/com/zioinfo/mall/category/mapper/CategoryMapper.class b/backend/target/classes/com/zioinfo/mall/category/mapper/CategoryMapper.class new file mode 100644 index 0000000..63f9624 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/category/mapper/CategoryMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/common/ApiResponse.class b/backend/target/classes/com/zioinfo/mall/common/ApiResponse.class new file mode 100644 index 0000000..6429e52 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/common/ApiResponse.class differ diff --git a/backend/target/classes/com/zioinfo/mall/common/CryptoUtil.class b/backend/target/classes/com/zioinfo/mall/common/CryptoUtil.class new file mode 100644 index 0000000..93f532b Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/common/CryptoUtil.class differ diff --git a/backend/target/classes/com/zioinfo/mall/common/GlobalExceptionHandler.class b/backend/target/classes/com/zioinfo/mall/common/GlobalExceptionHandler.class new file mode 100644 index 0000000..9d39787 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/common/GlobalExceptionHandler.class differ diff --git a/backend/target/classes/com/zioinfo/mall/config/CorsConfig.class b/backend/target/classes/com/zioinfo/mall/config/CorsConfig.class new file mode 100644 index 0000000..7b1ab1e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/config/CorsConfig.class differ diff --git a/backend/target/classes/com/zioinfo/mall/config/MyBatisConfig.class b/backend/target/classes/com/zioinfo/mall/config/MyBatisConfig.class new file mode 100644 index 0000000..6ff2bc2 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/config/MyBatisConfig.class differ diff --git a/backend/target/classes/com/zioinfo/mall/config/SecurityConfig.class b/backend/target/classes/com/zioinfo/mall/config/SecurityConfig.class new file mode 100644 index 0000000..fbc5f91 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/config/SecurityConfig.class differ diff --git a/backend/target/classes/com/zioinfo/mall/config/SpaForwardController.class b/backend/target/classes/com/zioinfo/mall/config/SpaForwardController.class new file mode 100644 index 0000000..b220ed8 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/config/SpaForwardController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/config/WebSocketConfig.class b/backend/target/classes/com/zioinfo/mall/config/WebSocketConfig.class new file mode 100644 index 0000000..5e8d530 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/config/WebSocketConfig.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cs/CsController.class b/backend/target/classes/com/zioinfo/mall/cs/CsController.class new file mode 100644 index 0000000..f9bcc1f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cs/CsController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cs/MallCsTicket.class b/backend/target/classes/com/zioinfo/mall/cs/MallCsTicket.class new file mode 100644 index 0000000..07d879b Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cs/MallCsTicket.class differ diff --git a/backend/target/classes/com/zioinfo/mall/cs/mapper/CsMapper.class b/backend/target/classes/com/zioinfo/mall/cs/mapper/CsMapper.class new file mode 100644 index 0000000..5479005 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/cs/mapper/CsMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/delivery/DeliveryController.class b/backend/target/classes/com/zioinfo/mall/delivery/DeliveryController.class new file mode 100644 index 0000000..5ea2fcd Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/delivery/DeliveryController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/delivery/MallDelivery.class b/backend/target/classes/com/zioinfo/mall/delivery/MallDelivery.class new file mode 100644 index 0000000..8efbfd9 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/delivery/MallDelivery.class differ diff --git a/backend/target/classes/com/zioinfo/mall/delivery/mapper/DeliveryMapper.class b/backend/target/classes/com/zioinfo/mall/delivery/mapper/DeliveryMapper.class new file mode 100644 index 0000000..3664636 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/delivery/mapper/DeliveryMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/EventController$CopyRequest.class b/backend/target/classes/com/zioinfo/mall/event/EventController$CopyRequest.class new file mode 100644 index 0000000..9b284a1 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/EventController$CopyRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/EventController.class b/backend/target/classes/com/zioinfo/mall/event/EventController.class new file mode 100644 index 0000000..c57c21b Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/EventController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/EventService.class b/backend/target/classes/com/zioinfo/mall/event/EventService.class new file mode 100644 index 0000000..02e692f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/EventService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/MallEvent.class b/backend/target/classes/com/zioinfo/mall/event/MallEvent.class new file mode 100644 index 0000000..2838a57 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/MallEvent.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/MallEventBanner.class b/backend/target/classes/com/zioinfo/mall/event/MallEventBanner.class new file mode 100644 index 0000000..9f81c3f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/MallEventBanner.class differ diff --git a/backend/target/classes/com/zioinfo/mall/event/mapper/EventMapper.class b/backend/target/classes/com/zioinfo/mall/event/mapper/EventMapper.class new file mode 100644 index 0000000..0f6ea8f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/event/mapper/EventMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/AddressVerifier.class b/backend/target/classes/com/zioinfo/mall/gateway/AddressVerifier.class new file mode 100644 index 0000000..30fd5a5 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/AddressVerifier.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/AvalaraCalculator.class b/backend/target/classes/com/zioinfo/mall/gateway/AvalaraCalculator.class new file mode 100644 index 0000000..9ecd3bc Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/AvalaraCalculator.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/EmailSender.class b/backend/target/classes/com/zioinfo/mall/gateway/EmailSender.class new file mode 100644 index 0000000..27b00af Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/EmailSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/GatewayController.class b/backend/target/classes/com/zioinfo/mall/gateway/GatewayController.class new file mode 100644 index 0000000..6677305 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/GatewayController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/GoogleMapsVerifier.class b/backend/target/classes/com/zioinfo/mall/gateway/GoogleMapsVerifier.class new file mode 100644 index 0000000..efa2c58 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/GoogleMapsVerifier.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/MockAddressVerifier.class b/backend/target/classes/com/zioinfo/mall/gateway/MockAddressVerifier.class new file mode 100644 index 0000000..e173e4d Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/MockAddressVerifier.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/MockEmailSender.class b/backend/target/classes/com/zioinfo/mall/gateway/MockEmailSender.class new file mode 100644 index 0000000..0be68f1 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/MockEmailSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/MockPaymentGateway.class b/backend/target/classes/com/zioinfo/mall/gateway/MockPaymentGateway.class new file mode 100644 index 0000000..f6fd337 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/MockPaymentGateway.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/MockSmsSender.class b/backend/target/classes/com/zioinfo/mall/gateway/MockSmsSender.class new file mode 100644 index 0000000..fd169c2 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/MockSmsSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/MockTaxCalculator.class b/backend/target/classes/com/zioinfo/mall/gateway/MockTaxCalculator.class new file mode 100644 index 0000000..2cf3182 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/MockTaxCalculator.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/PaymentGateway.class b/backend/target/classes/com/zioinfo/mall/gateway/PaymentGateway.class new file mode 100644 index 0000000..2224daa Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/PaymentGateway.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/SendGridEmailSender.class b/backend/target/classes/com/zioinfo/mall/gateway/SendGridEmailSender.class new file mode 100644 index 0000000..e717653 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/SendGridEmailSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/SmartyVerifier.class b/backend/target/classes/com/zioinfo/mall/gateway/SmartyVerifier.class new file mode 100644 index 0000000..ba49076 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/SmartyVerifier.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/SmsSender.class b/backend/target/classes/com/zioinfo/mall/gateway/SmsSender.class new file mode 100644 index 0000000..fa2c4c0 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/SmsSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/StripeGateway.class b/backend/target/classes/com/zioinfo/mall/gateway/StripeGateway.class new file mode 100644 index 0000000..7d831c0 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/StripeGateway.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/TaxCalculator.class b/backend/target/classes/com/zioinfo/mall/gateway/TaxCalculator.class new file mode 100644 index 0000000..a7d63e6 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/TaxCalculator.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/TaxJarCalculator.class b/backend/target/classes/com/zioinfo/mall/gateway/TaxJarCalculator.class new file mode 100644 index 0000000..8ab8906 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/TaxJarCalculator.class differ diff --git a/backend/target/classes/com/zioinfo/mall/gateway/TwilioSmsSender.class b/backend/target/classes/com/zioinfo/mall/gateway/TwilioSmsSender.class new file mode 100644 index 0000000..84e5422 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/gateway/TwilioSmsSender.class differ diff --git a/backend/target/classes/com/zioinfo/mall/integration/CrmClient.class b/backend/target/classes/com/zioinfo/mall/integration/CrmClient.class new file mode 100644 index 0000000..d162ceb Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/integration/CrmClient.class differ diff --git a/backend/target/classes/com/zioinfo/mall/integration/ErpClient.class b/backend/target/classes/com/zioinfo/mall/integration/ErpClient.class new file mode 100644 index 0000000..d7cc596 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/integration/ErpClient.class differ diff --git a/backend/target/classes/com/zioinfo/mall/integration/IntegrationController.class b/backend/target/classes/com/zioinfo/mall/integration/IntegrationController.class new file mode 100644 index 0000000..84346ca Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/integration/IntegrationController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/integration/ItsmClient.class b/backend/target/classes/com/zioinfo/mall/integration/ItsmClient.class new file mode 100644 index 0000000..b97ddcb Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/integration/ItsmClient.class differ diff --git a/backend/target/classes/com/zioinfo/mall/integration/ItsmSecuritySanitizer.class b/backend/target/classes/com/zioinfo/mall/integration/ItsmSecuritySanitizer.class new file mode 100644 index 0000000..e64b288 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/integration/ItsmSecuritySanitizer.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/InventoryController.class b/backend/target/classes/com/zioinfo/mall/inventory/InventoryController.class new file mode 100644 index 0000000..0f74599 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/InventoryController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/MallInventory.class b/backend/target/classes/com/zioinfo/mall/inventory/MallInventory.class new file mode 100644 index 0000000..3fdd365 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/MallInventory.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/MallStoreInventory.class b/backend/target/classes/com/zioinfo/mall/inventory/MallStoreInventory.class new file mode 100644 index 0000000..7513509 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/MallStoreInventory.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/StoreInventoryController.class b/backend/target/classes/com/zioinfo/mall/inventory/StoreInventoryController.class new file mode 100644 index 0000000..c471ea1 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/StoreInventoryController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/mapper/InventoryMapper.class b/backend/target/classes/com/zioinfo/mall/inventory/mapper/InventoryMapper.class new file mode 100644 index 0000000..62f9735 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/mapper/InventoryMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/inventory/mapper/StoreInventoryMapper.class b/backend/target/classes/com/zioinfo/mall/inventory/mapper/StoreInventoryMapper.class new file mode 100644 index 0000000..c397ec2 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/inventory/mapper/StoreInventoryMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$AdjustRequest.class b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$AdjustRequest.class new file mode 100644 index 0000000..767e457 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$AdjustRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$UsePointRequest.class b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$UsePointRequest.class new file mode 100644 index 0000000..3d8a8a4 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController$UsePointRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController.class b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController.class new file mode 100644 index 0000000..d578468 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyService.class b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyService.class new file mode 100644 index 0000000..06eab0f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/LoyaltyService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/MallPointLedger.class b/backend/target/classes/com/zioinfo/mall/loyalty/MallPointLedger.class new file mode 100644 index 0000000..34f86e1 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/MallPointLedger.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/MallTierBenefit.class b/backend/target/classes/com/zioinfo/mall/loyalty/MallTierBenefit.class new file mode 100644 index 0000000..9ff3be0 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/MallTierBenefit.class differ diff --git a/backend/target/classes/com/zioinfo/mall/loyalty/mapper/LoyaltyMapper.class b/backend/target/classes/com/zioinfo/mall/loyalty/mapper/LoyaltyMapper.class new file mode 100644 index 0000000..1eaa68e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/loyalty/mapper/LoyaltyMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/member/MallMember.class b/backend/target/classes/com/zioinfo/mall/member/MallMember.class new file mode 100644 index 0000000..bb6cbc6 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/member/MallMember.class differ diff --git a/backend/target/classes/com/zioinfo/mall/member/MemberController.class b/backend/target/classes/com/zioinfo/mall/member/MemberController.class new file mode 100644 index 0000000..34e5386 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/member/MemberController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/member/mapper/MemberMapper.class b/backend/target/classes/com/zioinfo/mall/member/mapper/MemberMapper.class new file mode 100644 index 0000000..efde69d Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/member/mapper/MemberMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/MallOrder.class b/backend/target/classes/com/zioinfo/mall/order/MallOrder.class new file mode 100644 index 0000000..d4fb3ff Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/MallOrder.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/MallOrderItem.class b/backend/target/classes/com/zioinfo/mall/order/MallOrderItem.class new file mode 100644 index 0000000..7653c48 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/MallOrderItem.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/OrderController.class b/backend/target/classes/com/zioinfo/mall/order/OrderController.class new file mode 100644 index 0000000..fb54adb Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/OrderController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/OrderService$CheckoutRequest.class b/backend/target/classes/com/zioinfo/mall/order/OrderService$CheckoutRequest.class new file mode 100644 index 0000000..9de4e75 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/OrderService$CheckoutRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/OrderService.class b/backend/target/classes/com/zioinfo/mall/order/OrderService.class new file mode 100644 index 0000000..69d58dc Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/OrderService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/order/mapper/OrderMapper.class b/backend/target/classes/com/zioinfo/mall/order/mapper/OrderMapper.class new file mode 100644 index 0000000..2969144 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/order/mapper/OrderMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/payment/MallPayment.class b/backend/target/classes/com/zioinfo/mall/payment/MallPayment.class new file mode 100644 index 0000000..2804634 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/payment/MallPayment.class differ diff --git a/backend/target/classes/com/zioinfo/mall/payment/PaymentController.class b/backend/target/classes/com/zioinfo/mall/payment/PaymentController.class new file mode 100644 index 0000000..c29b39e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/payment/PaymentController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/payment/PaymentService$PayRequest.class b/backend/target/classes/com/zioinfo/mall/payment/PaymentService$PayRequest.class new file mode 100644 index 0000000..2a11f74 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/payment/PaymentService$PayRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/payment/PaymentService.class b/backend/target/classes/com/zioinfo/mall/payment/PaymentService.class new file mode 100644 index 0000000..761b272 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/payment/PaymentService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/payment/mapper/PaymentMapper.class b/backend/target/classes/com/zioinfo/mall/payment/mapper/PaymentMapper.class new file mode 100644 index 0000000..6e9594d Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/payment/mapper/PaymentMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/MallProduct.class b/backend/target/classes/com/zioinfo/mall/product/MallProduct.class new file mode 100644 index 0000000..0ecc3fc Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/MallProduct.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/MallProductImage.class b/backend/target/classes/com/zioinfo/mall/product/MallProductImage.class new file mode 100644 index 0000000..a403950 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/MallProductImage.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/MallProductOption.class b/backend/target/classes/com/zioinfo/mall/product/MallProductOption.class new file mode 100644 index 0000000..7206ef0 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/MallProductOption.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/MallProductSize.class b/backend/target/classes/com/zioinfo/mall/product/MallProductSize.class new file mode 100644 index 0000000..eed8d63 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/MallProductSize.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/ProductController.class b/backend/target/classes/com/zioinfo/mall/product/ProductController.class new file mode 100644 index 0000000..a8948d5 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/ProductController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/ProductService.class b/backend/target/classes/com/zioinfo/mall/product/ProductService.class new file mode 100644 index 0000000..373460e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/ProductService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/product/mapper/ProductMapper.class b/backend/target/classes/com/zioinfo/mall/product/mapper/ProductMapper.class new file mode 100644 index 0000000..045c9f9 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/product/mapper/ProductMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/promotion/MallCoupon.class b/backend/target/classes/com/zioinfo/mall/promotion/MallCoupon.class new file mode 100644 index 0000000..09194de Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/promotion/MallCoupon.class differ diff --git a/backend/target/classes/com/zioinfo/mall/promotion/MallPromotion.class b/backend/target/classes/com/zioinfo/mall/promotion/MallPromotion.class new file mode 100644 index 0000000..b47c961 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/promotion/MallPromotion.class differ diff --git a/backend/target/classes/com/zioinfo/mall/promotion/PromotionController$ValidateRequest.class b/backend/target/classes/com/zioinfo/mall/promotion/PromotionController$ValidateRequest.class new file mode 100644 index 0000000..8ee6a34 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/promotion/PromotionController$ValidateRequest.class differ diff --git a/backend/target/classes/com/zioinfo/mall/promotion/PromotionController.class b/backend/target/classes/com/zioinfo/mall/promotion/PromotionController.class new file mode 100644 index 0000000..cb29df2 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/promotion/PromotionController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/promotion/mapper/PromotionMapper.class b/backend/target/classes/com/zioinfo/mall/promotion/mapper/PromotionMapper.class new file mode 100644 index 0000000..34f3199 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/promotion/mapper/PromotionMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/realtime/OrderNotifier.class b/backend/target/classes/com/zioinfo/mall/realtime/OrderNotifier.class new file mode 100644 index 0000000..3e7fb76 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/realtime/OrderNotifier.class differ diff --git a/backend/target/classes/com/zioinfo/mall/realtime/OrderWebSocketHandler.class b/backend/target/classes/com/zioinfo/mall/realtime/OrderWebSocketHandler.class new file mode 100644 index 0000000..20963e2 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/realtime/OrderWebSocketHandler.class differ diff --git a/backend/target/classes/com/zioinfo/mall/review/MallReview.class b/backend/target/classes/com/zioinfo/mall/review/MallReview.class new file mode 100644 index 0000000..fe4b724 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/review/MallReview.class differ diff --git a/backend/target/classes/com/zioinfo/mall/review/ReviewController.class b/backend/target/classes/com/zioinfo/mall/review/ReviewController.class new file mode 100644 index 0000000..0608f8a Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/review/ReviewController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/review/mapper/ReviewMapper.class b/backend/target/classes/com/zioinfo/mall/review/mapper/ReviewMapper.class new file mode 100644 index 0000000..ff9a704 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/review/mapper/ReviewMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/schedule/MallHoliday.class b/backend/target/classes/com/zioinfo/mall/schedule/MallHoliday.class new file mode 100644 index 0000000..c008ab1 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/schedule/MallHoliday.class differ diff --git a/backend/target/classes/com/zioinfo/mall/schedule/MallScheduleSlot.class b/backend/target/classes/com/zioinfo/mall/schedule/MallScheduleSlot.class new file mode 100644 index 0000000..2cfb6ad Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/schedule/MallScheduleSlot.class differ diff --git a/backend/target/classes/com/zioinfo/mall/schedule/ScheduleController.class b/backend/target/classes/com/zioinfo/mall/schedule/ScheduleController.class new file mode 100644 index 0000000..0f014dd Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/schedule/ScheduleController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/schedule/ScheduleService.class b/backend/target/classes/com/zioinfo/mall/schedule/ScheduleService.class new file mode 100644 index 0000000..c0cdde7 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/schedule/ScheduleService.class differ diff --git a/backend/target/classes/com/zioinfo/mall/schedule/mapper/ScheduleMapper.class b/backend/target/classes/com/zioinfo/mall/schedule/mapper/ScheduleMapper.class new file mode 100644 index 0000000..6a125d5 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/schedule/mapper/ScheduleMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/store/MallStore.class b/backend/target/classes/com/zioinfo/mall/store/MallStore.class new file mode 100644 index 0000000..d8abc7c Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/store/MallStore.class differ diff --git a/backend/target/classes/com/zioinfo/mall/store/StoreController.class b/backend/target/classes/com/zioinfo/mall/store/StoreController.class new file mode 100644 index 0000000..19eef97 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/store/StoreController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/store/mapper/StoreMapper.class b/backend/target/classes/com/zioinfo/mall/store/mapper/StoreMapper.class new file mode 100644 index 0000000..dac64df Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/store/mapper/StoreMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/subscription/MallSubscription.class b/backend/target/classes/com/zioinfo/mall/subscription/MallSubscription.class new file mode 100644 index 0000000..396e883 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/subscription/MallSubscription.class differ diff --git a/backend/target/classes/com/zioinfo/mall/subscription/SubscriptionController.class b/backend/target/classes/com/zioinfo/mall/subscription/SubscriptionController.class new file mode 100644 index 0000000..63f539e Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/subscription/SubscriptionController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/subscription/mapper/SubscriptionMapper.class b/backend/target/classes/com/zioinfo/mall/subscription/mapper/SubscriptionMapper.class new file mode 100644 index 0000000..0e44a4f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/subscription/mapper/SubscriptionMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/transfer/MallTransfer.class b/backend/target/classes/com/zioinfo/mall/transfer/MallTransfer.class new file mode 100644 index 0000000..9b62914 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/transfer/MallTransfer.class differ diff --git a/backend/target/classes/com/zioinfo/mall/transfer/TransferController.class b/backend/target/classes/com/zioinfo/mall/transfer/TransferController.class new file mode 100644 index 0000000..307fc22 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/transfer/TransferController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/transfer/mapper/TransferMapper.class b/backend/target/classes/com/zioinfo/mall/transfer/mapper/TransferMapper.class new file mode 100644 index 0000000..e4a285c Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/transfer/mapper/TransferMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/wishlist/WishlistController.class b/backend/target/classes/com/zioinfo/mall/wishlist/WishlistController.class new file mode 100644 index 0000000..7732711 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/wishlist/WishlistController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/wishlist/mapper/WishlistMapper.class b/backend/target/classes/com/zioinfo/mall/wishlist/mapper/WishlistMapper.class new file mode 100644 index 0000000..3151cc6 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/wishlist/mapper/WishlistMapper.class differ diff --git a/backend/target/classes/com/zioinfo/mall/zone/MallDeliveryArea.class b/backend/target/classes/com/zioinfo/mall/zone/MallDeliveryArea.class new file mode 100644 index 0000000..f951c0f Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/zone/MallDeliveryArea.class differ diff --git a/backend/target/classes/com/zioinfo/mall/zone/MallZone.class b/backend/target/classes/com/zioinfo/mall/zone/MallZone.class new file mode 100644 index 0000000..e97c90d Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/zone/MallZone.class differ diff --git a/backend/target/classes/com/zioinfo/mall/zone/ZoneController.class b/backend/target/classes/com/zioinfo/mall/zone/ZoneController.class new file mode 100644 index 0000000..d204ad4 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/zone/ZoneController.class differ diff --git a/backend/target/classes/com/zioinfo/mall/zone/mapper/ZoneMapper.class b/backend/target/classes/com/zioinfo/mall/zone/mapper/ZoneMapper.class new file mode 100644 index 0000000..7814657 Binary files /dev/null and b/backend/target/classes/com/zioinfo/mall/zone/mapper/ZoneMapper.class differ diff --git a/backend/target/classes/db/schema.sql b/backend/target/classes/db/schema.sql new file mode 100644 index 0000000..e8783cf --- /dev/null +++ b/backend/target/classes/db/schema.sql @@ -0,0 +1,801 @@ +-- ============================================================================ +-- GUARDiA Mall — PostgreSQL 스키마 (mall_db) +-- 미국 다지점 꽃집 옴니채널 e-커머스 +-- 매장·ZIP배송권역·매장별재고ON/OFF·상품/3사이즈/옵션·장바구니·주문·스케줄링/타임슬롯· +-- 당일배송·구독·서지프라이싱·배송/기사라우팅·매장간재고이양·리뷰·회원·CS·분석·찜 +-- 모든 테이블 IF NOT EXISTS, 시드는 ON CONFLICT DO NOTHING (멱등). +-- ============================================================================ + +-- --------------------------------------------------------------------------- +-- 0. 공통 (인증/감사/설정/AI) +-- --------------------------------------------------------------------------- +-- 인증/관리자 계정 (auth UserMapper + admin AdminUserMapper 가 사용하는 테이블) +CREATE TABLE IF NOT EXISTS mall_account ( + id BIGSERIAL PRIMARY KEY, username VARCHAR(200) UNIQUE NOT NULL, password_hash VARCHAR(500) NOT NULL, + role VARCHAR(50) DEFAULT 'USER', display_name VARCHAR(200), + store_id BIGINT, -- StoreManager 배정 매장 (SuperAdmin=NULL) + is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT NOW() +); +-- 시드 비밀번호 = admin123 (bcrypt $2a$10) +INSERT INTO mall_account (username, password_hash, role, display_name, store_id) VALUES +('admin', '$2a$10$Uo4GFiJ2TZy9KlGRALfDt.gcE0e7..57rXBRaEv1mJG2XqANG3OI2', 'ADMIN', 'Super Admin (대표)', NULL), +('manager', '$2a$10$Uo4GFiJ2TZy9KlGRALfDt.gcE0e7..57rXBRaEv1mJG2XqANG3OI2', 'MANAGER', 'Store Manager (1호점)', 1), +('jane', '$2a$10$Uo4GFiJ2TZy9KlGRALfDt.gcE0e7..57rXBRaEv1mJG2XqANG3OI2', 'USER', 'Jane Doe', NULL) +ON CONFLICT (username) DO NOTHING; + +CREATE TABLE IF NOT EXISTS mall_audit_log ( + id BIGSERIAL PRIMARY KEY, actor VARCHAR(200), action VARCHAR(100), target VARCHAR(300), detail TEXT, created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_audit_action ON mall_audit_log(action); + +CREATE TABLE IF NOT EXISTS mall_setting (key VARCHAR(200) PRIMARY KEY, value TEXT, updated_at TIMESTAMP DEFAULT NOW()); +INSERT INTO mall_setting (key, value) VALUES +('ollama_text_model','llama3'), +('company_name','Montvale Florist'), +('company_tagline','100% Florist-Designed and Hand-Delivered!'), +('company_address','6 Railroad Ave, Montvale, NJ 07645'), +('company_phone','(201) 690-6721'), +('company_email','wecare@montvalefloristnj.com'), +('company_founded','2010'), +('company_rating','4.9'), +('company_review_count','44893'), +('social_instagram','@themontvaleflorist'), +('social_facebook','montvaleflorist1'), +('social_pinterest','montvaleflorist'), +('social_yelp','montvale-florist-montvale-3'), +('hours_weekday','Mon-Fri 9:00 AM - 5:30 PM'), +('hours_saturday','Sat 9:00 AM - 4:00 PM'), +('hours_sunday','Sun 9:00 AM - 12:00 PM'), +('payment_provider','mock'),('tax_provider','mock'),('address_provider','mock'), +('sms_provider','mock'),('email_provider','mock') +ON CONFLICT (key) DO NOTHING; + +CREATE TABLE IF NOT EXISTS mall_ai_result ( + id BIGSERIAL PRIMARY KEY, ai_type VARCHAR(60), prompt TEXT, result_json TEXT, model VARCHAR(60), + created_by VARCHAR(200), created_at TIMESTAMP DEFAULT NOW() +); + +-- --------------------------------------------------------------------------- +-- 1. 매장 (Stores) — 10+ 미국 매장 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_store ( + id BIGSERIAL PRIMARY KEY, code VARCHAR(40) UNIQUE NOT NULL, name VARCHAR(200) NOT NULL, + city VARCHAR(120), state VARCHAR(10), zip VARCHAR(10), address VARCHAR(400), + phone VARCHAR(40), timezone VARCHAR(60) DEFAULT 'America/New_York', + open_time VARCHAR(10) DEFAULT '09:00', close_time VARCHAR(10) DEFAULT '18:00', + same_day_cutoff VARCHAR(10) DEFAULT '12:00', -- 당일배송 마감 (매장 로컬타임) + delivery_radius_mi NUMERIC(6,2) DEFAULT 15.0, -- 배송 반경(마일) + daily_capacity INTEGER DEFAULT 50, -- 일일 처리 용량(주문수) + lat NUMERIC(10,6), lng NUMERIC(10,6), + active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT NOW() +); +-- 실데이터: Montvale Florist = 플래그십 1호점(id=1). 나머지는 트라이스테이트 확장 매장. +-- Montvale 운영시간/마감(당일배송): 월-금 9:00-17:30(마감 13:00=2PM 사이트표기 기준 보수적 1PM), 토 9:00-16:00(마감 12:00), 일 9:00-12:00(마감 10:00) +-- (id 명시: manager 계정 store_id=1 정합) +INSERT INTO mall_store (id, code, name, city, state, zip, address, phone, timezone, open_time, close_time, same_day_cutoff, delivery_radius_mi, daily_capacity, lat, lng) VALUES +(1,'MONTVALE','Montvale Florist','Montvale','NJ','07645','6 Railroad Ave','+1-201-690-6721','America/New_York','09:00','17:30','13:00',15.0,80,41.040800,-74.029900), +(2,'HACKENSACK','Montvale Florist — Hackensack','Hackensack','NJ','07601','120 Main St','+1-201-555-0102','America/New_York','09:00','17:30','13:00',12.0,60,40.885900,-74.043400), +(3,'PARAMUS','Montvale Florist — Paramus','Paramus','NJ','07652','201 Bergen Town Ctr','+1-201-555-0103','America/New_York','09:00','17:30','13:00',14.0,55,40.944500,-74.071500), +(4,'FORTLEE','Montvale Florist — Fort Lee','Fort Lee','NJ','07024','1605 Center Ave','+1-201-555-0104','America/New_York','09:00','17:30','13:00',12.0,50,40.850800,-73.970900), +(5,'ENGLEWOOD','Montvale Florist — Englewood','Englewood','NJ','07631','25 N Dean St','+1-201-555-0105','America/New_York','09:00','17:30','13:00',13.0,45,40.892900,-73.972700), +(6,'RIDGEWOOD','Montvale Florist — Ridgewood','Ridgewood','NJ','07450','10 E Ridgewood Ave','+1-201-555-0106','America/New_York','09:00','17:30','13:00',13.0,45,40.979500,-74.116600), +(7,'FAIRLAWN','Montvale Florist — Fair Lawn','Fair Lawn','NJ','07410','22-15 Broadway','+1-201-555-0107','America/New_York','09:00','17:30','13:00',12.0,40,40.940300,-74.131500), +(8,'TEANECK','Montvale Florist — Teaneck','Teaneck','NJ','07666','100 Cedar Ln','+1-201-555-0108','America/New_York','09:00','17:30','13:00',12.0,40,40.897700,-74.016000), +(9,'GARFIELD','Montvale Florist — Garfield','Garfield','NJ','07026','50 Outwater Ln','+1-973-555-0109','America/New_York','09:00','17:30','13:00',11.0,35,40.881400,-74.108500), +(10,'NYACK','Montvale Florist — Nyack (NY)','Nyack','NY','10960','30 S Broadway','+1-845-555-0110','America/New_York','09:00','17:30','13:00',14.0,40,41.090900,-73.917800), +(11,'NANUET','Montvale Florist — Nanuet (NY)','Nanuet','NY','10954','75 W Route 59','+1-845-555-0111','America/New_York','09:00','17:30','13:00',15.0,35,41.088600,-74.013700) +ON CONFLICT (code) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_store','id'), GREATEST((SELECT MAX(id) FROM mall_store),1)); + +-- --------------------------------------------------------------------------- +-- 2. 배송권역 (Delivery_Zones) — ZIP → 매장 매핑 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_zone ( + id BIGSERIAL PRIMARY KEY, store_id BIGINT NOT NULL, zip VARCHAR(10) NOT NULL, + city VARCHAR(120), state VARCHAR(10), radius_mi NUMERIC(6,2) DEFAULT 15.0, + surge_eligible BOOLEAN DEFAULT TRUE, active BOOLEAN DEFAULT TRUE +); +CREATE INDEX IF NOT EXISTS idx_mall_zone_zip ON mall_zone(zip); +-- 실데이터: Montvale Florist 무료배송 권역 (NJ 07010–07699, NY 10520–10994) +-- 대표 ZIP을 플래그십(1) + 트라이스테이트 확장 매장에 매핑. surge 기본 ON. +INSERT INTO mall_zone (store_id, zip, city, state, radius_mi) VALUES +-- 플래그십 Montvale & 인근 (Bergen County core) +(1,'07645','Montvale','NJ',15.0),(1,'07677','Woodcliff Lake','NJ',15.0),(1,'07675','Westwood','NJ',15.0), +(1,'07656','Park Ridge','NJ',15.0),(1,'07647','Northvale','NJ',15.0),(1,'07648','Norwood','NJ',15.0), +(1,'07646','New Milford','NJ',15.0),(1,'07627','Demarest','NJ',15.0),(1,'07620','Alpine','NJ',15.0), +-- Hackensack +(2,'07601','Hackensack','NJ',12.0),(2,'07602','Hackensack','NJ',12.0),(2,'07603','Bogota','NJ',12.0), +(2,'07606','South Hackensack','NJ',12.0), +-- Paramus +(3,'07652','Paramus','NJ',14.0),(3,'07653','Paramus','NJ',14.0),(3,'07663','Saddle Brook','NJ',14.0), +-- Fort Lee +(4,'07024','Fort Lee','NJ',12.0),(4,'07020','Edgewater','NJ',12.0),(4,'07010','Cliffside Park','NJ',12.0), +(4,'07022','Fairview','NJ',12.0), +-- Englewood +(5,'07631','Englewood','NJ',13.0),(5,'07632','Englewood Cliffs','NJ',13.0),(5,'07650','Palisades Park','NJ',13.0), +(5,'07666','Teaneck','NJ',13.0), +-- Ridgewood +(6,'07450','Ridgewood','NJ',13.0),(6,'07452','Glen Rock','NJ',13.0),(6,'07432','Midland Park','NJ',13.0), +(6,'07446','Ramsey','NJ',13.0),(6,'07401','Allendale','NJ',13.0), +-- Fair Lawn +(7,'07410','Fair Lawn','NJ',12.0),(7,'07470','Wayne','NJ',12.0),(7,'07012','Clifton','NJ',12.0), +-- Teaneck +(8,'07670','Tenafly','NJ',12.0),(8,'07621','Bergenfield','NJ',12.0),(8,'07624','Closter','NJ',12.0), +-- Garfield +(9,'07026','Garfield','NJ',11.0),(9,'07055','Passaic','NJ',11.0),(9,'07057','Wallington','NJ',11.0), +-- Nyack NY (Rockland) +(10,'10960','Nyack','NY',14.0),(10,'10994','West Nyack','NY',14.0),(10,'10989','Valley Cottage','NY',14.0), +(10,'10968','Piermont','NY',14.0),(10,'10520','Croton-on-Hudson','NY',14.0), +-- Nanuet NY (Rockland) +(11,'10954','Nanuet','NY',15.0),(11,'10901','Suffern','NY',15.0),(11,'10952','Monsey','NY',15.0), +(11,'10977','Spring Valley','NY',15.0),(11,'10956','New City','NY',15.0) +ON CONFLICT DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 2b. 배송지역 (Delivery Areas) — Montvale Florist 당일배송 68개 시(NJ) +-- 도시 단위(같은 당일배송 권역) + 대표 ZIP/좌표 → 최근접 매장 거리 계산 근거. +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_delivery_area ( + id BIGSERIAL PRIMARY KEY, + store_id BIGINT NOT NULL DEFAULT 1, -- 매핑 매장(Montvale 플래그십=1) + city VARCHAR(120) NOT NULL, + state VARCHAR(10) NOT NULL DEFAULT 'NJ', + zip VARCHAR(10), -- 대표 ZIP + lat NUMERIC(10,6), lng NUMERIC(10,6), -- 대표 좌표(시 중심) + same_day BOOLEAN DEFAULT TRUE, -- 동일(당일) 배송 표시 + active BOOLEAN DEFAULT TRUE, + CONSTRAINT uq_mall_delivery_area UNIQUE (city, state) +); +CREATE INDEX IF NOT EXISTS idx_mall_delivery_area_city ON mall_delivery_area(city); +CREATE INDEX IF NOT EXISTS idx_mall_delivery_area_zip ON mall_delivery_area(zip); +INSERT INTO mall_delivery_area (store_id, city, state, zip, lat, lng, same_day) VALUES +(1,'Allendale','NJ','07401',41.041400,-74.129400,TRUE),(1,'Alpine','NJ','07620',40.957000,-73.930900,TRUE), +(1,'Bergenfield','NJ','07621',40.927400,-73.997400,TRUE),(1,'Bogota','NJ','07603',40.875300,-74.029600,TRUE), +(1,'Carlstadt','NJ','07072',40.840300,-74.090300,TRUE),(1,'Cliffside Park','NJ','07010',40.821300,-73.987800,TRUE), +(1,'Closter','NJ','07624',40.973100,-73.961800,TRUE),(1,'Cresskill','NJ','07626',40.941900,-73.959700,TRUE), +(1,'Demarest','NJ','07627',40.957300,-73.962800,TRUE),(1,'Dumont','NJ','07628',40.940500,-73.992700,TRUE), +(1,'East Rutherford','NJ','07073',40.836700,-74.097900,TRUE),(1,'Edgewater','NJ','07020',40.827500,-73.974700,TRUE), +(1,'Elmwood Park','NJ','07407',40.904100,-74.118500,TRUE),(1,'Emerson','NJ','07630',40.976300,-74.026900,TRUE), +(1,'Englewood Cliffs','NJ','07632',40.886000,-73.952200,TRUE),(1,'Englewood','NJ','07631',40.892900,-73.972700,TRUE), +(1,'Fair Lawn','NJ','07410',40.940300,-74.131500,TRUE),(1,'Fairview','NJ','07022',40.811900,-74.001100,TRUE), +(1,'Fort Lee','NJ','07024',40.850800,-73.970900,TRUE),(1,'Franklin Lakes','NJ','07417',41.013800,-74.207300,TRUE), +(1,'Garfield','NJ','07026',40.881400,-74.108500,TRUE),(1,'Glen Rock','NJ','07452',40.962900,-74.132900,TRUE), +(1,'Hackensack','NJ','07601',40.885900,-74.043400,TRUE),(1,'Harrington Park','NJ','07640',40.985100,-73.980200,TRUE), +(1,'Hasbrouck Heights','NJ','07604',40.858500,-74.075000,TRUE),(1,'Haworth','NJ','07641',40.960600,-73.991200,TRUE), +(1,'Hillsdale','NJ','07642',41.000200,-74.040000,TRUE),(1,'Ho-Ho-Kus','NJ','07423',40.998900,-74.103200,TRUE), +(1,'Leonia','NJ','07605',40.862400,-73.989900,TRUE),(1,'Little Ferry','NJ','07643',40.851800,-74.040400,TRUE), +(1,'Lodi','NJ','07644',40.882600,-74.083100,TRUE),(1,'Lyndhurst','NJ','07071',40.812200,-74.124200,TRUE), +(1,'Mahwah','NJ','07430',41.087400,-74.159000,TRUE),(1,'Maywood','NJ','07607',40.902000,-74.061800,TRUE), +(1,'Midland Park','NJ','07432',40.989400,-74.142200,TRUE),(1,'Millburn','NJ','07041',40.725800,-74.302900,TRUE), +(1,'Montvale','NJ','07645',41.040800,-74.029900,TRUE),(1,'Moonachie','NJ','07074',40.842500,-74.046500,TRUE), +(1,'New Milford','NJ','07646',40.934700,-74.019100,TRUE),(1,'North Arlington','NJ','07031',40.788400,-74.133400,TRUE), +(1,'Northvale','NJ','07647',41.007400,-73.948300,TRUE),(1,'Norwood','NJ','07648',40.994400,-73.958800,TRUE), +(1,'Oakland','NJ','07436',41.029900,-74.265400,TRUE),(1,'Oradell','NJ','07649',40.955700,-74.034000,TRUE), +(1,'Palisades Park','NJ','07650',40.848200,-73.997300,TRUE),(1,'Paramus','NJ','07652',40.944500,-74.071500,TRUE), +(1,'Park Ridge','NJ','07656',41.038200,-74.041700,TRUE),(1,'Ramsey','NJ','07446',41.057300,-74.141100,TRUE), +(1,'Ridgefield Park','NJ','07660',40.857200,-74.022600,TRUE),(1,'Ridgefield','NJ','07657',40.832800,-74.001500,TRUE), +(1,'Ridgewood','NJ','07450',40.979500,-74.116600,TRUE),(1,'River Edge','NJ','07661',40.927300,-74.039600,TRUE), +(1,'Rochelle Park','NJ','07662',40.906900,-74.077800,TRUE),(1,'Rutherford','NJ','07070',40.826600,-74.106500,TRUE), +(1,'Saddle Brook','NJ','07663',40.902300,-74.092700,TRUE),(1,'Saddle River','NJ','07458',41.029900,-74.099500,TRUE), +(1,'Secaucus','NJ','07094',40.789000,-74.056500,TRUE),(1,'South Hackensack','NJ','07606',40.861700,-74.050900,TRUE), +(1,'Teaneck','NJ','07666',40.897700,-74.016000,TRUE),(1,'Tenafly','NJ','07670',40.925700,-73.962900,TRUE), +(1,'Teterboro','NJ','07608',40.857800,-74.060800,TRUE),(1,'Township Of Washington','NJ','07676',40.992000,-74.063000,TRUE), +(1,'Waldwick','NJ','07463',41.012000,-74.118600,TRUE),(1,'Wallington','NJ','07057',40.853100,-74.106000,TRUE), +(1,'Westwood','NJ','07675',40.991900,-74.032900,TRUE),(1,'Wood Ridge','NJ','07075',40.844700,-74.087500,TRUE), +(1,'Woodcliff Lake','NJ','07677',41.022300,-74.062700,TRUE),(1,'Wyckoff','NJ','07481',41.009600,-74.172600,TRUE) +ON CONFLICT (city, state) DO UPDATE + SET store_id=EXCLUDED.store_id, zip=EXCLUDED.zip, lat=EXCLUDED.lat, lng=EXCLUDED.lng, + same_day=EXCLUDED.same_day, active=TRUE; +-- 앱 계정 권한(소유자 postgres로 생성 시 대비) — 신규 테이블/시퀀스 한정 +DO $$ BEGIN + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname='mall_user') THEN + GRANT SELECT, INSERT, UPDATE, DELETE ON mall_delivery_area TO mall_user; + GRANT USAGE, SELECT ON SEQUENCE mall_delivery_area_id_seq TO mall_user; + END IF; +END $$; + +-- --------------------------------------------------------------------------- +-- 3. 카탈로그 / 상품 / 사이즈 / 옵션 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_category ( + id BIGSERIAL PRIMARY KEY, parent_id BIGINT, name VARCHAR(200) NOT NULL, code VARCHAR(60), + sort_order INTEGER DEFAULT 0, active BOOLEAN DEFAULT TRUE +); +-- 실데이터: Montvale Florist (montvalefloristnj.com) 카테고리 트리 +-- Occasions / Flower Type / Plants / Colors / Collections / Price Range +INSERT INTO mall_category (id, parent_id, name, code, sort_order) VALUES +-- 최상위 +(1,NULL,'Occasions','OCCASION',1),(2,NULL,'Flower Type','FLOWER',2), +(15,NULL,'Plants','PLANTS',3),(16,NULL,'Colors','COLOR',4), +(17,NULL,'Collections','COLLECTION',5),(18,NULL,'Price Range','PRICE',6), +-- Occasions +(3,1,'Birthday','BIRTHDAY',1),(4,1,'Anniversary','ANNIVERSARY',2),(5,1,'Sympathy & Funeral','SYMPATHY',3), +(6,1,'Get Well','GETWELL',4),(7,1,'Love & Romance','ROMANCE',5),(8,1,'Congratulations','CONGRATS',6), +(19,1,'Thinking of You','THINKING',7),(20,1,'Thank You','THANKYOU',8),(21,1,'Just Because','JUSTBECAUSE',9), +-- Flower Type +(9,2,'Roses','ROSES',1),(10,2,'Tulips','TULIPS',2),(11,2,'Lilies','LILIES',3), +(12,2,'Sunflowers','SUNFLOWERS',4),(13,2,'Hydrangeas','HYDRANGEAS',5),(14,2,'Mixed','MIXED',6), +-- Plants +(22,15,'Blooming Plants','BLOOMING_PLANTS',1),(23,15,'Green Plants','GREEN_PLANTS',2), +-- Colors +(24,16,'Red','RED',1),(25,16,'Pink','PINK',2),(26,16,'White','WHITE',3), +(27,16,'Purple','PURPLE',4),(28,16,'Yellow','YELLOW',5),(29,16,'Green','GREEN',6),(30,16,'Mixed','MIXED_COLOR',7), +-- Collections +(31,17,'Premium Collection','PREMIUM',1),(32,17,'Gift Baskets','GIFT_BASKETS',2), +(33,17,'Wedding','WEDDING',3),(34,17,'Custom Designs','CUSTOM',4),(35,17,'Florist''s Choice Daily Deal','DAILY_DEAL',5), +-- Price Range +(36,18,'Under $50','UNDER_50',1),(37,18,'$50 - $60','PR_50_60',2), +(38,18,'$60 - $80','PR_60_80',3),(39,18,'Over $80','OVER_80',4) +ON CONFLICT (id) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_category','id'), GREATEST((SELECT MAX(id) FROM mall_category),1)); + +-- 상품: 행사/꽃종류/유통기한/사이즈는 별도 테이블(mall_product_size) +CREATE TABLE IF NOT EXISTS mall_product ( + id BIGSERIAL PRIMARY KEY, category_id BIGINT, sku VARCHAR(80), name VARCHAR(300) NOT NULL, + brand VARCHAR(120), description TEXT, price NUMERIC(12,2) NOT NULL, sale_price NUMERIC(12,2), + status VARCHAR(30) DEFAULT 'ON_SALE', stock INTEGER DEFAULT 0, thumbnail VARCHAR(600), + occasion VARCHAR(60), -- BIRTHDAY/ANNIVERSARY/... + flower_type VARCHAR(60), -- ROSES/TULIPS/... + shelf_life_days INTEGER DEFAULT 5, -- 생화 시한성(유통기한 일수) + rating_avg NUMERIC(3,2) DEFAULT 0, review_count INTEGER DEFAULT 0, sales_count INTEGER DEFAULT 0, + created_at TIMESTAMP DEFAULT NOW() +); + +-- 3사이즈 (Original / Deluxe / Grand) — Bouqs 패턴 +CREATE TABLE IF NOT EXISTS mall_product_size ( + id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL, + size_code VARCHAR(20) NOT NULL, -- ORIGINAL / DELUXE / GRAND + label VARCHAR(60), price NUMERIC(12,2) NOT NULL, stem_count INTEGER, sort_order INTEGER DEFAULT 0 +); +CREATE INDEX IF NOT EXISTS idx_mall_psize_product ON mall_product_size(product_id); + +-- 옵션 (화병/카드메시지/포장) +CREATE TABLE IF NOT EXISTS mall_product_option ( + id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL, option_name VARCHAR(120), + option_value VARCHAR(200), extra_price NUMERIC(12,2) DEFAULT 0, stock INTEGER DEFAULT 0, + sku_suffix VARCHAR(60), option_type VARCHAR(40) -- VASE / CARD_MESSAGE / WRAP +); +CREATE TABLE IF NOT EXISTS mall_product_image ( + id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL, url VARCHAR(600), sort_order INTEGER DEFAULT 0, is_main BOOLEAN DEFAULT FALSE +); + +-- 실데이터: Montvale Florist 실상품(실명·실가) — image_url=/img/products/. +-- brand='Montvale Florist'. price = 사이트 표기 "From" 가격. 이미지는 backend static에서 그대로 서빙. +INSERT INTO mall_product (id, category_id, sku, name, brand, description, price, sale_price, status, stock, thumbnail, occasion, flower_type, shelf_life_days, rating_avg, review_count, sales_count) VALUES +(1,35,'MV-DAILY-DEAL','Florist''s Choice Daily Deal','Montvale Florist','Can''t decide? How about a surprise! A creative mix of seasonal blooms arranged with the designer''s freshest selection. Measures 10"-20" H (size will vary). 100% Florist-Designed and Hand-Delivered.',69.99,NULL,'ON_SALE',120,'/img/products/florists-choice-daily-deal.png','JUSTBECAUSE','MIXED',6,4.9,142,640), +(2,3,'MV-RADIANT-RAINBOW','Radiant Rainbow™','Montvale Florist','A vibrant, joyful arrangement bursting with a rainbow of seasonal blooms. Perfect for birthdays and any happy celebration.',79.95,NULL,'ON_SALE',90,'/img/products/radiant-rainbow.jpg','BIRTHDAY','MIXED',6,4.9,118,420), +(3,5,'MV-HALCYON-HEART','Halcyon Heart™','Montvale Florist','A serene, heartfelt tribute of soft blooms expressing peace, love, and remembrance.',79.95,NULL,'ON_SALE',60,'/img/products/halcyon-heart.jpg','SYMPATHY','MIXED',6,4.8,64,180), +(4,5,'MV-GRACEFUL-EMBRACE','Graceful Embrace','Montvale Florist','An elegant arrangement of gentle blooms offering comfort and a graceful embrace of sympathy.',79.95,NULL,'ON_SALE',55,'/img/products/graceful-embrace.jpg','SYMPATHY','MIXED',6,4.7,52,150), +(5,31,'MV-BLOOMING-DAYDREAM','Blooming Daydream','Montvale Florist','A premium, dreamy bouquet of lush garden blooms — a beautiful daydream brought to life.',99.95,NULL,'ON_SALE',45,'/img/products/blooming-daydream.jpg','ANNIVERSARY','MIXED',5,4.9,40,160), +(6,3,'MV-SPRING-SERENADE','Spring Serenade','Montvale Florist','A fresh, fragrant medley of spring flowers that sings of the season.',79.95,NULL,'ON_SALE',60,'/img/products/spring-serenade.jpg','BIRTHDAY','MIXED',5,4.7,38,140), +(7,23,'MV-GREEN-GRACE','Green Grace','Montvale Florist','A lush, verdant arrangement of greens and textured foliage — graceful and grounding.',99.95,NULL,'ON_SALE',40,'/img/products/green-grace.jpg','SYMPATHY','GREEN',7,4.8,30,110), +(8,9,'MV-12-RED-ROSES','12 Classic Red Roses','Montvale Florist','A timeless dozen of premium long-stemmed red roses — the ultimate expression of love.',99.95,NULL,'ON_SALE',100,'/img/products/classic-red-roses.jpg','ROMANCE','ROSES',6,4.9,210,720), +(9,20,'MV-JOYFUL-THANKS','Joyful Thanks™','Montvale Florist','A cheerful thank-you bouquet of bright seasonal blooms to express heartfelt gratitude.',59.95,NULL,'ON_SALE',80,'/img/products/joyful-thanks.jpg','THANKYOU','MIXED',6,4.6,58,210), +(10,31,'MV-BREATHTAKING-BEAUTY','Breathtaking Beauty™','Montvale Florist','A stunning premium arrangement of luxurious blooms that takes the breath away.',99.95,NULL,'ON_SALE',45,'/img/products/breathtaking-beauty.jpg','ROMANCE','MIXED',5,4.9,72,260), +(11,9,'MV-SWEETEST-ROSES','Sweetest Roses™','Montvale Florist','An opulent display of the sweetest premium roses — grand romance in full bloom.',199.99,NULL,'ON_SALE',25,'/img/products/sweetest-roses.jpg','ROMANCE','ROSES',6,5.0,44,120), +(12,32,'MV-FRUIT-BASKET','Fruit Basket','Montvale Florist','A bountiful gourmet fruit basket filled with fresh seasonal fruit — a wholesome, comforting gift.',99.95,NULL,'ON_SALE',40,'/img/products/fruit-basket.jpg','GETWELL','MIXED',10,4.6,33,140), +(13,13,'MV-HYDRANGEA-HIGHLIGHT','Hydrangea Highlight','Montvale Florist','Lush hydrangeas take center stage in this elegant, full-bodied arrangement.',79.95,NULL,'ON_SALE',45,'/img/products/hydrangea-highlight.jpg','BIRTHDAY','HYDRANGEAS',5,4.8,40,150), +(14,3,'MV-FULL-OF-SMILES','Full of Smiles','Montvale Florist','A bright, playful bouquet bursting with color to bring a smile to anyone''s day.',59.95,NULL,'ON_SALE',75,'/img/products/full-of-smiles.jpg','GETWELL','MIXED',6,4.6,71,260), +(15,35,'MV-FC-BIRTHDAY','Florist''s Choice for Birthday','Montvale Florist','Let our designer create a one-of-a-kind birthday arrangement with the freshest blooms of the day.',69.95,NULL,'ON_SALE',70,'/img/products/florists-choice-birthday.jpg','BIRTHDAY','MIXED',6,4.7,64,230), +(16,7,'MV-RASPBERRIES-BLISS','Raspberries & Bliss','Montvale Florist','A romantic blend of berry-toned blooms — pure blissful indulgence.',79.99,NULL,'ON_SALE',50,'/img/products/raspberries-and-bliss.jpg','ROMANCE','MIXED',6,4.7,32,120), +(17,31,'MV-MAGNIFICENT-MIDNIGHT','Magnificent Midnight','Montvale Florist','A dramatic premium arrangement of deep, moody blooms — magnificently bold.',199.95,NULL,'ON_SALE',25,'/img/products/magnificent-midnight.jpg','ANNIVERSARY','MIXED',5,4.9,28,90), +(18,31,'MV-FAIRY-BLOSSOM','Fairy Blossom Bouquet','Montvale Florist','A whimsical, ethereal bouquet of delicate blossoms — a touch of fairytale magic.',124.99,NULL,'ON_SALE',35,'/img/products/fairy-blossom-bouquet.jpg','ANNIVERSARY','MIXED',5,4.8,21,80), +(19,9,'MV-12-WHITE-ROSES','Dozen White Roses','Montvale Florist','A pristine dozen of premium white roses — pure elegance for any tribute or celebration.',99.95,NULL,'ON_SALE',70,'/img/products/dozen-white-roses.jpg','SYMPATHY','ROSES',6,4.8,55,200), +(20,9,'MV-LOVE-BRETT','Love Brett','Montvale Florist','A heartfelt rose arrangement designed to say "I love you" in the language of flowers.',99.95,NULL,'ON_SALE',45,'/img/products/love-brett.gif','ROMANCE','ROSES',6,4.6,18,60), +(21,9,'MV-SWEET-HONEY-KISSES','Sweet Honey Kisses','Montvale Florist','Warm honey and blush tones blend in this sweet, romantic rose bouquet.',79.95,NULL,'ON_SALE',50,'/img/products/sweet-honey-kisses.jpg','ROMANCE','ROSES',6,4.6,24,90), +(22,27,'MV-LAVENDER-LUST','Lavender Lust','Montvale Florist','A dreamy lavender-hued arrangement — soft, romantic, and utterly captivating.',79.95,NULL,'ON_SALE',45,'/img/products/lavender-lust.jpg','ROMANCE','MIXED',6,4.7,26,95), +(23,5,'MV-GARDEN-MEMORIES','Garden of Memories','Montvale Florist','A gentle garden-style arrangement honoring cherished memories with grace.',69.95,NULL,'ON_SALE',50,'/img/products/garden-of-memories.jpg','SYMPATHY','MIXED',6,4.7,30,110), +(24,11,'MV-TENDER-LILY-SPRAY','Tender Sentiments Lily Spray™','Montvale Florist','A graceful funeral lily spray expressing tender sentiments and deep sympathy.',159.95,NULL,'ON_SALE',20,'/img/products/tender-sentiments-lily-spray.jpg','SYMPATHY','LILIES',7,4.8,15,40), +(25,22,'MV-PEACE-LILY-PLANT','Peace Lily Plant','Montvale Florist','A lush, easy-care peace lily plant — a living symbol of peace and lasting remembrance.',79.95,NULL,'ON_SALE',55,'/img/products/peace-lily-plant.jpg','SYMPATHY','LILIES',30,4.8,42,160), +(26,32,'MV-TWILIGHT-BASKET','Love''s Twilight Sympathy Basket™','Montvale Florist','A serene basket of soft twilight blooms offering comfort and sympathy.',129.95,NULL,'ON_SALE',30,'/img/products/loves-twilight-sympathy-basket.jpg','SYMPATHY','MIXED',6,4.7,18,60), +(27,5,'MV-IN-LOVING-MEMORY','In Loving Memory','Montvale Florist','A dignified tribute arrangement crafted in loving memory of those dearly missed.',159.95,NULL,'ON_SALE',25,'/img/products/in-loving-memory.jpg','SYMPATHY','MIXED',6,4.8,22,70), +(28,32,'MV-AMETHYST-BASKET','Amethyst Sunset Sympathy Basket™','Montvale Florist','A rich basket of amethyst and sunset-toned blooms expressing heartfelt condolence.',129.95,NULL,'ON_SALE',28,'/img/products/amethyst-sunset-sympathy-basket.jpg','SYMPATHY','PURPLE',6,4.7,16,55), +(29,5,'MV-CALMING-COMFORT','Calming Comfort™','Montvale Florist','A soothing arrangement of soft pastel blooms offering calm and comfort in times of loss.',129.95,NULL,'ON_SALE',30,'/img/products/calming-comfort.jpg','SYMPATHY','MIXED',6,4.8,20,65), +(30,23,'MV-VERDANT-GARDENS','Verdant Gardens','Montvale Florist','A fresh, green garden arrangement full of lush foliage and natural texture.',79.95,NULL,'ON_SALE',45,'/img/products/verdant-gardens.jpg','SYMPATHY','GREEN',7,4.6,18,60), +(31,31,'MV-WITH-OPEN-HEARTS','With Open Hearts™','Montvale Florist','A grand, heartfelt premium tribute of abundant blooms offered with open hearts.',249.95,NULL,'ON_SALE',18,'/img/products/with-open-hearts.jpg','SYMPATHY','MIXED',6,4.9,12,40), +(32,7,'MV-STRAWBERRY-BLUSH','Strawberry Blush','Montvale Florist','A romantic blush-and-berry arrangement, sweet and softly captivating.',99.95,NULL,'ON_SALE',45,'/img/products/strawberry-blush.jpg','ROMANCE','PINK',6,4.7,24,85), +(33,35,'MV-FC-ROMANCE','Florist''s Choice for Romance','Montvale Florist','A designer''s romantic masterpiece, crafted with the most luxurious blooms of the day.',149.99,NULL,'ON_SALE',35,'/img/products/florists-choice-romance.jpg','ROMANCE','MIXED',6,4.8,20,70), +(34,7,'MV-DELIGHTFUL-DUALITY','Delightful Duality','Montvale Florist','A striking two-tone arrangement balancing bold and soft blooms in delightful harmony.',99.95,NULL,'ON_SALE',40,'/img/products/delightful-duality.jpg','ROMANCE','MIXED',6,4.7,19,65), +(35,31,'MV-NOTHING-COMPARES','Nothing Compares','Montvale Florist','An unrivaled premium arrangement of the rarest, most exquisite blooms — nothing compares.',299.95,NULL,'ON_SALE',15,'/img/products/nothing-compares.jpg','ROMANCE','MIXED',5,5.0,14,45), +(36,23,'MV-EMERALD-GARDEN','Emerald Garden','Montvale Florist','A rich emerald-green plant garden, lush and long-lasting.',119.95,NULL,'ON_SALE',30,'/img/products/emerald-garden.jpg','SYMPATHY','GREEN',30,4.7,17,55), +(37,5,'MV-FOREVER-SYMPATHY','Forever With Sympathy','Montvale Florist','A timeless sympathy arrangement of soft blooms expressing lasting condolence.',79.95,NULL,'ON_SALE',40,'/img/products/forever-with-sympathy.jpg','SYMPATHY','MIXED',6,4.6,16,55) +ON CONFLICT (id) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_product','id'), GREATEST((SELECT MAX(id) FROM mall_product),1)); + +-- 상품 메인 이미지 시드 (detail 갤러리) — thumbnail 경로를 main 이미지로 +INSERT INTO mall_product_image (product_id, url, sort_order, is_main) +SELECT p.id, p.thumbnail, 0, TRUE FROM mall_product p +WHERE p.thumbnail IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM mall_product_image i WHERE i.product_id=p.id); + +-- 3사이즈 시드 (모든 상품에 Original/Deluxe/Grand) +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'ORIGINAL','Original', p.price, 12, 1 FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='ORIGINAL'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'DELUXE','Deluxe', ROUND(p.price*1.4,2), 18, 2 FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='DELUXE'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'GRAND','Grand', ROUND(p.price*1.9,2), 24, 3 FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='GRAND'); + +-- 옵션 시드 (화병/카드/포장) +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Vase','Glass Vase Upgrade', 12.00, 999, 'VASE' FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='VASE'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Wrap','Premium Gift Wrap', 6.00, 999, 'WRAP' FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='WRAP'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Card','Personalized Card Message', 0.00, 999, 'CARD_MESSAGE' FROM mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='CARD_MESSAGE'); + +-- --------------------------------------------------------------------------- +-- 실데이터 보강: Montvale Florist any-occasion·sympathy 신규 상품 (id 38~70) +-- 크롤링: montvalefloristnj.com/any-occasion · /sympathy-and-funeral · /get-well +-- category_id: 5=Sympathy & Funeral, 6=Get Well. brand='Montvale Florist'. 이미지 캡쳐 그대로(/img/products/.jpg) +-- --------------------------------------------------------------------------- +INSERT INTO mall_product (id, category_id, sku, name, brand, description, price, sale_price, status, stock, thumbnail, occasion, flower_type, shelf_life_days, rating_avg, review_count, sales_count) VALUES +(38,6,'MV-EUROPEAN-TERRACE','European Terrace™','Montvale Florist','A lush European-style garden basket of blooming and green plants — a living terrace of natural beauty. 100% Florist-Designed and Hand-Delivered.',99.95,NULL,'ON_SALE',35,'/img/products/european-terrace.jpg','GETWELL','MIXED',7,4.80,34,120), +(39,5,'MV-FOND-REMEM-SPRAY','Fond Remembrance Standing Spray','Montvale Florist','A graceful funeral standing spray of soft blooms expressing fond remembrance and heartfelt sympathy.',159.95,NULL,'ON_SALE',35,'/img/products/fond-remembrance-standing-spray.jpg','SYMPATHY','MIXED',7,4.80,18,55), +(40,5,'MV-LAVENDER-MEM-SPRAY','Lavender Memories Spray™','Montvale Florist','A serene standing spray of lavender-hued blooms honoring cherished memories with grace and peace.',179.95,NULL,'ON_SALE',35,'/img/products/lavender-memories-spray.jpg','SYMPATHY','PURPLE',7,4.80,14,45), +(41,5,'MV-BRIGHT-MEMORIES','Bright Memories','Montvale Florist','A warm, uplifting tribute of bright seasonal blooms celebrating a life brightly lived.',129.95,NULL,'ON_SALE',35,'/img/products/bright-memories.jpg','SYMPATHY','MIXED',6,4.70,16,50), +(42,5,'MV-ADORING-TRIBUTE','Adoring Tribute','Montvale Florist','An adoring floral tribute of elegant blooms offered in loving honor and remembrance.',149.95,NULL,'ON_SALE',35,'/img/products/adoring-tribute.jpg','SYMPATHY','MIXED',6,4.80,12,40), +(43,5,'MV-SWEET-COMFORT','Sweet Comfort','Montvale Florist','A soothing arrangement of soft, sweet blooms offering comfort and solace in times of loss.',129.95,NULL,'ON_SALE',35,'/img/products/sweet-comfort.jpg','SYMPATHY','MIXED',6,4.70,15,48), +(44,5,'MV-JOYFUL-MEMORIES','Joyful Memories','Montvale Florist','A vibrant tribute of cheerful blooms celebrating the joyful memories of a treasured life.',129.95,NULL,'ON_SALE',35,'/img/products/joyful-memories.jpg','SYMPATHY','MIXED',6,4.70,13,42), +(45,5,'MV-PASSIONATE-FAITH','Passionate Faith Sympathy Wreath™','Montvale Florist','A dignified sympathy wreath of rich blooms expressing passionate faith and eternal devotion.',199.95,NULL,'ON_SALE',35,'/img/products/passionate-faith-sympathy-wreath.jpg','SYMPATHY','MIXED',7,4.80,10,32), +(46,5,'MV-SPIRITED-REMEM','Spirited Remembrance™','Montvale Florist','A spirited arrangement of lively blooms honoring a vibrant spirit and lasting remembrance.',129.95,NULL,'ON_SALE',35,'/img/products/spirited-remembrance.jpg','SYMPATHY','MIXED',6,4.70,14,44), +(47,5,'MV-FOND-REMEM-TRIBUTE','Fond Remembrance Tribute','Montvale Florist','A heartfelt tribute of gentle blooms expressing fond remembrance and deep sympathy.',129.95,NULL,'ON_SALE',35,'/img/products/fond-remembrance-tribute.jpg','SYMPATHY','MIXED',6,4.70,12,38), +(48,5,'MV-HEAVENS-PROMISE','Heaven''s Promise Sympathy Tribute™','Montvale Florist','A peaceful sympathy tribute of soft blooms evoking heaven''s promise of eternal peace.',129.95,NULL,'ON_SALE',35,'/img/products/heavens-promise-sympathy-tribute.jpg','SYMPATHY','MIXED',6,4.80,11,36), +(49,5,'MV-ENDURING-FAITH','Enduring Faith','Montvale Florist','A grand standing tribute of abundant blooms expressing enduring faith and steadfast love.',249.95,NULL,'ON_SALE',35,'/img/products/enduring-faith.jpg','SYMPATHY','MIXED',7,4.90,9,28), +(50,5,'MV-GENTLE-REPOSE','Gentle Repose Lily Spray™','Montvale Florist','A graceful lily standing spray offering gentle repose and serene, heartfelt condolence.',199.95,NULL,'ON_SALE',35,'/img/products/gentle-repose-lily-spray.jpg','SYMPATHY','LILIES',7,4.80,10,30), +(51,5,'MV-STARGAZER-WREATH','Stargazer Sentiments Wreath™','Montvale Florist','A striking sympathy wreath featuring stargazer lilies — a beautiful expression of heartfelt sentiments.',229.95,NULL,'ON_SALE',35,'/img/products/stargazer-sentiments-wreath.jpg','SYMPATHY','LILIES',7,4.80,8,26), +(52,5,'MV-WARM-REMEM','Warm Remembrance','Montvale Florist','A warm tribute of golden and amber blooms honoring a cherished life with heartfelt remembrance.',129.95,NULL,'ON_SALE',35,'/img/products/warm-remembrance.jpg','SYMPATHY','MIXED',6,4.70,13,41), +(53,5,'MV-SHADES-REMEM','Shades of Remembrance™','Montvale Florist','A tonal tribute of layered blooms in soft shades expressing tender remembrance and sympathy.',129.95,NULL,'ON_SALE',35,'/img/products/shades-of-remembrance.jpg','SYMPATHY','MIXED',6,4.70,12,39), +(54,5,'MV-TENDER-CASKET','Tender Sentiments Casket Spray™','Montvale Florist','An elegant casket spray of abundant blooms expressing the most tender sentiments and deep sympathy.',249.95,NULL,'ON_SALE',35,'/img/products/tender-sentiments-casket-spray.jpg','SYMPATHY','MIXED',7,4.90,9,27), +(55,5,'MV-FROM-THE-HEART','From the Heart','Montvale Florist','A sincere arrangement of heartfelt blooms offered straight from the heart in loving sympathy.',129.95,NULL,'ON_SALE',35,'/img/products/from-the-heart.jpg','SYMPATHY','MIXED',6,4.70,14,43), +(56,5,'MV-GARDEN-PATH','Garden Path Tribute','Montvale Florist','A natural garden-style tribute of soft blooms tracing a gentle path of remembrance.',129.95,NULL,'ON_SALE',35,'/img/products/garden-path-tribute.jpg','SYMPATHY','MIXED',6,4.70,11,37), +(57,5,'MV-HEAVENLY-HORIZONS','Heavenly Horizons Spray™','Montvale Florist','A serene standing spray of soft blooms evoking heavenly horizons and eternal peace.',179.95,NULL,'ON_SALE',35,'/img/products/heavenly-horizons-spray.jpg','SYMPATHY','MIXED',7,4.80,10,31), +(58,5,'MV-ROSY-HEART-WREATH','Rosy Remembrance Heart Wreath™','Montvale Florist','A heart-shaped sympathy wreath of roses and soft blooms — a rosy tribute of enduring love.',249.95,NULL,'ON_SALE',35,'/img/products/rosy-remembrance-heart-wreath.jpg','SYMPATHY','ROSES',6,4.90,8,25), +(59,5,'MV-LOVE-PRAYERS-CROSS','Love and Prayers Sympathy Cross™','Montvale Florist','A dignified sympathy cross of pristine blooms expressing love, faith, and heartfelt prayers.',229.95,NULL,'ON_SALE',35,'/img/products/love-and-prayers-sympathy-cross.jpg','SYMPATHY','MIXED',7,4.80,9,29), +(60,5,'MV-ENDURING-LOVE-WREATH','Enduring Love Wreath™','Montvale Florist','A grand sympathy wreath of abundant blooms symbolizing enduring, unbroken love and remembrance.',299.95,NULL,'ON_SALE',35,'/img/products/enduring-love-wreath.jpg','SYMPATHY','MIXED',7,4.90,7,22), +(61,5,'MV-SHINING-LIGHT','Shining Light Tribute','Montvale Florist','A radiant tribute of bright blooms honoring a shining light and a life that brightened many.',129.95,NULL,'ON_SALE',35,'/img/products/shining-light-tribute.jpg','SYMPATHY','MIXED',6,4.70,12,38), +(62,5,'MV-LOVING-THOUGHTS','Loving Thoughts Wreath','Montvale Florist','A classic sympathy wreath of soft blooms conveying loving thoughts and heartfelt condolence.',249.95,NULL,'ON_SALE',35,'/img/products/loving-thoughts-wreath.jpg','SYMPATHY','MIXED',7,4.80,8,24), +(63,5,'MV-SYMPATHETIC-HEART','Sympathetic Heart Standing Spray™','Montvale Florist','A heart-shaped standing spray of abundant blooms offering deep, sympathetic comfort.',279.95,NULL,'ON_SALE',35,'/img/products/sympathetic-heart-standing-spray.jpg','SYMPATHY','MIXED',7,4.90,7,21), +(64,5,'MV-INTO-OPEN-ARMS','Into Open Arms','Montvale Florist','A welcoming tribute of soft blooms embracing a loved one into open, eternal arms.',129.00,NULL,'ON_SALE',35,'/img/products/into-open-arms.jpg','SYMPATHY','MIXED',6,4.70,11,35), +(65,5,'MV-ENCIRCLED-LOVE','Encircled By Love™','Montvale Florist','A circular sympathy wreath of lush blooms expressing a love that encircles eternally.',249.95,NULL,'ON_SALE',35,'/img/products/encircled-by-love.jpg','SYMPATHY','MIXED',7,4.80,8,26), +(66,5,'MV-STARGAZER-CROSS','Stargazer Sympathies Cross™','Montvale Florist','A sympathy cross featuring stargazer lilies — a graceful expression of faith and sympathy.',229.95,NULL,'ON_SALE',35,'/img/products/stargazer-sympathies-cross.jpg','SYMPATHY','LILIES',7,4.80,8,25), +(67,5,'MV-ALWAYS-REMEM-SPRAY','Always Remembered Sympathy Spray™','Montvale Florist','A standing sympathy spray of soft blooms honoring a loved one always remembered.',199.95,NULL,'ON_SALE',35,'/img/products/always-remembered-sympathy-spray.jpg','SYMPATHY','MIXED',7,4.80,9,29), +(68,5,'MV-FOREVER-ADORED-CASKET','Forever Adored Casket Spray','Montvale Florist','A luxurious casket spray of abundant premium blooms honoring one forever adored.',329.95,NULL,'ON_SALE',35,'/img/products/forever-adored-casket-spray.jpg','SYMPATHY','MIXED',7,4.90,6,18), +(69,5,'MV-PASSIONATE-GRACE','Passionate Grace Wreath™','Montvale Florist','A sympathy wreath of rich, graceful blooms expressing passionate grace and devotion.',249.95,NULL,'ON_SALE',35,'/img/products/passionate-grace-wreath.jpg','SYMPATHY','MIXED',7,4.80,7,23), +(70,5,'MV-LOVES-REMEM-WREATH','Love''s Remembrance Wreath™','Montvale Florist','A grand sympathy wreath of abundant blooms expressing love''s lasting remembrance.',279.95,NULL,'ON_SALE',35,'/img/products/loves-remembrance-wreath.jpg','SYMPATHY','MIXED',7,4.90,6,20) +ON CONFLICT (id) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_product','id'), GREATEST((SELECT MAX(id) FROM mall_product),1)); + +-- 신규 상품(38~70) 메인 이미지/사이즈/옵션 +INSERT INTO mall_product_image (product_id, url, sort_order, is_main) +SELECT p.id, p.thumbnail, 0, TRUE FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND p.thumbnail IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM mall_product_image i WHERE i.product_id=p.id); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'ORIGINAL','Original', p.price, 12, 1 FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='ORIGINAL'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'DELUXE','Deluxe', ROUND(p.price*1.4,2), 18, 2 FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='DELUXE'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'GRAND','Grand', ROUND(p.price*1.9,2), 24, 3 FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='GRAND'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Vase','Glass Vase Upgrade', 12.00, 999, 'VASE' FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='VASE'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Wrap','Premium Gift Wrap', 6.00, 999, 'WRAP' FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='WRAP'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Card','Personalized Card Message', 0.00, 999, 'CARD_MESSAGE' FROM mall_product p +WHERE p.id BETWEEN 38 AND 70 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='CARD_MESSAGE'); + +-- --------------------------------------------------------------------------- +-- 실데이터 보강: Montvale Florist 시즌 디자이너 상품 (id 71~73) +-- 크롤링: montvalefloristnj.com /flowers-over-80 · /flowers-60-to-80 (전 카탈로그 대조 후 신규만) +-- brand='Montvale Florist'. 이미지 캡쳐 그대로(/img/products/., 원본 Cloudinary). price=사이트 Standard. +-- --------------------------------------------------------------------------- +INSERT INTO mall_product (id, category_id, sku, name, brand, description, price, sale_price, status, stock, thumbnail, occasion, flower_type, shelf_life_days, rating_avg, review_count, sales_count) VALUES +(71,31,'MV-MOTHERS-DAY-DESIGNER','Mother''s Day Designer Bouquet','Montvale Florist','Give this truly special gift to the woman who has done so much. Using only the freshest and most beautiful flowers, our experts will create a one-of-a-kind arrangement just for her. Mom''s gorgeous flowers will include the designer''s choice of fresh blooms. Measures 10"-20" H (size will vary). 100% Florist-Designed and Hand-Delivered.',249.95,NULL,'ON_SALE',30,'/img/products/mothers-day-designer-bouquet.png','ANNIVERSARY','MIXED',6,4.00,3,40), +(72,7,'MV-VALENTINES-SPECIAL','Valentine''s Day Special Bouquet','Montvale Florist','Your Valentine deserves the best. And nothing says "I love you" like a one-of-a-kind bouquet. Just leave it up to our floral designers — they''ll select from our most beautiful blooms to create a romantic showstopper for your sweetheart. Your special arrangement will include the designer''s choice of fresh blooms. Measures 10"-20" H (size will vary).',399.99,NULL,'ON_SALE',20,'/img/products/valentines-day-special-bouquet.png','ROMANCE','MIXED',6,5.00,3,60), +(73,35,'MV-VERY-MERRY-XMAS','Very Merry Christmas Artist''s Design','Montvale Florist','Celebrate the season with a festive holiday arrangement personally crafted by our designers using the designer''s choice of fresh seasonal blooms. Each Very Merry Christmas design is uniquely arranged for your recipient with Christmassy cheer. Measures 10"-20" H (size will vary).',79.95,NULL,'ON_SALE',45,'/img/products/very-merry-christmas-artists-design.jpg','JUSTBECAUSE','MIXED',6,5.00,3,80) +ON CONFLICT (id) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_product','id'), GREATEST((SELECT MAX(id) FROM mall_product),1)); + +INSERT INTO mall_product_image (product_id, url, sort_order, is_main) +SELECT p.id, p.thumbnail, 0, TRUE FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND p.thumbnail IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM mall_product_image i WHERE i.product_id=p.id); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'ORIGINAL','Standard', p.price, 12, 1 FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='ORIGINAL'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'DELUXE','Deluxe', ROUND(p.price*1.4,2), 18, 2 FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='DELUXE'); +INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) +SELECT p.id, 'GRAND','Premium', ROUND(p.price*1.9,2), 24, 3 FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_size s WHERE s.product_id=p.id AND s.size_code='GRAND'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Vase','Glass Vase Upgrade', 12.00, 999, 'VASE' FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='VASE'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Wrap','Premium Gift Wrap', 6.00, 999, 'WRAP' FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='WRAP'); +INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, option_type) +SELECT p.id, 'Card','Personalized Card Message', 0.00, 999, 'CARD_MESSAGE' FROM mall_product p +WHERE p.id BETWEEN 71 AND 73 AND NOT EXISTS (SELECT 1 FROM mall_product_option o WHERE o.product_id=p.id AND o.option_type='CARD_MESSAGE'); + +-- --------------------------------------------------------------------------- +-- 4. 매장별 재고 ON/OFF (Store_Inventory) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_store_inventory ( + id BIGSERIAL PRIMARY KEY, store_id BIGINT NOT NULL, product_id BIGINT NOT NULL, + available BOOLEAN DEFAULT TRUE, -- 당일 입고 ON/OFF + on_hand INTEGER DEFAULT 0, + updated_by VARCHAR(200), updated_at TIMESTAMP DEFAULT NOW(), + UNIQUE(store_id, product_id) +); +CREATE INDEX IF NOT EXISTS idx_mall_sinv_store ON mall_store_inventory(store_id); +-- 모든 매장 × 모든 상품 = 가용(ON) 기본 시드 +INSERT INTO mall_store_inventory (store_id, product_id, available, on_hand) +SELECT s.id, p.id, TRUE, 25 FROM mall_store s CROSS JOIN mall_product p +WHERE NOT EXISTS (SELECT 1 FROM mall_store_inventory si WHERE si.store_id=s.id AND si.product_id=p.id); + +-- 단일 재고 (옵션 없는 ERP 동기 — 기존 호환) +CREATE TABLE IF NOT EXISTS mall_inventory ( + id BIGSERIAL PRIMARY KEY, product_id BIGINT, option_id BIGINT, sku VARCHAR(80), + on_hand INTEGER DEFAULT 0, reserved INTEGER DEFAULT 0, safety_stock INTEGER DEFAULT 0, + erp_sync_status VARCHAR(20) DEFAULT 'NONE', updated_at TIMESTAMP DEFAULT NOW() +); + +-- --------------------------------------------------------------------------- +-- 5. 스케줄링 (타임슬롯·당일마감·공휴일 블록아웃·서지프라이싱) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_schedule_slot ( + id BIGSERIAL PRIMARY KEY, store_id BIGINT NOT NULL, slot_date DATE NOT NULL, + slot_label VARCHAR(60) NOT NULL, -- 'Morning 9-12', 'Afternoon 12-3', 'Evening 3-6' + start_time VARCHAR(10), end_time VARCHAR(10), + capacity INTEGER DEFAULT 20, booked INTEGER DEFAULT 0, + surge_multiplier NUMERIC(4,2) DEFAULT 1.00, -- 서지프라이싱 배수 + active BOOLEAN DEFAULT TRUE +); +CREATE INDEX IF NOT EXISTS idx_mall_slot_store_date ON mall_schedule_slot(store_id, slot_date); + +-- 공휴일 블록아웃 + 서지 (밸런타인/어머니날) +CREATE TABLE IF NOT EXISTS mall_holiday ( + id BIGSERIAL PRIMARY KEY, holiday_date DATE NOT NULL, name VARCHAR(120), + blocked BOOLEAN DEFAULT FALSE, -- 주문 차단 + surge_multiplier NUMERIC(4,2) DEFAULT 1.00, + store_id BIGINT, -- NULL=전 매장 + UNIQUE(holiday_date, store_id) +); +INSERT INTO mall_holiday (holiday_date, name, blocked, surge_multiplier, store_id) VALUES +('2026-02-14','Valentine''s Day', FALSE, 1.50, NULL), +('2026-05-10','Mother''s Day', FALSE, 1.40, NULL), +('2026-12-25','Christmas Day', TRUE, 1.00, NULL) +ON CONFLICT (holiday_date, store_id) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 6. 장바구니 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_cart_item ( + id BIGSERIAL PRIMARY KEY, owner VARCHAR(200) NOT NULL, product_id BIGINT, option_id BIGINT, + size_code VARCHAR(20), product_name VARCHAR(300), option_label VARCHAR(200), + unit_price NUMERIC(12,2), quantity INTEGER DEFAULT 1, + card_message VARCHAR(500), created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_cart_owner ON mall_cart_item(owner); + +-- --------------------------------------------------------------------------- +-- 7. 주문 (로컬배송 vs 매장픽업, 예약 날짜·슬롯) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_order ( + id BIGSERIAL PRIMARY KEY, order_no VARCHAR(40) UNIQUE NOT NULL, owner VARCHAR(200) NOT NULL, + store_id BIGINT, -- 처리 매장 + fulfillment_type VARCHAR(20) DEFAULT 'DELIVERY', -- DELIVERY / PICKUP + status VARCHAR(30) DEFAULT 'PENDING', + total_amount NUMERIC(12,2), discount_amount NUMERIC(12,2) DEFAULT 0, + tax_amount NUMERIC(12,2) DEFAULT 0, surge_amount NUMERIC(12,2) DEFAULT 0, + pay_amount NUMERIC(12,2), + receiver_name VARCHAR(200), receiver_phone VARCHAR(60), address VARCHAR(600), + delivery_zip VARCHAR(10), + scheduled_date DATE, slot_id BIGINT, slot_label VARCHAR(60), + card_message VARCHAR(500), memo VARCHAR(500), coupon_id BIGINT, + proof_photo_url VARCHAR(600), -- 꽃사진(제작완료) Proof of Quality + pod_photo_url VARCHAR(600), -- 문앞사진 Proof of Delivery + created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_order_store ON mall_order(store_id); +CREATE INDEX IF NOT EXISTS idx_mall_order_status ON mall_order(status); + +CREATE TABLE IF NOT EXISTS mall_order_item ( + id BIGSERIAL PRIMARY KEY, order_id BIGINT NOT NULL, product_id BIGINT, option_id BIGINT, + size_code VARCHAR(20), product_name VARCHAR(300), option_label VARCHAR(200), + unit_price NUMERIC(12,2), quantity INTEGER, line_amount NUMERIC(12,2) +); + +-- --------------------------------------------------------------------------- +-- 8. 결제 (민감정보 AES 암호화 *_enc) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_payment ( + id BIGSERIAL PRIMARY KEY, order_id BIGINT, method VARCHAR(40), pg_tid VARCHAR(120), + amount NUMERIC(12,2), status VARCHAR(30) DEFAULT 'READY', + card_no_enc VARCHAR(500), account_no_enc VARCHAR(500), + vbank_no VARCHAR(60), vbank_bank VARCHAR(80), + paid_at TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() +); + +-- --------------------------------------------------------------------------- +-- 9. 구독 (주간/격주/월간) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_subscription ( + id BIGSERIAL PRIMARY KEY, owner VARCHAR(200) NOT NULL, store_id BIGINT, product_id BIGINT, + size_code VARCHAR(20), frequency VARCHAR(20) DEFAULT 'WEEKLY', -- WEEKLY/BIWEEKLY/MONTHLY + delivery_zip VARCHAR(10), address VARCHAR(600), receiver_name VARCHAR(200), receiver_phone VARCHAR(60), + next_delivery_date DATE, status VARCHAR(20) DEFAULT 'ACTIVE', -- ACTIVE/PAUSED/CANCELLED + price NUMERIC(12,2), created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_sub_owner ON mall_subscription(owner); + +-- --------------------------------------------------------------------------- +-- 10. 매장간 재고 이양 (Transfer) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_transfer ( + id BIGSERIAL PRIMARY KEY, from_store_id BIGINT NOT NULL, to_store_id BIGINT NOT NULL, + product_id BIGINT NOT NULL, quantity INTEGER NOT NULL, + status VARCHAR(20) DEFAULT 'REQUESTED', -- REQUESTED/APPROVED/REJECTED/COMPLETED + requested_by VARCHAR(200), approved_by VARCHAR(200), reason VARCHAR(400), + ai_recommended BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() +); + +-- --------------------------------------------------------------------------- +-- 11. 배송 / 기사 라우팅 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_delivery ( + id BIGSERIAL PRIMARY KEY, order_id BIGINT, store_id BIGINT, + carrier VARCHAR(120), tracking_no VARCHAR(120), + driver_name VARCHAR(120), driver_phone VARCHAR(60), + status VARCHAR(30) DEFAULT 'READY', -- READY/IN_TRANSIT/OUT_FOR_DELIVERY/DELIVERED/FAILED + receiver_name VARCHAR(200), address VARCHAR(600), delivery_zip VARCHAR(10), + lat NUMERIC(10,6), lng NUMERIC(10,6), route_seq INTEGER, eta VARCHAR(40), pod_photo_url VARCHAR(600), + shipped_at TIMESTAMP, delivered_at TIMESTAMP, + created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() +); + +-- --------------------------------------------------------------------------- +-- 12. 리뷰 / 회원 / CS / 찜 +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_review ( + id BIGSERIAL PRIMARY KEY, product_id BIGINT, order_id BIGINT, author VARCHAR(200), + rating INTEGER, title VARCHAR(300), content TEXT, image_url VARCHAR(600), + helpful_count INTEGER DEFAULT 0, store_id BIGINT, created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_review_product ON mall_review(product_id); +INSERT INTO mall_review (product_id, author, rating, title, content, store_id) VALUES +(8,'jane',5,'Stunning red roses','A perfect classic dozen — arrived fresh and beautifully arranged. My wife loved them!',1), +(2,'jane',5,'So radiant!','The Radiant Rainbow lived up to its name — vibrant and full of life.',1), +(1,'jane',5,'Best surprise','The Florist''s Choice Daily Deal was even prettier than I imagined. Trust the designers!',1), +(14,'jane',4,'Brought a smile','Full of Smiles really did brighten the whole room.',1) +ON CONFLICT DO NOTHING; + +-- 실데이터: Montvale Florist 상품 상세 페이지 실제 고객 리뷰 (Lovingly 검증 리뷰, montvalefloristnj.com) +-- 멱등: 동일 (product_id, author, content) 존재 시 INSERT 생략. store_id=1. created_at=사이트 표기일. +DO $$ +DECLARE r RECORD; +BEGIN + FOR r IN + SELECT * FROM (VALUES + ('Florist''s Choice Daily Deal','Natalie',5,'absolutely wonderful! i''ve been ordering bouquets for my mom''s birthday every year from here and they''ve always delivered the most beautiful flowers. thank you montvale florist!','2025-09-30'), + ('Florist''s Choice Daily Deal','Nickoletta',5,'Beautiful, fresh flowers and excellent customer service - thank you!','2025-07-02'), + ('Florist''s Choice Daily Deal','Maria',5,'Flowers were very fresh and beautifully arranged. Never disappointed with my orders! Great florist- I''ll continue to use them!','2025-03-29'), + ('Radiant Rainbow™','shilpa',5,'Flowers are beautiful!! Staff is always wonderful!! This is the place to go in Bergen County!','2026-03-27'), + ('Radiant Rainbow™','Anonymous',5,'Excellent prompt same day service. Like ordering a pizza to be delivered. Great job!','2026-03-04'), + ('Radiant Rainbow™','James',5,'It was so easy to work online with Montvale Florist. Great selection, Great delivery. Overall very pleased. Thank you.','2025-09-14'), + ('12 Classic Red Roses','Robert',5,'They were absolutely beautiful!','2026-02-19'), + ('12 Classic Red Roses','Louis',5,'The roses and style of arrangement with Baby Breathe was perfect. The delivery time was also perfect... thanks again','2026-02-18'), + ('12 Classic Red Roses','Dave',5,'Once again you ''delivered''- the red roses are spectacular! My girlfriend Sarah loved the bouquet!','2025-05-28'), + ('Breathtaking Beauty™','Nikki',5,'I ordered flowers for my moms birthday and they are absolutely gorgeous and the vase itself is stunning. We couldn''t believe how big the arrangement was! Exceeded expectations and will be ordering again.','2026-03-28'), + ('Breathtaking Beauty™','Kathy',5,'Our Aunt Joan loved the flowers and said they were beautiful!!','2026-03-02'), + ('Breathtaking Beauty™','Gaddy',5,'Absolutely beautiful arrangements and exceptional service! I ordered a birthday bouquet for my wife from Montvale Florist, and they went above and beyond. The arrangement was stunning, fresh, vibrant, and full of color. It''s not just flowers, it''s an experience. I''ll definitely be ordering from them again for every special occasion.','2025-11-13'), + ('Full of Smiles','Karen',5,'Very good service. Flowers looked beautiful and were delivered on time.','2018-03-13'), + ('Full of Smiles','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Full of Smiles','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Dozen White Roses','Kate',5,'So happy with Montvale Florist and the beautiful white roses delivered for my grandmother''s wake. Easy to work with and happy with the results. Would recommend!','2021-12-19'), + ('Dozen White Roses','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Dozen White Roses','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Blooming Daydream','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Blooming Daydream','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Blooming Daydream','Linda',5,'Fiftieth Anniversary bouquet stunning and delivered right on time.','2026-04-20'), + ('Halcyon Heart™','Brittany',5,'great experience ordering from here! was super easy and quick .. will definitely repeat.. my sister loved the flowers too they look super duper beautiful!! thanks for making gift-giving easy :D -britt','2022-08-31'), + ('Halcyon Heart™','Jody',5,'Five stars! Thank you so much! You hit this one out the park!','2022-01-15'), + ('Halcyon Heart™','Josette',5,'My People said they were beautiful thank you for a great job I will be happy to use you again','2021-05-25'), + ('Peace Lily Plant','Roseann',5,'Exceeded expectations - great work!','2020-05-28'), + ('Peace Lily Plant','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Peace Lily Plant','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Joyful Thanks™','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Joyful Thanks™','Maria',5,'absolutely gorgeous flowers. helpful staff.','2026-02-26'), + ('Joyful Thanks™','Susan',5,'She said they were absolutely gorgeous ! Thank you!','2024-08-21'), + ('Spring Serenade','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Spring Serenade','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Spring Serenade','Linda',5,'Fiftieth Anniversary bouquet stunning and delivered right on time.','2026-04-20'), + ('Sweetest Roses™','JosephCallahan',5,'Joe and his staff have once again done a fantastic job creating a beautiful piece. I highly recommend Montvale Florist','2025-08-31'), + ('Sweetest Roses™','Joseph',5,'Everything was perfect and looked even better than we could have imagined. You did the most amazing job and can''t thank you enough.','2023-09-01'), + ('Sweetest Roses™','Joseph',5,'All I can say is ''Wow'' My girlfriend loved her flowers. She sent me a picture right away, and they were gorgeous. I called at 1130 am, and they were delivered. Great job!!!','2023-06-17'), + ('Strawberry Blush','Judith',5,'The flowers were beautiful as usual. We love your arrangements!','2022-05-03'), + ('Strawberry Blush','Roxanne',5,'Yes princess kim was very happy! I will continue to use Montvale florist! I give you five stars. Thanks again foxy','2022-04-19'), + ('Strawberry Blush','Joan',5,'she loved her flowers and I loved that you were able to get them to her so quickly. thanks again.','2021-12-26'), + ('Hydrangea Highlight','Judith',5,'Yes she did those are her favorite flowers Next week I''ll be ordering for Christmas you guys are so great thank you','2025-12-19'), + ('Hydrangea Highlight','Mamie',5,'The lovely floral arrangement that I chose for delivery from their website was spot on. I live out of state and often with online floral orders you may not get what you ordered. Montvale Florist proved to be trustworthy. I was so pleased and so was the recipient!','2021-10-14'), + ('Hydrangea Highlight','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Green Grace','Ethan',5,'Thank you for your fast and wonderful service. I ordered a plant arrangement for my family who moved into their new home and it came within hours of the order fresh and lovely arranged. Thank you.','2026-01-31'), + ('Green Grace','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Green Grace','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Graceful Embrace','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Graceful Embrace','Tracey',5,'Thank you arrangement was lovely and delivered same day! Will definitely order from here again!','2024-07-31'), + ('Graceful Embrace','Kristine',5,'Highly recommend. Delivered a beautiful flower arrangement on short notice.','2023-06-17'), + ('In Loving Memory','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('In Loving Memory','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('In Loving Memory','Linda',5,'Fiftieth Anniversary bouquet stunning and delivered right on time.','2026-04-20'), + ('Lavender Lust','Andrew',5,'Timely delivery, beautiful flowers!','2024-02-18'), + ('Lavender Lust','Barbara',5,'Flowers were delivered on time and were beautiful. My cousin was delighted with the arrangement.','2026-05-13'), + ('Lavender Lust','Patricia',5,'My daughter in law loved the arrangement. Thank you so much.','2026-05-13'), + ('Mother''s Day Designer Bouquet','Joseph',5,'I would like to thank you for such an excellent service that you provided as florist for our big day. Your arrangements blew us away. Thank you so much as it was an amazing surprise and they were delivered on time as I asked for.','2023-05-12'), + ('Mother''s Day Designer Bouquet','Christian',5,'Very good.','2022-05-21'), + ('Mother''s Day Designer Bouquet','Josh',2,'I was disappointed by this bouquet. I spent on the deluxe version of the Mother''s Day Designer bouquet, and what was delivered was a smaller bouquet than expected. Customer service confirmed it was their Deluxe size.','2022-05-11'), + ('Valentine''s Day Special Bouquet','Stephan',5,'Valentine gifts was great my girl loved the flowers & chocolate','2024-02-19'), + ('Valentine''s Day Special Bouquet','Joseph',5,'I want to thank you for the excellent service that you provided as a florist for surprising my love. Your arrangements blew us away. The arrangement looked beautiful, and everything you did looked magical. Thank you for helping us make our day so perfect.','2024-01-17'), + ('Valentine''s Day Special Bouquet','Annalise',5,'Montvale florist always makes the most beautiful arrangements. They have always been reliable and accommodating. Everyone we have encountered who works there is friendly and hardworking. I am very pleased with the service.','2023-02-18'), + ('Very Merry Christmas Artist''s Design','David',5,'My mom loved the Christmas flower arrangement you delivered! We weren''t able to celebrate with her due to Covid, but your arrangement let her know we were thinking about her, thank you!','2020-12-30'), + ('Very Merry Christmas Artist''s Design','Jan',5,'Thank you for the lovely flowers you did for our family friends in New Jersey they were very nice and Christmassy','2020-12-26'), + ('Very Merry Christmas Artist''s Design','Karen',5,'Flowers were beautiful! I''ll definitely order from them again. Great job!!!','2020-12-25') + ) AS t(pname, author, rating, content, rdate) + LOOP + INSERT INTO mall_review (product_id, author, rating, title, content, store_id, created_at) + SELECT p.id, r.author, r.rating, NULL, r.content, 1, r.rdate::timestamp + FROM mall_product p + WHERE p.name = r.pname + AND NOT EXISTS (SELECT 1 FROM mall_review v WHERE v.product_id=p.id AND v.author=r.author AND v.content=r.content); + END LOOP; +END $$; + +-- 리뷰에 맞춰 상품 통계 갱신: 기존(1~70) review_count는 마케팅 집계 수치 → 실제행수가 클 때만 상향, 신규(71~73)는 실제값. +UPDATE mall_product p SET + review_count = CASE WHEN p.id BETWEEN 71 AND 73 THEN sub.cnt ELSE GREATEST(p.review_count, sub.cnt) END, + rating_avg = sub.avg_rating +FROM (SELECT product_id, COUNT(*) AS cnt, ROUND(AVG(rating)::numeric,2) AS avg_rating FROM mall_review GROUP BY product_id) sub +WHERE p.id = sub.product_id; + +CREATE TABLE IF NOT EXISTS mall_member ( + id BIGSERIAL PRIMARY KEY, username VARCHAR(200) UNIQUE, display_name VARCHAR(200), + email VARCHAR(200), phone VARCHAR(60), default_zip VARCHAR(10), default_address VARCHAR(600), + crm_customer_key VARCHAR(120), tier VARCHAR(40) DEFAULT 'STANDARD', + created_at TIMESTAMP DEFAULT NOW() +); +INSERT INTO mall_member (username, display_name, email, default_zip) VALUES +('jane','Jane Doe','jane@example.com','07645') ON CONFLICT (username) DO NOTHING; + +CREATE TABLE IF NOT EXISTS mall_cs_ticket ( + id BIGSERIAL PRIMARY KEY, owner VARCHAR(200), order_no VARCHAR(40), category VARCHAR(60), + subject VARCHAR(300), content TEXT, status VARCHAR(20) DEFAULT 'OPEN', + itsm_sr_id VARCHAR(60), ai_reply TEXT, created_at TIMESTAMP DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS mall_wishlist ( + id BIGSERIAL PRIMARY KEY, owner VARCHAR(200) NOT NULL, product_id BIGINT NOT NULL, + created_at TIMESTAMP DEFAULT NOW(), UNIQUE(owner, product_id) +); + +-- --------------------------------------------------------------------------- +-- 13. 프로모션 (기존 호환) +-- --------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS mall_promotion ( + id BIGSERIAL PRIMARY KEY, title VARCHAR(300), banner VARCHAR(600), description TEXT, + category_id BIGINT, start_date DATE, end_date DATE, active BOOLEAN DEFAULT TRUE +); +CREATE TABLE IF NOT EXISTS mall_coupon ( + id BIGSERIAL PRIMARY KEY, code VARCHAR(60) UNIQUE, name VARCHAR(200), + discount_type VARCHAR(20) DEFAULT 'FIXED', discount_value NUMERIC(12,2), + min_order_amount NUMERIC(12,2) DEFAULT 0, max_discount NUMERIC(12,2), + valid_from DATE, valid_to DATE, issued_limit INTEGER, issued_count INTEGER DEFAULT 0, + active BOOLEAN DEFAULT TRUE +); +INSERT INTO mall_coupon (code, name, discount_type, discount_value, min_order_amount) VALUES +('WELCOME10','Welcome $10 Off','FIXED',10.00,50.00), +('SPRING15','Spring 15%','PERCENT',15.00,40.00) +ON CONFLICT (code) DO NOTHING; + +-- --------------------------------------------------------------------------- +-- 14. 등급별 고객관리 (Loyalty) — 등급기준·등급별 혜택·포인트 원장 +-- --------------------------------------------------------------------------- +-- 등급 기준(누적 구매액/주문수 임계). 자동 산정 시 12개월 누적값과 비교. +-- tier_code: BASIC / SILVER / GOLD / VIP (rank ASC = 낮은 등급) +CREATE TABLE IF NOT EXISTS mall_tier_benefit ( + id BIGSERIAL PRIMARY KEY, + tier_code VARCHAR(20) UNIQUE NOT NULL, -- BASIC/SILVER/GOLD/VIP + name VARCHAR(80) NOT NULL, + tier_rank INTEGER NOT NULL, -- 1=BASIC ... 4=VIP + min_spend_12m NUMERIC(12,2) DEFAULT 0, -- 등급 진입 누적 구매액(12개월) + min_orders_12m INTEGER DEFAULT 0, -- 등급 진입 누적 주문수(12개월) + discount_rate NUMERIC(5,2) DEFAULT 0, -- 등급 할인율(%) + free_ship_threshold NUMERIC(12,2), -- 무료배송 임계액(NULL=없음, 0=항상 무료) + point_earn_rate NUMERIC(5,2) DEFAULT 1.0, -- 포인트 적립률(% of pay_amount) + priority_slot BOOLEAN DEFAULT FALSE, -- 피크시즌 우선 타임슬롯 + birthday_coupon BOOLEAN DEFAULT FALSE, -- 생일 쿠폰/꽃 + exclusive_events BOOLEAN DEFAULT FALSE, -- 전용 이벤트 접근 + color VARCHAR(20), -- UI 배지 색상 + active BOOLEAN DEFAULT TRUE, updated_at TIMESTAMP DEFAULT NOW() +); +INSERT INTO mall_tier_benefit + (tier_code, name, tier_rank, min_spend_12m, min_orders_12m, discount_rate, free_ship_threshold, point_earn_rate, priority_slot, birthday_coupon, exclusive_events, color) VALUES +('BASIC','일반 (Basic)', 1, 0.00, 0, 0.00, NULL, 1.0, FALSE, FALSE, FALSE, '#9CA3AF'), +('SILVER','실버 (Silver)',2, 300.00, 3, 3.00, 75.00, 1.5, FALSE, TRUE, FALSE, '#94A3B8'), +('GOLD','골드 (Gold)', 3, 1000.00, 8, 5.00, 50.00, 2.0, TRUE, TRUE, TRUE, '#D4AF37'), +('VIP','VIP', 4, 3000.00,20, 8.00, 0.00, 3.0, TRUE, TRUE, TRUE, '#7C3AED') +ON CONFLICT (tier_code) DO NOTHING; + +-- 포인트 원장(ledger): 적립(EARN)/사용(USE)/만료(EXPIRE)/조정(ADJUST). 잔액=SUM(points). +CREATE TABLE IF NOT EXISTS mall_point_ledger ( + id BIGSERIAL PRIMARY KEY, owner VARCHAR(200) NOT NULL, + entry_type VARCHAR(20) NOT NULL, -- EARN/USE/EXPIRE/ADJUST + points INTEGER NOT NULL, -- 적립 +, 사용/만료 - + order_no VARCHAR(40), reason VARCHAR(300), + expire_at DATE, -- 적립분 만료일(EARN) + created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_point_owner ON mall_point_ledger(owner); + +-- --------------------------------------------------------------------------- +-- 15. 이벤트 / 캠페인 (Event) +-- --------------------------------------------------------------------------- +-- event_type: DISCOUNT/POINT_BONUS/GIFT/TIER_ONLY/SEASON +CREATE TABLE IF NOT EXISTS mall_event ( + id BIGSERIAL PRIMARY KEY, code VARCHAR(60) UNIQUE, title VARCHAR(300) NOT NULL, + event_type VARCHAR(30) DEFAULT 'DISCOUNT', + description TEXT, + start_date DATE, end_date DATE, + target_tiers VARCHAR(120), -- 콤마구분 등급코드(빈값=전체) 예: 'GOLD,VIP' + store_ids VARCHAR(200), -- 콤마구분 매장ID(빈값=전 매장/권역) + coupon_id BIGINT, -- 연계 쿠폰(이벤트 참여 시 발급) + bonus_point_rate NUMERIC(5,2), -- POINT_BONUS 추가 적립률(%) + gift_description VARCHAR(300), -- GIFT 사은품 설명 + status VARCHAR(20) DEFAULT 'DRAFT', -- DRAFT/PUBLISHED/ENDED + active BOOLEAN DEFAULT TRUE, + created_by VARCHAR(200), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_event_status ON mall_event(status); + +-- 스토어프론트 배너(이미지/문구/링크) +CREATE TABLE IF NOT EXISTS mall_event_banner ( + id BIGSERIAL PRIMARY KEY, event_id BIGINT NOT NULL, + image_url VARCHAR(600), headline VARCHAR(300), subtext VARCHAR(400), + link_url VARCHAR(600), sort_order INTEGER DEFAULT 0, active BOOLEAN DEFAULT TRUE +); +CREATE INDEX IF NOT EXISTS idx_mall_evtbanner_event ON mall_event_banner(event_id); + +-- 이벤트 참여 이력(성과 집계용) +CREATE TABLE IF NOT EXISTS mall_event_participation ( + id BIGSERIAL PRIMARY KEY, event_id BIGINT NOT NULL, owner VARCHAR(200) NOT NULL, + coupon_id BIGINT, order_no VARCHAR(40), reward VARCHAR(200), + created_at TIMESTAMP DEFAULT NOW() +); +CREATE INDEX IF NOT EXISTS idx_mall_evtpart_event ON mall_event_participation(event_id); + +-- 샘플 시즌 이벤트 시드 (밸런타인·어머니날) +INSERT INTO mall_event (id, code, title, event_type, description, start_date, end_date, target_tiers, coupon_id, bonus_point_rate, status, active, created_by) VALUES +(1,'VDAY2026','Valentine''s Day Bloom Sale','SEASON','Celebrate love with 15% off select bouquets.','2026-02-07','2026-02-14','', 2, NULL,'PUBLISHED',TRUE,'system'), +(2,'MDAY2026','Mother''s Day Special','SEASON','Honor Mom — bonus points + free delivery on Deluxe.','2026-05-03','2026-05-10','', NULL, 2.0,'PUBLISHED',TRUE,'system'), +(3,'VIPSPRING','VIP Spring Preview','TIER_ONLY','Exclusive early access for Gold & VIP members.','2026-03-01','2026-03-31','GOLD,VIP', NULL, NULL,'PUBLISHED',TRUE,'system') +ON CONFLICT (id) DO NOTHING; +SELECT setval(pg_get_serial_sequence('mall_event','id'), GREATEST((SELECT MAX(id) FROM mall_event),1)); + +INSERT INTO mall_event_banner (event_id, image_url, headline, subtext, link_url, sort_order) VALUES +(1,'/img/event-valentine.jpg','Valentine''s Day Bloom Sale','15% off romantic roses & more','/events/VDAY2026',1), +(2,'/img/event-mother.jpg','Mother''s Day Special','Bonus points + free delivery on Deluxe','/events/MDAY2026',1) +ON CONFLICT DO NOTHING; diff --git a/backend/target/classes/mapper/AdminUserMapper.xml b/backend/target/classes/mapper/AdminUserMapper.xml new file mode 100644 index 0000000..0279811 --- /dev/null +++ b/backend/target/classes/mapper/AdminUserMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + INSERT INTO mall_account (username, password_hash, role, display_name, is_active) + VALUES (#{username}, #{passwordHash}, #{role}, #{displayName}, #{active}) + + + UPDATE mall_account SET role = #{role} WHERE id = #{id} + UPDATE mall_account SET is_active = #{active} WHERE id = #{id} + UPDATE mall_account SET password_hash = #{passwordHash} WHERE id = #{id} + DELETE FROM mall_account WHERE id = #{id} + + + + + diff --git a/backend/target/classes/mapper/AnalyticsMapper.xml b/backend/target/classes/mapper/AnalyticsMapper.xml new file mode 100644 index 0000000..5bf8c40 --- /dev/null +++ b/backend/target/classes/mapper/AnalyticsMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/backend/target/classes/mapper/AuditLogMapper.xml b/backend/target/classes/mapper/AuditLogMapper.xml new file mode 100644 index 0000000..5d054fe --- /dev/null +++ b/backend/target/classes/mapper/AuditLogMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + INSERT INTO mall_audit_log (actor, action, target, detail) + VALUES (#{actor}, #{action}, #{target}, #{detail}) + + + + + diff --git a/backend/target/classes/mapper/CartMapper.xml b/backend/target/classes/mapper/CartMapper.xml new file mode 100644 index 0000000..8db80d4 --- /dev/null +++ b/backend/target/classes/mapper/CartMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + INSERT INTO mall_cart_item (owner, product_id, option_id, size_code, card_message, quantity) + VALUES (#{owner}, #{productId}, #{optionId}, #{sizeCode}, #{cardMessage}, COALESCE(#{quantity},1)) + + UPDATE mall_cart_item SET quantity = #{quantity} WHERE id = #{id} AND owner = #{owner} + DELETE FROM mall_cart_item WHERE id = #{id} AND owner = #{owner} + DELETE FROM mall_cart_item WHERE owner = #{owner} + diff --git a/backend/target/classes/mapper/CategoryMapper.xml b/backend/target/classes/mapper/CategoryMapper.xml new file mode 100644 index 0000000..4e8df76 --- /dev/null +++ b/backend/target/classes/mapper/CategoryMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + INSERT INTO mall_category (parent_id, name, code, sort_order, active) + VALUES (#{parentId}, #{name}, #{code}, COALESCE(#{sortOrder},0), COALESCE(#{active},TRUE)) + + + UPDATE mall_category SET parent_id=#{parentId}, name=#{name}, code=#{code}, + sort_order=COALESCE(#{sortOrder},sort_order), active=COALESCE(#{active},active) WHERE id=#{id} + + DELETE FROM mall_category WHERE id=#{id} + diff --git a/backend/target/classes/mapper/CsMapper.xml b/backend/target/classes/mapper/CsMapper.xml new file mode 100644 index 0000000..190af3a --- /dev/null +++ b/backend/target/classes/mapper/CsMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + INSERT INTO mall_cs_ticket (owner, order_no, category, subject, content, status) + VALUES (#{owner}, #{orderNo}, #{category}, #{subject}, #{content}, COALESCE(#{status},'OPEN')) + + UPDATE mall_cs_ticket SET itsm_sr_id = #{srId} WHERE id = #{id} + UPDATE mall_cs_ticket SET ai_reply = #{aiReply}, status = 'ANSWERED' WHERE id = #{id} + UPDATE mall_cs_ticket SET status = #{status} WHERE id = #{id} + diff --git a/backend/target/classes/mapper/DeliveryMapper.xml b/backend/target/classes/mapper/DeliveryMapper.xml new file mode 100644 index 0000000..2d45caf --- /dev/null +++ b/backend/target/classes/mapper/DeliveryMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + INSERT INTO mall_delivery (order_id, carrier, tracking_no, status, receiver_name, address, shipped_at) + VALUES (#{orderId}, #{carrier}, #{trackingNo}, COALESCE(#{status},'READY'), #{receiverName}, #{address}, #{shippedAt}) + + + UPDATE mall_delivery SET carrier=#{carrier}, tracking_no=#{trackingNo}, status=COALESCE(#{status},status), + receiver_name=#{receiverName}, address=#{address} WHERE id=#{id} + + + UPDATE mall_delivery SET status=#{status}, + shipped_at = CASE WHEN #{status}='IN_TRANSIT' AND shipped_at IS NULL THEN NOW() ELSE shipped_at END, + delivered_at = CASE WHEN #{status}='DELIVERED' THEN NOW() ELSE delivered_at END + WHERE id=#{id} + + diff --git a/backend/target/classes/mapper/EventMapper.xml b/backend/target/classes/mapper/EventMapper.xml new file mode 100644 index 0000000..29968e8 --- /dev/null +++ b/backend/target/classes/mapper/EventMapper.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + INSERT INTO mall_event + (code, title, event_type, description, start_date, end_date, target_tiers, store_ids, + coupon_id, bonus_point_rate, gift_description, status, active, created_by) + VALUES + (#{code}, #{title}, COALESCE(#{eventType},'DISCOUNT'), #{description}, #{startDate}, #{endDate}, + #{targetTiers}, #{storeIds}, #{couponId}, #{bonusPointRate}, #{giftDescription}, + COALESCE(#{status},'DRAFT'), COALESCE(#{active},TRUE), #{createdBy}) + + + UPDATE mall_event SET + title=#{title}, event_type=COALESCE(#{eventType},event_type), description=#{description}, + start_date=#{startDate}, end_date=#{endDate}, target_tiers=#{targetTiers}, store_ids=#{storeIds}, + coupon_id=#{couponId}, bonus_point_rate=#{bonusPointRate}, gift_description=#{giftDescription}, + status=COALESCE(#{status},status), active=COALESCE(#{active},active), updated_at=NOW() + WHERE id=#{id} + + UPDATE mall_event SET status=#{status}, updated_at=NOW() WHERE id=#{id} + DELETE FROM mall_event WHERE id=#{id} + + + + + + + INSERT INTO mall_event_banner (event_id, image_url, headline, subtext, link_url, sort_order, active) + VALUES (#{eventId}, #{imageUrl}, #{headline}, #{subtext}, #{linkUrl}, COALESCE(#{sortOrder},0), COALESCE(#{active},TRUE)) + + DELETE FROM mall_event_banner WHERE id=#{id} + DELETE FROM mall_event_banner WHERE event_id=#{eventId} + + + + INSERT INTO mall_event_participation (event_id, owner, coupon_id, order_no, reward) + VALUES (#{eventId}, #{owner}, #{couponId}, #{orderNo}, #{reward}) + + + + diff --git a/backend/target/classes/mapper/InventoryMapper.xml b/backend/target/classes/mapper/InventoryMapper.xml new file mode 100644 index 0000000..fc4e766 --- /dev/null +++ b/backend/target/classes/mapper/InventoryMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + INSERT INTO mall_inventory (product_id, option_id, sku, on_hand, reserved, safety_stock, erp_sync_status) + VALUES (#{productId}, #{optionId}, #{sku}, COALESCE(#{onHand},0), COALESCE(#{reserved},0), COALESCE(#{safetyStock},0), COALESCE(#{erpSyncStatus},'NONE')) + + UPDATE mall_inventory SET on_hand = GREATEST(COALESCE(on_hand,0) + #{delta}, 0), updated_at = NOW() WHERE id = #{id} + + UPDATE mall_inventory SET erp_sync_status = #{status}, + on_hand = COALESCE(#{onHand}, on_hand), updated_at = NOW() WHERE id = #{id} + + diff --git a/backend/target/classes/mapper/LoyaltyMapper.xml b/backend/target/classes/mapper/LoyaltyMapper.xml new file mode 100644 index 0000000..f1c66b6 --- /dev/null +++ b/backend/target/classes/mapper/LoyaltyMapper.xml @@ -0,0 +1,86 @@ + + + + + + + + + + INSERT INTO mall_tier_benefit + (tier_code, name, tier_rank, min_spend_12m, min_orders_12m, discount_rate, free_ship_threshold, + point_earn_rate, priority_slot, birthday_coupon, exclusive_events, color, active) + VALUES + (#{tierCode}, #{name}, #{tierRank}, COALESCE(#{minSpend12m},0), COALESCE(#{minOrders12m},0), + COALESCE(#{discountRate},0), #{freeShipThreshold}, COALESCE(#{pointEarnRate},1.0), + COALESCE(#{prioritySlot},FALSE), COALESCE(#{birthdayCoupon},FALSE), COALESCE(#{exclusiveEvents},FALSE), + #{color}, COALESCE(#{active},TRUE)) + + + UPDATE mall_tier_benefit SET + name=#{name}, tier_rank=#{tierRank}, + min_spend_12m=COALESCE(#{minSpend12m},min_spend_12m), + min_orders_12m=COALESCE(#{minOrders12m},min_orders_12m), + discount_rate=COALESCE(#{discountRate},discount_rate), + free_ship_threshold=#{freeShipThreshold}, + point_earn_rate=COALESCE(#{pointEarnRate},point_earn_rate), + priority_slot=COALESCE(#{prioritySlot},priority_slot), + birthday_coupon=COALESCE(#{birthdayCoupon},birthday_coupon), + exclusive_events=COALESCE(#{exclusiveEvents},exclusive_events), + color=#{color}, active=COALESCE(#{active},active), updated_at=NOW() + WHERE id=#{id} + + DELETE FROM mall_tier_benefit WHERE id=#{id} + + + + + + + UPDATE mall_member SET tier = #{tier} WHERE username = #{username} + + + + + + INSERT INTO mall_point_ledger (owner, entry_type, points, order_no, reason, expire_at) + VALUES (#{owner}, #{entryType}, #{points}, #{orderNo}, #{reason}, #{expireAt}) + + + + + + + + diff --git a/backend/target/classes/mapper/MemberMapper.xml b/backend/target/classes/mapper/MemberMapper.xml new file mode 100644 index 0000000..9430eb6 --- /dev/null +++ b/backend/target/classes/mapper/MemberMapper.xml @@ -0,0 +1,14 @@ + + + + + + INSERT INTO mall_member (username, display_name, email, phone, default_zip, default_address, crm_customer_key, tier) + VALUES (#{username}, #{displayName}, #{email}, #{phone}, #{defaultZip}, #{defaultAddress}, #{crmCustomerKey}, COALESCE(#{tier},'STANDARD')) + ON CONFLICT (username) DO UPDATE SET + display_name = EXCLUDED.display_name, email = EXCLUDED.email, phone = EXCLUDED.phone, + default_zip = EXCLUDED.default_zip, default_address = EXCLUDED.default_address + + diff --git a/backend/target/classes/mapper/OrderMapper.xml b/backend/target/classes/mapper/OrderMapper.xml new file mode 100644 index 0000000..c94c3ce --- /dev/null +++ b/backend/target/classes/mapper/OrderMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + INSERT INTO mall_order (order_no, owner, store_id, fulfillment_type, status, total_amount, discount_amount, + tax_amount, surge_amount, pay_amount, receiver_name, receiver_phone, address, delivery_zip, + scheduled_date, slot_id, slot_label, card_message, memo, coupon_id) + VALUES (#{orderNo}, #{owner}, #{storeId}, COALESCE(#{fulfillmentType},'DELIVERY'), COALESCE(#{status},'PENDING'), + #{totalAmount}, COALESCE(#{discountAmount},0), COALESCE(#{taxAmount},0), COALESCE(#{surgeAmount},0), + #{payAmount}, #{receiverName}, #{receiverPhone}, #{address}, #{deliveryZip}, + #{scheduledDate}, #{slotId}, #{slotLabel}, #{cardMessage}, #{memo}, #{couponId}) + + UPDATE mall_order SET status = #{status}, updated_at = NOW() WHERE id = #{id} + UPDATE mall_order SET proof_photo_url = #{url}, updated_at = NOW() WHERE id = #{id} + UPDATE mall_order SET pod_photo_url = #{url}, updated_at = NOW() WHERE id = #{id} + + + + INSERT INTO mall_order_item (order_id, product_id, option_id, size_code, product_name, option_label, unit_price, quantity, line_amount) + VALUES (#{orderId}, #{productId}, #{optionId}, #{sizeCode}, #{productName}, #{optionLabel}, #{unitPrice}, #{quantity}, #{lineAmount}) + + diff --git a/backend/target/classes/mapper/PaymentMapper.xml b/backend/target/classes/mapper/PaymentMapper.xml new file mode 100644 index 0000000..1c76c0e --- /dev/null +++ b/backend/target/classes/mapper/PaymentMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + INSERT INTO mall_payment (order_id, method, pg_tid, amount, status, card_no_enc, account_no_enc, vbank_no, vbank_bank, paid_at) + VALUES (#{orderId}, #{method}, #{pgTid}, #{amount}, COALESCE(#{status},'READY'), + #{cardNoEnc}, #{accountNoEnc}, #{vbankNo}, #{vbankBank}, #{paidAt}) + + UPDATE mall_payment SET status = #{status}, paid_at = CASE WHEN #{status}='PAID' THEN NOW() ELSE paid_at END WHERE id = #{id} + diff --git a/backend/target/classes/mapper/ProductMapper.xml b/backend/target/classes/mapper/ProductMapper.xml new file mode 100644 index 0000000..a601fe6 --- /dev/null +++ b/backend/target/classes/mapper/ProductMapper.xml @@ -0,0 +1,81 @@ + + + + + + + AND category_id = #{categoryId} + AND (name ILIKE '%' || #{keyword} || '%' OR brand ILIKE '%' || #{keyword} || '%' OR description ILIKE '%' || #{keyword} || '%') + AND status = #{status} + AND occasion = #{occasion} + AND flower_type = #{flowerType} + AND COALESCE(sale_price, price) <= #{maxPrice} + + + + + + + + + + + INSERT INTO mall_product (category_id, sku, name, brand, description, price, sale_price, status, stock, thumbnail, + occasion, flower_type, shelf_life_days) + VALUES (#{categoryId}, #{sku}, #{name}, #{brand}, #{description}, #{price}, #{salePrice}, + COALESCE(#{status},'ON_SALE'), COALESCE(#{stock},0), #{thumbnail}, + #{occasion}, #{flowerType}, COALESCE(#{shelfLifeDays},5)) + + + + UPDATE mall_product SET category_id=#{categoryId}, name=#{name}, brand=#{brand}, description=#{description}, + price=#{price}, sale_price=#{salePrice}, status=COALESCE(#{status},status), stock=COALESCE(#{stock},stock), + thumbnail=#{thumbnail}, occasion=COALESCE(#{occasion},occasion), flower_type=COALESCE(#{flowerType},flower_type), + shelf_life_days=COALESCE(#{shelfLifeDays},shelf_life_days) WHERE id=#{id} + + UPDATE mall_product SET status=#{status} WHERE id=#{id} + UPDATE mall_product SET sales_count = COALESCE(sales_count,0) + #{qty}, stock = GREATEST(COALESCE(stock,0) - #{qty}, 0) WHERE id=#{id} + DELETE FROM mall_product WHERE id=#{id} + + + + INSERT INTO mall_product_option (product_id, option_name, option_value, extra_price, stock, sku_suffix, option_type) + VALUES (#{productId}, #{optionName}, #{optionValue}, COALESCE(#{extraPrice},0), COALESCE(#{stock},0), #{skuSuffix}, #{optionType}) + + DELETE FROM mall_product_option WHERE product_id = #{productId} + + + + INSERT INTO mall_product_size (product_id, size_code, label, price, stem_count, sort_order) + VALUES (#{productId}, #{sizeCode}, #{label}, #{price}, #{stemCount}, COALESCE(#{sortOrder},0)) + + DELETE FROM mall_product_size WHERE product_id = #{productId} + + + + INSERT INTO mall_product_image (product_id, url, sort_order, is_main) + VALUES (#{productId}, #{url}, COALESCE(#{sortOrder},0), COALESCE(#{isMain},FALSE)) + + DELETE FROM mall_product_image WHERE product_id = #{productId} + + diff --git a/backend/target/classes/mapper/PromotionMapper.xml b/backend/target/classes/mapper/PromotionMapper.xml new file mode 100644 index 0000000..9819fbd --- /dev/null +++ b/backend/target/classes/mapper/PromotionMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + + INSERT INTO mall_coupon (code, name, discount_type, discount_value, min_order_amount, max_discount, valid_from, valid_to, issued_limit, issued_count, active) + VALUES (#{code}, #{name}, #{discountType}, #{discountValue}, COALESCE(#{minOrderAmount},0), #{maxDiscount}, #{validFrom}, #{validTo}, #{issuedLimit}, 0, COALESCE(#{active},TRUE)) + + + UPDATE mall_coupon SET name=#{name}, discount_type=#{discountType}, discount_value=#{discountValue}, + min_order_amount=COALESCE(#{minOrderAmount},min_order_amount), max_discount=#{maxDiscount}, + valid_from=#{validFrom}, valid_to=#{validTo}, issued_limit=#{issuedLimit}, active=COALESCE(#{active},active) WHERE id=#{id} + + UPDATE mall_coupon SET issued_count = COALESCE(issued_count,0)+1 WHERE id=#{id} + DELETE FROM mall_coupon WHERE id=#{id} + + + + + + INSERT INTO mall_promotion (title, banner, description, category_id, start_date, end_date, active) + VALUES (#{title}, #{banner}, #{description}, #{categoryId}, #{startDate}, #{endDate}, COALESCE(#{active},TRUE)) + + + UPDATE mall_promotion SET title=#{title}, banner=#{banner}, description=#{description}, category_id=#{categoryId}, + start_date=#{startDate}, end_date=#{endDate}, active=COALESCE(#{active},active) WHERE id=#{id} + + DELETE FROM mall_promotion WHERE id=#{id} + + diff --git a/backend/target/classes/mapper/ReviewMapper.xml b/backend/target/classes/mapper/ReviewMapper.xml new file mode 100644 index 0000000..0604b35 --- /dev/null +++ b/backend/target/classes/mapper/ReviewMapper.xml @@ -0,0 +1,26 @@ + + + + + + + INSERT INTO mall_review (product_id, order_id, author, rating, title, content, image_url, store_id, helpful_count) + VALUES (#{productId}, #{orderId}, #{author}, #{rating}, #{title}, #{content}, #{imageUrl}, #{storeId}, 0) + + DELETE FROM mall_review WHERE id = #{id} AND author = #{author} + UPDATE mall_review SET helpful_count = COALESCE(helpful_count,0) + 1 WHERE id = #{id} + + + UPDATE mall_product SET + rating_avg = (SELECT COALESCE(ROUND(AVG(rating)::numeric,2),0) FROM mall_review WHERE product_id = #{productId}), + review_count = (SELECT COUNT(*) FROM mall_review WHERE product_id = #{productId}) + WHERE id = #{productId} + + + diff --git a/backend/target/classes/mapper/ScheduleMapper.xml b/backend/target/classes/mapper/ScheduleMapper.xml new file mode 100644 index 0000000..29da6e8 --- /dev/null +++ b/backend/target/classes/mapper/ScheduleMapper.xml @@ -0,0 +1,33 @@ + + + + + + + INSERT INTO mall_schedule_slot (store_id, slot_date, slot_label, start_time, end_time, capacity, booked, surge_multiplier, active) + VALUES (#{storeId}, #{slotDate}, #{slotLabel}, #{startTime}, #{endTime}, COALESCE(#{capacity},20), + COALESCE(#{booked},0), COALESCE(#{surgeMultiplier},1.00), COALESCE(#{active},TRUE)) + + UPDATE mall_schedule_slot SET booked = COALESCE(booked,0) + 1 WHERE id = #{id} AND booked < capacity + UPDATE mall_schedule_slot SET active = #{active} WHERE id = #{id} + + + + + INSERT INTO mall_holiday (holiday_date, name, blocked, surge_multiplier, store_id) + VALUES (#{holidayDate}, #{name}, COALESCE(#{blocked},FALSE), COALESCE(#{surgeMultiplier},1.00), #{storeId}) + ON CONFLICT (holiday_date, store_id) DO UPDATE SET + name = EXCLUDED.name, blocked = EXCLUDED.blocked, surge_multiplier = EXCLUDED.surge_multiplier + + UPDATE mall_holiday SET blocked = #{blocked} WHERE id = #{id} + diff --git a/backend/target/classes/mapper/SettingMapper.xml b/backend/target/classes/mapper/SettingMapper.xml new file mode 100644 index 0000000..51d3ca3 --- /dev/null +++ b/backend/target/classes/mapper/SettingMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + INSERT INTO mall_setting (key, value, updated_at) + VALUES (#{key}, #{value}, NOW()) + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW() + + + diff --git a/backend/target/classes/mapper/StoreInventoryMapper.xml b/backend/target/classes/mapper/StoreInventoryMapper.xml new file mode 100644 index 0000000..42f77df --- /dev/null +++ b/backend/target/classes/mapper/StoreInventoryMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + INSERT INTO mall_store_inventory (store_id, product_id, available, on_hand, updated_by, updated_at) + VALUES (#{storeId}, #{productId}, COALESCE(#{available},TRUE), COALESCE(#{onHand},0), #{updatedBy}, NOW()) + ON CONFLICT (store_id, product_id) DO UPDATE SET + available = EXCLUDED.available, on_hand = EXCLUDED.on_hand, updated_by = EXCLUDED.updated_by, updated_at = NOW() + + + INSERT INTO mall_store_inventory (store_id, product_id, available, updated_by, updated_at) + VALUES (#{storeId}, #{productId}, #{available}, #{updatedBy}, NOW()) + ON CONFLICT (store_id, product_id) DO UPDATE SET + available = #{available}, updated_by = #{updatedBy}, updated_at = NOW() + + + UPDATE mall_store_inventory SET on_hand = GREATEST(COALESCE(on_hand,0) + #{delta}, 0), updated_at = NOW() + WHERE store_id = #{storeId} AND product_id = #{productId} + + diff --git a/backend/target/classes/mapper/StoreMapper.xml b/backend/target/classes/mapper/StoreMapper.xml new file mode 100644 index 0000000..073e9e9 --- /dev/null +++ b/backend/target/classes/mapper/StoreMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + INSERT INTO mall_store (code, name, city, state, zip, address, phone, timezone, open_time, close_time, + same_day_cutoff, delivery_radius_mi, daily_capacity, lat, lng, active) + VALUES (#{code}, #{name}, #{city}, #{state}, #{zip}, #{address}, #{phone}, COALESCE(#{timezone},'America/New_York'), + COALESCE(#{openTime},'09:00'), COALESCE(#{closeTime},'18:00'), COALESCE(#{sameDayCutoff},'12:00'), + COALESCE(#{deliveryRadiusMi},15.0), COALESCE(#{dailyCapacity},50), #{lat}, #{lng}, COALESCE(#{active},TRUE)) + + + UPDATE mall_store SET name=#{name}, city=#{city}, state=#{state}, zip=#{zip}, address=#{address}, phone=#{phone}, + timezone=COALESCE(#{timezone},timezone), open_time=COALESCE(#{openTime},open_time), close_time=COALESCE(#{closeTime},close_time), + same_day_cutoff=COALESCE(#{sameDayCutoff},same_day_cutoff), delivery_radius_mi=COALESCE(#{deliveryRadiusMi},delivery_radius_mi), + daily_capacity=COALESCE(#{dailyCapacity},daily_capacity), lat=COALESCE(#{lat},lat), lng=COALESCE(#{lng},lng) + WHERE id=#{id} + + UPDATE mall_store SET active=#{active} WHERE id=#{id} + diff --git a/backend/target/classes/mapper/SubscriptionMapper.xml b/backend/target/classes/mapper/SubscriptionMapper.xml new file mode 100644 index 0000000..8fc5c68 --- /dev/null +++ b/backend/target/classes/mapper/SubscriptionMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + INSERT INTO mall_subscription (owner, store_id, product_id, size_code, frequency, delivery_zip, address, + receiver_name, receiver_phone, next_delivery_date, status, price) + VALUES (#{owner}, #{storeId}, #{productId}, #{sizeCode}, COALESCE(#{frequency},'WEEKLY'), #{deliveryZip}, #{address}, + #{receiverName}, #{receiverPhone}, #{nextDeliveryDate}, COALESCE(#{status},'ACTIVE'), #{price}) + + UPDATE mall_subscription SET status = #{status} WHERE id = #{id} + UPDATE mall_subscription SET next_delivery_date = #{nextDeliveryDate} WHERE id = #{id} + diff --git a/backend/target/classes/mapper/TransferMapper.xml b/backend/target/classes/mapper/TransferMapper.xml new file mode 100644 index 0000000..da385b1 --- /dev/null +++ b/backend/target/classes/mapper/TransferMapper.xml @@ -0,0 +1,21 @@ + + + + + + + INSERT INTO mall_transfer (from_store_id, to_store_id, product_id, quantity, status, requested_by, reason, ai_recommended) + VALUES (#{fromStoreId}, #{toStoreId}, #{productId}, #{quantity}, COALESCE(#{status},'REQUESTED'), + #{requestedBy}, #{reason}, COALESCE(#{aiRecommended},FALSE)) + + + UPDATE mall_transfer SET status = #{status}, approved_by = #{approvedBy}, updated_at = NOW() WHERE id = #{id} + + diff --git a/backend/target/classes/mapper/UserMapper.xml b/backend/target/classes/mapper/UserMapper.xml new file mode 100644 index 0000000..a9d98da --- /dev/null +++ b/backend/target/classes/mapper/UserMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + INSERT INTO mall_account (username, password_hash, role, display_name, is_active) + VALUES (#{username}, #{passwordHash}, #{role}, #{displayName}, #{active}) + + + + + diff --git a/backend/target/classes/mapper/WishlistMapper.xml b/backend/target/classes/mapper/WishlistMapper.xml new file mode 100644 index 0000000..1f5e8e1 --- /dev/null +++ b/backend/target/classes/mapper/WishlistMapper.xml @@ -0,0 +1,16 @@ + + + + + + INSERT INTO mall_wishlist (owner, product_id) VALUES (#{owner}, #{productId}) + ON CONFLICT (owner, product_id) DO NOTHING + + DELETE FROM mall_wishlist WHERE owner = #{owner} AND product_id = #{productId} + + diff --git a/backend/target/classes/mapper/ZoneMapper.xml b/backend/target/classes/mapper/ZoneMapper.xml new file mode 100644 index 0000000..32537b5 --- /dev/null +++ b/backend/target/classes/mapper/ZoneMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + INSERT INTO mall_zone (store_id, zip, city, state, radius_mi, surge_eligible, active) + VALUES (#{storeId}, #{zip}, #{city}, #{state}, COALESCE(#{radiusMi},15.0), COALESCE(#{surgeEligible},TRUE), COALESCE(#{active},TRUE)) + + DELETE FROM mall_zone WHERE id = #{id} + + + + + + diff --git a/backend/target/classes/static/apple-touch-icon.png b/backend/target/classes/static/apple-touch-icon.png new file mode 100644 index 0000000..227b08d Binary files /dev/null and b/backend/target/classes/static/apple-touch-icon.png differ diff --git a/backend/target/classes/static/assets/index-BzL8NSpt.css b/backend/target/classes/static/assets/index-BzL8NSpt.css new file mode 100644 index 0000000..c3c6ffa --- /dev/null +++ b/backend/target/classes/static/assets/index-BzL8NSpt.css @@ -0,0 +1 @@ +*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-bottom-24{bottom:-6rem}.-bottom-6{bottom:-1.5rem}.-bottom-\[1px\]{bottom:-1px}.-left-20{left:-5rem}.-right-1{right:-.25rem}.-right-16{right:-4rem}.-top-1{top:-.25rem}.-top-20{top:-5rem}.bottom-0{bottom:0}.bottom-7{bottom:1.75rem}.left-0{left:0}.left-1\/2{left:50%}.left-3{left:.75rem}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-5{right:1.25rem}.right-6{right:1.5rem}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:.5rem}.top-20{top:5rem}.top-3{top:.75rem}.top-5{top:1.25rem}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.col-span-2{grid-column:span 2 / span 2}.col-span-3{grid-column:span 3 / span 3}.col-span-4{grid-column:span 4 / span 4}.m-auto{margin:auto}.mx-auto{margin-left:auto;margin-right:auto}.-mt-0\.5{margin-top:-.125rem}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-7{margin-bottom:1.75rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-7{margin-top:1.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-\[4\/5\]{aspect-ratio:4/5}.aspect-\[5\/4\]{aspect-ratio:5/4}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-44{height:11rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-\[2px\]{height:2px}.h-\[72px\]{height:72px}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.min-h-\[78vh\]{min-height:78vh}.min-h-screen{min-height:100vh}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-32{width:8rem}.w-44{width:11rem}.w-48{width:12rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[360px\]{width:360px}.w-auto{width:auto}.w-full{width:100%}.min-w-\[18px\]{min-width:18px}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes heartbeat{0%,to{transform:scale(1)}30%{transform:scale(1.3)}60%{transform:scale(.95)}}.animate-heartbeat{animation:heartbeat .6s ease-in-out}.cursor-not-allowed{cursor:not-allowed}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-10{gap:2.5rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-7{gap:1.75rem}.gap-8{gap:2rem}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-20>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-blush-100\/60>:not([hidden])~:not([hidden]){border-color:#fbe8ef99}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.75rem}.rounded-4xl{border-radius:2.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-r-2{border-right-width:2px}.border-t{border-top-width:1px}.border-amber-400\/30{border-color:#fbbf244d}.border-amber-500\/30{border-color:#f59e0b4d}.border-bloom{--tw-border-opacity: 1;border-color:rgb(208 90 130 / var(--tw-border-opacity, 1))}.border-blush-100{--tw-border-opacity: 1;border-color:rgb(251 232 239 / var(--tw-border-opacity, 1))}.border-blush-100\/60{border-color:#fbe8ef99}.border-blush-100\/70{border-color:#fbe8efb3}.border-blush-400{--tw-border-opacity: 1;border-color:rgb(224 122 156 / var(--tw-border-opacity, 1))}.border-blush-50{--tw-border-opacity: 1;border-color:rgb(253 244 247 / var(--tw-border-opacity, 1))}.border-blush-500{--tw-border-opacity: 1;border-color:rgb(208 90 130 / var(--tw-border-opacity, 1))}.border-brand{--tw-border-opacity: 1;border-color:rgb(0 160 200 / var(--tw-border-opacity, 1))}.border-cream\/10{border-color:#fdfaf51a}.border-edge{--tw-border-opacity: 1;border-color:rgb(38 48 74 / var(--tw-border-opacity, 1))}.border-edge\/50{border-color:#26304a80}.border-emerald-500\/30{border-color:#10b9814d}.border-rose-500\/30{border-color:#f43f5e4d}.border-sky-500\/30{border-color:#0ea5e94d}.border-slate-300\/30{border-color:#cbd5e14d}.border-slate-500\/30{border-color:#64748b4d}.border-slate-600\/30{border-color:#4755694d}.border-violet-500\/30{border-color:#8b5cf64d}.border-white\/70{border-color:#ffffffb3}.bg-amber-400\/15{background-color:#fbbf2426}.bg-amber-500\/15{background-color:#f59e0b26}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-bloom{--tw-bg-opacity: 1;background-color:rgb(208 90 130 / var(--tw-bg-opacity, 1))}.bg-blush-50{--tw-bg-opacity: 1;background-color:rgb(253 244 247 / var(--tw-bg-opacity, 1))}.bg-blush-500{--tw-bg-opacity: 1;background-color:rgb(208 90 130 / var(--tw-bg-opacity, 1))}.bg-brand{--tw-bg-opacity: 1;background-color:rgb(0 160 200 / var(--tw-bg-opacity, 1))}.bg-brand2{--tw-bg-opacity: 1;background-color:rgb(0 90 140 / var(--tw-bg-opacity, 1))}.bg-card{--tw-bg-opacity: 1;background-color:rgb(26 34 52 / var(--tw-bg-opacity, 1))}.bg-card\/60{background-color:#1a223499}.bg-cream{--tw-bg-opacity: 1;background-color:rgb(253 250 245 / var(--tw-bg-opacity, 1))}.bg-cream\/10{background-color:#fdfaf51a}.bg-cream\/90{background-color:#fdfaf5e6}.bg-emerald-500\/15{background-color:#10b98126}.bg-gold{--tw-bg-opacity: 1;background-color:rgb(196 163 90 / var(--tw-bg-opacity, 1))}.bg-ink{--tw-bg-opacity: 1;background-color:rgb(11 15 23 / var(--tw-bg-opacity, 1))}.bg-ivory{--tw-bg-opacity: 1;background-color:rgb(251 246 238 / var(--tw-bg-opacity, 1))}.bg-leaf\/10{background-color:#4e6e431a}.bg-panel{--tw-bg-opacity: 1;background-color:rgb(19 25 39 / var(--tw-bg-opacity, 1))}.bg-petal{--tw-bg-opacity: 1;background-color:rgb(251 232 239 / var(--tw-bg-opacity, 1))}.bg-rose-500\/15{background-color:#f43f5e26}.bg-sage-700{--tw-bg-opacity: 1;background-color:rgb(64 88 55 / var(--tw-bg-opacity, 1))}.bg-sage-800{--tw-bg-opacity: 1;background-color:rgb(54 72 47 / var(--tw-bg-opacity, 1))}.bg-sky-500\/15{background-color:#0ea5e926}.bg-slate-300\/20{background-color:#cbd5e133}.bg-slate-500\/15{background-color:#64748b26}.bg-slate-600\/20{background-color:#47556933}.bg-transparent{background-color:transparent}.bg-violet-500\/15{background-color:#8b5cf626}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/15{background-color:#ffffff26}.bg-white\/45{background-color:#ffffff73}.bg-white\/60{background-color:#fff9}.bg-white\/70{background-color:#ffffffb3}.bg-white\/85{background-color:#ffffffd9}.bg-white\/90{background-color:#ffffffe6}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.from-amber-400{--tw-gradient-from: #fbbf24 var(--tw-gradient-from-position);--tw-gradient-to: rgb(251 191 36 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-bloom2{--tw-gradient-from: #993456 var(--tw-gradient-from-position);--tw-gradient-to: rgb(153 52 86 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blush-100{--tw-gradient-from: #fbe8ef var(--tw-gradient-from-position);--tw-gradient-to: rgb(251 232 239 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blush-50{--tw-gradient-from: #fdf4f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(253 244 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blush-900\/10{--tw-gradient-from: rgb(107 42 65 / .1) var(--tw-gradient-from-position);--tw-gradient-to: rgb(107 42 65 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blush-900\/70{--tw-gradient-from: rgb(107 42 65 / .7) var(--tw-gradient-from-position);--tw-gradient-to: rgb(107 42 65 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blush-900\/75{--tw-gradient-from: rgb(107 42 65 / .75) var(--tw-gradient-from-position);--tw-gradient-to: rgb(107 42 65 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-sage-700{--tw-gradient-from: #405837 var(--tw-gradient-from-position);--tw-gradient-to: rgb(64 88 55 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-sage-900\/40{--tw-gradient-from: rgb(46 61 41 / .4) var(--tw-gradient-from-position);--tw-gradient-to: rgb(46 61 41 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-300{--tw-gradient-from: #cbd5e1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(203 213 225 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-slate-400{--tw-gradient-from: #94a3b8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(148 163 184 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-violet-500{--tw-gradient-from: #8b5cf6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(139 92 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-blush-900\/20{--tw-gradient-to: rgb(107 42 65 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(107 42 65 / .2) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-blush-900\/40{--tw-gradient-to: rgb(107 42 65 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(107 42 65 / .4) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-cream{--tw-gradient-to: rgb(253 250 245 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #fdfaf5 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-amber-500{--tw-gradient-to: #f59e0b var(--tw-gradient-to-position)}.to-bloom{--tw-gradient-to: #d05a82 var(--tw-gradient-to-position)}.to-fuchsia-500{--tw-gradient-to: #d946ef var(--tw-gradient-to-position)}.to-ivory{--tw-gradient-to: #fbf6ee var(--tw-gradient-to-position)}.to-sage-100{--tw-gradient-to: #e6ede2 var(--tw-gradient-to-position)}.to-sage-50{--tw-gradient-to: #f4f7f3 var(--tw-gradient-to-position)}.to-sage-800{--tw-gradient-to: #36482f var(--tw-gradient-to-position)}.to-slate-400{--tw-gradient-to: #94a3b8 var(--tw-gradient-to-position)}.to-slate-500{--tw-gradient-to: #64748b var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-10{padding:2.5rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-14{padding-top:3.5rem;padding-bottom:3.5rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-20{padding-top:5rem;padding-bottom:5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1\.5{padding-bottom:.375rem}.pb-10{padding-bottom:2.5rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[20px\]{font-size:20px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-light{font-weight:300}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-\[1\.05\]{line-height:1.05}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-\[0\.12em\]{letter-spacing:.12em}.tracking-\[0\.25em\]{letter-spacing:.25em}.tracking-\[0\.2em\]{letter-spacing:.2em}.tracking-\[0\.35em\]{letter-spacing:.35em}.tracking-\[0\.3em\]{letter-spacing:.3em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[\#3c4043\]{--tw-text-opacity: 1;color:rgb(60 64 67 / var(--tw-text-opacity, 1))}.text-\[\#43343a\]{--tw-text-opacity: 1;color:rgb(67 52 58 / var(--tw-text-opacity, 1))}.text-\[\#5a474d\]{--tw-text-opacity: 1;color:rgb(90 71 77 / var(--tw-text-opacity, 1))}.text-\[\#6b5258\]{--tw-text-opacity: 1;color:rgb(107 82 88 / var(--tw-text-opacity, 1))}.text-\[\#8a7077\]{--tw-text-opacity: 1;color:rgb(138 112 119 / var(--tw-text-opacity, 1))}.text-\[\#a08a90\]{--tw-text-opacity: 1;color:rgb(160 138 144 / var(--tw-text-opacity, 1))}.text-\[\#e6edf6\]{--tw-text-opacity: 1;color:rgb(230 237 246 / var(--tw-text-opacity, 1))}.text-accent{--tw-text-opacity: 1;color:rgb(61 220 151 / var(--tw-text-opacity, 1))}.text-amber-300{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-bloom{--tw-text-opacity: 1;color:rgb(208 90 130 / var(--tw-text-opacity, 1))}.text-bloom\/30{color:#d05a824d}.text-bloom\/40{color:#d05a8266}.text-bloom2{--tw-text-opacity: 1;color:rgb(153 52 86 / var(--tw-text-opacity, 1))}.text-blush-200{--tw-text-opacity: 1;color:rgb(246 205 218 / var(--tw-text-opacity, 1))}.text-blush-200\/40{color:#f6cdda66}.text-blush-300{--tw-text-opacity: 1;color:rgb(238 167 190 / var(--tw-text-opacity, 1))}.text-blush-400{--tw-text-opacity: 1;color:rgb(224 122 156 / var(--tw-text-opacity, 1))}.text-blush-500{--tw-text-opacity: 1;color:rgb(208 90 130 / var(--tw-text-opacity, 1))}.text-blush-600{--tw-text-opacity: 1;color:rgb(184 67 107 / var(--tw-text-opacity, 1))}.text-blush-700{--tw-text-opacity: 1;color:rgb(153 52 86 / var(--tw-text-opacity, 1))}.text-blush-900{--tw-text-opacity: 1;color:rgb(107 42 65 / var(--tw-text-opacity, 1))}.text-brand{--tw-text-opacity: 1;color:rgb(0 160 200 / var(--tw-text-opacity, 1))}.text-cream\/50{color:#fdfaf580}.text-cream\/60{color:#fdfaf599}.text-cream\/70{color:#fdfaf5b3}.text-cream\/75{color:#fdfaf5bf}.text-cream\/80{color:#fdfaf5cc}.text-cream\/85{color:#fdfaf5d9}.text-cream\/90{color:#fdfaf5e6}.text-cream\/95{color:#fdfaf5f2}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-gold{--tw-text-opacity: 1;color:rgb(196 163 90 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-ink{--tw-text-opacity: 1;color:rgb(11 15 23 / var(--tw-text-opacity, 1))}.text-leaf{--tw-text-opacity: 1;color:rgb(78 110 67 / var(--tw-text-opacity, 1))}.text-rose-400{--tw-text-opacity: 1;color:rgb(251 113 133 / var(--tw-text-opacity, 1))}.text-sage-200{--tw-text-opacity: 1;color:rgb(205 221 198 / var(--tw-text-opacity, 1))}.text-sage-300{--tw-text-opacity: 1;color:rgb(168 195 158 / var(--tw-text-opacity, 1))}.text-sage-300\/40{color:#a8c39e66}.text-sage-600{--tw-text-opacity: 1;color:rgb(78 110 67 / var(--tw-text-opacity, 1))}.text-sage-700{--tw-text-opacity: 1;color:rgb(64 88 55 / var(--tw-text-opacity, 1))}.text-sage-800{--tw-text-opacity: 1;color:rgb(54 72 47 / var(--tw-text-opacity, 1))}.text-sky-400{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-violet-300{--tw-text-opacity: 1;color:rgb(196 181 253 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/20{color:#fff3}.text-white\/70{color:#ffffffb3}.text-white\/85{color:#ffffffd9}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.accent-bloom{accent-color:#d05a82}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-bloom{--tw-shadow: 0 20px 60px -18px rgba(153,52,86,.3);--tw-shadow-colored: 0 20px 60px -18px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-petal{--tw-shadow: 0 10px 40px -12px rgba(208,90,130,.25);--tw-shadow-colored: 0 10px 40px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 8px 30px -10px rgba(110,80,90,.18);--tw-shadow-colored: 0 8px 30px -10px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-bloom{--tw-shadow-color: #d05a82;--tw-shadow: var(--tw-shadow-colored)}.shadow-petal{--tw-shadow-color: #fbe8ef;--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.drop-shadow-sm{--tw-drop-shadow: drop-shadow(0 1px 1px rgb(0 0 0 / .05));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}:root{--blush: #d05a82;--blush-deep: #993456;--sage: #4e6e43;--cream: #fdfaf5;--gold: #c4a35a}body{margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#43343a;background:var(--cream);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}*{box-sizing:border-box}html.lang-ko body,html.lang-ko .admin-shell,html.lang-ko input,html.lang-ko textarea,html.lang-ko select,html.lang-ko button,html.lang-ko p,html.lang-ko span,html.lang-ko a,html.lang-ko li,html.lang-ko td,html.lang-ko th,html.lang-ko label,html.lang-ko h1,html.lang-ko h2,html.lang-ko h3,html.lang-ko h4{font-family:Malgun Gothic,맑은 고딕,Apple SD Gothic Neo,Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}html.lang-ko .font-display{font-family:Cormorant Garamond,Malgun Gothic,맑은 고딕,Georgia,serif}html.lang-ko .font-serif{font-family:Playfair Display,Malgun Gothic,맑은 고딕,Georgia,serif}.admin-shell{color-scheme:dark;background:#0b0f17;color:#e6edf6;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.font-display{font-family:Cormorant Garamond,Georgia,serif}.font-serif{font-family:Playfair Display,Georgia,serif}html{scroll-behavior:smooth}::-moz-selection{background:#d05a822e}::selection{background:#d05a822e}.botanical-divider{display:flex;align-items:center;justify-content:center;gap:.75rem;color:#a8c39e}.botanical-divider:before,.botanical-divider:after{content:"";height:1px;flex:1;max-width:7rem;background:linear-gradient(to var(--dir, right),transparent,rgba(168,195,158,.7))}.botanical-divider:before{--dir: left}.petal-layer{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;pointer-events:none;z-index:0}.petal{position:absolute;top:-8vh;border-radius:50% 0 50% 50%;background:radial-gradient(circle at 30% 30%,#eea7bef2,#d05a828c);opacity:0;will-change:transform,opacity;animation:petalfall linear infinite}.petal.sage{background:radial-gradient(circle at 30% 30%,#a8c39ee6,#648a5680)}.petal.cream{background:radial-gradient(circle at 30% 30%,#fdf6eef2,#c4a35a66)}.zoom-frame{overflow:hidden}.zoom-frame img{transition:transform .9s cubic-bezier(.22,1,.36,1)}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.petal-layer{display:none}}.thin-scroll::-webkit-scrollbar{height:6px}.thin-scroll::-webkit-scrollbar-thumb{background:#d05a8240;border-radius:999px}.placeholder\:text-blush-300::-moz-placeholder{--tw-text-opacity: 1;color:rgb(238 167 190 / var(--tw-text-opacity, 1))}.placeholder\:text-blush-300::placeholder{--tw-text-opacity: 1;color:rgb(238 167 190 / var(--tw-text-opacity, 1))}.focus-within\:border-bloom:focus-within{--tw-border-opacity: 1;border-color:rgb(208 90 130 / var(--tw-border-opacity, 1))}.hover\:border-bloom:hover{--tw-border-opacity: 1;border-color:rgb(208 90 130 / var(--tw-border-opacity, 1))}.hover\:border-blush-300:hover{--tw-border-opacity: 1;border-color:rgb(238 167 190 / var(--tw-border-opacity, 1))}.hover\:bg-bloom2:hover{--tw-bg-opacity: 1;background-color:rgb(153 52 86 / var(--tw-bg-opacity, 1))}.hover\:bg-blush-100:hover{--tw-bg-opacity: 1;background-color:rgb(251 232 239 / var(--tw-bg-opacity, 1))}.hover\:bg-blush-50:hover{--tw-bg-opacity: 1;background-color:rgb(253 244 247 / var(--tw-bg-opacity, 1))}.hover\:bg-blush-600:hover{--tw-bg-opacity: 1;background-color:rgb(184 67 107 / var(--tw-bg-opacity, 1))}.hover\:bg-brand\/90:hover{background-color:#00a0c8e6}.hover\:bg-card\/60:hover{background-color:#1a223499}.hover\:bg-cream:hover{--tw-bg-opacity: 1;background-color:rgb(253 250 245 / var(--tw-bg-opacity, 1))}.hover\:bg-panel\/50:hover{background-color:#13192780}.hover\:bg-petal:hover{--tw-bg-opacity: 1;background-color:rgb(251 232 239 / var(--tw-bg-opacity, 1))}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/30:hover{background-color:#ffffff4d}.hover\:bg-white\/70:hover{background-color:#ffffffb3}.hover\:text-bloom:hover,.hover\:text-blush-500:hover{--tw-text-opacity: 1;color:rgb(208 90 130 / var(--tw-text-opacity, 1))}.hover\:text-blush-600:hover{--tw-text-opacity: 1;color:rgb(184 67 107 / var(--tw-text-opacity, 1))}.hover\:text-blush-700:hover{--tw-text-opacity: 1;color:rgb(153 52 86 / var(--tw-text-opacity, 1))}.hover\:text-brand:hover{--tw-text-opacity: 1;color:rgb(0 160 200 / var(--tw-text-opacity, 1))}.hover\:text-cream\/80:hover{color:#fdfaf5cc}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-bloom:hover{--tw-shadow: 0 20px 60px -18px rgba(153,52,86,.3);--tw-shadow-colored: 0 20px 60px -18px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-shadow-color: #d05a82;--tw-shadow: var(--tw-shadow-colored)}.focus\:border-bloom:focus{--tw-border-opacity: 1;border-color:rgb(208 90 130 / var(--tw-border-opacity, 1))}.focus\:border-blush-300:focus{--tw-border-opacity: 1;border-color:rgb(238 167 190 / var(--tw-border-opacity, 1))}.focus\:border-blush-400:focus{--tw-border-opacity: 1;border-color:rgb(224 122 156 / var(--tw-border-opacity, 1))}.focus\:border-brand:focus{--tw-border-opacity: 1;border-color:rgb(0 160 200 / var(--tw-border-opacity, 1))}.disabled\:opacity-60:disabled{opacity:.6}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:gap-2{gap:.5rem}.group:hover .group-hover\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:flex{display:flex}.sm\:flex-row{flex-direction:row}.sm\:justify-between{justify-content:space-between}.sm\:gap-3{gap:.75rem}}@media (min-width: 768px){.md\:left-5{left:1.25rem}.md\:right-5{right:1.25rem}.md\:col-span-1{grid-column:span 1 / span 1}.md\:col-span-2{grid-column:span 2 / span 2}.md\:block{display:block}.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-\[200px_1fr\]{grid-template-columns:200px 1fr}.md\:flex-row{flex-direction:row}.md\:p-10{padding:2.5rem}.md\:p-12{padding:3rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-6xl{font-size:3.75rem;line-height:1}}@media (min-width: 1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}} diff --git a/backend/target/classes/static/assets/index-CUN395kM.js b/backend/target/classes/static/assets/index-CUN395kM.js new file mode 100644 index 0000000..f0e4756 --- /dev/null +++ b/backend/target/classes/static/assets/index-CUN395kM.js @@ -0,0 +1,489 @@ +var wA=e=>{throw TypeError(e)};var Qg=(e,t,n)=>t.has(e)||wA("Cannot "+n);var R=(e,t,n)=>(Qg(e,t,"read from private field"),n?n.call(e):t.get(e)),ce=(e,t,n)=>t.has(e)?wA("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),ee=(e,t,n,r)=>(Qg(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),Oe=(e,t,n)=>(Qg(e,t,"access private method"),n);var rh=(e,t,n,r)=>({set _(a){ee(e,t,a,n)},get _(){return R(e,t,r)}});(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))r(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const s of i.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(a){if(a.ep)return;a.ep=!0;const i=n(a);fetch(a.href,i)}})();var ah=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ie(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var $P={exports:{}},xy={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var az=Symbol.for("react.transitional.element"),iz=Symbol.for("react.fragment");function kP(e,t,n){var r=null;if(n!==void 0&&(r=""+n),t.key!==void 0&&(r=""+t.key),"key"in t){n={};for(var a in t)a!=="key"&&(n[a]=t[a])}else n=t;return t=n.ref,{$$typeof:az,type:e,key:r,ref:t!==void 0?t:null,props:n}}xy.Fragment=iz;xy.jsx=kP;xy.jsxs=kP;$P.exports=xy;var u=$P.exports,LP={exports:{}},be={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var aS=Symbol.for("react.transitional.element"),sz=Symbol.for("react.portal"),oz=Symbol.for("react.fragment"),lz=Symbol.for("react.strict_mode"),cz=Symbol.for("react.profiler"),uz=Symbol.for("react.consumer"),fz=Symbol.for("react.context"),dz=Symbol.for("react.forward_ref"),hz=Symbol.for("react.suspense"),pz=Symbol.for("react.memo"),zP=Symbol.for("react.lazy"),mz=Symbol.for("react.activity"),jA=Symbol.iterator;function yz(e){return e===null||typeof e!="object"?null:(e=jA&&e[jA]||e["@@iterator"],typeof e=="function"?e:null)}var IP={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},BP=Object.assign,UP={};function Oc(e,t,n){this.props=e,this.context=t,this.refs=UP,this.updater=n||IP}Oc.prototype.isReactComponent={};Oc.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Oc.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function FP(){}FP.prototype=Oc.prototype;function iS(e,t,n){this.props=e,this.context=t,this.refs=UP,this.updater=n||IP}var sS=iS.prototype=new FP;sS.constructor=iS;BP(sS,Oc.prototype);sS.isPureReactComponent=!0;var AA=Array.isArray;function Fb(){}var at={H:null,A:null,T:null,S:null},VP=Object.prototype.hasOwnProperty;function oS(e,t,n){var r=n.ref;return{$$typeof:aS,type:e,key:t,ref:r!==void 0?r:null,props:n}}function gz(e,t){return oS(e.type,t,e.props)}function lS(e){return typeof e=="object"&&e!==null&&e.$$typeof===aS}function vz(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(n){return t[n]})}var OA=/\/+/g;function Zg(e,t){return typeof e=="object"&&e!==null&&e.key!=null?vz(""+e.key):t.toString(36)}function bz(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch(typeof e.status=="string"?e.then(Fb,Fb):(e.status="pending",e.then(function(t){e.status==="pending"&&(e.status="fulfilled",e.value=t)},function(t){e.status==="pending"&&(e.status="rejected",e.reason=t)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}function Bo(e,t,n,r,a){var i=typeof e;(i==="undefined"||i==="boolean")&&(e=null);var s=!1;if(e===null)s=!0;else switch(i){case"bigint":case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case aS:case sz:s=!0;break;case zP:return s=e._init,Bo(s(e._payload),t,n,r,a)}}if(s)return a=a(e),s=r===""?"."+Zg(e,0):r,AA(a)?(n="",s!=null&&(n=s.replace(OA,"$&/")+"/"),Bo(a,t,n,"",function(c){return c})):a!=null&&(lS(a)&&(a=gz(a,n+(a.key==null||e&&e.key===a.key?"":(""+a.key).replace(OA,"$&/")+"/")+s)),t.push(a)),1;s=0;var o=r===""?".":r+":";if(AA(e))for(var l=0;l>>1,H=P[F];if(0>>1;Fa(te,I))Za(ye,te)?(P[F]=ye,P[Z]=I,F=Z):(P[F]=te,P[q]=I,F=q);else if(Za(ye,I))P[F]=ye,P[Z]=I,F=Z;else break e}}return k}function a(P,k){var I=P.sortIndex-k.sortIndex;return I!==0?I:P.id-k.id}if(e.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var s=Date,o=s.now();e.unstable_now=function(){return s.now()-o}}var l=[],c=[],f=1,d=null,h=3,p=!1,m=!1,g=!1,b=!1,y=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,x=typeof setImmediate<"u"?setImmediate:null;function w(P){for(var k=n(c);k!==null;){if(k.callback===null)r(c);else if(k.startTime<=P)r(c),k.sortIndex=k.expirationTime,t(l,k);else break;k=n(c)}}function S(P){if(g=!1,w(P),!m)if(n(l)!==null)m=!0,j||(j=!0,C());else{var k=n(c);k!==null&&$(S,k.startTime-P)}}var j=!1,O=-1,E=5,T=-1;function N(){return b?!0:!(e.unstable_now()-TP&&N());){var F=d.callback;if(typeof F=="function"){d.callback=null,h=d.priorityLevel;var H=F(d.expirationTime<=P);if(P=e.unstable_now(),typeof H=="function"){d.callback=H,w(P),k=!0;break t}d===n(l)&&r(l),w(P)}else r(l);d=n(l)}if(d!==null)k=!0;else{var Y=n(c);Y!==null&&$(S,Y.startTime-P),k=!1}}break e}finally{d=null,h=I,p=!1}k=void 0}}finally{k?C():j=!1}}}var C;if(typeof x=="function")C=function(){x(M)};else if(typeof MessageChannel<"u"){var L=new MessageChannel,D=L.port2;L.port1.onmessage=M,C=function(){D.postMessage(null)}}else C=function(){y(M,0)};function $(P,k){O=y(function(){P(e.unstable_now())},k)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(P){P.callback=null},e.unstable_forceFrameRate=function(P){0>P||125F?(P.sortIndex=I,t(c,P),n(l)===null&&P===n(c)&&(g?(v(O),O=-1):g=!0,$(S,I-F))):(P.sortIndex=H,t(l,P),m||p||(m=!0,j||(j=!0,C()))),P},e.unstable_shouldYield=N,e.unstable_wrapCallback=function(P){var k=h;return function(){var I=h;h=k;try{return P.apply(this,arguments)}finally{h=I}}}})(KP);qP.exports=KP;var wz=qP.exports,GP={exports:{}},vn={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var jz=A;function YP(e){var t="https://react.dev/errors/"+e;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(XP)}catch(e){console.error(e)}}XP(),GP.exports=vn;var Ez=GP.exports;/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var kt=wz,WP=A,Tz=Ez;function U(e){var t="https://react.dev/errors/"+e;if(1Ho||(e.current=Yb[Ho],Yb[Ho]=null,Ho--)}function Ze(e,t){Ho++,Yb[Ho]=e.current,e.current=t}var na=ua(null),cf=ua(null),ki=ua(null),wp=ua(null);function jp(e,t){switch(Ze(ki,t),Ze(cf,e),Ze(na,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?D2(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=D2(t),e=wD(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}qt(na),Ze(na,e)}function kl(){qt(na),qt(cf),qt(ki)}function Xb(e){e.memoizedState!==null&&Ze(wp,e);var t=na.current,n=wD(t,e.type);t!==n&&(Ze(cf,e),Ze(na,n))}function Ap(e){cf.current===e&&(qt(na),qt(cf)),wp.current===e&&(qt(wp),xf._currentValue=Fs)}var Jg,CA;function ps(e){if(Jg===void 0)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);Jg=t&&t[1]||"",CA=-1)":-1a||l[r]!==c[a]){var f=` +`+l[r].replace(" at new "," at ");return e.displayName&&f.includes("")&&(f=f.replace("",e.displayName)),f}while(1<=r&&0<=a);break}}}finally{ev=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?ps(n):""}function Mz(e,t){switch(e.tag){case 26:case 27:case 5:return ps(e.type);case 16:return ps("Lazy");case 13:return e.child!==t&&t!==null?ps("Suspense Fallback"):ps("Suspense");case 19:return ps("SuspenseList");case 0:case 15:return tv(e.type,!1);case 11:return tv(e.type.render,!1);case 1:return tv(e.type,!0);case 31:return ps("Activity");default:return""}}function _A(e){try{var t="",n=null;do t+=Mz(e,n),n=e,e=e.return;while(e);return t}catch(r){return` +Error generating stack: `+r.message+` +`+r.stack}}var Wb=Object.prototype.hasOwnProperty,fS=kt.unstable_scheduleCallback,nv=kt.unstable_cancelCallback,Rz=kt.unstable_shouldYield,Dz=kt.unstable_requestPaint,qn=kt.unstable_now,$z=kt.unstable_getCurrentPriorityLevel,rM=kt.unstable_ImmediatePriority,aM=kt.unstable_UserBlockingPriority,Op=kt.unstable_NormalPriority,kz=kt.unstable_LowPriority,iM=kt.unstable_IdlePriority,Lz=kt.log,zz=kt.unstable_setDisableYieldValue,wd=null,Kn=null;function Ci(e){if(typeof Lz=="function"&&zz(e),Kn&&typeof Kn.setStrictMode=="function")try{Kn.setStrictMode(wd,e)}catch{}}var Gn=Math.clz32?Math.clz32:Uz,Iz=Math.log,Bz=Math.LN2;function Uz(e){return e>>>=0,e===0?32:31-(Iz(e)/Bz|0)|0}var oh=256,lh=262144,ch=4194304;function ms(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function jy(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var a=0,i=e.suspendedLanes,s=e.pingedLanes;e=e.warmLanes;var o=r&134217727;return o!==0?(r=o&~i,r!==0?a=ms(r):(s&=o,s!==0?a=ms(s):n||(n=o&~e,n!==0&&(a=ms(n))))):(o=r&~i,o!==0?a=ms(o):s!==0?a=ms(s):n||(n=r&~e,n!==0&&(a=ms(n)))),a===0?0:t!==0&&t!==a&&!(t&i)&&(i=a&-a,n=t&-t,i>=n||i===32&&(n&4194048)!==0)?t:a}function jd(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Fz(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function sM(){var e=ch;return ch<<=1,!(ch&62914560)&&(ch=4194304),e}function rv(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ad(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Vz(e,t,n,r,a,i){var s=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var o=e.entanglements,l=e.expirationTimes,c=e.hiddenUpdates;for(n=s&~n;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Xz=/[\n"\\]/g;function fr(e){return e.replace(Xz,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Jb(e,t,n,r,a,i,s,o){e.name="",s!=null&&typeof s!="function"&&typeof s!="symbol"&&typeof s!="boolean"?e.type=s:e.removeAttribute("type"),t!=null?s==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+lr(t)):e.value!==""+lr(t)&&(e.value=""+lr(t)):s!=="submit"&&s!=="reset"||e.removeAttribute("value"),t!=null?e0(e,s,lr(t)):n!=null?e0(e,s,lr(n)):r!=null&&e.removeAttribute("value"),a==null&&i!=null&&(e.defaultChecked=!!i),a!=null&&(e.checked=a&&typeof a!="function"&&typeof a!="symbol"),o!=null&&typeof o!="function"&&typeof o!="symbol"&&typeof o!="boolean"?e.name=""+lr(o):e.removeAttribute("name")}function mM(e,t,n,r,a,i,s,o){if(i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.type=i),t!=null||n!=null){if(!(i!=="submit"&&i!=="reset"||t!=null)){Zb(e);return}n=n!=null?""+lr(n):"",t=t!=null?""+lr(t):n,o||t===e.value||(e.value=t),e.defaultValue=t}r=r??a,r=typeof r!="function"&&typeof r!="symbol"&&!!r,e.checked=o?e.checked:!!r,e.defaultChecked=!!r,s!=null&&typeof s!="function"&&typeof s!="symbol"&&typeof s!="boolean"&&(e.name=s),Zb(e)}function e0(e,t,n){t==="number"&&Ep(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function dl(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),n0=!1;if(Ha)try{var eu={};Object.defineProperty(eu,"passive",{get:function(){n0=!0}}),window.addEventListener("test",eu,eu),window.removeEventListener("test",eu,eu)}catch{n0=!1}var _i=null,gS=null,Qh=null;function xM(){if(Qh)return Qh;var e,t=gS,n=t.length,r,a="value"in _i?_i.value:_i.textContent,i=a.length;for(e=0;e=Du),UA=" ",FA=!1;function wM(e,t){switch(e){case"keyup":return jI.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function jM(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Go=!1;function OI(e,t){switch(e){case"compositionend":return jM(t);case"keypress":return t.which!==32?null:(FA=!0,UA);case"textInput":return e=t.data,e===UA&&FA?null:e;default:return null}}function EI(e,t){if(Go)return e==="compositionend"||!bS&&wM(e,t)?(e=xM(),Qh=gS=_i=null,Go=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=GA(n)}}function TM(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?TM(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function NM(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Ep(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Ep(e.document)}return t}function xS(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var DI=Ha&&"documentMode"in document&&11>=document.documentMode,Yo=null,r0=null,ku=null,a0=!1;function XA(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;a0||Yo==null||Yo!==Ep(r)||(r=Yo,"selectionStart"in r&&xS(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),ku&&df(ku,r)||(ku=r,r=Hp(r0,"onSelect"),0>=s,a-=s,Yr=1<<32-Gn(t)+a|n<E?(T=O,O=null):T=O.sibling;var N=h(y,O,x[E],w);if(N===null){O===null&&(O=T);break}e&&O&&N.alternate===null&&t(y,O),v=i(N,v,E),j===null?S=N:j.sibling=N,j=N,O=T}if(E===x.length)return n(y,O),Ce&&Oa(y,E),S;if(O===null){for(;EE?(T=O,O=null):T=O.sibling;var M=h(y,O,N.value,w);if(M===null){O===null&&(O=T);break}e&&O&&M.alternate===null&&t(y,O),v=i(M,v,E),j===null?S=M:j.sibling=M,j=M,O=T}if(N.done)return n(y,O),Ce&&Oa(y,E),S;if(O===null){for(;!N.done;E++,N=x.next())N=d(y,N.value,w),N!==null&&(v=i(N,v,E),j===null?S=N:j.sibling=N,j=N);return Ce&&Oa(y,E),S}for(O=r(O);!N.done;E++,N=x.next())N=p(O,y,E,N.value,w),N!==null&&(e&&N.alternate!==null&&O.delete(N.key===null?E:N.key),v=i(N,v,E),j===null?S=N:j.sibling=N,j=N);return e&&O.forEach(function(C){return t(y,C)}),Ce&&Oa(y,E),S}function b(y,v,x,w){if(typeof x=="object"&&x!==null&&x.type===Vo&&x.key===null&&(x=x.props.children),typeof x=="object"&&x!==null){switch(x.$$typeof){case sh:e:{for(var S=x.key;v!==null;){if(v.key===S){if(S=x.type,S===Vo){if(v.tag===7){n(y,v.sibling),w=a(v,x.props.children),w.return=y,y=w;break e}}else if(v.elementType===S||typeof S=="object"&&S!==null&&S.$$typeof===hi&&ys(S)===v.type){n(y,v.sibling),w=a(v,x.props),nu(w,x),w.return=y,y=w;break e}n(y,v);break}else t(y,v);v=v.sibling}x.type===Vo?(w=Vs(x.props.children,y.mode,w,x.key),w.return=y,y=w):(w=Jh(x.type,x.key,x.props,null,y.mode,w),nu(w,x),w.return=y,y=w)}return s(y);case wu:e:{for(S=x.key;v!==null;){if(v.key===S)if(v.tag===4&&v.stateNode.containerInfo===x.containerInfo&&v.stateNode.implementation===x.implementation){n(y,v.sibling),w=a(v,x.children||[]),w.return=y,y=w;break e}else{n(y,v);break}else t(y,v);v=v.sibling}w=dv(x,y.mode,w),w.return=y,y=w}return s(y);case hi:return x=ys(x),b(y,v,x,w)}if(ju(x))return m(y,v,x,w);if(Jc(x)){if(S=Jc(x),typeof S!="function")throw Error(U(150));return x=S.call(x),g(y,v,x,w)}if(typeof x.then=="function")return b(y,v,hh(x),w);if(x.$$typeof===Ca)return b(y,v,dh(y,x),w);ph(y,x)}return typeof x=="string"&&x!==""||typeof x=="number"||typeof x=="bigint"?(x=""+x,v!==null&&v.tag===6?(n(y,v.sibling),w=a(v,x),w.return=y,y=w):(n(y,v),w=fv(x,y.mode,w),w.return=y,y=w),s(y)):n(y,v)}return function(y,v,x,w){try{mf=0;var S=b(y,v,x,w);return ml=null,S}catch(O){if(O===Cc||O===Cy)throw O;var j=Fn(29,O,null,y.mode);return j.lanes=w,j.return=y,j}finally{}}}var eo=VM(!0),HM=VM(!1),pi=!1;function CS(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function f0(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function zi(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ii(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Me&2){var a=r.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),r.pending=t,t=Np(e),$M(e,null,n),t}return Ny(e,r,t,n),Np(e)}function zu(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194048)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,lM(e,n)}}function pv(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var a=null,i=null;if(n=n.firstBaseUpdate,n!==null){do{var s={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};i===null?a=i=s:i=i.next=s,n=n.next}while(n!==null);i===null?a=i=t:i=i.next=t}else a=i=t;n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:i,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var d0=!1;function Iu(){if(d0){var e=pl;if(e!==null)throw e}}function Bu(e,t,n,r){d0=!1;var a=e.updateQueue;pi=!1;var i=a.firstBaseUpdate,s=a.lastBaseUpdate,o=a.shared.pending;if(o!==null){a.shared.pending=null;var l=o,c=l.next;l.next=null,s===null?i=c:s.next=c,s=l;var f=e.alternate;f!==null&&(f=f.updateQueue,o=f.lastBaseUpdate,o!==s&&(o===null?f.firstBaseUpdate=c:o.next=c,f.lastBaseUpdate=l))}if(i!==null){var d=a.baseState;s=0,f=c=l=null,o=i;do{var h=o.lane&-536870913,p=h!==o.lane;if(p?(Te&h)===h:(r&h)===h){h!==0&&h===Il&&(d0=!0),f!==null&&(f=f.next={lane:0,tag:o.tag,payload:o.payload,callback:null,next:null});e:{var m=e,g=o;h=t;var b=n;switch(g.tag){case 1:if(m=g.payload,typeof m=="function"){d=m.call(b,d,h);break e}d=m;break e;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,h=typeof m=="function"?m.call(b,d,h):m,h==null)break e;d=it({},d,h);break e;case 2:pi=!0}}h=o.callback,h!==null&&(e.flags|=64,p&&(e.flags|=8192),p=a.callbacks,p===null?a.callbacks=[h]:p.push(h))}else p={lane:h,tag:o.tag,payload:o.payload,callback:o.callback,next:null},f===null?(c=f=p,l=d):f=f.next=p,s|=h;if(o=o.next,o===null){if(o=a.shared.pending,o===null)break;p=o,o=p.next,p.next=null,a.lastBaseUpdate=p,a.shared.pending=null}}while(!0);f===null&&(l=d),a.baseState=l,a.firstBaseUpdate=c,a.lastBaseUpdate=f,i===null&&(a.shared.lanes=0),Zi|=s,e.lanes=s,e.memoizedState=d}}function qM(e,t){if(typeof e!="function")throw Error(U(191,e));e.call(t)}function KM(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ei?i:8;var s=he.T,o={};he.T=o,FS(e,!1,t,n);try{var l=a(),c=he.S;if(c!==null&&c(o,l),l!==null&&typeof l=="object"&&typeof l.then=="function"){var f=VI(l,r);Uu(e,t,f,Yn(e))}else Uu(e,t,r,Yn(e))}catch(d){Uu(e,t,{then:function(){},status:"rejected",reason:d},Yn())}finally{De.p=i,s!==null&&o.types!==null&&(s.types=o.types),he.T=s}}function XI(){}function g0(e,t,n,r){if(e.tag!==5)throw Error(U(476));var a=gR(e).queue;yR(e,a,t,Fs,n===null?XI:function(){return vR(e),n(r)})}function gR(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:Fs,baseState:Fs,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ka,lastRenderedState:Fs},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ka,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function vR(e){var t=gR(e);t.next===null&&(t=e.alternate.memoizedState),Uu(e,t.next.queue,{},Yn())}function US(){return en(xf)}function bR(){return wt().memoizedState}function xR(){return wt().memoizedState}function WI(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=Yn();e=zi(n);var r=Ii(t,e,n);r!==null&&(Nn(r,t,n),zu(r,t,n)),t={cache:ES()},e.payload=t;return}t=t.return}}function QI(e,t,n){var r=Yn();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ry(e)?wR(t,n):(n=wS(e,t,n,r),n!==null&&(Nn(n,e,r),jR(n,t,r)))}function SR(e,t,n){var r=Yn();Uu(e,t,n,r)}function Uu(e,t,n,r){var a={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ry(e))wR(t,a);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var s=t.lastRenderedState,o=i(s,n);if(a.hasEagerState=!0,a.eagerState=o,Qn(o,s))return Ny(e,t,a,0),Ye===null&&Ty(),!1}catch{}finally{}if(n=wS(e,t,a,r),n!==null)return Nn(n,e,r),jR(n,t,r),!0}return!1}function FS(e,t,n,r){if(r={lane:2,revertLane:QS(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ry(e)){if(t)throw Error(U(479))}else t=wS(e,n,r,2),t!==null&&Nn(t,e,2)}function Ry(e){var t=e.alternate;return e===xe||t!==null&&t===xe}function wR(e,t){yl=Dp=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function jR(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,lM(e,n)}}var gf={readContext:en,use:Py,useCallback:pt,useContext:pt,useEffect:pt,useImperativeHandle:pt,useLayoutEffect:pt,useInsertionEffect:pt,useMemo:pt,useReducer:pt,useRef:pt,useState:pt,useDebugValue:pt,useDeferredValue:pt,useTransition:pt,useSyncExternalStore:pt,useId:pt,useHostTransitionStatus:pt,useFormState:pt,useActionState:pt,useOptimistic:pt,useMemoCache:pt,useCacheRefresh:pt};gf.useEffectEvent=pt;var AR={readContext:en,use:Py,useCallback:function(e,t){return fn().memoizedState=[e,t===void 0?null:t],e},useContext:en,useEffect:u2,useImperativeHandle:function(e,t,n){n=n!=null?n.concat([e]):null,np(4194308,4,fR.bind(null,t,e),n)},useLayoutEffect:function(e,t){return np(4194308,4,e,t)},useInsertionEffect:function(e,t){np(4,2,e,t)},useMemo:function(e,t){var n=fn();t=t===void 0?null:t;var r=e();if(to){Ci(!0);try{e()}finally{Ci(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=fn();if(n!==void 0){var a=n(t);if(to){Ci(!0);try{n(t)}finally{Ci(!1)}}}else a=t;return r.memoizedState=r.baseState=a,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:a},r.queue=e,e=e.dispatch=QI.bind(null,xe,e),[r.memoizedState,e]},useRef:function(e){var t=fn();return e={current:e},t.memoizedState=e},useState:function(e){e=m0(e);var t=e.queue,n=SR.bind(null,xe,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:IS,useDeferredValue:function(e,t){var n=fn();return BS(n,e,t)},useTransition:function(){var e=m0(!1);return e=yR.bind(null,xe,e.queue,!0,!1),fn().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=xe,a=fn();if(Ce){if(n===void 0)throw Error(U(407));n=n()}else{if(n=t(),Ye===null)throw Error(U(349));Te&127||QM(r,t,n)}a.memoizedState=n;var i={value:n,getSnapshot:t};return a.queue=i,u2(JM.bind(null,r,i,e),[e]),r.flags|=2048,Ul(9,{destroy:void 0},ZM.bind(null,r,i,n,t),null),n},useId:function(){var e=fn(),t=Ye.identifierPrefix;if(Ce){var n=Xr,r=Yr;n=(r&~(1<<32-Gn(r)-1)).toString(32)+n,t="_"+t+"R_"+n,n=$p++,0<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof r.is=="string"?s.createElement("select",{is:r.is}):s.createElement("select"),r.multiple?i.multiple=!0:r.size&&(i.size=r.size);break;default:i=typeof r.is=="string"?s.createElement(a,{is:r.is}):s.createElement(a)}}i[Qt]=t,i[_n]=r;e:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)i.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break e;for(;s.sibling===null;){if(s.return===null||s.return===t)break e;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=i;e:switch(tn(i,a,r),a){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}r&&ga(t)}}return et(t),wv(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&ga(t);else{if(typeof r!="string"&&t.stateNode===null)throw Error(U(166));if(e=ki.current,_o(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Zt,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[Qt]=t,e=!!(e.nodeValue===n||r!==null&&r.suppressHydrationWarning===!0||SD(e.nodeValue,n)),e||Wi(t,!0)}else e=qp(e).createTextNode(r),e[Qt]=t,t.stateNode=e}return et(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=_o(t),n!==null){if(e===null){if(!r)throw Error(U(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(U(557));e[Qt]=t}else Zs(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;et(t),e=!1}else n=hv(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Un(t),t):(Un(t),null);if(t.flags&128)throw Error(U(558))}return et(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=_o(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(U(318));if(a=t.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(U(317));a[Qt]=t}else Zs(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;et(t),a=!1}else a=hv(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Un(t),t):(Un(t),null)}return Un(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),i=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(i=r.memoizedState.cachePool.pool),i!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),mh(t,t.updateQueue),et(t),null);case 4:return kl(),e===null&&ZS(t.stateNode.containerInfo),et(t),null;case 10:return La(t.type),et(t),null;case 19:if(qt(xt),r=t.memoizedState,r===null)return et(t),null;if(a=(t.flags&128)!==0,i=r.rendering,i===null)if(a)ru(r,!1);else{if(vt!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(i=Rp(e),i!==null){for(t.flags|=128,ru(r,!1),e=i.updateQueue,t.updateQueue=e,mh(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)kM(n,e),n=n.sibling;return Ze(xt,xt.current&1|2),Ce&&Oa(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&qn()>Ip&&(t.flags|=128,a=!0,ru(r,!1),t.lanes=4194304)}else{if(!a)if(e=Rp(i),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,mh(t,e),ru(r,!0),r.tail===null&&r.tailMode==="hidden"&&!i.alternate&&!Ce)return et(t),null}else 2*qn()-r.renderingStartTime>Ip&&n!==536870912&&(t.flags|=128,a=!0,ru(r,!1),t.lanes=4194304);r.isBackwards?(i.sibling=t.child,t.child=i):(e=r.last,e!==null?e.sibling=i:t.child=i,r.last=i)}return r.tail!==null?(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=qn(),e.sibling=null,n=xt.current,Ze(xt,a?n&1|2:n&1),Ce&&Oa(t,r.treeForkCount),e):(et(t),null);case 22:case 23:return Un(t),_S(),r=t.memoizedState!==null,e!==null?e.memoizedState!==null!==r&&(t.flags|=8192):r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(et(t),t.subtreeFlags&6&&(t.flags|=8192)):et(t),n=t.updateQueue,n!==null&&mh(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&qt(Hs),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),La(Tt),et(t),null;case 25:return null;case 30:return null}throw Error(U(156,t.tag))}function nB(e,t){switch(OS(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return La(Tt),kl(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Ap(t),null;case 31:if(t.memoizedState!==null){if(Un(t),t.alternate===null)throw Error(U(340));Zs()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Un(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(U(340));Zs()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return qt(xt),null;case 4:return kl(),null;case 10:return La(t.type),null;case 22:case 23:return Un(t),_S(),e!==null&&qt(Hs),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return La(Tt),null;case 25:return null;default:return null}}function kR(e,t){switch(OS(t),t.tag){case 3:La(Tt),kl();break;case 26:case 27:case 5:Ap(t);break;case 4:kl();break;case 31:t.memoizedState!==null&&Un(t);break;case 13:Un(t);break;case 19:qt(xt);break;case 10:La(t.type);break;case 22:case 23:Un(t),_S(),e!==null&&qt(Hs);break;case 24:La(Tt)}}function Cd(e,t){try{var n=t.updateQueue,r=n!==null?n.lastEffect:null;if(r!==null){var a=r.next;n=a;do{if((n.tag&e)===e){r=void 0;var i=n.create,s=n.inst;r=i(),s.destroy=r}n=n.next}while(n!==a)}}catch(o){Ue(t,t.return,o)}}function Qi(e,t,n){try{var r=t.updateQueue,a=r!==null?r.lastEffect:null;if(a!==null){var i=a.next;r=i;do{if((r.tag&e)===e){var s=r.inst,o=s.destroy;if(o!==void 0){s.destroy=void 0,a=t;var l=n,c=o;try{c()}catch(f){Ue(a,l,f)}}}r=r.next}while(r!==i)}}catch(f){Ue(t,t.return,f)}}function LR(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{KM(t,n)}catch(r){Ue(e,e.return,r)}}}function zR(e,t,n){n.props=no(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(r){Ue(e,t,r)}}function Fu(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n=="function"?e.refCleanup=n(r):n.current=r}}catch(a){Ue(e,t,a)}}function Wr(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r=="function")try{r()}catch(a){Ue(e,t,a)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n=="function")try{n(null)}catch(a){Ue(e,t,a)}else n.current=null}function IR(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":n.autoFocus&&r.focus();break e;case"img":n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(a){Ue(e,e.return,a)}}function jv(e,t,n){try{var r=e.stateNode;AB(r,e.type,n,t),r[_n]=t}catch(a){Ue(e,e.return,a)}}function BR(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&ts(e.type)||e.tag===4}function Av(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||BR(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&ts(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function w0(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=_a));else if(r!==4&&(r===27&&ts(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(w0(e,t,n),e=e.sibling;e!==null;)w0(e,t,n),e=e.sibling}function zp(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&ts(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(zp(e,t,n),e=e.sibling;e!==null;)zp(e,t,n),e=e.sibling}function UR(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,a=t.attributes;a.length;)t.removeAttributeNode(a[0]);tn(t,r,n),t[Qt]=e,t[_n]=n}catch(i){Ue(e,e.return,i)}}var Na=!1,Et=!1,Ov=!1,j2=typeof WeakSet=="function"?WeakSet:Set,Ft=null;function rB(e,t){if(e=e.containerInfo,C0=Xp,e=NM(e),xS(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var s=0,o=-1,l=-1,c=0,f=0,d=e,h=null;t:for(;;){for(var p;d!==n||a!==0&&d.nodeType!==3||(o=s+a),d!==i||r!==0&&d.nodeType!==3||(l=s+r),d.nodeType===3&&(s+=d.nodeValue.length),(p=d.firstChild)!==null;)h=d,d=p;for(;;){if(d===e)break t;if(h===n&&++c===a&&(o=s),h===i&&++f===r&&(l=s),(p=d.nextSibling)!==null)break;d=h,h=d.parentNode}d=p}n=o===-1||l===-1?null:{start:o,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(_0={focusedElem:e,selectionRange:n},Xp=!1,Ft=t;Ft!==null;)if(t=Ft,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,Ft=e;else for(;Ft!==null;){switch(t=Ft,i=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(n=0;n title"))),tn(i,r,n),i[Qt]=e,Vt(i),r=i;break e;case"link":var s=V2("link","href",a).get(r+(n.href||""));if(s){for(var o=0;ob&&(s=b,b=g,g=s);var y=YA(o,g),v=YA(o,b);if(y&&v&&(p.rangeCount!==1||p.anchorNode!==y.node||p.anchorOffset!==y.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var x=d.createRange();x.setStart(y.node,y.offset),p.removeAllRanges(),g>b?(p.addRange(x),p.extend(v.node,v.offset)):(x.setEnd(v.node,v.offset),p.addRange(x))}}}}for(d=[],p=o;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof o.focus=="function"&&o.focus(),o=0;on?32:n,he.T=null,n=O0,O0=null;var i=Ui,s=za;if(Dt=0,Vl=Ui=null,za=0,Me&6)throw Error(U(331));var o=Me;if(Me|=4,ZR(i.current),XR(i,i.current,s,n),Me=o,_d(0,!1),Kn&&typeof Kn.onPostCommitFiberRoot=="function")try{Kn.onPostCommitFiberRoot(wd,i)}catch{}return!0}finally{De.p=a,he.T=r,hD(e,t)}}function T2(e,t,n){t=dr(n,t),t=b0(e.stateNode,t,2),e=Ii(e,t,2),e!==null&&(Ad(e,2),fa(e))}function Ue(e,t,n){if(e.tag===3)T2(e,e,n);else for(;t!==null;){if(t.tag===3){T2(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof r.componentDidCatch=="function"&&(Bi===null||!Bi.has(r))){e=dr(n,e),n=CR(2),r=Ii(t,n,2),r!==null&&(_R(n,r,t,e),Ad(r,2),fa(r));break}}t=t.return}}function Tv(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new sB;var a=new Set;r.set(t,a)}else a=r.get(t),a===void 0&&(a=new Set,r.set(t,a));a.has(n)||(YS=!0,a.add(n),e=fB.bind(null,e,t,n),t.then(e,e))}function fB(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Ye===e&&(Te&n)===n&&(vt===4||vt===3&&(Te&62914560)===Te&&300>qn()-Dy?!(Me&2)&&Hl(e,0):XS|=n,Fl===Te&&(Fl=0)),fa(e)}function mD(e,t){t===0&&(t=sM()),e=vo(e,t),e!==null&&(Ad(e,t),fa(e))}function dB(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),mD(e,n)}function hB(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(U(314))}r!==null&&r.delete(t),mD(e,n)}function pB(e,t){return fS(e,t)}var Fp=null,Fo=null,T0=!1,Vp=!1,Nv=!1,Ri=0;function fa(e){e!==Fo&&e.next===null&&(Fo===null?Fp=Fo=e:Fo=Fo.next=e),Vp=!0,T0||(T0=!0,yB())}function _d(e,t){if(!Nv&&Vp){Nv=!0;do for(var n=!1,r=Fp;r!==null;){if(e!==0){var a=r.pendingLanes;if(a===0)var i=0;else{var s=r.suspendedLanes,o=r.pingedLanes;i=(1<<31-Gn(42|e)+1)-1,i&=a&~(s&~o),i=i&201326741?i&201326741|1:i?i|2:0}i!==0&&(n=!0,N2(r,i))}else i=Te,i=jy(r,r===Ye?i:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(i&3)||jd(r,i)||(n=!0,N2(r,i));r=r.next}while(n);Nv=!1}}function mB(){yD()}function yD(){Vp=T0=!1;var e=0;Ri!==0&&EB()&&(e=Ri);for(var t=qn(),n=null,r=Fp;r!==null;){var a=r.next,i=gD(r,t);i===0?(r.next=null,n===null?Fp=a:n.next=a,a===null&&(Fo=n)):(n=r,(e!==0||i&3)&&(Vp=!0)),r=a}Dt!==0&&Dt!==5||_d(e),Ri!==0&&(Ri=0)}function gD(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,a=e.expirationTimes,i=e.pendingLanes&-62914561;0o)break;var f=l.transferSize,d=l.initiatorType;f&&R2(d)&&(l=l.responseEnd,s+=f*(l"u"?null:document;function ED(e,t,n){var r=Pc;if(r&&typeof t=="string"&&t){var a=fr(t);a='link[rel="'+e+'"][href="'+a+'"]',typeof n=="string"&&(a+='[crossorigin="'+n+'"]'),B2.has(a)||(B2.add(a),e={rel:e,crossOrigin:n,href:t},r.querySelector(a)===null&&(t=r.createElement("link"),tn(t,"link",e),Vt(t),r.head.appendChild(t)))}}function $B(e){ei.D(e),ED("dns-prefetch",e,null)}function kB(e,t){ei.C(e,t),ED("preconnect",e,t)}function LB(e,t,n){ei.L(e,t,n);var r=Pc;if(r&&e&&t){var a='link[rel="preload"][as="'+fr(t)+'"]';t==="image"&&n&&n.imageSrcSet?(a+='[imagesrcset="'+fr(n.imageSrcSet)+'"]',typeof n.imageSizes=="string"&&(a+='[imagesizes="'+fr(n.imageSizes)+'"]')):a+='[href="'+fr(e)+'"]';var i=a;switch(t){case"style":i=ql(e);break;case"script":i=Mc(e)}vr.has(i)||(e=it({rel:"preload",href:t==="image"&&n&&n.imageSrcSet?void 0:e,as:t},n),vr.set(i,e),r.querySelector(a)!==null||t==="style"&&r.querySelector(Pd(i))||t==="script"&&r.querySelector(Md(i))||(t=r.createElement("link"),tn(t,"link",e),Vt(t),r.head.appendChild(t)))}}function zB(e,t){ei.m(e,t);var n=Pc;if(n&&e){var r=t&&typeof t.as=="string"?t.as:"script",a='link[rel="modulepreload"][as="'+fr(r)+'"][href="'+fr(e)+'"]',i=a;switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":i=Mc(e)}if(!vr.has(i)&&(e=it({rel:"modulepreload",href:e},t),vr.set(i,e),n.querySelector(a)===null)){switch(r){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(Md(i)))return}r=n.createElement("link"),tn(r,"link",e),Vt(r),n.head.appendChild(r)}}}function IB(e,t,n){ei.S(e,t,n);var r=Pc;if(r&&e){var a=fl(r).hoistableStyles,i=ql(e);t=t||"default";var s=a.get(i);if(!s){var o={loading:0,preload:null};if(s=r.querySelector(Pd(i)))o.loading=5;else{e=it({rel:"stylesheet",href:e,"data-precedence":t},n),(n=vr.get(i))&&JS(e,n);var l=s=r.createElement("link");Vt(l),tn(l,"link",e),l._p=new Promise(function(c,f){l.onload=c,l.onerror=f}),l.addEventListener("load",function(){o.loading|=1}),l.addEventListener("error",function(){o.loading|=2}),o.loading|=4,sp(s,t,r)}s={type:"stylesheet",instance:s,count:1,state:o},a.set(i,s)}}}function BB(e,t){ei.X(e,t);var n=Pc;if(n&&e){var r=fl(n).hoistableScripts,a=Mc(e),i=r.get(a);i||(i=n.querySelector(Md(a)),i||(e=it({src:e,async:!0},t),(t=vr.get(a))&&ew(e,t),i=n.createElement("script"),Vt(i),tn(i,"link",e),n.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},r.set(a,i))}}function UB(e,t){ei.M(e,t);var n=Pc;if(n&&e){var r=fl(n).hoistableScripts,a=Mc(e),i=r.get(a);i||(i=n.querySelector(Md(a)),i||(e=it({src:e,async:!0,type:"module"},t),(t=vr.get(a))&&ew(e,t),i=n.createElement("script"),Vt(i),tn(i,"link",e),n.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},r.set(a,i))}}function U2(e,t,n,r){var a=(a=ki.current)?Kp(a):null;if(!a)throw Error(U(446));switch(e){case"meta":case"title":return null;case"style":return typeof n.precedence=="string"&&typeof n.href=="string"?(t=ql(n.href),n=fl(a).hoistableStyles,r=n.get(t),r||(r={type:"style",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};case"link":if(n.rel==="stylesheet"&&typeof n.href=="string"&&typeof n.precedence=="string"){e=ql(n.href);var i=fl(a).hoistableStyles,s=i.get(e);if(s||(a=a.ownerDocument||a,s={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},i.set(e,s),(i=a.querySelector(Pd(e)))&&!i._p&&(s.instance=i,s.state.loading=5),vr.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vr.set(e,n),i||FB(a,e,n,s.state))),t&&r===null)throw Error(U(528,""));return s}if(t&&r!==null)throw Error(U(529,""));return null;case"script":return t=n.async,n=n.src,typeof n=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=Mc(n),n=fl(a).hoistableScripts,r=n.get(t),r||(r={type:"script",instance:null,count:0,state:null},n.set(t,r)),r):{type:"void",instance:null,count:0,state:null};default:throw Error(U(444,e))}}function ql(e){return'href="'+fr(e)+'"'}function Pd(e){return'link[rel="stylesheet"]['+e+"]"}function TD(e){return it({},e,{"data-precedence":e.precedence,precedence:null})}function FB(e,t,n,r){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?r.loading=1:(t=e.createElement("link"),r.preload=t,t.addEventListener("load",function(){return r.loading|=1}),t.addEventListener("error",function(){return r.loading|=2}),tn(t,"link",n),Vt(t),e.head.appendChild(t))}function Mc(e){return'[src="'+fr(e)+'"]'}function Md(e){return"script[async]"+e}function F2(e,t,n){if(t.count++,t.instance===null)switch(t.type){case"style":var r=e.querySelector('style[data-href~="'+fr(n.href)+'"]');if(r)return t.instance=r,Vt(r),r;var a=it({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement("style"),Vt(r),tn(r,"style",a),sp(r,n.precedence,e),t.instance=r;case"stylesheet":a=ql(n.href);var i=e.querySelector(Pd(a));if(i)return t.state.loading|=4,t.instance=i,Vt(i),i;r=TD(n),(a=vr.get(a))&&JS(r,a),i=(e.ownerDocument||e).createElement("link"),Vt(i);var s=i;return s._p=new Promise(function(o,l){s.onload=o,s.onerror=l}),tn(i,"link",r),t.state.loading|=4,sp(i,n.precedence,e),t.instance=i;case"script":return i=Mc(n.src),(a=e.querySelector(Md(i)))?(t.instance=a,Vt(a),a):(r=n,(a=vr.get(i))&&(r=it({},n),ew(r,a)),e=e.ownerDocument||e,a=e.createElement("script"),Vt(a),tn(a,"link",r),e.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(U(443,t.type))}else t.type==="stylesheet"&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,sp(r,n.precedence,e));return t.instance}function sp(e,t,n){for(var r=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=r.length?r[r.length-1]:null,i=a,s=0;s title"):null)}function VB(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return e=t.disabled,typeof t.precedence=="string"&&e==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function ND(e){return!(e.type==="stylesheet"&&!(e.state.loading&3))}function HB(e,t,n,r){if(n.type==="stylesheet"&&(typeof r.media!="string"||matchMedia(r.media).matches!==!1)&&!(n.state.loading&4)){if(n.instance===null){var a=ql(r.href),i=t.querySelector(Pd(a));if(i){t=i._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=Gp.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=i,Vt(i);return}i=t.ownerDocument||t,r=TD(r),(a=vr.get(a))&&JS(r,a),i=i.createElement("link"),Vt(i);var s=i;s._p=new Promise(function(o,l){s.onload=o,s.onerror=l}),tn(i,"link",r),n.instance=i}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Gp.bind(e),t.addEventListener("load",n),t.addEventListener("error",n))}}var Dv=0;function qB(e,t){return e.stylesheets&&e.count===0&&lp(e,e.stylesheets),0Dv?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(a)}}:null}function Gp(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)lp(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yp=null;function lp(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yp=new Map,t.forEach(KB,e),Yp=null,Gp.call(e))}function KB(e,t){if(!(t.state.loading&4)){var n=Yp.get(e);if(n)var r=n.get(null);else{n=new Map,Yp.set(e,n);for(var a=e.querySelectorAll("link[data-precedence],style[data-precedence]"),i=0;i"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(kD)}catch(e){console.error(e)}}kD(),HP.exports=Sy;var e8=HP.exports;const t8=Ie(e8);var Rd=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},Rs,Si,jl,OP,n8=(OP=class extends Rd{constructor(){super();ce(this,Rs);ce(this,Si);ce(this,jl);ee(this,jl,t=>{if(typeof window<"u"&&window.addEventListener){const n=()=>t();return window.addEventListener("visibilitychange",n,!1),()=>{window.removeEventListener("visibilitychange",n)}}})}onSubscribe(){R(this,Si)||this.setEventListener(R(this,jl))}onUnsubscribe(){var t;this.hasListeners()||((t=R(this,Si))==null||t.call(this),ee(this,Si,void 0))}setEventListener(t){var n;ee(this,jl,t),(n=R(this,Si))==null||n.call(this),ee(this,Si,t(r=>{typeof r=="boolean"?this.setFocused(r):this.onFocus()}))}setFocused(t){R(this,Rs)!==t&&(ee(this,Rs,t),this.onFocus())}onFocus(){const t=this.isFocused();this.listeners.forEach(n=>{n(t)})}isFocused(){var t;return typeof R(this,Rs)=="boolean"?R(this,Rs):((t=globalThis.document)==null?void 0:t.visibilityState)!=="hidden"}},Rs=new WeakMap,Si=new WeakMap,jl=new WeakMap,OP),iw=new n8,r8={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},wi,rS,EP,a8=(EP=class{constructor(){ce(this,wi,r8);ce(this,rS,!1)}setTimeoutProvider(e){ee(this,wi,e)}setTimeout(e,t){return R(this,wi).setTimeout(e,t)}clearTimeout(e){R(this,wi).clearTimeout(e)}setInterval(e,t){return R(this,wi).setInterval(e,t)}clearInterval(e){R(this,wi).clearInterval(e)}},wi=new WeakMap,rS=new WeakMap,EP),As=new a8;function i8(e){setTimeout(e,0)}var s8=typeof window>"u"||"Deno"in globalThis;function En(){}function o8(e,t){return typeof e=="function"?e(t):e}function z0(e){return typeof e=="number"&&e>=0&&e!==1/0}function LD(e,t){return Math.max(e+(t||0)-Date.now(),0)}function qi(e,t){return typeof e=="function"?e(t):e}function In(e,t){return typeof e=="function"?e(t):e}function Q2(e,t){const{type:n="all",exact:r,fetchStatus:a,predicate:i,queryKey:s,stale:o}=e;if(s){if(r){if(t.queryHash!==sw(s,t.options))return!1}else if(!Af(t.queryKey,s))return!1}if(n!=="all"){const l=t.isActive();if(n==="active"&&!l||n==="inactive"&&l)return!1}return!(typeof o=="boolean"&&t.isStale()!==o||a&&a!==t.state.fetchStatus||i&&!i(t))}function Z2(e,t){const{exact:n,status:r,predicate:a,mutationKey:i}=e;if(i){if(!t.options.mutationKey)return!1;if(n){if(jf(t.options.mutationKey)!==jf(i))return!1}else if(!Af(t.options.mutationKey,i))return!1}return!(r&&t.state.status!==r||a&&!a(t))}function sw(e,t){return((t==null?void 0:t.queryKeyHashFn)||jf)(e)}function jf(e){return JSON.stringify(e,(t,n)=>B0(n)?Object.keys(n).sort().reduce((r,a)=>(r[a]=n[a],r),{}):n)}function Af(e,t){return e===t?!0:typeof e!=typeof t?!1:e&&t&&typeof e=="object"&&typeof t=="object"?Object.keys(t).every(n=>Af(e[n],t[n])):!1}var l8=Object.prototype.hasOwnProperty;function zD(e,t,n=0){if(e===t)return e;if(n>500)return t;const r=J2(e)&&J2(t);if(!r&&!(B0(e)&&B0(t)))return t;const i=(r?e:Object.keys(e)).length,s=r?t:Object.keys(t),o=s.length,l=r?new Array(o):{};let c=0;for(let f=0;f{As.setTimeout(t,e)})}function U0(e,t,n){return typeof n.structuralSharing=="function"?n.structuralSharing(e,t):n.structuralSharing!==!1?zD(e,t):t}function u8(e,t,n=0){const r=[...e,t];return n&&r.length>n?r.slice(1):r}function f8(e,t,n=0){const r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var ow=Symbol();function ID(e,t){return!e.queryFn&&(t!=null&&t.initialPromise)?()=>t.initialPromise:!e.queryFn||e.queryFn===ow?()=>Promise.reject(new Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function BD(e,t){return typeof e=="function"?e(...t):!!e}function d8(e,t,n){let r=!1,a;return Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(a??(a=t()),r||(r=!0,a.aborted?n():a.addEventListener("abort",n,{once:!0})),a)}),e}var Of=(()=>{let e=()=>s8;return{isServer(){return e()},setIsServer(t){e=t}}})();function F0(){let e,t;const n=new Promise((a,i)=>{e=a,t=i});n.status="pending",n.catch(()=>{});function r(a){Object.assign(n,a),delete n.resolve,delete n.reject}return n.resolve=a=>{r({status:"fulfilled",value:a}),e(a)},n.reject=a=>{r({status:"rejected",reason:a}),t(a)},n}var h8=i8;function p8(){let e=[],t=0,n=o=>{o()},r=o=>{o()},a=h8;const i=o=>{t?e.push(o):a(()=>{n(o)})},s=()=>{const o=e;e=[],o.length&&a(()=>{r(()=>{o.forEach(l=>{n(l)})})})};return{batch:o=>{let l;t++;try{l=o()}finally{t--,t||s()}return l},batchCalls:o=>(...l)=>{i(()=>{o(...l)})},schedule:i,setNotifyFunction:o=>{n=o},setBatchNotifyFunction:o=>{r=o},setScheduler:o=>{a=o}}}var Wt=p8(),Al,ji,Ol,TP,m8=(TP=class extends Rd{constructor(){super();ce(this,Al,!0);ce(this,ji);ce(this,Ol);ee(this,Ol,t=>{if(typeof window<"u"&&window.addEventListener){const n=()=>t(!0),r=()=>t(!1);return window.addEventListener("online",n,!1),window.addEventListener("offline",r,!1),()=>{window.removeEventListener("online",n),window.removeEventListener("offline",r)}}})}onSubscribe(){R(this,ji)||this.setEventListener(R(this,Ol))}onUnsubscribe(){var t;this.hasListeners()||((t=R(this,ji))==null||t.call(this),ee(this,ji,void 0))}setEventListener(t){var n;ee(this,Ol,t),(n=R(this,ji))==null||n.call(this),ee(this,ji,t(this.setOnline.bind(this)))}setOnline(t){R(this,Al)!==t&&(ee(this,Al,t),this.listeners.forEach(r=>{r(t)}))}isOnline(){return R(this,Al)}},Al=new WeakMap,ji=new WeakMap,Ol=new WeakMap,TP),Qp=new m8;function y8(e){return Math.min(1e3*2**e,3e4)}function UD(e){return(e??"online")==="online"?Qp.isOnline():!0}var V0=class extends Error{constructor(e){super("CancelledError"),this.revert=e==null?void 0:e.revert,this.silent=e==null?void 0:e.silent}};function FD(e){let t=!1,n=0,r;const a=F0(),i=()=>a.status!=="pending",s=g=>{var b;if(!i()){const y=new V0(g);h(y),(b=e.onCancel)==null||b.call(e,y)}},o=()=>{t=!0},l=()=>{t=!1},c=()=>iw.isFocused()&&(e.networkMode==="always"||Qp.isOnline())&&e.canRun(),f=()=>UD(e.networkMode)&&e.canRun(),d=g=>{i()||(r==null||r(),a.resolve(g))},h=g=>{i()||(r==null||r(),a.reject(g))},p=()=>new Promise(g=>{var b;r=y=>{(i()||c())&&g(y)},(b=e.onPause)==null||b.call(e)}).then(()=>{var g;r=void 0,i()||(g=e.onContinue)==null||g.call(e)}),m=()=>{if(i())return;let g;const b=n===0?e.initialPromise:void 0;try{g=b??e.fn()}catch(y){g=Promise.reject(y)}Promise.resolve(g).then(d).catch(y=>{var j;if(i())return;const v=e.retry??(Of.isServer()?0:3),x=e.retryDelay??y8,w=typeof x=="function"?x(n,y):x,S=v===!0||typeof v=="number"&&nc()?void 0:p()).then(()=>{t?h(y):m()})})};return{promise:a,status:()=>a.status,cancel:s,continue:()=>(r==null||r(),a),cancelRetry:o,continueRetry:l,canStart:f,start:()=>(f()?m():p().then(m),a)}}var Ds,NP,VD=(NP=class{constructor(){ce(this,Ds)}destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),z0(this.gcTime)&&ee(this,Ds,As.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(Of.isServer()?1/0:5*60*1e3))}clearGcTimeout(){R(this,Ds)!==void 0&&(As.clearTimeout(R(this,Ds)),ee(this,Ds,void 0))}},Ds=new WeakMap,NP);function g8(e){return{onFetch:(t,n)=>{var f,d,h,p,m;const r=t.options,a=(h=(d=(f=t.fetchOptions)==null?void 0:f.meta)==null?void 0:d.fetchMore)==null?void 0:h.direction,i=((p=t.state.data)==null?void 0:p.pages)||[],s=((m=t.state.data)==null?void 0:m.pageParams)||[];let o={pages:[],pageParams:[]},l=0;const c=async()=>{let g=!1;const b=x=>{d8(x,()=>t.signal,()=>g=!0)},y=ID(t.options,t.fetchOptions),v=async(x,w,S)=>{if(g)return Promise.reject(t.signal.reason);if(w==null&&x.pages.length)return Promise.resolve(x);const O=(()=>{const M={client:t.client,queryKey:t.queryKey,pageParam:w,direction:S?"backward":"forward",meta:t.options.meta};return b(M),M})(),E=await y(O),{maxPages:T}=t.options,N=S?f8:u8;return{pages:N(x.pages,E,T),pageParams:N(x.pageParams,w,T)}};if(a&&i.length){const x=a==="backward",w=x?v8:tO,S={pages:i,pageParams:s},j=w(r,S);o=await v(S,j,x)}else{const x=e??i.length;do{const w=l===0?s[0]??r.initialPageParam:tO(r,o);if(l>0&&w==null)break;o=await v(o,w),l++}while(l{var g,b;return(b=(g=t.options).persister)==null?void 0:b.call(g,c,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n)}:t.fetchFn=c}}}function tO(e,{pages:t,pageParams:n}){const r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function v8(e,{pages:t,pageParams:n}){var r;return t.length>0?(r=e.getPreviousPageParam)==null?void 0:r.call(e,t[0],t,n[0],n):void 0}var El,$s,Tl,sr,ks,It,yd,Ls,zn,HD,ja,CP,b8=(CP=class extends VD{constructor(t){super();ce(this,zn);ce(this,El);ce(this,$s);ce(this,Tl);ce(this,sr);ce(this,ks);ce(this,It);ce(this,yd);ce(this,Ls);ee(this,Ls,!1),ee(this,yd,t.defaultOptions),this.setOptions(t.options),this.observers=[],ee(this,ks,t.client),ee(this,sr,R(this,ks).getQueryCache()),this.queryKey=t.queryKey,this.queryHash=t.queryHash,ee(this,$s,rO(this.options)),this.state=t.state??R(this,$s),this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return R(this,El)}get promise(){var t;return(t=R(this,It))==null?void 0:t.promise}setOptions(t){if(this.options={...R(this,yd),...t},t!=null&&t._type&&ee(this,El,t._type),this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){const n=rO(this.options);n.data!==void 0&&(this.setState(nO(n.data,n.dataUpdatedAt)),ee(this,$s,n))}}optionalRemove(){!this.observers.length&&this.state.fetchStatus==="idle"&&R(this,sr).remove(this)}setData(t,n){const r=U0(this.state.data,t,this.options);return Oe(this,zn,ja).call(this,{data:r,type:"success",dataUpdatedAt:n==null?void 0:n.updatedAt,manual:n==null?void 0:n.manual}),r}setState(t){Oe(this,zn,ja).call(this,{type:"setState",state:t})}cancel(t){var r,a;const n=(r=R(this,It))==null?void 0:r.promise;return(a=R(this,It))==null||a.cancel(t),n?n.then(En).catch(En):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return R(this,$s)}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(t=>In(t.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===ow||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0?this.observers.some(t=>qi(t.options.staleTime,this)==="static"):!1}isStale(){return this.getObserversCount()>0?this.observers.some(t=>t.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(t=0){return this.state.data===void 0?!0:t==="static"?!1:this.state.isInvalidated?!0:!LD(this.state.dataUpdatedAt,t)}onFocus(){var n;const t=this.observers.find(r=>r.shouldFetchOnWindowFocus());t==null||t.refetch({cancelRefetch:!1}),(n=R(this,It))==null||n.continue()}onOnline(){var n;const t=this.observers.find(r=>r.shouldFetchOnReconnect());t==null||t.refetch({cancelRefetch:!1}),(n=R(this,It))==null||n.continue()}addObserver(t){this.observers.includes(t)||(this.observers.push(t),this.clearGcTimeout(),R(this,sr).notify({type:"observerAdded",query:this,observer:t}))}removeObserver(t){this.observers.includes(t)&&(this.observers=this.observers.filter(n=>n!==t),this.observers.length||(R(this,It)&&(R(this,Ls)||Oe(this,zn,HD).call(this)?R(this,It).cancel({revert:!0}):R(this,It).cancelRetry()),this.scheduleGc()),R(this,sr).notify({type:"observerRemoved",query:this,observer:t}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||Oe(this,zn,ja).call(this,{type:"invalidate"})}async fetch(t,n){var c,f,d,h,p,m,g,b,y,v,x;if(this.state.fetchStatus!=="idle"&&((c=R(this,It))==null?void 0:c.status())!=="rejected"){if(this.state.data!==void 0&&(n!=null&&n.cancelRefetch))this.cancel({silent:!0});else if(R(this,It))return R(this,It).continueRetry(),R(this,It).promise}if(t&&this.setOptions(t),!this.options.queryFn){const w=this.observers.find(S=>S.options.queryFn);w&&this.setOptions(w.options)}const r=new AbortController,a=w=>{Object.defineProperty(w,"signal",{enumerable:!0,get:()=>(ee(this,Ls,!0),r.signal)})},i=()=>{const w=ID(this.options,n),j=(()=>{const O={client:R(this,ks),queryKey:this.queryKey,meta:this.meta};return a(O),O})();return ee(this,Ls,!1),this.options.persister?this.options.persister(w,j,this):w(j)},o=(()=>{const w={fetchOptions:n,options:this.options,queryKey:this.queryKey,client:R(this,ks),state:this.state,fetchFn:i};return a(w),w})(),l=R(this,El)==="infinite"?g8(this.options.pages):this.options.behavior;l==null||l.onFetch(o,this),ee(this,Tl,this.state),(this.state.fetchStatus==="idle"||this.state.fetchMeta!==((f=o.fetchOptions)==null?void 0:f.meta))&&Oe(this,zn,ja).call(this,{type:"fetch",meta:(d=o.fetchOptions)==null?void 0:d.meta}),ee(this,It,FD({initialPromise:n==null?void 0:n.initialPromise,fn:o.fetchFn,onCancel:w=>{w instanceof V0&&w.revert&&this.setState({...R(this,Tl),fetchStatus:"idle"}),r.abort()},onFail:(w,S)=>{Oe(this,zn,ja).call(this,{type:"failed",failureCount:w,error:S})},onPause:()=>{Oe(this,zn,ja).call(this,{type:"pause"})},onContinue:()=>{Oe(this,zn,ja).call(this,{type:"continue"})},retry:o.options.retry,retryDelay:o.options.retryDelay,networkMode:o.options.networkMode,canRun:()=>!0}));try{const w=await R(this,It).start();if(w===void 0)throw new Error(`${this.queryHash} data is undefined`);return this.setData(w),(p=(h=R(this,sr).config).onSuccess)==null||p.call(h,w,this),(g=(m=R(this,sr).config).onSettled)==null||g.call(m,w,this.state.error,this),w}catch(w){if(w instanceof V0){if(w.silent)return R(this,It).promise;if(w.revert){if(this.state.data===void 0)throw w;return this.state.data}}throw Oe(this,zn,ja).call(this,{type:"error",error:w}),(y=(b=R(this,sr).config).onError)==null||y.call(b,w,this),(x=(v=R(this,sr).config).onSettled)==null||x.call(v,this.state.data,w,this),w}finally{this.scheduleGc()}}},El=new WeakMap,$s=new WeakMap,Tl=new WeakMap,sr=new WeakMap,ks=new WeakMap,It=new WeakMap,yd=new WeakMap,Ls=new WeakMap,zn=new WeakSet,HD=function(){return this.state.fetchStatus==="paused"&&this.state.status==="pending"},ja=function(t){const n=r=>{switch(t.type){case"failed":return{...r,fetchFailureCount:t.failureCount,fetchFailureReason:t.error};case"pause":return{...r,fetchStatus:"paused"};case"continue":return{...r,fetchStatus:"fetching"};case"fetch":return{...r,...qD(r.data,this.options),fetchMeta:t.meta??null};case"success":const a={...r,...nO(t.data,t.dataUpdatedAt),dataUpdateCount:r.dataUpdateCount+1,...!t.manual&&{fetchStatus:"idle",fetchFailureCount:0,fetchFailureReason:null}};return ee(this,Tl,t.manual?a:void 0),a;case"error":const i=t.error;return{...r,error:i,errorUpdateCount:r.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:r.fetchFailureCount+1,fetchFailureReason:i,fetchStatus:"idle",status:"error",isInvalidated:!0};case"invalidate":return{...r,isInvalidated:!0};case"setState":return{...r,...t.state}}};this.state=n(this.state),Wt.batch(()=>{this.observers.forEach(r=>{r.onQueryUpdate()}),R(this,sr).notify({query:this,type:"updated",action:t})})},CP);function qD(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:UD(t.networkMode)?"fetching":"paused",...e===void 0&&{error:null,status:"pending"}}}function nO(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:"success"}}function rO(e){const t=typeof e.initialData=="function"?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt=="function"?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?"success":"pending",fetchStatus:"idle"}}var jn,Ne,gd,un,zs,Nl,Ea,Ai,vd,Cl,_l,Is,Bs,Oi,Pl,ze,Tu,H0,q0,K0,G0,Y0,X0,W0,KD,_P,x8=(_P=class extends Rd{constructor(t,n){super();ce(this,ze);ce(this,jn);ce(this,Ne);ce(this,gd);ce(this,un);ce(this,zs);ce(this,Nl);ce(this,Ea);ce(this,Ai);ce(this,vd);ce(this,Cl);ce(this,_l);ce(this,Is);ce(this,Bs);ce(this,Oi);ce(this,Pl,new Set);this.options=n,ee(this,jn,t),ee(this,Ai,null),ee(this,Ea,F0()),this.bindMethods(),this.setOptions(n)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(R(this,Ne).addObserver(this),aO(R(this,Ne),this.options)?Oe(this,ze,Tu).call(this):this.updateResult(),Oe(this,ze,G0).call(this))}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Q0(R(this,Ne),this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Q0(R(this,Ne),this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,Oe(this,ze,Y0).call(this),Oe(this,ze,X0).call(this),R(this,Ne).removeObserver(this)}setOptions(t){const n=this.options,r=R(this,Ne);if(this.options=R(this,jn).defaultQueryOptions(t),this.options.enabled!==void 0&&typeof this.options.enabled!="boolean"&&typeof this.options.enabled!="function"&&typeof In(this.options.enabled,R(this,Ne))!="boolean")throw new Error("Expected enabled to be a boolean or a callback that returns a boolean");Oe(this,ze,W0).call(this),R(this,Ne).setOptions(this.options),n._defaulted&&!I0(this.options,n)&&R(this,jn).getQueryCache().notify({type:"observerOptionsUpdated",query:R(this,Ne),observer:this});const a=this.hasListeners();a&&iO(R(this,Ne),r,this.options,n)&&Oe(this,ze,Tu).call(this),this.updateResult(),a&&(R(this,Ne)!==r||In(this.options.enabled,R(this,Ne))!==In(n.enabled,R(this,Ne))||qi(this.options.staleTime,R(this,Ne))!==qi(n.staleTime,R(this,Ne)))&&Oe(this,ze,H0).call(this);const i=Oe(this,ze,q0).call(this);a&&(R(this,Ne)!==r||In(this.options.enabled,R(this,Ne))!==In(n.enabled,R(this,Ne))||i!==R(this,Oi))&&Oe(this,ze,K0).call(this,i)}getOptimisticResult(t){const n=R(this,jn).getQueryCache().build(R(this,jn),t),r=this.createResult(n,t);return w8(this,r)&&(ee(this,un,r),ee(this,Nl,this.options),ee(this,zs,R(this,Ne).state)),r}getCurrentResult(){return R(this,un)}trackResult(t,n){return new Proxy(t,{get:(r,a)=>(this.trackProp(a),n==null||n(a),a==="promise"&&(this.trackProp("data"),!this.options.experimental_prefetchInRender&&R(this,Ea).status==="pending"&&R(this,Ea).reject(new Error("experimental_prefetchInRender feature flag is not enabled"))),Reflect.get(r,a))})}trackProp(t){R(this,Pl).add(t)}getCurrentQuery(){return R(this,Ne)}refetch({...t}={}){return this.fetch({...t})}fetchOptimistic(t){const n=R(this,jn).defaultQueryOptions(t),r=R(this,jn).getQueryCache().build(R(this,jn),n);return r.fetch().then(()=>this.createResult(r,n))}fetch(t){return Oe(this,ze,Tu).call(this,{...t,cancelRefetch:t.cancelRefetch??!0}).then(()=>(this.updateResult(),R(this,un)))}createResult(t,n){var T;const r=R(this,Ne),a=this.options,i=R(this,un),s=R(this,zs),o=R(this,Nl),c=t!==r?t.state:R(this,gd),{state:f}=t;let d={...f},h=!1,p;if(n._optimisticResults){const N=this.hasListeners(),M=!N&&aO(t,n),C=N&&iO(t,r,n,a);(M||C)&&(d={...d,...qD(f.data,t.options)}),n._optimisticResults==="isRestoring"&&(d.fetchStatus="idle")}let{error:m,errorUpdatedAt:g,status:b}=d;p=d.data;let y=!1;if(n.placeholderData!==void 0&&p===void 0&&b==="pending"){let N;i!=null&&i.isPlaceholderData&&n.placeholderData===(o==null?void 0:o.placeholderData)?(N=i.data,y=!0):N=typeof n.placeholderData=="function"?n.placeholderData((T=R(this,_l))==null?void 0:T.state.data,R(this,_l)):n.placeholderData,N!==void 0&&(b="success",p=U0(i==null?void 0:i.data,N,n),h=!0)}if(n.select&&p!==void 0&&!y)if(i&&p===(s==null?void 0:s.data)&&n.select===R(this,vd))p=R(this,Cl);else try{ee(this,vd,n.select),p=n.select(p),p=U0(i==null?void 0:i.data,p,n),ee(this,Cl,p),ee(this,Ai,null)}catch(N){ee(this,Ai,N)}R(this,Ai)&&(m=R(this,Ai),p=R(this,Cl),g=Date.now(),b="error");const v=d.fetchStatus==="fetching",x=b==="pending",w=b==="error",S=x&&v,j=p!==void 0,E={status:b,fetchStatus:d.fetchStatus,isPending:x,isSuccess:b==="success",isError:w,isInitialLoading:S,isLoading:S,data:p,dataUpdatedAt:d.dataUpdatedAt,error:m,errorUpdatedAt:g,failureCount:d.fetchFailureCount,failureReason:d.fetchFailureReason,errorUpdateCount:d.errorUpdateCount,isFetched:t.isFetched(),isFetchedAfterMount:d.dataUpdateCount>c.dataUpdateCount||d.errorUpdateCount>c.errorUpdateCount,isFetching:v,isRefetching:v&&!x,isLoadingError:w&&!j,isPaused:d.fetchStatus==="paused",isPlaceholderData:h,isRefetchError:w&&j,isStale:lw(t,n),refetch:this.refetch,promise:R(this,Ea),isEnabled:In(n.enabled,t)!==!1};if(this.options.experimental_prefetchInRender){const N=E.data!==void 0,M=E.status==="error"&&!N,C=$=>{M?$.reject(E.error):N&&$.resolve(E.data)},L=()=>{const $=ee(this,Ea,E.promise=F0());C($)},D=R(this,Ea);switch(D.status){case"pending":t.queryHash===r.queryHash&&C(D);break;case"fulfilled":(M||E.data!==D.value)&&L();break;case"rejected":(!M||E.error!==D.reason)&&L();break}}return E}updateResult(){const t=R(this,un),n=this.createResult(R(this,Ne),this.options);if(ee(this,zs,R(this,Ne).state),ee(this,Nl,this.options),R(this,zs).data!==void 0&&ee(this,_l,R(this,Ne)),I0(n,t))return;ee(this,un,n);const r=()=>{if(!t)return!0;const{notifyOnChangeProps:a}=this.options,i=typeof a=="function"?a():a;if(i==="all"||!i&&!R(this,Pl).size)return!0;const s=new Set(i??R(this,Pl));return this.options.throwOnError&&s.add("error"),Object.keys(R(this,un)).some(o=>{const l=o;return R(this,un)[l]!==t[l]&&s.has(l)})};Oe(this,ze,KD).call(this,{listeners:r()})}onQueryUpdate(){this.updateResult(),this.hasListeners()&&Oe(this,ze,G0).call(this)}},jn=new WeakMap,Ne=new WeakMap,gd=new WeakMap,un=new WeakMap,zs=new WeakMap,Nl=new WeakMap,Ea=new WeakMap,Ai=new WeakMap,vd=new WeakMap,Cl=new WeakMap,_l=new WeakMap,Is=new WeakMap,Bs=new WeakMap,Oi=new WeakMap,Pl=new WeakMap,ze=new WeakSet,Tu=function(t){Oe(this,ze,W0).call(this);let n=R(this,Ne).fetch(this.options,t);return t!=null&&t.throwOnError||(n=n.catch(En)),n},H0=function(){Oe(this,ze,Y0).call(this);const t=qi(this.options.staleTime,R(this,Ne));if(Of.isServer()||R(this,un).isStale||!z0(t))return;const r=LD(R(this,un).dataUpdatedAt,t)+1;ee(this,Is,As.setTimeout(()=>{R(this,un).isStale||this.updateResult()},r))},q0=function(){return(typeof this.options.refetchInterval=="function"?this.options.refetchInterval(R(this,Ne)):this.options.refetchInterval)??!1},K0=function(t){Oe(this,ze,X0).call(this),ee(this,Oi,t),!(Of.isServer()||In(this.options.enabled,R(this,Ne))===!1||!z0(R(this,Oi))||R(this,Oi)===0)&&ee(this,Bs,As.setInterval(()=>{(this.options.refetchIntervalInBackground||iw.isFocused())&&Oe(this,ze,Tu).call(this)},R(this,Oi)))},G0=function(){Oe(this,ze,H0).call(this),Oe(this,ze,K0).call(this,Oe(this,ze,q0).call(this))},Y0=function(){R(this,Is)!==void 0&&(As.clearTimeout(R(this,Is)),ee(this,Is,void 0))},X0=function(){R(this,Bs)!==void 0&&(As.clearInterval(R(this,Bs)),ee(this,Bs,void 0))},W0=function(){const t=R(this,jn).getQueryCache().build(R(this,jn),this.options);if(t===R(this,Ne))return;const n=R(this,Ne);ee(this,Ne,t),ee(this,gd,t.state),this.hasListeners()&&(n==null||n.removeObserver(this),t.addObserver(this))},KD=function(t){Wt.batch(()=>{t.listeners&&this.listeners.forEach(n=>{n(R(this,un))}),R(this,jn).getQueryCache().notify({query:R(this,Ne),type:"observerResultsUpdated"})})},_P);function S8(e,t){return In(t.enabled,e)!==!1&&e.state.data===void 0&&!(e.state.status==="error"&&In(t.retryOnMount,e)===!1)}function aO(e,t){return S8(e,t)||e.state.data!==void 0&&Q0(e,t,t.refetchOnMount)}function Q0(e,t,n){if(In(t.enabled,e)!==!1&&qi(t.staleTime,e)!=="static"){const r=typeof n=="function"?n(e):n;return r==="always"||r!==!1&&lw(e,t)}return!1}function iO(e,t,n,r){return(e!==t||In(r.enabled,e)===!1)&&(!n.suspense||e.state.status!=="error")&&lw(e,n)}function lw(e,t){return In(t.enabled,e)!==!1&&e.isStaleByTime(qi(t.staleTime,e))}function w8(e,t){return!I0(e.getCurrentResult(),t)}var bd,Hr,an,Us,qr,ci,PP,j8=(PP=class extends VD{constructor(t){super();ce(this,qr);ce(this,bd);ce(this,Hr);ce(this,an);ce(this,Us);ee(this,bd,t.client),this.mutationId=t.mutationId,ee(this,an,t.mutationCache),ee(this,Hr,[]),this.state=t.state||A8(),this.setOptions(t.options),this.scheduleGc()}setOptions(t){this.options=t,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(t){R(this,Hr).includes(t)||(R(this,Hr).push(t),this.clearGcTimeout(),R(this,an).notify({type:"observerAdded",mutation:this,observer:t}))}removeObserver(t){ee(this,Hr,R(this,Hr).filter(n=>n!==t)),this.scheduleGc(),R(this,an).notify({type:"observerRemoved",mutation:this,observer:t})}optionalRemove(){R(this,Hr).length||(this.state.status==="pending"?this.scheduleGc():R(this,an).remove(this))}continue(){var t;return((t=R(this,Us))==null?void 0:t.continue())??this.execute(this.state.variables)}async execute(t){var s,o,l,c,f,d,h,p,m,g,b,y,v,x,w,S,j,O;const n=()=>{Oe(this,qr,ci).call(this,{type:"continue"})},r={client:R(this,bd),meta:this.options.meta,mutationKey:this.options.mutationKey};ee(this,Us,FD({fn:()=>this.options.mutationFn?this.options.mutationFn(t,r):Promise.reject(new Error("No mutationFn found")),onFail:(E,T)=>{Oe(this,qr,ci).call(this,{type:"failed",failureCount:E,error:T})},onPause:()=>{Oe(this,qr,ci).call(this,{type:"pause"})},onContinue:n,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>R(this,an).canRun(this)}));const a=this.state.status==="pending",i=!R(this,Us).canStart();try{if(a)n();else{Oe(this,qr,ci).call(this,{type:"pending",variables:t,isPaused:i}),R(this,an).config.onMutate&&await R(this,an).config.onMutate(t,this,r);const T=await((o=(s=this.options).onMutate)==null?void 0:o.call(s,t,r));T!==this.state.context&&Oe(this,qr,ci).call(this,{type:"pending",context:T,variables:t,isPaused:i})}const E=await R(this,Us).start();return await((c=(l=R(this,an).config).onSuccess)==null?void 0:c.call(l,E,t,this.state.context,this,r)),await((d=(f=this.options).onSuccess)==null?void 0:d.call(f,E,t,this.state.context,r)),await((p=(h=R(this,an).config).onSettled)==null?void 0:p.call(h,E,null,this.state.variables,this.state.context,this,r)),await((g=(m=this.options).onSettled)==null?void 0:g.call(m,E,null,t,this.state.context,r)),Oe(this,qr,ci).call(this,{type:"success",data:E}),E}catch(E){try{await((y=(b=R(this,an).config).onError)==null?void 0:y.call(b,E,t,this.state.context,this,r))}catch(T){Promise.reject(T)}try{await((x=(v=this.options).onError)==null?void 0:x.call(v,E,t,this.state.context,r))}catch(T){Promise.reject(T)}try{await((S=(w=R(this,an).config).onSettled)==null?void 0:S.call(w,void 0,E,this.state.variables,this.state.context,this,r))}catch(T){Promise.reject(T)}try{await((O=(j=this.options).onSettled)==null?void 0:O.call(j,void 0,E,t,this.state.context,r))}catch(T){Promise.reject(T)}throw Oe(this,qr,ci).call(this,{type:"error",error:E}),E}finally{R(this,an).runNext(this)}}},bd=new WeakMap,Hr=new WeakMap,an=new WeakMap,Us=new WeakMap,qr=new WeakSet,ci=function(t){const n=r=>{switch(t.type){case"failed":return{...r,failureCount:t.failureCount,failureReason:t.error};case"pause":return{...r,isPaused:!0};case"continue":return{...r,isPaused:!1};case"pending":return{...r,context:t.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:t.isPaused,status:"pending",variables:t.variables,submittedAt:Date.now()};case"success":return{...r,data:t.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...r,data:void 0,error:t.error,failureCount:r.failureCount+1,failureReason:t.error,isPaused:!1,status:"error"}}};this.state=n(this.state),Wt.batch(()=>{R(this,Hr).forEach(r=>{r.onMutationUpdate(t)}),R(this,an).notify({mutation:this,type:"updated",action:t})})},PP);function A8(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}var Ta,_r,xd,MP,O8=(MP=class extends Rd{constructor(t={}){super();ce(this,Ta);ce(this,_r);ce(this,xd);this.config=t,ee(this,Ta,new Set),ee(this,_r,new Map),ee(this,xd,0)}build(t,n,r){const a=new j8({client:t,mutationCache:this,mutationId:++rh(this,xd)._,options:t.defaultMutationOptions(n),state:r});return this.add(a),a}add(t){R(this,Ta).add(t);const n=Sh(t);if(typeof n=="string"){const r=R(this,_r).get(n);r?r.push(t):R(this,_r).set(n,[t])}this.notify({type:"added",mutation:t})}remove(t){if(R(this,Ta).delete(t)){const n=Sh(t);if(typeof n=="string"){const r=R(this,_r).get(n);if(r)if(r.length>1){const a=r.indexOf(t);a!==-1&&r.splice(a,1)}else r[0]===t&&R(this,_r).delete(n)}}this.notify({type:"removed",mutation:t})}canRun(t){const n=Sh(t);if(typeof n=="string"){const r=R(this,_r).get(n),a=r==null?void 0:r.find(i=>i.state.status==="pending");return!a||a===t}else return!0}runNext(t){var r;const n=Sh(t);if(typeof n=="string"){const a=(r=R(this,_r).get(n))==null?void 0:r.find(i=>i!==t&&i.state.isPaused);return(a==null?void 0:a.continue())??Promise.resolve()}else return Promise.resolve()}clear(){Wt.batch(()=>{R(this,Ta).forEach(t=>{this.notify({type:"removed",mutation:t})}),R(this,Ta).clear(),R(this,_r).clear()})}getAll(){return Array.from(R(this,Ta))}find(t){const n={exact:!0,...t};return this.getAll().find(r=>Z2(n,r))}findAll(t={}){return this.getAll().filter(n=>Z2(t,n))}notify(t){Wt.batch(()=>{this.listeners.forEach(n=>{n(t)})})}resumePausedMutations(){const t=this.getAll().filter(n=>n.state.isPaused);return Wt.batch(()=>Promise.all(t.map(n=>n.continue().catch(En))))}},Ta=new WeakMap,_r=new WeakMap,xd=new WeakMap,MP);function Sh(e){var t;return(t=e.options.scope)==null?void 0:t.id}var Kr,RP,E8=(RP=class extends Rd{constructor(t={}){super();ce(this,Kr);this.config=t,ee(this,Kr,new Map)}build(t,n,r){const a=n.queryKey,i=n.queryHash??sw(a,n);let s=this.get(i);return s||(s=new b8({client:t,queryKey:a,queryHash:i,options:t.defaultQueryOptions(n),state:r,defaultOptions:t.getQueryDefaults(a)}),this.add(s)),s}add(t){R(this,Kr).has(t.queryHash)||(R(this,Kr).set(t.queryHash,t),this.notify({type:"added",query:t}))}remove(t){const n=R(this,Kr).get(t.queryHash);n&&(t.destroy(),n===t&&R(this,Kr).delete(t.queryHash),this.notify({type:"removed",query:t}))}clear(){Wt.batch(()=>{this.getAll().forEach(t=>{this.remove(t)})})}get(t){return R(this,Kr).get(t)}getAll(){return[...R(this,Kr).values()]}find(t){const n={exact:!0,...t};return this.getAll().find(r=>Q2(n,r))}findAll(t={}){const n=this.getAll();return Object.keys(t).length>0?n.filter(r=>Q2(t,r)):n}notify(t){Wt.batch(()=>{this.listeners.forEach(n=>{n(t)})})}onFocus(){Wt.batch(()=>{this.getAll().forEach(t=>{t.onFocus()})})}onOnline(){Wt.batch(()=>{this.getAll().forEach(t=>{t.onOnline()})})}},Kr=new WeakMap,RP),mt,Ei,Ti,Ml,Rl,Ni,Dl,$l,DP,T8=(DP=class{constructor(e={}){ce(this,mt);ce(this,Ei);ce(this,Ti);ce(this,Ml);ce(this,Rl);ce(this,Ni);ce(this,Dl);ce(this,$l);ee(this,mt,e.queryCache||new E8),ee(this,Ei,e.mutationCache||new O8),ee(this,Ti,e.defaultOptions||{}),ee(this,Ml,new Map),ee(this,Rl,new Map),ee(this,Ni,0)}mount(){rh(this,Ni)._++,R(this,Ni)===1&&(ee(this,Dl,iw.subscribe(async e=>{e&&(await this.resumePausedMutations(),R(this,mt).onFocus())})),ee(this,$l,Qp.subscribe(async e=>{e&&(await this.resumePausedMutations(),R(this,mt).onOnline())})))}unmount(){var e,t;rh(this,Ni)._--,R(this,Ni)===0&&((e=R(this,Dl))==null||e.call(this),ee(this,Dl,void 0),(t=R(this,$l))==null||t.call(this),ee(this,$l,void 0))}isFetching(e){return R(this,mt).findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return R(this,Ei).findAll({...e,status:"pending"}).length}getQueryData(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=R(this,mt).get(t.queryHash))==null?void 0:n.state.data}ensureQueryData(e){const t=this.defaultQueryOptions(e),n=R(this,mt).build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(qi(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return R(this,mt).findAll(e).map(({queryKey:t,state:n})=>{const r=n.data;return[t,r]})}setQueryData(e,t,n){const r=this.defaultQueryOptions({queryKey:e}),a=R(this,mt).get(r.queryHash),i=a==null?void 0:a.state.data,s=o8(t,i);if(s!==void 0)return R(this,mt).build(this,r).setData(s,{...n,manual:!0})}setQueriesData(e,t,n){return Wt.batch(()=>R(this,mt).findAll(e).map(({queryKey:r})=>[r,this.setQueryData(r,t,n)]))}getQueryState(e){var n;const t=this.defaultQueryOptions({queryKey:e});return(n=R(this,mt).get(t.queryHash))==null?void 0:n.state}removeQueries(e){const t=R(this,mt);Wt.batch(()=>{t.findAll(e).forEach(n=>{t.remove(n)})})}resetQueries(e,t){const n=R(this,mt);return Wt.batch(()=>(n.findAll(e).forEach(r=>{r.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){const n={revert:!0,...t},r=Wt.batch(()=>R(this,mt).findAll(e).map(a=>a.cancel(n)));return Promise.all(r).then(En).catch(En)}invalidateQueries(e,t={}){return Wt.batch(()=>(R(this,mt).findAll(e).forEach(n=>{n.invalidate()}),(e==null?void 0:e.refetchType)==="none"?Promise.resolve():this.refetchQueries({...e,type:(e==null?void 0:e.refetchType)??(e==null?void 0:e.type)??"active"},t)))}refetchQueries(e,t={}){const n={...t,cancelRefetch:t.cancelRefetch??!0},r=Wt.batch(()=>R(this,mt).findAll(e).filter(a=>!a.isDisabled()&&!a.isStatic()).map(a=>{let i=a.fetch(void 0,n);return n.throwOnError||(i=i.catch(En)),a.state.fetchStatus==="paused"?Promise.resolve():i}));return Promise.all(r).then(En)}fetchQuery(e){const t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);const n=R(this,mt).build(this,t);return n.isStaleByTime(qi(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(En).catch(En)}fetchInfiniteQuery(e){return e._type="infinite",this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(En).catch(En)}ensureInfiniteQueryData(e){return e._type="infinite",this.ensureQueryData(e)}resumePausedMutations(){return Qp.isOnline()?R(this,Ei).resumePausedMutations():Promise.resolve()}getQueryCache(){return R(this,mt)}getMutationCache(){return R(this,Ei)}getDefaultOptions(){return R(this,Ti)}setDefaultOptions(e){ee(this,Ti,e)}setQueryDefaults(e,t){R(this,Ml).set(jf(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){const t=[...R(this,Ml).values()],n={};return t.forEach(r=>{Af(e,r.queryKey)&&Object.assign(n,r.defaultOptions)}),n}setMutationDefaults(e,t){R(this,Rl).set(jf(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){const t=[...R(this,Rl).values()],n={};return t.forEach(r=>{Af(e,r.mutationKey)&&Object.assign(n,r.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;const t={...R(this,Ti).queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=sw(t.queryKey,t)),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!=="always"),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===ow&&(t.enabled=!1),t}defaultMutationOptions(e){return e!=null&&e._defaulted?e:{...R(this,Ti).mutations,...(e==null?void 0:e.mutationKey)&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){R(this,mt).clear(),R(this,Ei).clear()}},mt=new WeakMap,Ei=new WeakMap,Ti=new WeakMap,Ml=new WeakMap,Rl=new WeakMap,Ni=new WeakMap,Dl=new WeakMap,$l=new WeakMap,DP),GD=A.createContext(void 0),nn=e=>{const t=A.useContext(GD);if(!t)throw new Error("No QueryClient set, use QueryClientProvider to set one");return t},N8=({client:e,children:t})=>(A.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),u.jsx(GD.Provider,{value:e,children:t})),YD=A.createContext(!1),C8=()=>A.useContext(YD);YD.Provider;function _8(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var P8=A.createContext(_8()),M8=()=>A.useContext(P8),R8=(e,t,n)=>{const r=n!=null&&n.state.error&&typeof e.throwOnError=="function"?BD(e.throwOnError,[n.state.error,n]):e.throwOnError;(e.suspense||e.experimental_prefetchInRender||r)&&(t.isReset()||(e.retryOnMount=!1))},D8=e=>{A.useEffect(()=>{e.clearReset()},[e])},$8=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:a})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(a&&e.data===void 0||BD(n,[e.error,r])),k8=e=>{if(e.suspense){const n=a=>a==="static"?a:Math.max(a??1e3,1e3),r=e.staleTime;e.staleTime=typeof r=="function"?(...a)=>n(r(...a)):n(r),typeof e.gcTime=="number"&&(e.gcTime=Math.max(e.gcTime,1e3))}},L8=(e,t)=>e.isLoading&&e.isFetching&&!t,z8=(e,t)=>(e==null?void 0:e.suspense)&&t.isPending,sO=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function I8(e,t,n){var p,m,g,b;const r=C8(),a=M8(),i=nn(),s=i.defaultQueryOptions(e);(m=(p=i.getDefaultOptions().queries)==null?void 0:p._experimental_beforeQuery)==null||m.call(p,s);const o=i.getQueryCache().get(s.queryHash),l=e.subscribed!==!1;s._optimisticResults=r?"isRestoring":l?"optimistic":void 0,k8(s),R8(s,a,o),D8(a);const c=!i.getQueryCache().get(s.queryHash),[f]=A.useState(()=>new t(i,s)),d=f.getOptimisticResult(s),h=!r&&l;if(A.useSyncExternalStore(A.useCallback(y=>{const v=h?f.subscribe(Wt.batchCalls(y)):En;return f.updateResult(),v},[f,h]),()=>f.getCurrentResult(),()=>f.getCurrentResult()),A.useEffect(()=>{f.setOptions(s)},[s,f]),z8(s,d))throw sO(s,f,a);if($8({result:d,errorResetBoundary:a,throwOnError:s.throwOnError,query:o,suspense:s.suspense}))throw d.error;if((b=(g=i.getDefaultOptions().queries)==null?void 0:g._experimental_afterQuery)==null||b.call(g,s,d),s.experimental_prefetchInRender&&!Of.isServer()&&L8(d,r)){const y=c?sO(s,f,a):o==null?void 0:o.promise;y==null||y.catch(En).finally(()=>{f.updateResult()})}return s.notifyOnChangeProps?d:f.trackResult(d)}function se(e,t){return I8(e,x8)}/** + * react-router v7.17.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var oO="popstate";function lO(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function B8(e={}){function t(r,a){var c;let i=(c=a.state)==null?void 0:c.masked,{pathname:s,search:o,hash:l}=i||r.location;return Z0("",{pathname:s,search:o,hash:l},a.state&&a.state.usr||null,a.state&&a.state.key||"default",i?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function n(r,a){return typeof a=="string"?a:Ef(a)}return F8(t,n,null,e)}function ut(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function br(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function U8(){return Math.random().toString(36).substring(2,10)}function cO(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Z0(e,t,n=null,r,a){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?Rc(t):t,state:n,key:t&&t.key||r||U8(),mask:a}}function Ef({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function Rc(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function F8(e,t,n,r={}){let{window:a=document.defaultView,v5Compat:i=!1}=r,s=a.history,o="POP",l=null,c=f();c==null&&(c=0,s.replaceState({...s.state,idx:c},""));function f(){return(s.state||{idx:null}).idx}function d(){o="POP";let b=f(),y=b==null?null:b-c;c=b,l&&l({action:o,location:g.location,delta:y})}function h(b,y){o="PUSH";let v=lO(b)?b:Z0(g.location,b,y);c=f()+1;let x=cO(v,c),w=g.createHref(v.mask||v);try{s.pushState(x,"",w)}catch(S){if(S instanceof DOMException&&S.name==="DataCloneError")throw S;a.location.assign(w)}i&&l&&l({action:o,location:g.location,delta:1})}function p(b,y){o="REPLACE";let v=lO(b)?b:Z0(g.location,b,y);c=f();let x=cO(v,c),w=g.createHref(v.mask||v);s.replaceState(x,"",w),i&&l&&l({action:o,location:g.location,delta:0})}function m(b){return V8(a,b)}let g={get action(){return o},get location(){return e(a,s)},listen(b){if(l)throw new Error("A history only accepts one active listener");return a.addEventListener(oO,d),l=b,()=>{a.removeEventListener(oO,d),l=null}},createHref(b){return t(a,b)},createURL:m,encodeLocation(b){let y=m(b);return{pathname:y.pathname,search:y.search,hash:y.hash}},push:h,replace:p,go(b){return s.go(b)}};return g}function V8(e,t,n=!1){let r="http://localhost";e&&(r=e.location.origin!=="null"?e.location.origin:e.location.href),ut(r,"No window.location.(origin|href) available to create URL");let a=typeof t=="string"?t:Ef(t);return a=a.replace(/ $/,"%20"),!n&&a.startsWith("//")&&(a=r+a),new URL(a,r)}function XD(e,t,n="/"){return H8(e,t,n,!1)}function H8(e,t,n,r,a){let i=typeof t=="string"?Rc(t):t,s=Xa(i.pathname||"/",n);if(s==null)return null;let o=q8(e),l=null,c=rU(s);for(let f=0;l==null&&f{let f={relativePath:c===void 0?s.path||"":c,caseSensitive:s.caseSensitive===!0,childrenIndex:o,route:s};if(f.relativePath.startsWith("/")){if(!f.relativePath.startsWith(r)&&l)return;ut(f.relativePath.startsWith(r),`Absolute route path "${f.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),f.relativePath=f.relativePath.slice(r.length)}let d=$r([r,f.relativePath]),h=n.concat(f);s.children&&s.children.length>0&&(ut(s.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${d}".`),WD(s.children,t,h,d,l)),!(s.path==null&&!s.index)&&t.push({path:d,score:J8(d,s.index),routesMeta:h})};return e.forEach((s,o)=>{var l;if(s.path===""||!((l=s.path)!=null&&l.includes("?")))i(s,o);else for(let c of QD(s.path))i(s,o,!0,c)}),t}function QD(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,a=n.endsWith("?"),i=n.replace(/\?$/,"");if(r.length===0)return a?[i,""]:[i];let s=QD(r.join("/")),o=[];return o.push(...s.map(l=>l===""?i:[i,l].join("/"))),a&&o.push(...s),o.map(l=>e.startsWith("/")&&l===""?"/":l)}function K8(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:eU(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}var G8=/^:[\w-]+$/,Y8=3,X8=2,W8=1,Q8=10,Z8=-2,uO=e=>e==="*";function J8(e,t){let n=e.split("/"),r=n.length;return n.some(uO)&&(r+=Z8),t&&(r+=X8),n.filter(a=>!uO(a)).reduce((a,i)=>a+(G8.test(i)?Y8:i===""?W8:Q8),r)}function eU(e,t){return e.length===t.length&&e.slice(0,-1).every((r,a)=>r===t[a])?e[e.length-1]-t[t.length-1]:0}function tU(e,t,n=!1){let{routesMeta:r}=e,a={},i="/",s=[];for(let o=0;o{if(f==="*"){let m=o[h]||"";s=i.slice(0,i.length-m.length).replace(/(.)\/+$/,"$1")}const p=o[h];return d&&!p?c[f]=void 0:c[f]=(p||"").replace(/%2F/g,"/"),c},{}),pathname:i,pathnameBase:s,pattern:e}}function nU(e,t=!1,n=!0){br(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let r=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(s,o,l,c,f)=>{if(r.push({paramName:o,isOptional:l!=null}),l){let d=f.charAt(c+s.length);return d&&d!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(r.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),r]}function rU(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return br(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Xa(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}var aU=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function iU(e,t="/"){let{pathname:n,search:r="",hash:a=""}=typeof e=="string"?Rc(e):e,i;return n?(n=ZD(n),n.startsWith("/")?i=fO(n.substring(1),"/"):i=fO(n,t)):i=t,{pathname:i,search:lU(r),hash:cU(a)}}function fO(e,t){let n=Jp(t).split("/");return e.split("/").forEach(a=>{a===".."?n.length>1&&n.pop():a!=="."&&n.push(a)}),n.length>1?n.join("/"):"/"}function $v(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function sU(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function cw(e){let t=sU(e);return t.map((n,r)=>r===t.length-1?n.pathname:n.pathnameBase)}function Iy(e,t,n,r=!1){let a;typeof e=="string"?a=Rc(e):(a={...e},ut(!a.pathname||!a.pathname.includes("?"),$v("?","pathname","search",a)),ut(!a.pathname||!a.pathname.includes("#"),$v("#","pathname","hash",a)),ut(!a.search||!a.search.includes("#"),$v("#","search","hash",a)));let i=e===""||a.pathname==="",s=i?"/":a.pathname,o;if(s==null)o=n;else{let d=t.length-1;if(!r&&s.startsWith("..")){let h=s.split("/");for(;h[0]==="..";)h.shift(),d-=1;a.pathname=h.join("/")}o=d>=0?t[d]:"/"}let l=iU(a,o),c=s&&s!=="/"&&s.endsWith("/"),f=(i||s===".")&&n.endsWith("/");return!l.pathname.endsWith("/")&&(c||f)&&(l.pathname+="/"),l}var ZD=e=>e.replace(/\/\/+/g,"/"),$r=e=>ZD(e.join("/")),Jp=e=>e.replace(/\/+$/,""),oU=e=>Jp(e).replace(/^\/*/,"/"),lU=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,cU=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,uU=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||"",this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function fU(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function dU(e){let t=e.map(n=>n.route.path).filter(Boolean);return $r(t)||"/"}var JD=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function e$(e,t){let n=e;if(typeof n!="string"||!aU.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,a=!1;if(JD)try{let i=new URL(window.location.href),s=n.startsWith("//")?new URL(i.protocol+n):new URL(n),o=Xa(s.pathname,t);s.origin===i.origin&&o!=null?n=o+s.search+s.hash:a=!0}catch{br(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:a,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var t$=["POST","PUT","PATCH","DELETE"];new Set(t$);var hU=["GET",...t$];new Set(hU);var Dc=A.createContext(null);Dc.displayName="DataRouter";var By=A.createContext(null);By.displayName="DataRouterState";var n$=A.createContext(!1);function pU(){return A.useContext(n$)}var r$=A.createContext({isTransitioning:!1});r$.displayName="ViewTransition";var mU=A.createContext(new Map);mU.displayName="Fetchers";var yU=A.createContext(null);yU.displayName="Await";var er=A.createContext(null);er.displayName="Navigation";var Dd=A.createContext(null);Dd.displayName="Location";var wr=A.createContext({outlet:null,matches:[],isDataRoute:!1});wr.displayName="Route";var uw=A.createContext(null);uw.displayName="RouteError";var a$="REACT_ROUTER_ERROR",gU="REDIRECT",vU="ROUTE_ERROR_RESPONSE";function bU(e){if(e.startsWith(`${a$}:${gU}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function xU(e){if(e.startsWith(`${a$}:${vU}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new uU(t.status,t.statusText,t.data)}catch{}}function SU(e,{relative:t}={}){ut($c(),"useHref() may be used only in the context of a component.");let{basename:n,navigator:r}=A.useContext(er),{hash:a,pathname:i,search:s}=$d(e,{relative:t}),o=i;return n!=="/"&&(o=i==="/"?n:$r([n,i])),r.createHref({pathname:o,search:s,hash:a})}function $c(){return A.useContext(Dd)!=null}function jr(){return ut($c(),"useLocation() may be used only in the context of a component."),A.useContext(Dd).location}var i$="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function s$(e){A.useContext(er).static||A.useLayoutEffect(e)}function Kt(){let{isDataRoute:e}=A.useContext(wr);return e?kU():wU()}function wU(){ut($c(),"useNavigate() may be used only in the context of a component.");let e=A.useContext(Dc),{basename:t,navigator:n}=A.useContext(er),{matches:r}=A.useContext(wr),{pathname:a}=jr(),i=JSON.stringify(cw(r)),s=A.useRef(!1);return s$(()=>{s.current=!0}),A.useCallback((l,c={})=>{if(br(s.current,i$),!s.current)return;if(typeof l=="number"){n.go(l);return}let f=Iy(l,JSON.parse(i),a,c.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:$r([t,f.pathname])),(c.replace?n.replace:n.push)(f,c.state,c)},[t,n,i,a,e])}var jU=A.createContext(null);function AU(e){let t=A.useContext(wr).outlet;return A.useMemo(()=>t&&A.createElement(jU.Provider,{value:e},t),[t,e])}function o$(){let{matches:e}=A.useContext(wr),t=e[e.length-1];return(t==null?void 0:t.params)??{}}function $d(e,{relative:t}={}){let{matches:n}=A.useContext(wr),{pathname:r}=jr(),a=JSON.stringify(cw(n));return A.useMemo(()=>Iy(e,JSON.parse(a),r,t==="path"),[e,a,r,t])}function OU(e,t){return l$(e,t)}function l$(e,t,n){var b;ut($c(),"useRoutes() may be used only in the context of a component.");let{navigator:r}=A.useContext(er),{matches:a}=A.useContext(wr),i=a[a.length-1],s=i?i.params:{},o=i?i.pathname:"/",l=i?i.pathnameBase:"/",c=i&&i.route;{let y=c&&c.path||"";u$(o,!c||y.endsWith("*")||y.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${o}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let f=jr(),d;if(t){let y=typeof t=="string"?Rc(t):t;ut(l==="/"||((b=y.pathname)==null?void 0:b.startsWith(l)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${l}" but pathname "${y.pathname}" was given in the \`location\` prop.`),d=y}else d=f;let h=d.pathname||"/",p=h;if(l!=="/"){let y=l.replace(/^\//,"").split("/");p="/"+h.replace(/^\//,"").split("/").slice(y.length).join("/")}let m=n&&n.state.matches.length?n.state.matches.map(y=>Object.assign(y,{route:n.manifest[y.route.id]||y.route})):XD(e,{pathname:p});br(c||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),br(m==null||m[m.length-1].route.element!==void 0||m[m.length-1].route.Component!==void 0||m[m.length-1].route.lazy!==void 0,`Matched leaf route at location "${d.pathname}${d.search}${d.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let g=_U(m&&m.map(y=>Object.assign({},y,{params:Object.assign({},s,y.params),pathname:$r([l,r.encodeLocation?r.encodeLocation(y.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:y.pathname]),pathnameBase:y.pathnameBase==="/"?l:$r([l,r.encodeLocation?r.encodeLocation(y.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:y.pathnameBase])})),a,n);return t&&g?A.createElement(Dd.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...d},navigationType:"POP"}},g):g}function EU(){let e=$U(),t=fU(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},i={padding:"2px 4px",backgroundColor:r},s=null;return console.error("Error handled by React Router default ErrorBoundary:",e),s=A.createElement(A.Fragment,null,A.createElement("p",null,"💿 Hey developer 👋"),A.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",A.createElement("code",{style:i},"ErrorBoundary")," or"," ",A.createElement("code",{style:i},"errorElement")," prop on your route.")),A.createElement(A.Fragment,null,A.createElement("h2",null,"Unexpected Application Error!"),A.createElement("h3",{style:{fontStyle:"italic"}},t),n?A.createElement("pre",{style:a},n):null,s)}var TU=A.createElement(EU,null),c$=class extends A.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=xU(e.digest);n&&(e=n)}let t=e!==void 0?A.createElement(wr.Provider,{value:this.props.routeContext},A.createElement(uw.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?A.createElement(NU,{error:e},t):t}};c$.contextType=n$;var kv=new WeakMap;function NU({children:e,error:t}){let{basename:n}=A.useContext(er);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=bU(t.digest);if(r){let a=kv.get(t);if(a)throw a;let i=e$(r.location,n);if(JD&&!kv.get(t))if(i.isExternal||r.reloadDocument)window.location.href=i.absoluteURL||i.to;else{const s=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(i.to,{replace:r.replace}));throw kv.set(t,s),s}return A.createElement("meta",{httpEquiv:"refresh",content:`0;url=${i.absoluteURL||i.to}`})}}return e}function CU({routeContext:e,match:t,children:n}){let r=A.useContext(Dc);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),A.createElement(wr.Provider,{value:e},n)}function _U(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,i=r==null?void 0:r.errors;if(i!=null){let f=a.findIndex(d=>d.route.id&&(i==null?void 0:i[d.route.id])!==void 0);ut(f>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(i).join(",")}`),a=a.slice(0,Math.min(a.length,f+1))}let s=!1,o=-1;if(n&&r){s=r.renderFallback;for(let f=0;f=0?a=a.slice(0,o+1):a=[a[0]];break}}}}let l=n==null?void 0:n.onError,c=r&&l?(f,d)=>{var h,p;l(f,{location:r.location,params:((p=(h=r.matches)==null?void 0:h[0])==null?void 0:p.params)??{},pattern:dU(r.matches),errorInfo:d})}:void 0;return a.reduceRight((f,d,h)=>{let p,m=!1,g=null,b=null;r&&(p=i&&d.route.id?i[d.route.id]:void 0,g=d.route.errorElement||TU,s&&(o<0&&h===0?(u$("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,b=null):o===h&&(m=!0,b=d.route.hydrateFallbackElement||null)));let y=t.concat(a.slice(0,h+1)),v=()=>{let x;return p?x=g:m?x=b:d.route.Component?x=A.createElement(d.route.Component,null):d.route.element?x=d.route.element:x=f,A.createElement(CU,{match:d,routeContext:{outlet:f,matches:y,isDataRoute:r!=null},children:x})};return r&&(d.route.ErrorBoundary||d.route.errorElement||h===0)?A.createElement(c$,{location:r.location,revalidation:r.revalidation,component:g,error:p,children:v(),routeContext:{outlet:null,matches:y,isDataRoute:!0},onError:c}):v()},null)}function fw(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function PU(e){let t=A.useContext(Dc);return ut(t,fw(e)),t}function MU(e){let t=A.useContext(By);return ut(t,fw(e)),t}function RU(e){let t=A.useContext(wr);return ut(t,fw(e)),t}function dw(e){let t=RU(e),n=t.matches[t.matches.length-1];return ut(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function DU(){return dw("useRouteId")}function $U(){var r;let e=A.useContext(uw),t=MU("useRouteError"),n=dw("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function kU(){let{router:e}=PU("useNavigate"),t=dw("useNavigate"),n=A.useRef(!1);return s$(()=>{n.current=!0}),A.useCallback(async(a,i={})=>{br(n.current,i$),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...i}))},[e,t])}var dO={};function u$(e,t,n){!t&&!dO[e]&&(dO[e]=!0,br(!1,n))}A.memo(LU);function LU({routes:e,manifest:t,future:n,state:r,isStatic:a,onError:i}){return l$(e,void 0,{manifest:t,state:r,isStatic:a,onError:i})}function em({to:e,replace:t,state:n,relative:r}){ut($c()," may be used only in the context of a component.");let{static:a}=A.useContext(er);br(!a," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:i}=A.useContext(wr),{pathname:s}=jr(),o=Kt(),l=Iy(e,cw(i),s,r==="path"),c=JSON.stringify(l);return A.useEffect(()=>{o(JSON.parse(c),{replace:t,state:n,relative:r})},[o,c,r,t,n]),null}function f$(e){return AU(e.context)}function Se(e){ut(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function zU({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:i=!1,useTransitions:s}){ut(!$c(),"You cannot render a inside another . You should never have more than one in your app.");let o=e.replace(/^\/*/,"/"),l=A.useMemo(()=>({basename:o,navigator:a,static:i,useTransitions:s,future:{}}),[o,a,i,s]);typeof n=="string"&&(n=Rc(n));let{pathname:c="/",search:f="",hash:d="",state:h=null,key:p="default",mask:m}=n,g=A.useMemo(()=>{let b=Xa(c,o);return b==null?null:{location:{pathname:b,search:f,hash:d,state:h,key:p,mask:m},navigationType:r}},[o,c,f,d,h,p,r,m]);return br(g!=null,` is not able to match the URL "${c}${f}${d}" because it does not start with the basename, so the won't render anything.`),g==null?null:A.createElement(er.Provider,{value:l},A.createElement(Dd.Provider,{children:t,value:g}))}function IU({children:e,location:t}){return OU(J0(e),t)}function J0(e,t=[]){let n=[];return A.Children.forEach(e,(r,a)=>{if(!A.isValidElement(r))return;let i=[...t,a];if(r.type===A.Fragment){n.push.apply(n,J0(r.props.children,i));return}ut(r.type===Se,`[${typeof r.type=="string"?r.type:r.type.name}] is not a component. All component children of must be a or `),ut(!r.props.index||!r.props.children,"An index route cannot have child routes.");let s={id:r.props.id||i.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(s.children=J0(r.props.children,i)),n.push(s)}),n}var up="get",fp="application/x-www-form-urlencoded";function Uy(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function BU(e){return Uy(e)&&e.tagName.toLowerCase()==="button"}function UU(e){return Uy(e)&&e.tagName.toLowerCase()==="form"}function FU(e){return Uy(e)&&e.tagName.toLowerCase()==="input"}function VU(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function HU(e,t){return e.button===0&&(!t||t==="_self")&&!VU(e)}function ex(e=""){return new URLSearchParams(typeof e=="string"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(a=>[n,a]):[[n,r]])},[]))}function qU(e,t){let n=ex(e);return t&&t.forEach((r,a)=>{n.has(a)||t.getAll(a).forEach(i=>{n.append(a,i)})}),n}var wh=null;function KU(){if(wh===null)try{new FormData(document.createElement("form"),0),wh=!1}catch{wh=!0}return wh}var GU=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Lv(e){return e!=null&&!GU.has(e)?(br(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${fp}"`),null):e}function YU(e,t){let n,r,a,i,s;if(UU(e)){let o=e.getAttribute("action");r=o?Xa(o,t):null,n=e.getAttribute("method")||up,a=Lv(e.getAttribute("enctype"))||fp,i=new FormData(e)}else if(BU(e)||FU(e)&&(e.type==="submit"||e.type==="image")){let o=e.form;if(o==null)throw new Error('Cannot submit a