@fieldia/map 0.19.0 → 0.20.0

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 (66) hide show
  1. package/README.md +90 -3
  2. package/package.json +4 -4
  3. package/src/lib/address-labels.d.mts +14 -2
  4. package/src/lib/address-labels.d.ts +14 -2
  5. package/src/lib/address-labels.js.map +1 -1
  6. package/src/lib/address-labels.mjs.map +1 -1
  7. package/src/lib/address-line.d.mts +10 -1
  8. package/src/lib/address-line.d.ts +10 -1
  9. package/src/lib/address-line.js +25 -8
  10. package/src/lib/address-line.js.map +1 -1
  11. package/src/lib/address-line.mjs +24 -8
  12. package/src/lib/address-line.mjs.map +1 -1
  13. package/src/lib/address-names.d.mts +38 -0
  14. package/src/lib/address-names.d.ts +38 -0
  15. package/src/lib/address-names.js +240 -0
  16. package/src/lib/address-names.js.map +1 -0
  17. package/src/lib/address-names.mjs +232 -0
  18. package/src/lib/address-names.mjs.map +1 -0
  19. package/src/lib/address-parts.d.mts +128 -10
  20. package/src/lib/address-parts.d.ts +128 -10
  21. package/src/lib/address-parts.js +836 -17
  22. package/src/lib/address-parts.js.map +1 -1
  23. package/src/lib/address-parts.mjs +827 -14
  24. package/src/lib/address-parts.mjs.map +1 -1
  25. package/src/lib/address-search.d.mts +8 -4
  26. package/src/lib/address-search.d.ts +8 -4
  27. package/src/lib/address-search.js +27 -9
  28. package/src/lib/address-search.js.map +1 -1
  29. package/src/lib/address-search.mjs +28 -10
  30. package/src/lib/address-search.mjs.map +1 -1
  31. package/src/lib/address-suggest.d.mts +5 -2
  32. package/src/lib/address-suggest.d.ts +5 -2
  33. package/src/lib/address-suggest.js +161 -28
  34. package/src/lib/address-suggest.js.map +1 -1
  35. package/src/lib/address-suggest.mjs +161 -28
  36. package/src/lib/address-suggest.mjs.map +1 -1
  37. package/src/lib/form-map.js +9 -7
  38. package/src/lib/form-map.js.map +1 -1
  39. package/src/lib/form-map.mjs +10 -8
  40. package/src/lib/form-map.mjs.map +1 -1
  41. package/src/lib/place.js +21 -10
  42. package/src/lib/place.js.map +1 -1
  43. package/src/lib/place.mjs +21 -10
  44. package/src/lib/place.mjs.map +1 -1
  45. package/src/lib/providers.d.mts +6 -0
  46. package/src/lib/providers.d.ts +6 -0
  47. package/src/lib/providers.js +46 -97
  48. package/src/lib/providers.js.map +1 -1
  49. package/src/lib/providers.mjs +46 -97
  50. package/src/lib/providers.mjs.map +1 -1
  51. package/src/lib/route-line.d.mts +9 -0
  52. package/src/lib/route-line.d.ts +9 -0
  53. package/src/lib/route-line.js +13 -0
  54. package/src/lib/route-line.js.map +1 -1
  55. package/src/lib/route-line.mjs +11 -0
  56. package/src/lib/route-line.mjs.map +1 -1
  57. package/src/lib/routes.js +6 -2
  58. package/src/lib/routes.js.map +1 -1
  59. package/src/lib/routes.mjs +6 -2
  60. package/src/lib/routes.mjs.map +1 -1
  61. package/src/lib/search-box.d.mts +15 -3
  62. package/src/lib/search-box.d.ts +15 -3
  63. package/src/lib/search-box.js +118 -34
  64. package/src/lib/search-box.js.map +1 -1
  65. package/src/lib/search-box.mjs +118 -34
  66. package/src/lib/search-box.mjs.map +1 -1
package/README.md CHANGED
@@ -252,7 +252,7 @@ pin, or the bubble, that holds the place they were on.
252
252
  | Provider | Road | Dark | Satellite | Traffic | Address search | Routes | Reachable area |
253
253
  | --- | --- | --- | --- | --- | --- | --- | --- |
254
254
  | `azureMaps({ key })` or `({ token, clientId })` | yes | yes | yes | yes, from zoom 6, in dark colours on the dark map, drawn again every four minutes | yes, as people type | car, foot | car |
255
- | `googleMaps({ key, region, logo })` (Map Tiles API) | yes | no | yes | yes, its traffic layer | Places API, as people type | car, bike, foot (Routes API) | no |
255
+ | `googleMaps({ key, region, logo })` (Map Tiles API) | yes | no | yes | yes, its traffic layer | Places API, as people type | car (with traffic), foot; bike where Google has bicycle routes, none in Egypt, Saudi Arabia, the UAE or Jordan (Routes API) | no: Google's Isochrones API is in preview, and Fieldia does not use it yet |
256
256
  | `mapbox({ token, trafficStyle })` | yes | yes | yes | from `trafficStyle`, a style of yours with Mapbox Traffic's lines alone | yes, as people type | car (traffic), bike, foot | car, bike, foot |
257
257
  | `tiles({ url, credit, trafficUrl, route, reach })` | the app's own map images | | | the app's own (`trafficUrl`) | the app's own | the app's own | the app's own |
258
258
  | `openStreetMap()` | yes, **for demos only** | no | no | no | Photon, as people type, nearest first (or `{ search: 'nominatim' }`, on Enter) | OSRM's demo server, car only (or `osrmUrl`) | no |
@@ -267,11 +267,98 @@ treat an app in use as heavy use. Photon can run on your own server
267
267
  (`openStreetMap({ photonUrl })`).
268
268
 
269
269
  Suggestions come as people type where the provider allows it, nearest where the
270
- map is looking first, each on two lines (the place, then where it is); Enter
271
- takes the first. "My location" says how sure it is: a rough location (a
270
+ map is looking first (a map of the whole world, opened with no centre, looks
271
+ nowhere), each on two lines (the place, then where it is); Enter takes the one
272
+ marked with the arrows (Down marks the first, Up the last, each going round at
273
+ the end), or the first of a list made for the words in the box:
274
+ words typed after the list came are searched for at once, and nothing is
275
+ picked from the list before them. "My location" says how sure it is: a rough location (a
272
276
  desktop's, placed by its network) shows the circle it may be anywhere in, says
273
277
  how wide, and names no address from it.
274
278
 
279
+ An address with suggestions (`address-search` on a char field) keeps them to
280
+ the `countries` the page names (ISO codes; "UK" is read as "GB", a code no one
281
+ knows is left out and said in the console). Azure Maps is asked once for each
282
+ country, up to ten (an autocomplete request is a tenth of a Search
283
+ transaction); Google, for fifteen at most; Mapbox and Nominatim, for the list;
284
+ Photon's answers are kept to them. Nearest `near` first (or where the app's
285
+ maps open), so give a point in the page's own country: Azure ranks another
286
+ country's suggestions by their distance from it. Addresses come before shops
287
+ and malls where the provider says which are which (Google, Azure), and an
288
+ address field asks Azure for no postcodes alone, and the word for a district
289
+ typed before its name ("حي الروضة") is left out of the words it is asked, as
290
+ Azure names its districts without it. A suggestion of Azure's is located when
291
+ picked, asked of Azure's geocoding by its own address in its structured form
292
+ (its street, its district for the locality where it names one, then its
293
+ locality, its governorate or province, postcode and country), and only
294
+ there: a district named alike in another town is never taken for it, as no
295
+ hit outside its own admin districts is. A street is placed in its own
296
+ district: the stretch that says it is there, else one in the district's box
297
+ as Azure has it (a road with a name a little beyond it, as it runs on into
298
+ the next); never a street of the name in another district ("Kamel El
299
+ Shenawy" in Garden City, not New Cairo's), and for a street named by its
300
+ number alone ("30 Street", "شارع 6") never another district's of that number.
301
+ Its city is read from them each country's way (in Egypt the governorate's
302
+ city where the governorate is one, Zamalek is Cairo's, and the town
303
+ elsewhere, Mansoura in Dakahlia; in Saudi Arabia the governorate's city; in
304
+ the emirate of Abu Dhabi, the city it is in); a suggestion that names no
305
+ region ("البرشاء 2") takes its city and region from the place found, and one
306
+ that says less of a place listed beside it is left out. A region or a city
307
+ of Egypt, Saudi Arabia, the UAE or Jordan is named one way in each language,
308
+ whichever of its names or codes Azure gives ("Sharjah Emirate", "Ash
309
+ Shāriqah" and "SH" are Sharjah; "Ţanţā" and "طنطا" are Tanta), and once in a
310
+ line ("Giza", never "Giza, Al Jizah"); a district Azure names only in its own
311
+ line is said too ("30 Street, Al Fisht, Sharjah"), and named so where it is
312
+ a road's with no name of its own ("Abu Tina", never Azure's French
313
+ "Charjah"). It is said to be only near (`precise: false`) when Azure is
314
+ unsure of it, or finds only the street for a house, the district for a
315
+ street (its own, before its town), the town for a district; found nowhere in
316
+ its own districts, no place is written (the field says so under the box),
317
+ and its parts still are. A search still waiting when
318
+ a suggestion is picked or the box is left is dropped, and Enter never searches
319
+ for the address a pick wrote. The place and parts a pick wrote stay while the
320
+ words are only edited (a flat added, a word taken out); once the box is left
321
+ emptied, or with the address picked typed over (all of it selected, then typed
322
+ or pasted), they go with it.
323
+
324
+ Azure's and Google's suggestions, places and parts were checked against their
325
+ live services in October 2026, in English and Arabic, across Egypt, Saudi
326
+ Arabia, the UAE and Jordan. Mapbox's are read as its documentation describes
327
+ them and have not yet been checked against its live service.
328
+
329
+ Escape drops a search waiting or on its way, as more typing, a pick and
330
+ leaving the box do, and no search is said to be going once it is dropped; a
331
+ list closed takes what was said of it with it. A search waiting is never
332
+ sent; one on its way is not called back, as the provider has it and may bill
333
+ it, but its answer opens nothing. While one address is typed, words asked for
334
+ once (near the same place) show what they brought again, however they come
335
+ back (a letter taken back, Enter after Escape), and words still on their way,
336
+ though dropped, are waited for, not asked again; after a pick they are a new
337
+ address's, asked for anew, and what is still on its way is called back. A
338
+ pick that finds no place, or no parts, takes back the ones the pick before it
339
+ wrote (another address's), never a place set by hand since, as emptying the
340
+ box and leaving it does (with other words typed in their place or none);
341
+ words only edited keep them. One found only near the address (`precise:
342
+ false`) is written, and the field says so under the box; one whose place the
343
+ map did not answer for (a line dropped, the provider down) says that, not
344
+ that it is not on the map. Google writes the UAE's addresses with dashes
345
+ between their pieces ("Sheikh Zayed Rd - Dubai - United Arab Emirates"): they
346
+ are read as its commas elsewhere, each piece said once, a landmark's name too,
347
+ and a suggestion's name not again on the line under it.
348
+
349
+ Google's costs, as its pricing pages put them (October 2026): a session of
350
+ suggestions ended by a pick bills its first 12 requests (Autocomplete
351
+ Requests) and the place's details (Place Details Essentials: its place, its
352
+ line and its parts, `location,formattedAddress,addressComponents`, are all
353
+ three that SKU's fields, asked for whatever the page keeps, as the parts name
354
+ the country the line is written with; the place's name, `displayName`, would
355
+ make it Pro, and the suggestion gives it); a session
356
+ never picked bills each request. A session's token goes with its first Place
357
+ Details alone: Google bills a token used again as no session. A route by car
358
+ asks for traffic, which makes it Compute Routes Pro; on foot (or by bike) with
359
+ up to 10 stops it is Essentials, 11 to 25 stops Pro, and Google refuses more
360
+ than 25.
361
+
275
362
  Pass your own `search` (and `reverse`) to `mapWidgets` to use your own address
276
363
  search with any provider.
277
364
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fieldia/map",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Fieldia's maps: a place and an area as fields, and a list's records on a map, on any map provider. Leaflet, loaded only where a map is shown.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://fieldia.dev",
@@ -21,9 +21,9 @@
21
21
  "./package.json": "./package.json"
22
22
  },
23
23
  "dependencies": {
24
- "@fieldia/core": "0.19.0",
25
- "@fieldia/viewer": "0.19.0",
26
- "@fieldia/widgets": "0.19.0",
24
+ "@fieldia/core": "0.20.0",
25
+ "@fieldia/viewer": "0.20.0",
26
+ "@fieldia/widgets": "0.20.0",
27
27
  "leaflet": "^1.9.4",
28
28
  "tslib": "^2.8.1"
29
29
  },
@@ -9,6 +9,15 @@ import { type MapLabels } from './labels.mjs';
9
9
  export interface AddressLabels {
10
10
  /** Said to screen readers as suggestions come: `{n}` how many. */
11
11
  suggested: string;
12
+ /**
13
+ * Shown under the box when the address picked is not found on the map, and
14
+ * no place is written for it; when it is placed only near it (`precise:
15
+ * false`); when its place could not be asked for, the map not answering (a
16
+ * line dropped). Their words come with the suggestions.
17
+ */
18
+ notPlaced: string;
19
+ placedNear: string;
20
+ locateFailed: string;
12
21
  addressKind: string;
13
22
  /** The designer's settings: the field a picked address's place goes into, the field its parts go into, the country it keeps to. */
14
23
  settingPlace: string;
@@ -16,6 +25,9 @@ export interface AddressLabels {
16
25
  settingCountry: string;
17
26
  anywhere: string;
18
27
  }
19
- export declare const ADDRESS_LABELS: Record<Locale, AddressLabels>;
28
+ /** The words said under the box, which come with the suggestions' code (address-suggest.ts). */
29
+ type SaidAfterAPick = 'notPlaced' | 'placedNear' | 'locateFailed';
30
+ export declare const ADDRESS_LABELS: Record<Locale, Omit<AddressLabels, SaidAfterAPick>>;
20
31
  /** An address field's words for a page's language, the maps' own with them, and the app's own over both. */
21
- export declare function addressLabels(locale: Locale | undefined, own?: Partial<MapLabels & AddressLabels>): MapLabels & AddressLabels;
32
+ export declare function addressLabels(locale: Locale | undefined, own?: Partial<MapLabels & AddressLabels>): MapLabels & Omit<AddressLabels, SaidAfterAPick> & Partial<AddressLabels>;
33
+ export {};
@@ -9,6 +9,15 @@ import { type MapLabels } from './labels';
9
9
  export interface AddressLabels {
10
10
  /** Said to screen readers as suggestions come: `{n}` how many. */
11
11
  suggested: string;
12
+ /**
13
+ * Shown under the box when the address picked is not found on the map, and
14
+ * no place is written for it; when it is placed only near it (`precise:
15
+ * false`); when its place could not be asked for, the map not answering (a
16
+ * line dropped). Their words come with the suggestions.
17
+ */
18
+ notPlaced: string;
19
+ placedNear: string;
20
+ locateFailed: string;
12
21
  addressKind: string;
13
22
  /** The designer's settings: the field a picked address's place goes into, the field its parts go into, the country it keeps to. */
14
23
  settingPlace: string;
@@ -16,6 +25,9 @@ export interface AddressLabels {
16
25
  settingCountry: string;
17
26
  anywhere: string;
18
27
  }
19
- export declare const ADDRESS_LABELS: Record<Locale, AddressLabels>;
28
+ /** The words said under the box, which come with the suggestions' code (address-suggest.ts). */
29
+ type SaidAfterAPick = 'notPlaced' | 'placedNear' | 'locateFailed';
30
+ export declare const ADDRESS_LABELS: Record<Locale, Omit<AddressLabels, SaidAfterAPick>>;
20
31
  /** An address field's words for a page's language, the maps' own with them, and the app's own over both. */
21
- export declare function addressLabels(locale: Locale | undefined, own?: Partial<MapLabels & AddressLabels>): MapLabels & AddressLabels;
32
+ export declare function addressLabels(locale: Locale | undefined, own?: Partial<MapLabels & AddressLabels>): MapLabels & Omit<AddressLabels, SaidAfterAPick> & Partial<AddressLabels>;
33
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"address-labels.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-labels.ts"],"names":[],"mappings":";;;AA4BA,sCAEC;AA7BD,qCAAsD;AAmBzC,QAAA,cAAc,GAAkC;IAC3D,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE;IAC7L,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACtL,EAAE,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE;IAClN,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE;CAC9L,CAAC;AAEF,4GAA4G;AAC5G,SAAgB,aAAa,CAAC,MAA0B,EAAE,GAAwC;IAChG,OAAO,EAAE,GAAG,mBAAU,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,sBAAc,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"address-labels.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-labels.ts"],"names":[],"mappings":";;;AAwCA,sCAEC;AAzCD,qCAAsD;AA+BzC,QAAA,cAAc,GAAwD;IACjF,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE;IAC7L,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACtL,EAAE,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE;IAClN,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE;CAC9L,CAAC;AAEF,4GAA4G;AAC5G,SAAgB,aAAa,CAAC,MAA0B,EAAE,GAAwC;IAChG,OAAO,EAAE,GAAG,mBAAU,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,sBAAc,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC;AACtF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"address-labels.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-labels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAkB,MAAM,UAAU,CAAC;AAmBtD,MAAM,CAAC,MAAM,cAAc,GAAkC;IAC3D,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE;IAC7L,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACtL,EAAE,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE;IAClN,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE;CAC9L,CAAC;AAEF,4GAA4G;AAC5G,MAAM,UAAU,aAAa,CAAC,MAA0B,EAAE,GAAwC;IAChG,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"address-labels.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-labels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAkB,MAAM,UAAU,CAAC;AA+BtD,MAAM,CAAC,MAAM,cAAc,GAAwD;IACjF,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE;IAC7L,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACtL,EAAE,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE;IAClN,EAAE,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE;CAC9L,CAAC;AAEF,4GAA4G;AAC5G,MAAM,UAAU,aAAa,CAAC,MAA0B,EAAE,GAAwC;IAChG,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC;AACtF,CAAC"}
@@ -1,2 +1,11 @@
1
1
  import type { Locale } from '@fieldia/core';
2
- export declare function addressLine(pieces: unknown[], locale?: Locale): string;
2
+ /** `before`: what is said already, on a line above (a suggestion's name), and not said again. */
3
+ export declare function addressLine(pieces: unknown[], locale?: Locale, before?: unknown[]): string;
4
+ /**
5
+ * The direction most of a text's letters are written in, for a box or a
6
+ * line that shows an address in its own words: "rtl" for one mostly in
7
+ * Arabic, though it starts with a Latin street ("El Tahrir، الإسماعيلية،
8
+ * مصر"), "ltr" for one mostly in Latin on an Arabic page ("1 Mohammed
9
+ * Mahmoud"); "" when there are no letters, or as many each way: the page's.
10
+ */
11
+ export declare function directionOf(text: string): 'ltr' | 'rtl' | '';
@@ -1,2 +1,11 @@
1
1
  import type { Locale } from '@fieldia/core';
2
- export declare function addressLine(pieces: unknown[], locale?: Locale): string;
2
+ /** `before`: what is said already, on a line above (a suggestion's name), and not said again. */
3
+ export declare function addressLine(pieces: unknown[], locale?: Locale, before?: unknown[]): string;
4
+ /**
5
+ * The direction most of a text's letters are written in, for a box or a
6
+ * line that shows an address in its own words: "rtl" for one mostly in
7
+ * Arabic, though it starts with a Latin street ("El Tahrir، الإسماعيلية،
8
+ * مصر"), "ltr" for one mostly in Latin on an Arabic page ("1 Mohammed
9
+ * Mahmoud"); "" when there are no letters, or as many each way: the page's.
10
+ */
11
+ export declare function directionOf(text: string): 'ltr' | 'rtl' | '';
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addressLine = addressLine;
4
+ exports.directionOf = directionOf;
4
5
  /**
5
6
  * An address on one line, as a field keeps it and a suggestion's second line
6
7
  * shows it: its pieces in order (a name or a street, then where it is), each
@@ -13,22 +14,38 @@ exports.addressLine = addressLine;
13
14
  * named after its city, stays: it was said first.
14
15
  */
15
16
  const MARKS = /[‎‏؜‪-‮⁦-⁩]/g;
16
- const words = (piece) => piece.toLowerCase().split(/\s+/);
17
+ /** A piece's words as compared: without the tatweel and the vowel marks Arabic may carry ("الشيـخ" is "الشيخ"). */
18
+ const words = (piece) => piece.replace(/\p{Mn}|\u0640/gu, '').toLowerCase().split(/\s+/);
17
19
  /** Whether `few` are in `many`, one after another, as whole words. */
18
20
  const within = (few, many) => many.some((_, at) => few.every((word, i) => many[at + i] === word));
19
- function addressLine(pieces, locale) {
20
- const said = [];
21
+ /** Its pieces, cut where the provider put commas, without the marks it put in Arabic. */
22
+ const cut = (pieces) => pieces.flatMap((p) => (typeof p === 'string' ? p.replace(MARKS, '').split(/[,،]/) : [])).map((piece) => piece.trim()).filter(Boolean);
23
+ /** `before`: what is said already, on a line above (a suggestion's name), and not said again. */
24
+ function addressLine(pieces, locale, before = []) {
25
+ const said = cut(before).map(words);
21
26
  const kept = [];
22
- for (const piece of pieces.flatMap((p) => (typeof p === 'string' ? p.replace(MARKS, '').split(/[,،]/) : []))) {
23
- const text = piece.trim();
24
- if (!text)
25
- continue;
27
+ for (const text of cut(pieces)) {
26
28
  const these = words(text);
27
- if (said.some((before) => within(before, these) && (before.length === these.length || !/\p{Nd}/u.test(text))))
29
+ if (said.some((earlier) => within(earlier, these) && (earlier.length === these.length || !/\p{Nd}/u.test(text))))
28
30
  continue;
29
31
  said.push(these);
30
32
  kept.push(text);
31
33
  }
32
34
  return kept.join(locale === 'ar' ? '، ' : ', ');
33
35
  }
36
+ /** Letters written right to left: Arabic's and Hebrew's. */
37
+ const RTL = /[\u0590-\u08FF\uFB1D-\uFDFF\uFE70-\uFEFF]/;
38
+ /**
39
+ * The direction most of a text's letters are written in, for a box or a
40
+ * line that shows an address in its own words: "rtl" for one mostly in
41
+ * Arabic, though it starts with a Latin street ("El Tahrir، الإسماعيلية،
42
+ * مصر"), "ltr" for one mostly in Latin on an Arabic page ("1 Mohammed
43
+ * Mahmoud"); "" when there are no letters, or as many each way: the page's.
44
+ */
45
+ function directionOf(text) {
46
+ const letters = text.match(/\p{L}/gu) ?? [];
47
+ const rtl = letters.filter((letter) => RTL.test(letter)).length;
48
+ const ltr = letters.length - rtl;
49
+ return rtl > ltr ? 'rtl' : ltr > rtl ? 'ltr' : '';
50
+ }
34
51
  //# sourceMappingURL=address-line.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"address-line.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-line.ts"],"names":[],"mappings":";;AAmBA,kCAYC;AA7BD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,cAAc,CAAC;AAC7B,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAClE,sEAAsE;AACtE,MAAM,MAAM,GAAG,CAAC,GAAa,EAAE,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAEtH,SAAgB,WAAW,CAAC,MAAiB,EAAE,MAAe;IAC5D,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7G,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,SAAS;QACxH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"address-line.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-line.ts"],"names":[],"mappings":";;AAwBA,kCAUC;AAYD,kCAKC;AAjDD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,cAAc,CAAC;AAC7B,mHAAmH;AACnH,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjG,sEAAsE;AACtE,MAAM,MAAM,GAAG,CAAC,GAAa,EAAE,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAEtH,yFAAyF;AACzF,MAAM,GAAG,GAAG,CAAC,MAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEzK,iGAAiG;AACjG,SAAgB,WAAW,CAAC,MAAiB,EAAE,MAAe,EAAE,SAAoB,EAAE;IACpF,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,SAAS;QAC3H,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,4DAA4D;AAC5D,MAAM,GAAG,GAAG,2CAA2C,CAAC;AAExD;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC;IACjC,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACpD,CAAC"}
@@ -10,22 +10,38 @@
10
10
  * named after its city, stays: it was said first.
11
11
  */
12
12
  const MARKS = /[‎‏؜‪-‮⁦-⁩]/g;
13
- const words = (piece) => piece.toLowerCase().split(/\s+/);
13
+ /** A piece's words as compared: without the tatweel and the vowel marks Arabic may carry ("الشيـخ" is "الشيخ"). */
14
+ const words = (piece) => piece.replace(/\p{Mn}|\u0640/gu, '').toLowerCase().split(/\s+/);
14
15
  /** Whether `few` are in `many`, one after another, as whole words. */
15
16
  const within = (few, many) => many.some((_, at) => few.every((word, i) => many[at + i] === word));
16
- export function addressLine(pieces, locale) {
17
- const said = [];
17
+ /** Its pieces, cut where the provider put commas, without the marks it put in Arabic. */
18
+ const cut = (pieces) => pieces.flatMap((p) => (typeof p === 'string' ? p.replace(MARKS, '').split(/[,،]/) : [])).map((piece) => piece.trim()).filter(Boolean);
19
+ /** `before`: what is said already, on a line above (a suggestion's name), and not said again. */
20
+ export function addressLine(pieces, locale, before = []) {
21
+ const said = cut(before).map(words);
18
22
  const kept = [];
19
- for (const piece of pieces.flatMap((p) => (typeof p === 'string' ? p.replace(MARKS, '').split(/[,،]/) : []))) {
20
- const text = piece.trim();
21
- if (!text)
22
- continue;
23
+ for (const text of cut(pieces)) {
23
24
  const these = words(text);
24
- if (said.some((before) => within(before, these) && (before.length === these.length || !/\p{Nd}/u.test(text))))
25
+ if (said.some((earlier) => within(earlier, these) && (earlier.length === these.length || !/\p{Nd}/u.test(text))))
25
26
  continue;
26
27
  said.push(these);
27
28
  kept.push(text);
28
29
  }
29
30
  return kept.join(locale === 'ar' ? '، ' : ', ');
30
31
  }
32
+ /** Letters written right to left: Arabic's and Hebrew's. */
33
+ const RTL = /[\u0590-\u08FF\uFB1D-\uFDFF\uFE70-\uFEFF]/;
34
+ /**
35
+ * The direction most of a text's letters are written in, for a box or a
36
+ * line that shows an address in its own words: "rtl" for one mostly in
37
+ * Arabic, though it starts with a Latin street ("El Tahrir، الإسماعيلية،
38
+ * مصر"), "ltr" for one mostly in Latin on an Arabic page ("1 Mohammed
39
+ * Mahmoud"); "" when there are no letters, or as many each way: the page's.
40
+ */
41
+ export function directionOf(text) {
42
+ const letters = text.match(/\p{L}/gu) ?? [];
43
+ const rtl = letters.filter((letter) => RTL.test(letter)).length;
44
+ const ltr = letters.length - rtl;
45
+ return rtl > ltr ? 'rtl' : ltr > rtl ? 'ltr' : '';
46
+ }
31
47
  //# sourceMappingURL=address-line.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"address-line.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-line.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,cAAc,CAAC;AAC7B,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAClE,sEAAsE;AACtE,MAAM,MAAM,GAAG,CAAC,GAAa,EAAE,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAEtH,MAAM,UAAU,WAAW,CAAC,MAAiB,EAAE,MAAe;IAC5D,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7G,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,SAAS;QACxH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"address-line.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/address-line.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,cAAc,CAAC;AAC7B,mHAAmH;AACnH,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjG,sEAAsE;AACtE,MAAM,MAAM,GAAG,CAAC,GAAa,EAAE,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAEtH,yFAAyF;AACzF,MAAM,GAAG,GAAG,CAAC,MAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEzK,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,MAAiB,EAAE,MAAe,EAAE,SAAoB,EAAE;IACpF,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,SAAS;QAC3H,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,4DAA4D;AAC5D,MAAM,GAAG,GAAG,2CAA2C,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC;IACjC,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { Locale } from '@fieldia/core';
2
+ /**
3
+ * What is known of the regions and cities of Egypt, Saudi Arabia, the UAE
4
+ * and Jordan, for reading Azure's addresses there, where each of its services
5
+ * names one place its own way: a region by its code ("RIY", "SH") or by a
6
+ * name ("Sharjah Emirate", "Ash Shāriqah", "منطقة الرياض", "مكة"), a city as
7
+ * a locality in another script ("Cairo" in an Arabic answer) or another
8
+ * spelling ("Ad Dammām", "الأسكندرية"). Each place here has one name in each
9
+ * language, which Fieldia writes, and every other name Azure was seen to give
10
+ * it (12–13 Oct 2026; each region's capital asked for in English and
11
+ * Arabic on 13 Oct). Loaded with the providers' address parts.
12
+ *
13
+ * A place is one of these only by its code or one of its names, the same
14
+ * words (without accents, vowel marks or tatweel, in lower case): never by
15
+ * a name that only sounds like one.
16
+ */
17
+ /** A place's names: in English, in Arabic, in French and German where they differ from English. */
18
+ export interface Known {
19
+ names: Partial<Record<Locale, string>> & {
20
+ en: string;
21
+ ar: string;
22
+ };
23
+ code?: string;
24
+ }
25
+ /**
26
+ * A name as two of Azure's answers write one place's: its words, without
27
+ * accents, tatweel, vowel marks or the direction marks Arabic carries, in
28
+ * lower case ("Ash Shāriqah" is "ash shariqah", "الشيـخ زايد" "الشيخ زايد").
29
+ */
30
+ export declare const nameKey: (name: unknown) => string;
31
+ /** A region (a governorate, a province, an emirate) of these countries, by Azure's code for it or by one of its names. */
32
+ export declare function knownRegion(country: string, ...names: string[]): Known | undefined;
33
+ /** A city of these countries, by one of its names. */
34
+ export declare function knownCity(country: string, name: string): Known | undefined;
35
+ /** A known place's name in a page's language: its own in French or German where it has one, its English one otherwise. */
36
+ export declare const nameIn: (known: Known, locale: Locale) => string;
37
+ /** Whether two names are one known city's or region's in a country ("Cairo" and "القاهرة"; "Al Jizah" and "Giza"). */
38
+ export declare function sameKnown(country: string, one: string, other: string): boolean;
@@ -0,0 +1,38 @@
1
+ import type { Locale } from '@fieldia/core';
2
+ /**
3
+ * What is known of the regions and cities of Egypt, Saudi Arabia, the UAE
4
+ * and Jordan, for reading Azure's addresses there, where each of its services
5
+ * names one place its own way: a region by its code ("RIY", "SH") or by a
6
+ * name ("Sharjah Emirate", "Ash Shāriqah", "منطقة الرياض", "مكة"), a city as
7
+ * a locality in another script ("Cairo" in an Arabic answer) or another
8
+ * spelling ("Ad Dammām", "الأسكندرية"). Each place here has one name in each
9
+ * language, which Fieldia writes, and every other name Azure was seen to give
10
+ * it (12–13 Oct 2026; each region's capital asked for in English and
11
+ * Arabic on 13 Oct). Loaded with the providers' address parts.
12
+ *
13
+ * A place is one of these only by its code or one of its names, the same
14
+ * words (without accents, vowel marks or tatweel, in lower case): never by
15
+ * a name that only sounds like one.
16
+ */
17
+ /** A place's names: in English, in Arabic, in French and German where they differ from English. */
18
+ export interface Known {
19
+ names: Partial<Record<Locale, string>> & {
20
+ en: string;
21
+ ar: string;
22
+ };
23
+ code?: string;
24
+ }
25
+ /**
26
+ * A name as two of Azure's answers write one place's: its words, without
27
+ * accents, tatweel, vowel marks or the direction marks Arabic carries, in
28
+ * lower case ("Ash Shāriqah" is "ash shariqah", "الشيـخ زايد" "الشيخ زايد").
29
+ */
30
+ export declare const nameKey: (name: unknown) => string;
31
+ /** A region (a governorate, a province, an emirate) of these countries, by Azure's code for it or by one of its names. */
32
+ export declare function knownRegion(country: string, ...names: string[]): Known | undefined;
33
+ /** A city of these countries, by one of its names. */
34
+ export declare function knownCity(country: string, name: string): Known | undefined;
35
+ /** A known place's name in a page's language: its own in French or German where it has one, its English one otherwise. */
36
+ export declare const nameIn: (known: Known, locale: Locale) => string;
37
+ /** Whether two names are one known city's or region's in a country ("Cairo" and "القاهرة"; "Al Jizah" and "Giza"). */
38
+ export declare function sameKnown(country: string, one: string, other: string): boolean;