@burdenoff/microfe-housingvista 2026.720.1 → 2026.720.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/housingvista/components/maps/PropertyMapView.d.ts +22 -0
  2. package/dist/housingvista/components/maps/PropertyMapView.d.ts.map +1 -0
  3. package/dist/housingvista/components/maps/PropertyMapView.js +175 -0
  4. package/dist/housingvista/components/maps/PropertyMapView.js.map +1 -0
  5. package/dist/housingvista/components/maps/index.d.ts +5 -0
  6. package/dist/housingvista/components/maps/index.d.ts.map +1 -0
  7. package/dist/housingvista/components/maps/index.js +2 -0
  8. package/dist/housingvista/components/maps/leaflet-setup.d.ts +27 -0
  9. package/dist/housingvista/components/maps/leaflet-setup.d.ts.map +1 -0
  10. package/dist/housingvista/components/maps/leaflet-setup.js +36 -0
  11. package/dist/housingvista/components/maps/leaflet-setup.js.map +1 -0
  12. package/dist/housingvista/hooks/index.d.ts +1 -0
  13. package/dist/housingvista/hooks/index.d.ts.map +1 -1
  14. package/dist/housingvista/hooks/index.js +7 -4
  15. package/dist/housingvista/hooks/index.js.map +1 -1
  16. package/dist/housingvista/pages/properties/PropertiesPage.d.ts.map +1 -1
  17. package/dist/housingvista/pages/properties/PropertiesPage.js +224 -160
  18. package/dist/housingvista/pages/properties/PropertiesPage.js.map +1 -1
  19. package/dist/microfe-housingvista.css +2 -0
  20. package/dist/node_modules/@react-leaflet/core/lib/attribution.js +12 -0
  21. package/dist/node_modules/@react-leaflet/core/lib/attribution.js.map +1 -0
  22. package/dist/node_modules/@react-leaflet/core/lib/component.js +39 -0
  23. package/dist/node_modules/@react-leaflet/core/lib/component.js.map +1 -0
  24. package/dist/node_modules/@react-leaflet/core/lib/context.js +23 -0
  25. package/dist/node_modules/@react-leaflet/core/lib/context.js.map +1 -0
  26. package/dist/node_modules/@react-leaflet/core/lib/div-overlay.js +15 -0
  27. package/dist/node_modules/@react-leaflet/core/lib/div-overlay.js.map +1 -0
  28. package/dist/node_modules/@react-leaflet/core/lib/element.js +30 -0
  29. package/dist/node_modules/@react-leaflet/core/lib/element.js.map +1 -0
  30. package/dist/node_modules/@react-leaflet/core/lib/events.js +14 -0
  31. package/dist/node_modules/@react-leaflet/core/lib/events.js.map +1 -0
  32. package/dist/node_modules/@react-leaflet/core/lib/generic.js +18 -0
  33. package/dist/node_modules/@react-leaflet/core/lib/generic.js.map +1 -0
  34. package/dist/node_modules/@react-leaflet/core/lib/grid-layer.js +9 -0
  35. package/dist/node_modules/@react-leaflet/core/lib/grid-layer.js.map +1 -0
  36. package/dist/node_modules/@react-leaflet/core/lib/layer.js +23 -0
  37. package/dist/node_modules/@react-leaflet/core/lib/layer.js.map +1 -0
  38. package/dist/node_modules/@react-leaflet/core/lib/pane.js +12 -0
  39. package/dist/node_modules/@react-leaflet/core/lib/pane.js.map +1 -0
  40. package/dist/node_modules/leaflet/dist/leaflet-src.js +4585 -0
  41. package/dist/node_modules/leaflet/dist/leaflet-src.js.map +1 -0
  42. package/dist/node_modules/react-leaflet/lib/MapContainer.js +33 -0
  43. package/dist/node_modules/react-leaflet/lib/MapContainer.js.map +1 -0
  44. package/dist/node_modules/react-leaflet/lib/Marker.js +16 -0
  45. package/dist/node_modules/react-leaflet/lib/Marker.js.map +1 -0
  46. package/dist/node_modules/react-leaflet/lib/Popup.js +37 -0
  47. package/dist/node_modules/react-leaflet/lib/Popup.js.map +1 -0
  48. package/dist/node_modules/react-leaflet/lib/TileLayer.js +18 -0
  49. package/dist/node_modules/react-leaflet/lib/TileLayer.js.map +1 -0
  50. package/dist/node_modules/react-leaflet/lib/hooks.js +18 -0
  51. package/dist/node_modules/react-leaflet/lib/hooks.js.map +1 -0
  52. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PropertiesPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertiesPage.tsx"],"sourcesContent":["/**\n * HousingVista Properties Listing Page\n * Migrated from legacy housingvista-frontend properties.tsx\n * @module housingvista\n */\n\nimport { useState, useMemo, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Plus, Grid, List, Building, SlidersHorizontal, X } from 'lucide-react';\nimport { EmphasisPanel, Pagination } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, PropertyCard, EmptyState, StatCard, LoadingSkeleton } from '../../components';\nimport {\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useDashboardStats,\n type PropertyFilterInput,\n} from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { useHousingVistaAnalytics, useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\nimport { notify } from '../../lib/toast';\nimport { cn } from '../../utils/helpers';\nimport type { PropertyType, PropertyStatus, PropertyCategory, ReraVerificationStatus } from '../../types';\n\nconst PAGE_SIZE = 9;\n\nexport const PropertiesPage = () => {\n const navigate = useNavigate();\n const { t } = useI18n();\n const { emit, emitResource, emitSearch } = useHousingVistaAnalytics();\n useTrackPageView('housingvista.property.viewed');\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const propertyTypes: { value: PropertyType | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyTypes.all', 'All Types') },\n { value: 'residential', label: tr('housingvista.properties.filters.propertyTypes.residential', 'Residential') },\n { value: 'commercial', label: tr('housingvista.properties.filters.propertyTypes.commercial', 'Commercial') },\n { value: 'industrial', label: tr('housingvista.properties.filters.propertyTypes.industrial', 'Industrial') },\n { value: 'agricultural', label: tr('housingvista.properties.filters.propertyTypes.agricultural', 'Agricultural') },\n { value: 'mixed_use', label: tr('housingvista.properties.filters.propertyTypes.mixedUse', 'Mixed Use') },\n ];\n\n const propertyStatuses: { value: PropertyStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyStatuses.all', 'All Status') },\n { value: 'for_sale', label: tr('housingvista.properties.filters.propertyStatuses.forSale', 'For Sale') },\n { value: 'for_rent', label: tr('housingvista.properties.filters.propertyStatuses.forRent', 'For Rent') },\n { value: 'sold', label: tr('housingvista.properties.filters.propertyStatuses.sold', 'Sold') },\n { value: 'rented', label: tr('housingvista.properties.filters.propertyStatuses.rented', 'Rented') },\n {\n value: 'under_contract',\n label: tr('housingvista.properties.filters.propertyStatuses.underContract', 'Under Contract'),\n },\n { value: 'off_market', label: tr('housingvista.properties.filters.propertyStatuses.offMarket', 'Off Market') },\n ];\n\n const propertyCategories: { value: PropertyCategory | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyCategories.all', 'All Categories') },\n { value: 'apartment', label: tr('housingvista.properties.filters.propertyCategories.apartment', 'Apartment') },\n { value: 'house', label: tr('housingvista.properties.filters.propertyCategories.house', 'House') },\n { value: 'villa', label: tr('housingvista.properties.filters.propertyCategories.villa', 'Villa') },\n { value: 'office', label: tr('housingvista.properties.filters.propertyCategories.office', 'Office') },\n { value: 'retail', label: tr('housingvista.properties.filters.propertyCategories.retail', 'Retail') },\n { value: 'warehouse', label: tr('housingvista.properties.filters.propertyCategories.warehouse', 'Warehouse') },\n { value: 'land', label: tr('housingvista.properties.filters.propertyCategories.land', 'Land') },\n { value: 'plot', label: tr('housingvista.properties.filters.propertyCategories.plot', 'Plot') },\n ];\n\n const priceRanges = [\n { value: 'all', label: tr('housingvista.properties.filters.priceRanges.all', 'Any Price'), min: 0, max: Infinity },\n {\n value: 'under_100k',\n label: tr('housingvista.properties.filters.priceRanges.under100k', 'Under $100K'),\n min: 0,\n max: 100000,\n },\n {\n value: '100k_500k',\n label: tr('housingvista.properties.filters.priceRanges.100kTo500k', '$100K - $500K'),\n min: 100000,\n max: 500000,\n },\n {\n value: '500k_1m',\n label: tr('housingvista.properties.filters.priceRanges.500kTo1m', '$500K - $1M'),\n min: 500000,\n max: 1000000,\n },\n {\n value: 'over_1m',\n label: tr('housingvista.properties.filters.priceRanges.over1m', 'Over $1M'),\n min: 1000000,\n max: Infinity,\n },\n ];\n\n const bedroomOptions = [\n { value: 'all', label: tr('housingvista.properties.filters.bedrooms.all', 'Any Bedrooms') },\n { value: '1', label: '1+' },\n { value: '2', label: '2+' },\n { value: '3', label: '3+' },\n { value: '4', label: '4+' },\n { value: '5', label: '5+' },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<PropertyType | 'all'>('all');\n const [selectedStatus, setSelectedStatus] = useState<PropertyStatus | 'all'>('all');\n const [selectedCategory, setSelectedCategory] = useState<PropertyCategory | 'all'>('all');\n const [selectedPriceRange, setSelectedPriceRange] = useState('all');\n const [selectedBedrooms, setSelectedBedrooms] = useState('all');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [showFilters, setShowFilters] = useState(false);\n\n const reraOptions: { value: ReraVerificationStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.rera.all', 'Any RERA status') },\n { value: 'verified', label: tr('housingvista.properties.filters.rera.verified', 'RERA Verified') },\n { value: 'pending', label: tr('housingvista.properties.filters.rera.pending', 'RERA Pending') },\n { value: 'not_applicable', label: tr('housingvista.properties.filters.rera.notApplicable', 'Not RERA-applicable') },\n { value: 'rejected', label: tr('housingvista.properties.filters.rera.rejected', 'RERA Rejected') },\n ];\n\n const [selectedRera, setSelectedRera] = useState<ReraVerificationStatus | 'all'>('all');\n\n const priceRange = priceRanges.find((r) => r.value === selectedPriceRange) ?? priceRanges[0];\n const minBedrooms = selectedBedrooms === 'all' ? 0 : Number(selectedBedrooms);\n\n // Debounce the search box so we don't refetch on every keystroke.\n const [debouncedSearch, setDebouncedSearch] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedSearch(searchQuery), 300);\n return () => clearTimeout(timer);\n }, [searchQuery]);\n\n // Analytics: emit search event when a non-empty debounced query is entered.\n useEffect(() => {\n if (debouncedSearch.trim()) {\n emitSearch('properties');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearch]);\n\n const { page, pageSize, pagination, setPage, setPageSize } = useServerPagination(PAGE_SIZE);\n\n // Every filter is resolved server-side (BOFF-3933) — the subgraph's\n // HousingVistaPropertyFilterInput now models price/bedrooms/category/RERA\n // directly, so pagination totals are always accurate at scale.\n const serverFilter = useMemo<PropertyFilterInput | undefined>(() => {\n const filter: PropertyFilterInput = {};\n if (debouncedSearch.trim()) filter.search = debouncedSearch.trim();\n if (selectedStatus !== 'all') filter.status = selectedStatus;\n if (selectedType !== 'all') filter.type = selectedType;\n if (selectedCategory !== 'all') filter.category = selectedCategory;\n if (priceRange.min > 0) filter.priceMin = priceRange.min;\n if (Number.isFinite(priceRange.max)) filter.priceMax = priceRange.max;\n if (minBedrooms > 0) filter.bedroomsMin = minBedrooms;\n if (selectedRera !== 'all') filter.reraVerificationStatus = selectedRera;\n return Object.keys(filter).length > 0 ? filter : undefined;\n }, [debouncedSearch, selectedStatus, selectedType, selectedCategory, priceRange, minBedrooms, selectedRera]);\n\n // Reset to first page whenever the server-side filter changes.\n useEffect(() => {\n setPage(1);\n }, [serverFilter, setPage]);\n\n const { data: properties, loading } = useProperties({ filter: serverFilter, pagination });\n // Portfolio-wide totals for the stats zone — independent of the current page slice.\n const { data: dashboardStats } = useDashboardStats();\n const { data: shortlists } = useShortlists();\n const { saveShortlist } = useSaveShortlist();\n const { removeShortlist } = useRemoveShortlist();\n\n const shortlistedIds = useMemo(() => new Set(shortlists.map((s) => s.propertyId)), [shortlists]);\n\n const toggleShortlist = async (propertyId: string) => {\n try {\n if (shortlistedIds.has(propertyId)) {\n await removeShortlist(propertyId);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(propertyId);\n emitResource('housingvista.shortlist.property_added', propertyId);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n // All filtering happens server-side now (see `serverFilter` above); the\n // page just renders the page slice the server already filtered.\n const filteredProperties = properties;\n\n const hasNextPage = properties.length >= pageSize;\n\n const hasActiveFilters =\n searchQuery ||\n selectedType !== 'all' ||\n selectedStatus !== 'all' ||\n selectedCategory !== 'all' ||\n selectedPriceRange !== 'all' ||\n selectedBedrooms !== 'all' ||\n selectedRera !== 'all';\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedType('all');\n setSelectedStatus('all');\n setSelectedCategory('all');\n setSelectedPriceRange('all');\n setSelectedBedrooms('all');\n setSelectedRera('all');\n };\n\n return (\n <PageLayout\n title={tr('housingvista.properties.title', 'Properties')}\n description={tr(\n 'housingvista.properties.description',\n 'Discover your perfect property from our comprehensive listings'\n )}\n purpose={tr(\n 'housingvista.properties.purpose',\n 'Browse, search, and filter every property in your portfolio or on the market. Use the filters to narrow by type, status, price, and bedrooms, then open any listing to see full details, schedule viewings, or start a transaction.'\n )}\n actions={\n <button\n onClick={() => {\n emit('housingvista.property.create_clicked');\n navigate('new');\n }}\n className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.properties.actions.addProperty', 'Add Property')}\n </button>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.properties.stats.totalProperties', 'Total Properties')}\n value={dashboardStats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n />\n <StatCard\n label={tr('housingvista.properties.stats.portfolioValue', 'Portfolio Value')}\n value={dashboardStats.totalValue}\n prefix=\"$\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.occupancyRate', 'Occupancy Rate')}\n value={dashboardStats.occupancyRate}\n unit=\"%\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.monthlyRevenue', 'Monthly Revenue')}\n value={dashboardStats.monthlyRevenue}\n prefix=\"$\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Search + View Toggle */}\n <FilterBar\n searchValue={searchQuery}\n onSearchChange={setSearchQuery}\n searchPlaceholder={tr(\n 'housingvista.properties.search.placeholder',\n 'Search properties by name, city, or neighborhood...'\n )}\n filters={\n <button\n onClick={() => setShowFilters((prev) => !prev)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium transition-colors',\n showFilters ? 'bg-foreground text-background' : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n {tr('housingvista.properties.filters.toggle', 'Filters')}\n {hasActiveFilters && (\n <span className=\"flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-[10px] font-bold text-action-primary-text\">\n !\n </span>\n )}\n </button>\n }\n actions={\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => setViewMode('grid')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'grid'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <Grid className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'list'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <List className=\"h-4 w-4\" />\n </button>\n </div>\n }\n />\n\n {/* Filter Dropdowns */}\n {showFilters && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('housingvista.properties.filters.title', 'Filters')}\n </h3>\n {hasActiveFilters && (\n <button\n onClick={clearFilters}\n className=\"inline-flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n {tr('housingvista.properties.filters.clearAll', 'Clear All')}\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6\">\n {/* Type */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.propertyType', 'Property Type')}\n </label>\n <select\n value={selectedType}\n onChange={(e) => setSelectedType(e.target.value as PropertyType | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyTypes.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Status */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.status', 'Status')}\n </label>\n <select\n value={selectedStatus}\n onChange={(e) => setSelectedStatus(e.target.value as PropertyStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyStatuses.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Category */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as PropertyCategory | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyCategories.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Price Range */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.priceRange', 'Price Range')}\n </label>\n <select\n value={selectedPriceRange}\n onChange={(e) => setSelectedPriceRange(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {priceRanges.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Bedrooms */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.bedrooms', 'Bedrooms')}\n </label>\n <select\n value={selectedBedrooms}\n onChange={(e) => setSelectedBedrooms(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {bedroomOptions.map((b) => (\n <option key={b.value} value={b.value}>\n {b.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* RERA verification (BOFF-4132) */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.rera', 'RERA')}\n </label>\n <select\n value={selectedRera}\n onChange={(e) => setSelectedRera(e.target.value as ReraVerificationStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {reraOptions.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Results Count */}\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {tr('housingvista.properties.results.showing', 'Showing')} {filteredProperties.length}{' '}\n {tr('housingvista.properties.results.properties', 'properties')}\n {page > 1 ? ` · page ${page}` : ''}\n </p>\n {hasActiveFilters && (\n <button onClick={clearFilters} className=\"text-sm text-text-secondary hover:text-text-primary\">\n {tr('housingvista.properties.results.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n\n {/* Property Grid / List */}\n {loading ? (\n <LoadingSkeleton variant=\"card\" count={6} />\n ) : filteredProperties.length > 0 ? (\n <>\n <div\n className={cn(viewMode === 'grid' ? 'grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3' : 'space-y-4')}\n >\n {filteredProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n currency={property.price.currency}\n location={[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(property.id)}\n isShortlisted={shortlistedIds.has(property.id)}\n onToggleShortlist={() => toggleShortlist(property.id)}\n reraStatus={property.reraVerificationStatus}\n />\n ))}\n </div>\n\n {/* Pagination (server-side): working prev/next + page-size, no silent truncation */}\n <Pagination\n page={page}\n pageSize={pageSize}\n hasNextPage={hasNextPage}\n hasPreviousPage={page > 1}\n loading={loading}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title={tr('housingvista.properties.empty.title', 'No properties found')}\n description={tr(\n 'housingvista.properties.empty.description',\n 'Try adjusting your search criteria or filters to find more properties.'\n )}\n action={\n <button\n onClick={clearFilters}\n className=\"rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n {tr('housingvista.properties.empty.clearAllFilters', 'Clear All Filters')}\n </button>\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PropertiesPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertiesPage.tsx"],"sourcesContent":["/**\n * HousingVista Properties Listing Page\n * Migrated from legacy housingvista-frontend properties.tsx\n * @module housingvista\n */\n\nimport { useState, useMemo, useEffect } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Plus, Grid, List, Map, Building, SlidersHorizontal, X } from 'lucide-react';\nimport { EmphasisPanel, Pagination } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, PropertyCard, EmptyState, StatCard, LoadingSkeleton } from '../../components';\nimport { PropertyMapView } from '../../components/maps';\nimport type { LeafletBoundsResult } from '../../components/maps';\nimport {\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useDashboardStats,\n type PropertyFilterInput,\n type PropertyGeoBoundsInput,\n} from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { useHousingVistaAnalytics, useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\nimport { notify } from '../../lib/toast';\nimport { cn } from '../../utils/helpers';\nimport type { PropertyType, PropertyStatus, PropertyCategory, ReraVerificationStatus } from '../../types';\n\n/** Encode/decode the map's bounds filter to/from URL search params so a map\n * search is shareable and survives a refresh (BOFF-4617). */\nfunction boundsToSearchParam(bounds: PropertyGeoBoundsInput): string {\n return [bounds.neLat, bounds.neLng, bounds.swLat, bounds.swLng].map((n) => n.toFixed(5)).join(',');\n}\n\nfunction boundsFromSearchParam(raw: string | null): PropertyGeoBoundsInput | undefined {\n if (!raw) return undefined;\n const parts = raw.split(',').map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return undefined;\n const [neLat, neLng, swLat, swLng] = parts;\n return { neLat, neLng, swLat, swLng };\n}\n\nconst PAGE_SIZE = 9;\n\nexport const PropertiesPage = () => {\n const navigate = useNavigate();\n const [searchParams, setSearchParams] = useSearchParams();\n const { t } = useI18n();\n const { emit, emitResource, emitSearch } = useHousingVistaAnalytics();\n useTrackPageView('housingvista.property.viewed');\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const propertyTypes: { value: PropertyType | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyTypes.all', 'All Types') },\n { value: 'residential', label: tr('housingvista.properties.filters.propertyTypes.residential', 'Residential') },\n { value: 'commercial', label: tr('housingvista.properties.filters.propertyTypes.commercial', 'Commercial') },\n { value: 'industrial', label: tr('housingvista.properties.filters.propertyTypes.industrial', 'Industrial') },\n { value: 'agricultural', label: tr('housingvista.properties.filters.propertyTypes.agricultural', 'Agricultural') },\n { value: 'mixed_use', label: tr('housingvista.properties.filters.propertyTypes.mixedUse', 'Mixed Use') },\n ];\n\n const propertyStatuses: { value: PropertyStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyStatuses.all', 'All Status') },\n { value: 'for_sale', label: tr('housingvista.properties.filters.propertyStatuses.forSale', 'For Sale') },\n { value: 'for_rent', label: tr('housingvista.properties.filters.propertyStatuses.forRent', 'For Rent') },\n { value: 'sold', label: tr('housingvista.properties.filters.propertyStatuses.sold', 'Sold') },\n { value: 'rented', label: tr('housingvista.properties.filters.propertyStatuses.rented', 'Rented') },\n {\n value: 'under_contract',\n label: tr('housingvista.properties.filters.propertyStatuses.underContract', 'Under Contract'),\n },\n { value: 'off_market', label: tr('housingvista.properties.filters.propertyStatuses.offMarket', 'Off Market') },\n ];\n\n const propertyCategories: { value: PropertyCategory | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyCategories.all', 'All Categories') },\n { value: 'apartment', label: tr('housingvista.properties.filters.propertyCategories.apartment', 'Apartment') },\n { value: 'house', label: tr('housingvista.properties.filters.propertyCategories.house', 'House') },\n { value: 'villa', label: tr('housingvista.properties.filters.propertyCategories.villa', 'Villa') },\n { value: 'office', label: tr('housingvista.properties.filters.propertyCategories.office', 'Office') },\n { value: 'retail', label: tr('housingvista.properties.filters.propertyCategories.retail', 'Retail') },\n { value: 'warehouse', label: tr('housingvista.properties.filters.propertyCategories.warehouse', 'Warehouse') },\n { value: 'land', label: tr('housingvista.properties.filters.propertyCategories.land', 'Land') },\n { value: 'plot', label: tr('housingvista.properties.filters.propertyCategories.plot', 'Plot') },\n ];\n\n const priceRanges = [\n { value: 'all', label: tr('housingvista.properties.filters.priceRanges.all', 'Any Price'), min: 0, max: Infinity },\n {\n value: 'under_100k',\n label: tr('housingvista.properties.filters.priceRanges.under100k', 'Under $100K'),\n min: 0,\n max: 100000,\n },\n {\n value: '100k_500k',\n label: tr('housingvista.properties.filters.priceRanges.100kTo500k', '$100K - $500K'),\n min: 100000,\n max: 500000,\n },\n {\n value: '500k_1m',\n label: tr('housingvista.properties.filters.priceRanges.500kTo1m', '$500K - $1M'),\n min: 500000,\n max: 1000000,\n },\n {\n value: 'over_1m',\n label: tr('housingvista.properties.filters.priceRanges.over1m', 'Over $1M'),\n min: 1000000,\n max: Infinity,\n },\n ];\n\n const bedroomOptions = [\n { value: 'all', label: tr('housingvista.properties.filters.bedrooms.all', 'Any Bedrooms') },\n { value: '1', label: '1+' },\n { value: '2', label: '2+' },\n { value: '3', label: '3+' },\n { value: '4', label: '4+' },\n { value: '5', label: '5+' },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<PropertyType | 'all'>('all');\n const [selectedStatus, setSelectedStatus] = useState<PropertyStatus | 'all'>('all');\n const [selectedCategory, setSelectedCategory] = useState<PropertyCategory | 'all'>('all');\n const [selectedPriceRange, setSelectedPriceRange] = useState('all');\n const [selectedBedrooms, setSelectedBedrooms] = useState('all');\n const initialView = searchParams.get('view');\n const [viewMode, setViewModeState] = useState<'grid' | 'list' | 'map'>(\n initialView === 'map' || initialView === 'list' ? initialView : 'grid'\n );\n // Map-mode bounds filter (BOFF-4617) — round-tripped through the URL (`bounds`\n // query param) so a \"Search this area\" map view is shareable/bookmarkable.\n const [mapBounds, setMapBounds] = useState<PropertyGeoBoundsInput | undefined>(() =>\n boundsFromSearchParam(searchParams.get('bounds'))\n );\n const [showFilters, setShowFilters] = useState(false);\n\n const setViewMode = (mode: 'grid' | 'list' | 'map') => {\n setViewModeState(mode);\n const next = new URLSearchParams(searchParams);\n if (mode === 'grid') {\n next.delete('view');\n } else {\n next.set('view', mode);\n }\n if (mode !== 'map') {\n next.delete('bounds');\n }\n setSearchParams(next, { replace: true });\n };\n\n const handleSearchThisArea = (bounds: LeafletBoundsResult) => {\n setMapBounds(bounds);\n const next = new URLSearchParams(searchParams);\n next.set('view', 'map');\n next.set('bounds', boundsToSearchParam(bounds));\n setSearchParams(next, { replace: true });\n };\n\n const reraOptions: { value: ReraVerificationStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.rera.all', 'Any RERA status') },\n { value: 'verified', label: tr('housingvista.properties.filters.rera.verified', 'RERA Verified') },\n { value: 'pending', label: tr('housingvista.properties.filters.rera.pending', 'RERA Pending') },\n { value: 'not_applicable', label: tr('housingvista.properties.filters.rera.notApplicable', 'Not RERA-applicable') },\n { value: 'rejected', label: tr('housingvista.properties.filters.rera.rejected', 'RERA Rejected') },\n ];\n\n const [selectedRera, setSelectedRera] = useState<ReraVerificationStatus | 'all'>('all');\n\n const priceRange = priceRanges.find((r) => r.value === selectedPriceRange) ?? priceRanges[0];\n const minBedrooms = selectedBedrooms === 'all' ? 0 : Number(selectedBedrooms);\n\n // Debounce the search box so we don't refetch on every keystroke.\n const [debouncedSearch, setDebouncedSearch] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedSearch(searchQuery), 300);\n return () => clearTimeout(timer);\n }, [searchQuery]);\n\n // Analytics: emit search event when a non-empty debounced query is entered.\n useEffect(() => {\n if (debouncedSearch.trim()) {\n emitSearch('properties');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearch]);\n\n const { page, pageSize, pagination, setPage, setPageSize } = useServerPagination(PAGE_SIZE);\n\n // Every filter is resolved server-side (BOFF-3933) — the subgraph's\n // HousingVistaPropertyFilterInput now models price/bedrooms/category/RERA\n // directly, so pagination totals are always accurate at scale.\n const serverFilter = useMemo<PropertyFilterInput | undefined>(() => {\n const filter: PropertyFilterInput = {};\n if (debouncedSearch.trim()) filter.search = debouncedSearch.trim();\n if (selectedStatus !== 'all') filter.status = selectedStatus;\n if (selectedType !== 'all') filter.type = selectedType;\n if (selectedCategory !== 'all') filter.category = selectedCategory;\n if (priceRange.min > 0) filter.priceMin = priceRange.min;\n if (Number.isFinite(priceRange.max)) filter.priceMax = priceRange.max;\n if (minBedrooms > 0) filter.bedroomsMin = minBedrooms;\n if (selectedRera !== 'all') filter.reraVerificationStatus = selectedRera;\n return Object.keys(filter).length > 0 ? filter : undefined;\n }, [debouncedSearch, selectedStatus, selectedType, selectedCategory, priceRange, minBedrooms, selectedRera]);\n\n // Reset to first page whenever the server-side filter changes.\n useEffect(() => {\n setPage(1);\n }, [serverFilter, setPage]);\n\n const { data: properties, loading } = useProperties({ filter: serverFilter, pagination, skip: viewMode === 'map' });\n\n // Map mode (BOFF-4617): a separate, wider fetch bounded by the map's current\n // viewport instead of the grid/list's page-by-page pagination. Reapplying the\n // same non-geo filters (status/type/category/price/bedrooms/RERA) keeps the\n // map in sync with the filter panel.\n const mapFilter = useMemo<PropertyFilterInput | undefined>(() => {\n if (!mapBounds) return serverFilter;\n return { ...(serverFilter ?? {}), bounds: mapBounds };\n }, [serverFilter, mapBounds]);\n const { data: mapProperties, loading: mapLoading } = useProperties({\n filter: mapFilter,\n pagination: { limit: 200, offset: 0 },\n skip: viewMode !== 'map',\n });\n // Portfolio-wide totals for the stats zone — independent of the current page slice.\n const { data: dashboardStats } = useDashboardStats();\n const { data: shortlists } = useShortlists();\n const { saveShortlist } = useSaveShortlist();\n const { removeShortlist } = useRemoveShortlist();\n\n const shortlistedIds = useMemo(() => new Set(shortlists.map((s) => s.propertyId)), [shortlists]);\n\n const toggleShortlist = async (propertyId: string) => {\n try {\n if (shortlistedIds.has(propertyId)) {\n await removeShortlist(propertyId);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(propertyId);\n emitResource('housingvista.shortlist.property_added', propertyId);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n // All filtering happens server-side now (see `serverFilter` above); the\n // page just renders the page slice the server already filtered.\n const filteredProperties = properties;\n\n const hasNextPage = properties.length >= pageSize;\n\n const hasActiveFilters =\n searchQuery ||\n selectedType !== 'all' ||\n selectedStatus !== 'all' ||\n selectedCategory !== 'all' ||\n selectedPriceRange !== 'all' ||\n selectedBedrooms !== 'all' ||\n selectedRera !== 'all';\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedType('all');\n setSelectedStatus('all');\n setSelectedCategory('all');\n setSelectedPriceRange('all');\n setSelectedBedrooms('all');\n setSelectedRera('all');\n };\n\n return (\n <PageLayout\n title={tr('housingvista.properties.title', 'Properties')}\n description={tr(\n 'housingvista.properties.description',\n 'Discover your perfect property from our comprehensive listings'\n )}\n purpose={tr(\n 'housingvista.properties.purpose',\n 'Browse, search, and filter every property in your portfolio or on the market. Use the filters to narrow by type, status, price, and bedrooms, then open any listing to see full details, schedule viewings, or start a transaction.'\n )}\n actions={\n <button\n onClick={() => {\n emit('housingvista.property.create_clicked');\n navigate('new');\n }}\n className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.properties.actions.addProperty', 'Add Property')}\n </button>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.properties.stats.totalProperties', 'Total Properties')}\n value={dashboardStats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n />\n <StatCard\n label={tr('housingvista.properties.stats.portfolioValue', 'Portfolio Value')}\n value={dashboardStats.totalValue}\n prefix=\"$\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.occupancyRate', 'Occupancy Rate')}\n value={dashboardStats.occupancyRate}\n unit=\"%\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.monthlyRevenue', 'Monthly Revenue')}\n value={dashboardStats.monthlyRevenue}\n prefix=\"$\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Search + View Toggle */}\n <FilterBar\n searchValue={searchQuery}\n onSearchChange={setSearchQuery}\n searchPlaceholder={tr(\n 'housingvista.properties.search.placeholder',\n 'Search properties by name, city, or neighborhood...'\n )}\n filters={\n <button\n onClick={() => setShowFilters((prev) => !prev)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium transition-colors',\n showFilters ? 'bg-foreground text-background' : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n {tr('housingvista.properties.filters.toggle', 'Filters')}\n {hasActiveFilters && (\n <span className=\"flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-[10px] font-bold text-action-primary-text\">\n !\n </span>\n )}\n </button>\n }\n actions={\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => setViewMode('grid')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'grid'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <Grid className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'list'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <List className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('map')}\n aria-label={tr('housingvista.properties.viewMode.map', 'Map view')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'map'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <Map className=\"h-4 w-4\" />\n </button>\n </div>\n }\n />\n\n {/* Filter Dropdowns */}\n {showFilters && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('housingvista.properties.filters.title', 'Filters')}\n </h3>\n {hasActiveFilters && (\n <button\n onClick={clearFilters}\n className=\"inline-flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n {tr('housingvista.properties.filters.clearAll', 'Clear All')}\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6\">\n {/* Type */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.propertyType', 'Property Type')}\n </label>\n <select\n value={selectedType}\n onChange={(e) => setSelectedType(e.target.value as PropertyType | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyTypes.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Status */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.status', 'Status')}\n </label>\n <select\n value={selectedStatus}\n onChange={(e) => setSelectedStatus(e.target.value as PropertyStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyStatuses.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Category */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as PropertyCategory | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyCategories.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Price Range */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.priceRange', 'Price Range')}\n </label>\n <select\n value={selectedPriceRange}\n onChange={(e) => setSelectedPriceRange(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {priceRanges.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Bedrooms */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.bedrooms', 'Bedrooms')}\n </label>\n <select\n value={selectedBedrooms}\n onChange={(e) => setSelectedBedrooms(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {bedroomOptions.map((b) => (\n <option key={b.value} value={b.value}>\n {b.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* RERA verification (BOFF-4132) */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.rera', 'RERA')}\n </label>\n <select\n value={selectedRera}\n onChange={(e) => setSelectedRera(e.target.value as ReraVerificationStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {reraOptions.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Results Count */}\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {viewMode === 'map' ? (\n <>\n {tr('housingvista.properties.results.showingOnMap', 'Showing')} {mapProperties.length}{' '}\n {tr('housingvista.properties.results.properties', 'properties')}\n {mapBounds ? ` · ${tr('housingvista.properties.results.inThisArea', 'in this area')}` : ''}\n </>\n ) : (\n <>\n {tr('housingvista.properties.results.showing', 'Showing')} {filteredProperties.length}{' '}\n {tr('housingvista.properties.results.properties', 'properties')}\n {page > 1 ? ` · page ${page}` : ''}\n </>\n )}\n </p>\n {hasActiveFilters && (\n <button onClick={clearFilters} className=\"text-sm text-text-secondary hover:text-text-primary\">\n {tr('housingvista.properties.results.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n\n {/* Property Map (BOFF-4617) */}\n {viewMode === 'map' && (\n <PropertyMapView\n properties={mapProperties}\n loading={mapLoading}\n selectedIds={shortlistedIds}\n onSelectProperty={(id) => navigate(id)}\n onSearchThisArea={handleSearchThisArea}\n />\n )}\n\n {/* Property Grid / List */}\n {viewMode === 'map' ? null : loading ? (\n <LoadingSkeleton variant=\"card\" count={6} />\n ) : filteredProperties.length > 0 ? (\n <>\n <div\n className={cn(viewMode === 'grid' ? 'grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3' : 'space-y-4')}\n >\n {filteredProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n currency={property.price.currency}\n location={[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(property.id)}\n isShortlisted={shortlistedIds.has(property.id)}\n onToggleShortlist={() => toggleShortlist(property.id)}\n reraStatus={property.reraVerificationStatus}\n />\n ))}\n </div>\n\n {/* Pagination (server-side): working prev/next + page-size, no silent truncation */}\n <Pagination\n page={page}\n pageSize={pageSize}\n hasNextPage={hasNextPage}\n hasPreviousPage={page > 1}\n loading={loading}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title={tr('housingvista.properties.empty.title', 'No properties found')}\n description={tr(\n 'housingvista.properties.empty.description',\n 'Try adjusting your search criteria or filters to find more properties.'\n )}\n action={\n <button\n onClick={clearFilters}\n className=\"rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n {tr('housingvista.properties.empty.clearAllFilters', 'Clear All Filters')}\n </button>\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ .leaflet-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-container,.leaflet-pane>svg,.leaflet-pane>canvas,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;top:0;left:0}.leaflet-container{overflow:hidden}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-tile::selection{background:0 0}.leaflet-safari .leaflet-tile{image-rendering:-webkit-optimize-contrast}.leaflet-safari .leaflet-tile-container{-webkit-transform-origin:0 0;width:1600px;height:1600px}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container .leaflet-overlay-pane svg{max-width:none!important;max-height:none!important}.leaflet-container .leaflet-marker-pane img,.leaflet-container .leaflet-shadow-pane img,.leaflet-container .leaflet-tile-pane img,.leaflet-container img.leaflet-image-layer,.leaflet-container .leaflet-tile{width:auto;padding:0;max-width:none!important;max-height:none!important}.leaflet-container img.leaflet-tile{mix-blend-mode:plus-lighter}.leaflet-container.leaflet-touch-zoom{-ms-touch-action:pan-x pan-y;touch-action:pan-x pan-y}.leaflet-container.leaflet-touch-drag{-ms-touch-action:pinch-zoom;touch-action:none;touch-action:pinch-zoom}.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{-ms-touch-action:none;touch-action:none}.leaflet-container{-webkit-tap-highlight-color:transparent}.leaflet-container a{-webkit-tap-highlight-color:#33b5e566}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{box-sizing:border-box;z-index:800;width:0;height:0}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-pane{z-index:400}.leaflet-tile-pane{z-index:200}.leaflet-overlay-pane{z-index:400}.leaflet-shadow-pane{z-index:500}.leaflet-marker-pane{z-index:600}.leaflet-tooltip-pane{z-index:650}.leaflet-popup-pane{z-index:700}.leaflet-map-pane canvas{z-index:100}.leaflet-map-pane svg{z-index:200}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{z-index:800;pointer-events:visiblePainted;pointer-events:auto;position:relative}.leaflet-top,.leaflet-bottom{z-index:1000;pointer-events:none;position:absolute}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-popup{opacity:0;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-animated{transform-origin:0 0}svg.leaflet-zoom-animated{will-change:transform}.leaflet-zoom-anim .leaflet-zoom-animated{-webkit-transition:-webkit-transform .25s cubic-bezier(0,0,.25,1);-moz-transition:-moz-transform .25s cubic-bezier(0,0,.25,1);transition:transform .25s cubic-bezier(0,0,.25,1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile{transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-interactive{cursor:pointer}.leaflet-grab{cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.leaflet-crosshair,.leaflet-crosshair .leaflet-interactive{cursor:crosshair}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-grab,.leaflet-dragging .leaflet-grab .leaflet-interactive,.leaflet-dragging .leaflet-marker-draggable{cursor:move;cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-image-layer,.leaflet-pane>svg path,.leaflet-tile-container{pointer-events:none}.leaflet-marker-icon.leaflet-interactive,.leaflet-image-layer.leaflet-interactive,.leaflet-pane>svg path.leaflet-interactive,svg.leaflet-image-layer.leaflet-interactive path{pointer-events:visiblePainted;pointer-events:auto}.leaflet-container{outline-offset:1px;background:#ddd}.leaflet-container a{color:#0078a8}.leaflet-zoom-box{background:#ffffff80;border:2px dotted #38f}.leaflet-container{font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:.75rem;line-height:1.5}.leaflet-bar{border-radius:4px;box-shadow:0 1px 5px #000000a6}.leaflet-bar a{text-align:center;color:#000;background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;text-decoration:none;display:block}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover,.leaflet-bar a:focus{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom:none;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.leaflet-bar a.leaflet-disabled{cursor:default;color:#bbb;background-color:#f4f4f4}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-touch .leaflet-bar a:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.leaflet-touch .leaflet-bar a:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.leaflet-control-zoom-in,.leaflet-control-zoom-out{text-indent:1px;font:700 18px Lucida Console,Monaco,monospace}.leaflet-touch .leaflet-control-zoom-in,.leaflet-touch .leaflet-control-zoom-out{font-size:22px}.leaflet-control-layers{background:#fff;border-radius:5px;box-shadow:0 1px 5px #0006}.leaflet-control-layers-toggle{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAQAAAADQ4RFAAACf0lEQVR4AY1UM3gkARTePdvdoTxXKc+qTl3aU5U6b2Kbkz3Gtq3Zw6ziLGNPzrYx7946Tr6/ee/XeCQ4D3ykPtL5tHno4n0d/h3+xfuWHGLX81cn7r0iTNzjr7LrlxCqPtkbTQEHeqOrTy4Yyt3VCi/IOB0v7rVC7q45Q3Gr5K6jt+3Gl5nCoDD4MtO+j96Wu8atmhGqcNGHObuf8OM/x3AMx38+4Z2sPqzCxRFK2aF2e5Jol56XTLyggAMTL56XOMoS1W4pOyjUcGGQdZxU6qRh7B9Zp+PfpOFlqt0zyDZckPi1ttmIp03jX8gyJ8a/PG2yutpS/Vol7peZIbZcKBAEEheEIAgFbDkz5H6Zrkm2hVWGiXKiF4Ycw0RWKdtC16Q7qe3X4iOMxruonzegJzWaXFrU9utOSsLUmrc0YjeWYjCW4PDMADElpJSSQ0vQvA1Tm6/JlKnqFs1EGyZiFCqnRZTEJJJiKRYzVYzJck2Rm6P4iH+cmSY0YzimYa8l0EtTODFWhcMIMVqdsI2uiTvKmTisIDHJ3od5GILVhBCarCfVRmo4uTjkhrhzkiBV7SsaqS+TzrzM1qpGGUFt28pIySQHR6h7F6KSwGWm97ay+Z+ZqMcEjEWebE7wxCSQwpkhJqoZA5ivCdZDjJepuJ9IQjGGUmuXJdBFUygxVqVsxFsLMbDe8ZbDYVCGKxs+W080max1hFCarCfV+C1KATwcnvE9gRRuMP2prdbWGowm1KB1y+zwMMENkM755cJ2yPDtqhTI6ED1M/82yIDtC/4j4BijjeObflpO9I9MwXTCsSX8jWAFeHr05WoLTJ5G8IQVS/7vwR6ohirYM7f6HzYpogfS3R2OAAAAAElFTkSuQmCC);width:36px;height:36px}.leaflet-retina .leaflet-control-layers-toggle{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAQAAABvcdNgAAAEsklEQVR4AWL4TydIhpZK1kpWOlg0w3ZXP6D2soBtG42jeI6ZmQTHzAxiTbSJsYLjO9HhP+WOmcuhciVnmHVQcJnp7DFvScowZorad/+V/fVzMdMT2g9Cv9guXGv/7pYOrXh2U+RRR3dSd9JRx6bIFc/ekqHI29JC6pJ5ZEh1yWkhkbcFeSjxgx3L2m1cb1C7bceyxA+CNjT/Ifff+/kDk2u/w/33/IeCMOSaWZ4glosqT3DNnNZQ7Cs58/3Ce5HL78iZH/vKVIaYlqzfdLu8Vi7dnvUbEza5Idt36tquZFldl6N5Z/POLof0XLK61mZCmJSWjVF9tEjUluu74IUXvgttuVIHE7YxSkaYhJZam7yiM9Pv82JYfl9nptxZaxMJE4YSPty+vF0+Y2up9d3wwijfjZbabqm/3bZ9ecKHsiGmRflnn1MW4pjHf9oLufyn2z3y1D6n8g8TZhxyzipLNPnAUpsOiuWimg52psrTZYnOWYNDTMuWBWa0tJb4rgq1UvmutpaYEbZlwU3CLJm/ayYjHW5/h7xWLn9Hh1vepDkyf7dE7MtT5LR4e7yYpHrkhOUpEfssBLq2pPhAqoSWKUkk7EDqkmK6RrCEzqDjhNDWNE+XSMvkJRDWlZTmCW0l0PHQGRZY5t1L83kT0Y3l2SItk5JAWHl2dCOBm+fPu3fo5/3v61RMCO9Jx2EEYYhb0rmNQMX/vm7gqOEJLcXTGw3CAuRNeyaPWwjR8PRqKQ1PDA/dpv+on9Shox52WFnx0KY8onHayrJzm87i5h9xGw/tfkev0jGsQizqezUKjk12hBMKJ4kbCqGPVNXudyyrShovGw5CgxsRICxF6aRmSjlBnHRzg7Gx8fKqEubI2rahQYdR1YgDIRQO7JvQyD52hoIQx0mxa0ODtW2Iozn1le2iIRdzwWewedyZzewidueOGqlsn1MvcnQpuVwLGG3/IR1hIKxCjelIDZ8ldqWz25jWAsnldEnK0Zxro19TGVb2ffIZEsIO89EIEDvKMPrzmBOQcKQ+rroye6NgRRxqR4U8EAkz0CL6uSGOm6KQCdWjvjRiSP1BPalCRS5iQYiEIvxuBMJEWgzSoHADcVMuN7IuqqTeyUPq22qFimFtxDyBBJEwNyt6TM88blFHao/6tWWhuuOM4SAK4EI4QmFHA+SEyWlp4EQoJ13cYGzMu7yszEIBOm2rVmHUNqwAIQabISNMRstmdhNWcFLsSm+0tjJH1MdRxO5Nx0WDMhCtgD6OKgZeljJqJKc9po8juskR9XN0Y1lZ3mWjLR9JCO1jRDMd0fpYC2VnvjBSEFg7wBENc0R9HFlb0xvF1+TBEpF68d+DHR6IOWVv2BECtxo46hOFUBd/APU57WIoEwJhIi2CdpyZX0m93BZicktMj1AS9dClteUFAUNUIEygRZCtik5zSxI9MubTBH1GOiHsiLJ3OCoSZkILa9PxiN0EbvhsAo8tdAf9Seepd36lGWHmtNANTv5Jd0z4QYyeo/UEJqxKRpg5LZx6btLPsOaEmdMyxYdlc8LMaJnikDlhclqmPiQnTEpLUIZEwkRagjYkEibQErwhkTAKCLQEbUgkzJQWc/0PstHHcfEdQ+UAAAAASUVORK5CYII=);background-size:26px 26px}.leaflet-touch .leaflet-control-layers-toggle{width:44px;height:44px}.leaflet-control-layers .leaflet-control-layers-list,.leaflet-control-layers-expanded .leaflet-control-layers-toggle{display:none}.leaflet-control-layers-expanded .leaflet-control-layers-list{display:block;position:relative}.leaflet-control-layers-expanded{color:#333;background:#fff;padding:6px 10px 6px 6px}.leaflet-control-layers-scrollbar{padding-right:5px;overflow:hidden scroll}.leaflet-control-layers-selector{margin-top:2px;position:relative;top:1px}.leaflet-control-layers label{font-size:1.08333em;display:block}.leaflet-control-layers-separator{border-top:1px solid #ddd;height:0;margin:5px -10px 5px -6px}.leaflet-default-icon-path{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=)}.leaflet-container .leaflet-control-attribution{background:#fffc;margin:0}.leaflet-control-attribution,.leaflet-control-scale-line{color:#333;padding:0 5px;line-height:1.4}.leaflet-control-attribution a{text-decoration:none}.leaflet-control-attribution a:hover,.leaflet-control-attribution a:focus{text-decoration:underline}.leaflet-attribution-flag{width:1em;height:.6669em;vertical-align:baseline!important;display:inline!important}.leaflet-left .leaflet-control-scale{margin-left:5px}.leaflet-bottom .leaflet-control-scale{margin-bottom:5px}.leaflet-control-scale-line{white-space:nowrap;box-sizing:border-box;text-shadow:1px 1px #fff;background:#fffc;border:2px solid #777;border-top:none;padding:2px 5px 1px;line-height:1.1}.leaflet-control-scale-line:not(:first-child){border-top:2px solid #777;border-bottom:none;margin-top:-2px}.leaflet-control-scale-line:not(:first-child):not(:last-child){border-bottom:2px solid #777}.leaflet-touch .leaflet-control-attribution,.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{box-shadow:none}.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{background-clip:padding-box;border:2px solid #0003}.leaflet-popup{text-align:center;margin-bottom:20px;position:absolute}.leaflet-popup-content-wrapper{text-align:left;border-radius:12px;padding:1px}.leaflet-popup-content{min-height:1px;margin:13px 24px 13px 20px;font-size:1.08333em;line-height:1.3}.leaflet-popup-content p{margin:1.3em 0}.leaflet-popup-tip-container{pointer-events:none;width:40px;height:20px;margin-top:-1px;margin-left:-20px;position:absolute;left:50%;overflow:hidden}.leaflet-popup-tip{pointer-events:auto;width:17px;height:17px;margin:-10px auto 0;padding:1px;transform:rotate(45deg)}.leaflet-popup-content-wrapper,.leaflet-popup-tip{color:#333;background:#fff;box-shadow:0 3px 14px #0006}.leaflet-container a.leaflet-popup-close-button{text-align:center;color:#757575;background:0 0;border:none;width:24px;height:24px;font:16px/24px Tahoma,Verdana,sans-serif;text-decoration:none;position:absolute;top:0;right:0}.leaflet-container a.leaflet-popup-close-button:hover,.leaflet-container a.leaflet-popup-close-button:focus{color:#585858}.leaflet-popup-scrolled{overflow:auto}.leaflet-oldie .leaflet-popup-content-wrapper{-ms-zoom:1}.leaflet-oldie .leaflet-popup-tip{-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";width:24px;filter:progid:DXImageTransform.Microsoft.Matrix(M11=.707107, M12=.707107, M21=-.707107, M22=.707107);margin:0 auto}.leaflet-oldie .leaflet-control-zoom,.leaflet-oldie .leaflet-control-layers,.leaflet-oldie .leaflet-popup-content-wrapper,.leaflet-oldie .leaflet-popup-tip{border:1px solid #999}.leaflet-div-icon{background:#fff;border:1px solid #666}.leaflet-tooltip{color:#222;white-space:nowrap;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:#fff;border:1px solid #fff;border-radius:3px;padding:6px;position:absolute;box-shadow:0 1px 3px #0006}.leaflet-tooltip.leaflet-interactive{cursor:pointer;pointer-events:auto}.leaflet-tooltip-top:before,.leaflet-tooltip-bottom:before,.leaflet-tooltip-left:before,.leaflet-tooltip-right:before{pointer-events:none;content:"";background:0 0;border:6px solid #0000;position:absolute}.leaflet-tooltip-bottom{margin-top:6px}.leaflet-tooltip-top{margin-top:-6px}.leaflet-tooltip-bottom:before,.leaflet-tooltip-top:before{margin-left:-6px;left:50%}.leaflet-tooltip-top:before{border-top-color:#fff;margin-bottom:-12px;bottom:0}.leaflet-tooltip-bottom:before{border-bottom-color:#fff;margin-top:-12px;margin-left:-6px;top:0}.leaflet-tooltip-left{margin-left:-6px}.leaflet-tooltip-right{margin-left:6px}.leaflet-tooltip-left:before,.leaflet-tooltip-right:before{margin-top:-6px;top:50%}.leaflet-tooltip-left:before{border-left-color:#fff;margin-right:-12px;right:0}.leaflet-tooltip-right:before{border-right-color:#fff;margin-left:-12px;left:0}@media print{.leaflet-control{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.hv-pin-wrapper{background:0 0;border:0}.hv-pin{white-space:nowrap;background:var(--color-action-primary-bg);color:var(--color-action-primary-text);border:2px solid var(--color-bg-surface,#fff);cursor:pointer;border-radius:999px;align-items:center;gap:2px;padding:4px 8px;font:600 12px/1.2 inherit;display:inline-flex;transform:translate(-50%,-100%);box-shadow:0 2px 6px #00000040}.hv-pin--selected{background:var(--color-status-success-bg,var(--color-action-primary-bg));color:var(--color-status-success-text,var(--color-action-primary-text));box-shadow:0 0 0 3px var(--color-focus-ring,#0003)}.hv-pin__rera{background:var(--color-status-success-text,#16a34a);width:13px;height:13px;color:var(--color-status-success-bg,#fff);border-radius:50%;justify-content:center;align-items:center;font-size:9px;line-height:1;display:inline-flex}.hv-popup .leaflet-popup-content-wrapper{border-radius:12px;padding:0}.hv-popup .leaflet-popup-content{min-width:220px;margin:0}
2
+ /*$vite$:1*/
@@ -0,0 +1,12 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ //#region node_modules/@react-leaflet/core/lib/attribution.js
3
+ function n(n, r) {
4
+ let i = t(r);
5
+ e(function() {
6
+ r !== i.current && n.attributionControl != null && (i.current != null && n.attributionControl.removeAttribution(i.current), r != null && n.attributionControl.addAttribution(r)), i.current = r;
7
+ }, [n, r]);
8
+ }
9
+ //#endregion
10
+ export { n as useAttribution };
11
+
12
+ //# sourceMappingURL=attribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribution.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/attribution.js"],"sourcesContent":["import { useEffect, useRef } from 'react';\nexport function useAttribution(map, attribution) {\n const attributionRef = useRef(attribution);\n useEffect(function updateAttribution() {\n if (attribution !== attributionRef.current && map.attributionControl != null) {\n if (attributionRef.current != null) {\n map.attributionControl.removeAttribution(attributionRef.current);\n }\n if (attribution != null) {\n map.attributionControl.addAttribution(attribution);\n }\n }\n attributionRef.current = attribution;\n }, [\n map,\n attribution\n ]);\n}\n"],"x_google_ignoreList":[0],"mappings":";;AACA,SAAgB,EAAe,GAAK,GAAa;CAC7C,IAAM,IAAiB,EAAO,EAAY;AAC1C,GAAU,WAA6B;AASnC,EARI,MAAgB,EAAe,WAAW,EAAI,sBAAsB,SAChE,EAAe,WAAW,QAC1B,EAAI,mBAAmB,kBAAkB,EAAe,QAAQ,EAEhE,KAAe,QACf,EAAI,mBAAmB,eAAe,EAAY,GAG1D,EAAe,UAAU;IAC1B,CACC,GACA,EACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { LeafletContext as e } from "./context.js";
2
+ import t, { forwardRef as n, useEffect as r, useImperativeHandle as i, useState as a } from "react";
3
+ import { createPortal as o } from "react-dom";
4
+ //#region node_modules/@react-leaflet/core/lib/component.js
5
+ function s(r) {
6
+ function a(n, a) {
7
+ let { instance: o, context: s } = r(n).current;
8
+ i(a, () => o);
9
+ let { children: c } = n;
10
+ return c == null ? null : /* @__PURE__ */ t.createElement(e, { value: s }, c);
11
+ }
12
+ return /* @__PURE__ */ n(a);
13
+ }
14
+ function c(e) {
15
+ function t(t, n) {
16
+ let [s, c] = a(!1), { instance: l } = e(t, c).current;
17
+ i(n, () => l), r(function() {
18
+ s && l.update();
19
+ }, [
20
+ l,
21
+ s,
22
+ t.children
23
+ ]);
24
+ let u = l._contentNode;
25
+ return u ? /* @__PURE__ */ o(t.children, u) : null;
26
+ }
27
+ return /* @__PURE__ */ n(t);
28
+ }
29
+ function l(e) {
30
+ function t(t, n) {
31
+ let { instance: r } = e(t).current;
32
+ return i(n, () => r), null;
33
+ }
34
+ return /* @__PURE__ */ n(t);
35
+ }
36
+ //#endregion
37
+ export { s as createContainerComponent, c as createDivOverlayComponent, l as createLeafComponent };
38
+
39
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/component.js"],"sourcesContent":["import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { LeafletContext } from './context.js';\nexport function createContainerComponent(useElement) {\n function ContainerComponent(props, forwardedRef) {\n const { instance, context } = useElement(props).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n const { children } = props;\n return children == null ? null : /*#__PURE__*/ React.createElement(LeafletContext, {\n value: context\n }, children);\n }\n return /*#__PURE__*/ forwardRef(ContainerComponent);\n}\nexport function createDivOverlayComponent(useElement) {\n function OverlayComponent(props, forwardedRef) {\n const [isOpen, setOpen] = useState(false);\n const { instance } = useElement(props, setOpen).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n // biome-ignore lint/correctness/useExhaustiveDependencies: update overlay when children change\n useEffect(function updateOverlay() {\n if (isOpen) {\n instance.update();\n }\n }, [\n instance,\n isOpen,\n props.children\n ]);\n // @ts-ignore _contentNode missing in type definition\n const contentNode = instance._contentNode;\n return contentNode ? /*#__PURE__*/ createPortal(props.children, contentNode) : null;\n }\n return /*#__PURE__*/ forwardRef(OverlayComponent);\n}\nexport function createLeafComponent(useElement) {\n function LeafComponent(props, forwardedRef) {\n const { instance } = useElement(props).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n return null;\n }\n return /*#__PURE__*/ forwardRef(LeafComponent);\n}\n"],"x_google_ignoreList":[0],"mappings":";;;;AAGA,SAAgB,EAAyB,GAAY;CACjD,SAAS,EAAmB,GAAO,GAAc;EAC7C,IAAM,EAAE,aAAU,eAAY,EAAW,EAAM,CAAC;AAChD,IAAoB,SAAkB,EAAS;EAC/C,IAAM,EAAE,gBAAa;AACrB,SAAO,KAAY,OAAO,OAAqB,kBAAM,cAAc,GAAgB,EAC/E,OAAO,GACV,EAAE,EAAS;;AAEhB,QAAqB,kBAAW,EAAmB;;AAEvD,SAAgB,EAA0B,GAAY;CAClD,SAAS,EAAiB,GAAO,GAAc;EAC3C,IAAM,CAAC,GAAQ,KAAW,EAAS,GAAM,EACnC,EAAE,gBAAa,EAAW,GAAO,EAAQ,CAAC;AAGhD,EAFA,EAAoB,SAAkB,EAAS,EAE/C,EAAU,WAAyB;AAC/B,GAAI,KACA,EAAS,QAAQ;KAEtB;GACC;GACA;GACA,EAAM;GACT,CAAC;EAEF,IAAM,IAAc,EAAS;AAC7B,SAAO,IAA4B,kBAAa,EAAM,UAAU,EAAY,GAAG;;AAEnF,QAAqB,kBAAW,EAAiB;;AAErD,SAAgB,EAAoB,GAAY;CAC5C,SAAS,EAAc,GAAO,GAAc;EACxC,IAAM,EAAE,gBAAa,EAAW,EAAM,CAAC;AAEvC,SADA,EAAoB,SAAkB,EAAS,EACxC;;AAEX,QAAqB,kBAAW,EAAc"}
@@ -0,0 +1,23 @@
1
+ import { createContext as e, use as t } from "react";
2
+ function n(e) {
3
+ return Object.freeze({
4
+ __version: 1,
5
+ map: e
6
+ });
7
+ }
8
+ function r(e, t) {
9
+ return Object.freeze({
10
+ ...e,
11
+ ...t
12
+ });
13
+ }
14
+ var i = e(null);
15
+ function a() {
16
+ let e = t(i);
17
+ if (e == null) throw Error("No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>");
18
+ return e;
19
+ }
20
+ //#endregion
21
+ export { i as LeafletContext, n as createLeafletContext, r as extendContext, a as useLeafletContext };
22
+
23
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/context.js"],"sourcesContent":["import { createContext, use } from 'react';\nexport const CONTEXT_VERSION = 1;\nexport function createLeafletContext(map) {\n return Object.freeze({\n __version: CONTEXT_VERSION,\n map\n });\n}\nexport function extendContext(source, extra) {\n return Object.freeze({\n ...source,\n ...extra\n });\n}\nexport const LeafletContext = createContext(null);\nexport function useLeafletContext() {\n const context = use(LeafletContext);\n if (context == null) {\n throw new Error('No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>');\n }\n return context;\n}\n"],"x_google_ignoreList":[0],"mappings":";AAEA,SAAgB,EAAqB,GAAK;AACtC,QAAO,OAAO,OAAO;EACjB,WAAA;EACA;EACH,CAAC;;AAEN,SAAgB,EAAc,GAAQ,GAAO;AACzC,QAAO,OAAO,OAAO;EACjB,GAAG;EACH,GAAG;EACN,CAAC;;AAEN,IAAa,IAAiB,EAAc,KAAK;AACjD,SAAgB,IAAoB;CAChC,IAAM,IAAU,EAAI,EAAe;AACnC,KAAI,KAAW,KACX,OAAU,MAAM,8FAA8F;AAElH,QAAO"}
@@ -0,0 +1,15 @@
1
+ import { useAttribution as e } from "./attribution.js";
2
+ import { useLeafletContext as t } from "./context.js";
3
+ import { useEventHandlers as n } from "./events.js";
4
+ import { withPane as r } from "./pane.js";
5
+ //#region node_modules/@react-leaflet/core/lib/div-overlay.js
6
+ function i(i, a) {
7
+ return function(o, s) {
8
+ let c = t(), l = i(r(o, c), c);
9
+ return e(c.map, o.attribution), n(l.current, o.eventHandlers), a(l.current, c, o, s), l;
10
+ };
11
+ }
12
+ //#endregion
13
+ export { i as createDivOverlayHook };
14
+
15
+ //# sourceMappingURL=div-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"div-overlay.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/div-overlay.js"],"sourcesContent":["import { useAttribution } from './attribution.js';\nimport { useLeafletContext } from './context.js';\nimport { useEventHandlers } from './events.js';\nimport { withPane } from './pane.js';\nexport function createDivOverlayHook(useElement, useLifecycle) {\n return function useDivOverlay(props, setOpen) {\n const context = useLeafletContext();\n const elementRef = useElement(withPane(props, context), context);\n useAttribution(context.map, props.attribution);\n useEventHandlers(elementRef.current, props.eventHandlers);\n useLifecycle(elementRef.current, context, props, setOpen);\n return elementRef;\n };\n}\n"],"x_google_ignoreList":[0],"mappings":";;;;;AAIA,SAAgB,EAAqB,GAAY,GAAc;AAC3D,QAAO,SAAuB,GAAO,GAAS;EAC1C,IAAM,IAAU,GAAmB,EAC7B,IAAa,EAAW,EAAS,GAAO,EAAQ,EAAE,EAAQ;AAIhE,SAHA,EAAe,EAAQ,KAAK,EAAM,YAAY,EAC9C,EAAiB,EAAW,SAAS,EAAM,cAAc,EACzD,EAAa,EAAW,SAAS,GAAS,GAAO,EAAQ,EAClD"}
@@ -0,0 +1,30 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ //#region node_modules/@react-leaflet/core/lib/element.js
3
+ function n(e, t, n) {
4
+ return Object.freeze({
5
+ instance: e,
6
+ context: t,
7
+ container: n
8
+ });
9
+ }
10
+ function r(n, r) {
11
+ return r == null ? function(e, r) {
12
+ let i = t(void 0);
13
+ return i.current ||= n(e, r), i;
14
+ } : function(i, a) {
15
+ let o = t(void 0);
16
+ o.current ||= n(i, a);
17
+ let s = t(i), { instance: c } = o.current;
18
+ return e(function() {
19
+ s.current !== i && (r(c, i, s.current), s.current = i);
20
+ }, [
21
+ c,
22
+ i,
23
+ r
24
+ ]), o;
25
+ };
26
+ }
27
+ //#endregion
28
+ export { r as createElementHook, n as createElementObject };
29
+
30
+ //# sourceMappingURL=element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/element.js"],"sourcesContent":["import { useEffect, useRef } from 'react';\nexport function createElementObject(instance, context, container) {\n return Object.freeze({\n instance,\n context,\n container\n });\n}\nexport function createElementHook(createElement, updateElement) {\n if (updateElement == null) {\n return function useImmutableLeafletElement(props, context) {\n const elementRef = useRef(undefined);\n if (!elementRef.current) elementRef.current = createElement(props, context);\n return elementRef;\n };\n }\n return function useMutableLeafletElement(props, context) {\n const elementRef = useRef(undefined);\n if (!elementRef.current) elementRef.current = createElement(props, context);\n const propsRef = useRef(props);\n const { instance } = elementRef.current;\n useEffect(function updateElementProps() {\n if (propsRef.current !== props) {\n updateElement(instance, props, propsRef.current);\n propsRef.current = props;\n }\n }, [\n instance,\n props,\n updateElement\n ]);\n return elementRef;\n };\n}\n"],"x_google_ignoreList":[0],"mappings":";;AACA,SAAgB,EAAoB,GAAU,GAAS,GAAW;AAC9D,QAAO,OAAO,OAAO;EACjB;EACA;EACA;EACH,CAAC;;AAEN,SAAgB,EAAkB,GAAe,GAAe;AAQ5D,QAPI,KAAiB,OACV,SAAoC,GAAO,GAAS;EACvD,IAAM,IAAa,EAAO,KAAA,EAAU;AAEpC,SADA,AAAyB,EAAW,YAAU,EAAc,GAAO,EAAQ,EACpE;KAGR,SAAkC,GAAO,GAAS;EACrD,IAAM,IAAa,EAAO,KAAA,EAAU;AACpC,EAAyB,EAAW,YAAU,EAAc,GAAO,EAAQ;EAC3E,IAAM,IAAW,EAAO,EAAM,EACxB,EAAE,gBAAa,EAAW;AAWhC,SAVA,EAAU,WAA8B;AACpC,GAAI,EAAS,YAAY,MACrB,EAAc,GAAU,GAAO,EAAS,QAAQ,EAChD,EAAS,UAAU;KAExB;GACC;GACA;GACA;GACH,CAAC,EACK"}
@@ -0,0 +1,14 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ //#region node_modules/@react-leaflet/core/lib/events.js
3
+ function n(n, r) {
4
+ let i = t(void 0);
5
+ e(function() {
6
+ return r != null && n.instance.on(r), i.current = r, function() {
7
+ i.current != null && n.instance.off(i.current), i.current = null;
8
+ };
9
+ }, [n, r]);
10
+ }
11
+ //#endregion
12
+ export { n as useEventHandlers };
13
+
14
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/events.js"],"sourcesContent":["import { useEffect, useRef } from 'react';\nexport function useEventHandlers(element, eventHandlers) {\n const eventHandlersRef = useRef(undefined);\n useEffect(function addEventHandlers() {\n if (eventHandlers != null) {\n element.instance.on(eventHandlers);\n }\n eventHandlersRef.current = eventHandlers;\n return function removeEventHandlers() {\n if (eventHandlersRef.current != null) {\n element.instance.off(eventHandlersRef.current);\n }\n eventHandlersRef.current = null;\n };\n }, [\n element,\n eventHandlers\n ]);\n}\n"],"x_google_ignoreList":[0],"mappings":";;AACA,SAAgB,EAAiB,GAAS,GAAe;CACrD,IAAM,IAAmB,EAAO,KAAA,EAAU;AAC1C,GAAU,WAA4B;AAKlC,SAJI,KAAiB,QACjB,EAAQ,SAAS,GAAG,EAAc,EAEtC,EAAiB,UAAU,GACpB,WAA+B;AAIlC,GAHI,EAAiB,WAAW,QAC5B,EAAQ,SAAS,IAAI,EAAiB,QAAQ,EAElD,EAAiB,UAAU;;IAEhC,CACC,GACA,EACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { createContainerComponent as e, createDivOverlayComponent as t, createLeafComponent as n } from "./component.js";
2
+ import { createDivOverlayHook as r } from "./div-overlay.js";
3
+ import { createElementHook as i } from "./element.js";
4
+ import { createLayerHook as a } from "./layer.js";
5
+ //#region node_modules/@react-leaflet/core/lib/generic.js
6
+ function o(t, n) {
7
+ return e(a(i(t, n)));
8
+ }
9
+ function s(e, n) {
10
+ return t(r(i(e), n));
11
+ }
12
+ function c(e, t) {
13
+ return n(a(i(e, t)));
14
+ }
15
+ //#endregion
16
+ export { o as createLayerComponent, s as createOverlayComponent, c as createTileLayerComponent };
17
+
18
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/generic.js"],"sourcesContent":["import { createContainerComponent, createDivOverlayComponent, createLeafComponent } from './component.js';\nimport { createControlHook } from './control.js';\nimport { createDivOverlayHook } from './div-overlay.js';\nimport { createElementHook, createElementObject } from './element.js';\nimport { createLayerHook } from './layer.js';\nimport { createPathHook } from './path.js';\nexport function createControlComponent(createInstance) {\n function createElement(props, context) {\n return createElementObject(createInstance(props), context);\n }\n const useElement = createElementHook(createElement);\n const useControl = createControlHook(useElement);\n return createLeafComponent(useControl);\n}\nexport function createLayerComponent(createElement, updateElement) {\n const useElement = createElementHook(createElement, updateElement);\n const useLayer = createLayerHook(useElement);\n return createContainerComponent(useLayer);\n}\nexport function createOverlayComponent(createElement, useLifecycle) {\n const useElement = createElementHook(createElement);\n const useOverlay = createDivOverlayHook(useElement, useLifecycle);\n return createDivOverlayComponent(useOverlay);\n}\nexport function createPathComponent(createElement, updateElement) {\n const useElement = createElementHook(createElement, updateElement);\n const usePath = createPathHook(useElement);\n return createContainerComponent(usePath);\n}\nexport function createTileLayerComponent(createElement, updateElement) {\n const useElement = createElementHook(createElement, updateElement);\n const useLayer = createLayerHook(useElement);\n return createLeafComponent(useLayer);\n}\n"],"x_google_ignoreList":[0],"mappings":";;;;;AAcA,SAAgB,EAAqB,GAAe,GAAe;AAG/D,QAAO,EADU,EADE,EAAkB,GAAe,EAAc,CACtB,CACH;;AAE7C,SAAgB,EAAuB,GAAe,GAAc;AAGhE,QAAO,EADY,EADA,EAAkB,EAAc,EACC,EAAa,CACrB;;AAOhD,SAAgB,EAAyB,GAAe,GAAe;AAGnE,QAAO,EADU,EADE,EAAkB,GAAe,EAAc,CACtB,CACR"}
@@ -0,0 +1,9 @@
1
+ //#region node_modules/@react-leaflet/core/lib/grid-layer.js
2
+ function e(e, t, n) {
3
+ let { opacity: r, zIndex: i } = t;
4
+ r != null && r !== n.opacity && e.setOpacity(r), i != null && i !== n.zIndex && e.setZIndex(i);
5
+ }
6
+ //#endregion
7
+ export { e as updateGridLayer };
8
+
9
+ //# sourceMappingURL=grid-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-layer.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/grid-layer.js"],"sourcesContent":["export function updateGridLayer(layer, props, prevProps) {\n const { opacity, zIndex } = props;\n if (opacity != null && opacity !== prevProps.opacity) {\n layer.setOpacity(opacity);\n }\n if (zIndex != null && zIndex !== prevProps.zIndex) {\n layer.setZIndex(zIndex);\n }\n}\n"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAgB,EAAgB,GAAO,GAAO,GAAW;CACrD,IAAM,EAAE,YAAS,cAAW;AAI5B,CAHI,KAAW,QAAQ,MAAY,EAAU,WACzC,EAAM,WAAW,EAAQ,EAEzB,KAAU,QAAQ,MAAW,EAAU,UACvC,EAAM,UAAU,EAAO"}
@@ -0,0 +1,23 @@
1
+ import { useAttribution as e } from "./attribution.js";
2
+ import { useLeafletContext as t } from "./context.js";
3
+ import { useEventHandlers as n } from "./events.js";
4
+ import { withPane as r } from "./pane.js";
5
+ import { useEffect as i } from "react";
6
+ //#region node_modules/@react-leaflet/core/lib/layer.js
7
+ function a(e, t) {
8
+ i(function() {
9
+ return (t.layerContainer ?? t.map).addLayer(e.instance), function() {
10
+ t.layerContainer?.removeLayer(e.instance), t.map.removeLayer(e.instance);
11
+ };
12
+ }, [t, e]);
13
+ }
14
+ function o(i) {
15
+ return function(o) {
16
+ let s = t(), c = i(r(o, s), s);
17
+ return e(s.map, o.attribution), n(c.current, o.eventHandlers), a(c.current, s), c;
18
+ };
19
+ }
20
+ //#endregion
21
+ export { o as createLayerHook };
22
+
23
+ //# sourceMappingURL=layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/layer.js"],"sourcesContent":["import { useEffect } from 'react';\nimport { useAttribution } from './attribution.js';\nimport { useLeafletContext } from './context.js';\nimport { useEventHandlers } from './events.js';\nimport { withPane } from './pane.js';\nexport function useLayerLifecycle(element, context) {\n useEffect(function addLayer() {\n const container = context.layerContainer ?? context.map;\n container.addLayer(element.instance);\n return function removeLayer() {\n context.layerContainer?.removeLayer(element.instance);\n context.map.removeLayer(element.instance);\n };\n }, [\n context,\n element\n ]);\n}\nexport function createLayerHook(useElement) {\n return function useLayer(props) {\n const context = useLeafletContext();\n const elementRef = useElement(withPane(props, context), context);\n useAttribution(context.map, props.attribution);\n useEventHandlers(elementRef.current, props.eventHandlers);\n useLayerLifecycle(elementRef.current, context);\n return elementRef;\n };\n}\n"],"x_google_ignoreList":[0],"mappings":";;;;;;AAKA,SAAgB,EAAkB,GAAS,GAAS;AAChD,GAAU,WAAoB;AAG1B,UAFkB,EAAQ,kBAAkB,EAAQ,KAC1C,SAAS,EAAQ,SAAS,EAC7B,WAAuB;AAE1B,GADA,EAAQ,gBAAgB,YAAY,EAAQ,SAAS,EACrD,EAAQ,IAAI,YAAY,EAAQ,SAAS;;IAE9C,CACC,GACA,EACH,CAAC;;AAEN,SAAgB,EAAgB,GAAY;AACxC,QAAO,SAAkB,GAAO;EAC5B,IAAM,IAAU,GAAmB,EAC7B,IAAa,EAAW,EAAS,GAAO,EAAQ,EAAE,EAAQ;AAIhE,SAHA,EAAe,EAAQ,KAAK,EAAM,YAAY,EAC9C,EAAiB,EAAW,SAAS,EAAM,cAAc,EACzD,EAAkB,EAAW,SAAS,EAAQ,EACvC"}
@@ -0,0 +1,12 @@
1
+ //#region node_modules/@react-leaflet/core/lib/pane.js
2
+ function e(e, t) {
3
+ let n = e.pane ?? t.pane;
4
+ return n ? {
5
+ ...e,
6
+ pane: n
7
+ } : e;
8
+ }
9
+ //#endregion
10
+ export { e as withPane };
11
+
12
+ //# sourceMappingURL=pane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pane.js","names":[],"sources":["../../../../../node_modules/@react-leaflet/core/lib/pane.js"],"sourcesContent":["export function withPane(props, context) {\n const pane = props.pane ?? context.pane;\n return pane ? {\n ...props,\n pane\n } : props;\n}\n"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAgB,EAAS,GAAO,GAAS;CACrC,IAAM,IAAO,EAAM,QAAQ,EAAQ;AACnC,QAAO,IAAO;EACV,GAAG;EACH;EACH,GAAG"}