PageSourceSearch

https://petwellhk.com/assets/restaurantApi-J7TAaZ7f.js

js petwellhk.com collected 2026-10-06 05:23:53 UTC 13,167 bytes, 219 lines download raw bytes

1import{a4 as g}from"./main-m_sUF2N4.js";import{g as x}from"./hongKongDistricts--r8_jlh4.js";import{H as M,a as U,n as H,r as T,s as z,i as b}from"./placeSearchConfig-BfT0dFXT.js";function w(e){if(e==null||e==="")return null;let t=e;for(let n=0;n<3;n+=1){if(typeof t=="string"){const r=t.trim();if(!r)return null;try{t=JSON.parse(r)}catch{return null}continue}break}return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function te(e,t){return e!=null&&e.length?e.map(n=>(t==="en"?n.nameEn||n.nameZh:n.nameZh||n.nameEn)||n.slug).filter(Boolean):[]}const C={waterBowl:"restaurant.import.amenities.waterBowl",dogMenu:"restaurant.import.amenities.dogMenu",petTreats:"restaurant.import.amenities.petTreats",groomingServices:"restaurant.import.amenities.groomingServices",petStore:"restaurant.import.amenities.petStore",sanitationKits:"restaurant.import.amenities.sanitationKits",photoArea:"restaurant.import.amenities.photoArea",petFirstAidKit:"restaurant.import.amenities.petFirstAidKit",employeePetTraining:"restaurant.import.amenities.employeePetTraining",nutritionLabelsProvided:"restaurant.import.amenities.nutritionLabelsProvided"};function ne(e){return e!=null&&e.amenities?Object.keys(C).filter(t=>{var n;return((n=e.amenities)==null?void 0:n[t])===!0}):[]}function S(e){const t=e==null||typeof e=="string"?e:e.fehdLicenseStatus??e.fehd_license_status;if(typeof t!="string")return!1;const n=t.trim().toLowerCase();return n==="yes"||n==="y"||n==="true"}function re(e){return e.fehdLicensed===!0?!0:S(e.externalMetadata)}function G(e){const t=e.toLowerCase();return t==="openrice.com"||t.endsWith(".openrice.com")||t==="openrice.com.hk"||t.endsWith(".openrice.com.hk")}function $(e){if(!(e!=null&&e.trim()))return!1;try{const t=/^https?:\/\//i.test(e)?e:`https://${e}`;return G(new URL(t).hostname)}catch{return/openrice\.com(\.hk)?/i.test(e)}}function ie(e){return e!=null&&e.trim()?$(e)?null:e:null}const B=[{slug:"chinese",zh:"中菜",en:"Chinese"},{slug:"cantonese",zh:"粵菜",en:"Cantonese"},{slug:"japanese",zh:"日本菜",en:"Japanese"},{slug:"korean",zh:"韓國菜",en:"Korean"},{slug:"thai",zh:"泰國菜",en:"Thai"},{slug:"vietnamese",zh:"越南菜",en:"Vietnamese"},{slug:"indian",zh:"印度菜",en:"Indian"},{slug:"western",zh:"西式",en:"Western"},{slug:"italian",zh:"意大利菜",en:"Italian"},{slug:"french",zh:"法國菜",en:"French"},{slug:"american",zh:"美式",en:"American"},{slug:"mediterranean",zh:"地中海",en:"Mediterranean"},{slug:"fusion",zh:"融合菜",en:"Fusion"},{slug:"alaCarte",zh:"單點",en:"A la carte"},{slug:"buffet",zh:"自助餐",en:"Buffet"},{slug:"hotPot",zh:"火鍋",en:"Hot pot"},{slug:"bbqGrill",zh:"燒烤",en:"BBQ / Grill"},{slug:"dimSum",zh:"點心",en:"Dim sum"},{slug:"cafeLight",zh:"咖啡/輕食",en:"Cafe / Light meals"},{slug:"fastCasual",zh:"休閒快餐",en:"Fast casual"},{slug:"fineDining",zh:"高級餐飲",en:"Fine dining"},{slug:"other",zh:"其他",en:"Other"}],q=Object.fromEntries(B.map(e=>[e.slug,e]));function Y(e,t){if(!(e!=null&&e.length))return[];const n=new Set,r=[];for(const i of e){const a=typeof i=="string"?i.trim():"";if(!a||n.has(a))continue;const s=q[a];s&&(n.add(a),r.push(t==="en"?s.en:s.zh))}return r}function j(e){var c,u,h,d;const{totalRating:t,externalMetadata:n,combinedRating:r}=e;if(typeof r=="number"&&Number.isFinite(r)&&r>0)return r;const i=w(n),a=[],s=(u=(c=i==null?void 0:i.ratings)==null?void 0:c.google)==null?void 0:u.score,o=(d=(h=i==null?void 0:i.ratings)==null?void 0:h.openrice)==null?void 0:d.score;return typeof s=="number"&&Number.isFinite(s)&&s>0&&a.push(s),typeof o=="number"&&Number.isFinite(o)&&o>0&&a.push(o),typeof t=="number"&&Number.isFinite(t)&&t>0&&a.push(t),a.length===0?null:a.reduce((y,E)=>y+E,0)/a.length}function f(){return!1}function p(e){return e===!0||e===1||e==="1"||typeof e=="string"&&e.toLowerCase()==="true"}function N(e){return e===!0||e===1||e==="1"||typeof e=="string"&&e.toLowerCase()==="true"}function K(e){return x(e)}function m(e,t){if(!e)return"";const n=t==="en"?"en":"zh",r=n==="en"?"zh":"en";return e[n]||e[r]||""}function P(e,t="zh"){var o,c,u,h;const n=t==="en"?"en":"zh",r=w(e.externalMetadata),i=(o=r==null?void 0:r.types)==null?void 0:o.map(d=>(n==="en"?d.nameEn||d.nameZh:d.nameZh||d.nameEn)||d.slug).filter(
1Boolean).join(" · "),a=Y(r==null?void 0:r.dishStyles,n).join(" · "),s=[i,a].filter(Boolean).join(" · ");return{id:e.id,name:m(e.name,t),region:K(e.district),district:e.district||"",address:m(e.address,t),location:e.location,phone:e.phoneNo,availableHours:e.availableHours,reservationSettings:e.reservationSettings,rating:j({totalRating:e.totalRating,externalMetadata:r,combinedRating:e.combinedRating})??void 0,image:e.coverPhoto||((c=e.gallery)==null?void 0:c[0]),gallery:e.gallery,verified:N(e.verified),isDevListing:p(e.isDevListing),petEntryPolicy:e.petEntryPolicy,petAccessArea:e.petAccessArea,petPolicyNotes:m(e.petPolicyNotes,t),listingAlert:m(e.listingAlert,t)||void 0,website:e.website,is247:e.is247,puppuccino:e.puppuccino===!0,fehdLicensed:e.fehdLicensed===!0||S(r),externalMetadata:r,typeLabels:s||void 0,priceRange:(r==null?void 0:r.priceRange)??null,googleRating:((h=(u=r==null?void 0:r.ratings)==null?void 0:u.google)==null?void 0:h.score)??null,ownerSub:e.ownerSub??null,partnerPlan:e.partnerPlan??null,partnerPlanExpiresAt:e.partnerPlanExpiresAt??null,isPremium:b({ownerSub:e.ownerSub,partnerPlan:e.partnerPlan,partnerPlanExpiresAt:e.partnerPlanExpiresAt})}}function W(e,t,n,r){const a=(n-e)*Math.PI/180,s=(r-t)*Math.PI/180,o=Math.sin(a/2)*Math.sin(a/2)+Math.cos(e*Math.PI/180)*Math.cos(n*Math.PI/180)*Math.sin(s/2)*Math.sin(s/2);return 6371*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))}const Z=`
2        id
3        name { zh en }
4        address { zh en }
5        district
6        availableHours {
7          mon { start end }
8          tue { start end }
9          wed { start end }
10          thu { start end }
11          fri { start end }
12          sat { start end }
13          sun { start end }
14          otherConditions
15        }
16        coverPhoto
17        verified
18        isDevListing
19        petEntryPolicy
20        petAccessArea
21        totalRating
22        combinedRating
23        is247
24        fehdLicensed
25        puppuccino
26        externalMetadata
27        ownerSub
28        partnerPlan
29        partnerPlanExpiresAt
30`,O=`
31  query ListFehdRestaurants($limit: Int, $nextToken: String) {
32    listRestaurants(
33      filter: { fehdLicensed: { eq: true } }
34      limit: $limit
35      nextToken: $nextToken
36    ) {
37      items {
38${Z}
39      }
40      nextToken
41    }
42  }
43`,Q=`
44  query GetRestaurant($id: ID!) {
45    getRestaurant(id: $id) {
46      id
47      ownerSub
48      name { zh en }
49      address { zh en }
50      location { lat lon }
51      district
52      phoneNo
53      availableHours {
54        mon { start end }
55        tue { start end }
56        wed { start end }
57        thu { start end }
58        fri { start end }
59        sat { start end }
60        sun { start end }
61        otherConditions
62      }
63      reservationSettings
64      coverPhoto
65      gallery
66      verified
67      isDevListing
68      petEntryPolicy
69      petAccessArea
70      petPolicyNotes { zh en }
71      listingAlert { zh en }
72      photoSource
73      website
74      email
75      totalRating
76      combinedRating
77      is247
78      fehdLicensed
79      puppuccino
80      externalMetadata
81      partnerPlan
82      partnerPlanExpiresAt
83      reviews(limit: 80) {
84        items {
85          id
86          reviewerId
87          anonymous
88          title
89          description
90          totalRating
91          fileAttachments
92          source
93          partnerReply
94          partnerReplyAt
95          updatedAt
96          reviewer {
97            id
98            displayName
99            firstName
100            profileImage
101          }
102        }
103      }
104    }
105  }
106`,V=`
107  query GetRestaurant($id: ID!) {
108    getRestaurant(id: $id) {
109      id
110      ownerSub
111      name { zh en }
112      address { zh en }
113      location { lat lon }
114      district
115      phoneNo
116      availableHours {
117        mon { start end }
118        tue { start end }
119        wed { start end }
120        thu { start end }
121        fri { start end }
122        sat { start end }
123        sun { start end }
124        otherConditions
125      }
126      reservationSettings
127      coverPhoto
128      gallery
129      verified
130      isDevListing
131      petEntryPolicy
132      petAccessArea
133      petPolicyNotes { zh en }
134      listingAlert { zh en }
135      photoSource
136      website
137      email
138      totalRating
139      combinedRating
140      is247
141      fehdLicensed
142      puppuccino
143      externalMetadata
144      partnerPlan
145      partnerPlanExpiresAt
146      reviews(limit: 80) {
147        items {
148          id
149          title
150          description
151          totalRating
152          fileAttachments
153          source
154          updatedAt
155        }
156      }
157    }
158  }
159`,L=`
160  query GetRestaurant($id: ID!) {
161    getRestaurant(id: $id) {
162      id
163      ownerSub
164      name { zh en }
165      address { zh en }
166      location { lat lon }
167      district
168      phoneNo
169      availableHours {
170        mon { start end }
171        tue { start end }
172        wed { start end }
173        thu { start end }
174        fri { start end }
175        sat { start end }
176        sun { start end }
177        otherConditions
178      }
179      coverPhoto
180      gallery
181      verified
182      isDevListing
183      petEntryPolicy
184      petAccessArea
185      petPolicyNotes { zh en }
186      listingAlert { zh en }
187      photoSource
188      website
189      email
190      totalRating
191      combinedRating
192      is247
193      fehdLicensed
194      puppuccino
195      externalMetadata
196      partnerPlan
197      partnerPlanExpiresAt
198      reviews(limit: 80) {
199        items {
200          id
201          reviewerId
202          anonymous
203          title
204          description
205          totalRating
206          fileAttachments
207          source
208          updatedAt
209          reviewer {
210            id
211            displayName
212            firstName
213            profileImage
214          }
215        }
216      }
217    }
218  }
219`,se=12,F=48,oe=48;async function ae(e={},t="zh"){const{region:n,district:r,districts:i,keyword:a,sortMethod:s="rating-desc",is247:o,fehdLicensed:c,verified:u,petAccessArea:h,petEntryPolicy:d,limit:y=F,nextToken:E,fullFields:_=!1}=e;try{const l={location:e.location??M,limit:y,sortMethod:s};U(l,{region:n,district:r,districts:i}),a&&(l.keyword=a),o!==void 0&&(l.is247=o),c!==void 0&&(l.fehdLicensed=c),u===!0&&(l.verified=!0),h&&(l.petAccessArea=h),d&&(l.petEntryPolicy=d),f();const R=H(E);R&&(l.nextToken=R);const{items:D,total:I,nextToken:k}=await T("restaurant",l,{fullFields:_,fallback:"Failed to fetch restaurants"}),v=D.filter(A=>f()||!p(A.isDevListing)).map(A=>P(A,t));return{restaurants:s==="location"?v:z(v),total:I,nextToken:k}}catch(l){throw console.error("Error fetching restaurants:",l),l instanceof Error?l:new Error("Failed to fetch restaurants")}}async function ce(e={},t="zh"){const{limit:n=F,nextToken:r=null}=e;try{const i=await g(O,{limit:n,nextToken:r}),a=(i.listRestaurants.items||[]).filter(s=>!!(s!=null&&s.id)).filter(s=>f()||!p(s.isDevListing)).map(s=>P(s,t));return{restaurants:z(a),nextToken:i.listRestaurants.nextToken??null}}catch(i){throw console.error("Error fetching FEHD licensed restaurants:",i),new Error("Failed to fetch FEHD licensed restaurants")}}async function le(e){try{let t;try{t=await g(Q,{id:e})}catch(i){const a=i instanceof Error?i.message:String(i);if(/partnerReply/i.test(a)&&/FieldUndefined/i.test(a)){console.warn("getRestaurant: partnerReply not in schema yet; retrying without partnerReply");try{t=await g(V,{id:e})}catch(s){const o=s instanceof Error?s.message:String(s);if(/reservationSettings|FieldUndefined/i.test(o))console.warn("getRestaurant: reservationSettings unavailable; using legacy query"),t=await g(L,{id:e});else throw s}}else if(/reservationSettings/i.test(a)&&/FieldUndefined/i.test(a))console.warn("getRestaurant: reservationSettings unavailable; using legacy query"),t=await g(L,{id:e});else throw i}const n=t.getRestaurant;if(!n)throw new Error("Restaurant not found");if(p(n.isDevListing)&&!f())throw new Error("Restaurant not found");const r=w(n.externalMetadata);return{...n,externalMetadata:r,fehdLicensed:n.fehdLicensed===!0||S(r)}}catch(t){throw console.error("Error fetching restaurant:",t),t instanceof Error?t:new Error("Failed to fetch restaurant")}}async function ue(e,t,n="zh",r=5){try{const i={location:{lat:e,lon:t},limit:100,sortMethod:"location"};f();const{items:a}=await T("restaurant",i,{fullFields:!0,fallback:"Failed to fetch nearby restaurants"});return a.filter(o=>{var c,u;return N(o.verified)&&((c=o.location)==null?void 0:c.lat)&&((u=o.location)==null?void 0:u.lon)&&(f()||!p(o.isDevListing))}).map(o=>{const c=P(o,n),u=W(e,t,o.location.lat,o.location.lon);return{restaurant:c,distance:u}}).filter(({distance:o})=>o<=r).sort((o,c)=>o.distance!==c.distance?o.distance-c.distance:Number(b(c.restaurant))-Number(b(o.restaurant)))}catch(i){throw console.error("Error fetching nearby restaurants:",i),i instanceof Error?i:new Error("Failed to fetch nearby restaurants")}}export{C as A,oe as H,se as R,Y as a,ne as b,j as c,ie as d,ce as e,ae as f,te as g,le as h,re as i,F as 
219j,ue as k,w as p};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.