{
  "version": 3,
  "sources": ["../../lib/matcher.ts", "../../lib/simplify.ts", "../../lib/stemmer.ts"],
  "sourcesContent": [
    "/* eslint @typescript-eslint/no-this-alias: \"warn\" */\nimport whichPolygon from 'which-polygon';\n\nimport { simplify } from './simplify.ts';\n\n// JSON\nimport matchGroupsJSON from '../config/matchGroups.json' with {type: 'json'};\nimport genericWordsJSON from '../config/genericWords.json' with {type: 'json'};\nimport treesJSON from '../config/trees.json' with {type: 'json'};\n\nconst matchGroups = matchGroupsJSON.matchGroups;\nconst trees = treesJSON.trees;\n\n\ntype Vec2 = [number, number];\ntype Vec3 = [number, number, number];\ntype Location = Vec2 | Vec3 | string | number;\n\ninterface LocationSet {\n  include?: Array<Location>,\n  exclude?: Array<Location>\n};\n\ninterface LocationConflation {\n  validateLocation: (a: Location) => unknown;\n  resolveLocation: (a: Location) => unknown;\n  validateLocationSet: (a: LocationSet) => unknown;\n  resolveLocationSet: (a: LocationSet) => unknown;\n};\n\ntype HitType = 'primary' | 'alternate' | 'excludeGeneric' | 'excludeNamed';\ninterface Hit {\n  match: HitType;\n  itemID?: string;\n  area?: number;\n  kv?: string;\n  nsimple?: string;\n  pattern?: string;\n};\n\n\nexport class Matcher {\n  private matchIndex;\n  private genericWords = new Map();\n  private itemLocation;\n  private locationSets;\n  private locationIndex;\n  private warnings: Array<string> = [];\n\n\n  // `constructor`\n  // initialize the genericWords regexes\n  constructor() {\n    // The `matchIndex` is a specialized structure that allows us to quickly answer\n    //   _\"Given a [key/value tagpair, name, location], what canonical items (brands etc) can match it?\"_\n    //\n    // The index contains all valid combinations of k/v tagpairs and names\n    // matchIndex:\n    // {\n    //   'k/v': {\n    //     'primary':         Map (String 'nsimple' -> Set (itemIDs…),   // matches for tags like `name`, `name:xx`, etc.\n    //     'alternate':       Map (String 'nsimple' -> Set (itemIDs…),   // matches for tags like `alt_name`, `brand`, etc.\n    //     'excludeNamed':    Map (String 'pattern' -> RegExp),\n    //     'excludeGeneric':  Map (String 'pattern' -> RegExp)\n    //   },\n    // }\n    //\n    // {\n    //   'amenity/bank': {\n    //     'primary': {\n    //       'firstbank':              Set (\"firstbank-978cca\", \"firstbank-9794e6\", \"firstbank-f17495\", …),\n    //       …\n    //     },\n    //     'alternate': {\n    //       '1stbank':                Set (\"firstbank-f17495\"),\n    //       …\n    //     }\n    //   },\n    //   'shop/supermarket': {\n    //     'primary': {\n    //       'coop':                   Set (\"coop-76454b\", \"coop-ebf2d9\", \"coop-36e991\", …),\n    //       'coopfood':               Set (\"coopfood-a8278b\", …),\n    //       …\n    //     },\n    //     'alternate': {\n    //       'coop':                   Set (\"coopfood-a8278b\", …),\n    //       'federatedcooperatives':  Set (\"coop-76454b\", …),\n    //       'thecooperative':         Set (\"coopfood-a8278b\", …),\n    //       …\n    //     }\n    //   }\n    // }\n    //\n    this.matchIndex = undefined;\n\n    // The `genericWords` structure matches the contents of genericWords.json to instantiated RegExp objects\n    // Map (String 'pattern' -> RegExp),\n    this.genericWords = new Map();\n    (genericWordsJSON.genericWords || []).forEach(s => this.genericWords.set(s, new RegExp(s, 'i')));\n\n    // The `itemLocation` structure maps itemIDs to locationSetIDs:\n    // {\n    //   'firstbank-f17495':  '+[first_bank_western_us.geojson]',\n    //   'firstbank-978cca':  '+[first_bank_carolinas.geojson]',\n    //   'coop-76454b':       '+[Q16]',\n    //   'coopfood-a8278b':   '+[Q23666]',\n    //   …\n    // }\n    this.itemLocation = undefined;\n\n    // The `locationSets` structure maps locationSetIDs to *resolved* locationSets:\n    // {\n    //   '+[first_bank_western_us.geojson]':  GeoJSON {…},\n    //   '+[first_bank_carolinas.geojson]':   GeoJSON {…},\n    //   '+[Q16]':                            GeoJSON {…},\n    //   '+[Q23666]':                         GeoJSON {…},\n    //   …\n    // }\n    this.locationSets = undefined;\n\n    // The `locationIndex` is an instance of which-polygon spatial index for the locationSets.\n    this.locationIndex = undefined;\n\n    // Array of match conflict pairs (currently unused)\n    this.warnings = [];\n  }\n\n\n  //\n  // `buildMatchIndex()`\n  // Call this to prepare the matcher for use\n  //\n  // `data` needs to be an Object indexed on a 'tree/key/value' path.\n  // (e.g. cache filled by `fileTree.read` or data found in `dist/nsi.json`)\n  // {\n  //    'brands/amenity/bank': { properties: {}, items: [ {}, {}, … ] },\n  //    'brands/amenity/bar':  { properties: {}, items: [ {}, {}, … ] },\n  //    …\n  // }\n  //\n  buildMatchIndex(data: Record<string, any>): void {\n    const that = this;\n    if (that.matchIndex) return;   // it was built already\n    that.matchIndex = new Map();\n\n    const seenTree = new Map();  // warn if the same [k, v, nsimple] appears in multiple trees - #5625\n\n    Object.keys(data).forEach(tkv => {\n      const category = data[tkv];\n      const parts = tkv.split('/', 3);     // tkv = \"tree/key/value\"\n      const t = parts[0];\n      const k = parts[1];\n      const v = parts[2];\n      const thiskv = `${k}/${v}`;\n      const tree = trees[t];\n\n      let branch = that.matchIndex.get(thiskv);\n      if (!branch) {\n        branch = {\n          primary: new Map(),\n          alternate: new Map(),\n          excludeGeneric: new Map(),\n          excludeNamed: new Map()\n        };\n        that.matchIndex.set(thiskv, branch);\n      }\n\n      // ADD EXCLUSIONS\n      const properties = category.properties || {};\n      const exclude = properties.exclude || {};\n      (exclude.generic || []).forEach(s => branch.excludeGeneric.set(s, new RegExp(s, 'i')));\n      (exclude.named || []).forEach(s => branch.excludeNamed.set(s, new RegExp(s, 'i')));\n      const excludeRegexes = [...branch.excludeGeneric.values(), ...branch.excludeNamed.values()];\n\n\n      // ADD ITEMS\n      const items = category.items;\n      if (!Array.isArray(items) || !items.length) return;\n\n\n      // Primary name patterns, match tags to take first\n      //  e.g. `name`, `name:ru`\n      const primaryName = new RegExp(tree.nameTags.primary, 'i');\n\n      // Alternate name patterns, match tags to consider after primary\n      //  e.g. `alt_name`, `short_name`, `brand`, `brand:ru`, etc..\n      const alternateName = new RegExp(tree.nameTags.alternate, 'i');\n\n      // There are a few exceptions to the name matching regexes.\n      // Usually a tag suffix contains a language code like `name:en`, `name:ru`\n      // but we want to exclude things like `operator:type`, `name:etymology`, etc..\n      const notName = /:(colou?r|type|forward|backward|left|right|etymology|pronunciation|signed|wikipedia)$/i;\n\n      // For certain categories we do not want to match generic KV pairs like `building/yes` or `amenity/yes`\n      const skipGenericKV = skipGenericKVMatches(t, k, v);\n\n      // We will collect the generic KV pairs anyway (for the purpose of filtering them out of matchTags)\n      const genericKV = new Set([`${k}/yes`, `building/yes`]);\n\n      // Collect alternate tagpairs for this kv category from matchGroups.\n      // We might also pick up a few more generic KVs (like `shop/yes`)\n      const matchGroupKV = new Set();\n      Object.values(matchGroups).forEach(matchGroup => {\n        const inGroup = matchGroup.some(otherkv => otherkv === thiskv);\n        if (!inGroup) return;\n\n        matchGroup.forEach(otherkv => {\n          if (otherkv === thiskv) return;   // skip self\n          matchGroupKV.add(otherkv);\n\n          const otherk = otherkv.split('/', 2)[0];   // we might pick up a `shop/yes`\n          genericKV.add(`${otherk}/yes`);\n        });\n      });\n\n      // For each item, insert all [key, value, name] combinations into the match index\n      items.forEach(item => {\n        if (!item.id) return;\n\n        // Automatically remove redundant `matchTags` - #3417, #8137\n        // (i.e. This kv is already covered by matchGroups, so it doesn't need to be in `item.matchTags`\n        //  or this kv is the primary kv, so it doesn't need to be duplicated in `item.matchTags`)\n        if (Array.isArray(item.matchTags) && item.matchTags.length) {\n          item.matchTags = item.matchTags\n            .filter(matchTag => !matchGroupKV.has(matchTag) && (matchTag !== thiskv) && !genericKV.has(matchTag));\n\n          if (!item.matchTags.length) delete item.matchTags;\n        }\n\n        // key/value tagpairs to insert into the match index..\n        let kvTags = [`${thiskv}`]\n          .concat(item.matchTags || []);\n\n        if (!skipGenericKV) {\n          kvTags = kvTags\n            .concat(Array.from(genericKV));  // #3454 - match some generic tags\n        }\n\n        // Index all the namelike tag values\n        Object.keys(item.tags).forEach(osmkey => {\n          if (notName.test(osmkey)) return;   // osmkey is not a namelike tag, skip\n          const osmvalue = item.tags[osmkey];\n          if (!osmvalue || excludeRegexes.some(regex => regex.test(osmvalue))) return;   // osmvalue missing or excluded\n\n          if (primaryName.test(osmkey)) {\n            kvTags.forEach(kv => insertName('primary', t, kv, simplify(osmvalue), item.id));\n          } else if (alternateName.test(osmkey)) {\n            kvTags.forEach(kv => insertName('alternate', t, kv, simplify(osmvalue), item.id));\n          }\n        });\n\n        // Index `matchNames` after indexing all other names..\n        const keepMatchNames = new Set();\n        (item.matchNames || []).forEach(matchName => {\n          // If this matchname isn't already indexed, add it to the alternate index\n          const nsimple = simplify(matchName);\n          kvTags.forEach(kv => {\n            const branch = that.matchIndex.get(kv);\n            const primaryLeaf = branch && branch.primary.get(nsimple);\n            const alternateLeaf = branch && branch.alternate.get(nsimple);\n            const inPrimary = primaryLeaf && primaryLeaf.has(item.id);\n            const inAlternate = alternateLeaf && alternateLeaf.has(item.id);\n\n            if (!inPrimary && !inAlternate) {\n              insertName('alternate', t, kv, nsimple, item.id);\n              keepMatchNames.add(matchName);\n            }\n          });\n        });\n\n        // Automatically remove redundant `matchNames` - #3417\n        // (i.e. This name got indexed some other way, so it doesn't need to be in `item.matchNames`)\n        if (keepMatchNames.size) {\n          item.matchNames = Array.from(keepMatchNames);\n        } else {\n          delete item.matchNames;\n        }\n\n      });   // each item\n    });   // each tkv\n\n\n    // Insert this item into the matchIndex\n    function insertName(which: string, t: string, kv: string, nsimple: string, itemID: string) {\n      if (!nsimple) {\n        that.warnings.push(`Warning: skipping empty ${which} name for item ${t}/${kv}: ${itemID}`);\n        return;\n      }\n\n      let branch = that.matchIndex.get(kv);\n      if (!branch) {\n        branch = {\n          primary: new Map(),\n          alternate: new Map(),\n          excludeGeneric: new Map(),\n          excludeNamed: new Map()\n        };\n        that.matchIndex.set(kv, branch);\n      }\n\n      let leaf = branch[which].get(nsimple);\n      if (!leaf) {\n        leaf = new Set();\n        branch[which].set(nsimple, leaf);\n      }\n\n      leaf.add(itemID);   // insert\n\n      // check for duplicates - #5625\n      if (!/yes$/.test(kv)) {  // ignore genericKV like amenity/yes, building/yes, etc\n        const kvnsimple = `${kv}/${nsimple}`;\n        const existing = seenTree.get(kvnsimple);\n        if (existing && existing !== t) {\n          const items = Array.from(leaf);\n          that.warnings.push(`Duplicate cache key \"${kvnsimple}\" in trees \"${t}\" and \"${existing}\", check items: ${items}`);\n          return;\n        }\n        seenTree.set(kvnsimple, t);\n      }\n    }\n\n    // For certain categories we do not want to match generic KV pairs like `building/yes` or `amenity/yes`\n    function skipGenericKVMatches(t: string, k: string, v: string): boolean {\n      return (\n        t === 'flags' ||\n        t === 'transit' ||\n        k === 'landuse' ||\n        v === 'atm' ||\n        v === 'bicycle_parking' ||\n        v === 'car_sharing' ||\n        v === 'caravan_site' ||\n        v === 'charging_station' ||\n        v === 'dog_park' ||\n        v === 'parking' ||\n        v === 'phone' ||\n        v === 'playground' ||\n        v === 'post_box' ||\n        v === 'public_bookcase' ||\n        v === 'recycling' ||\n        v === 'vending_machine'\n      );\n    }\n  }\n\n\n  //\n  // `buildLocationIndex()`\n  // Call this to prepare a which-polygon location index.\n  // This *resolves* all the locationSets into GeoJSON, which takes some time.\n  // You can skip this step if you don't care about matching within a location.\n  //\n  // `data` needs to be an Object indexed on a 'tree/key/value' path.\n  // (e.g. cache filled by `fileTree.read` or data found in `dist/nsi.json`)\n  // {\n  //    'brands/amenity/bank': { properties: {}, items: [ {}, {}, … ] },\n  //    'brands/amenity/bar':  { properties: {}, items: [ {}, {}, … ] },\n  //    …\n  // }\n  //\n  buildLocationIndex(data: Record<string, any>, loco: LocationConflation): void {\n    const that = this;\n    if (that.locationIndex) return;   // it was built already\n\n    that.itemLocation = new Map();\n    that.locationSets = new Map();\n\n    Object.keys(data).forEach(tkv => {\n      const items = data[tkv].items;\n      if (!Array.isArray(items) || !items.length) return;\n\n      items.forEach(item => {\n        if (that.itemLocation.has(item.id)) return;   // we've seen item id already - shouldn't be possible?\n\n        let resolved;\n        try {\n          resolved = loco.resolveLocationSet(item.locationSet);   // resolve a feature for this locationSet\n        } catch (err: unknown) {\n          const message = (err instanceof Error) ? err.message : err;\n          console.warn(`buildLocationIndex: ${message}`);     // couldn't resolve\n        }\n        if (!resolved || !resolved.id) return;\n\n        that.itemLocation.set(item.id, resolved.id);      // link it to the item\n        if (that.locationSets.has(resolved.id)) return;   // we've seen this locationSet feature before..\n\n        // First time seeing this locationSet feature, make a copy and add to locationSet cache..\n        const feature = _cloneDeep(resolved.feature);\n        feature.id = resolved.id;      // Important: always use the locationSet `id` (`+[Q30]`), not the feature `id` (`Q30`)\n        feature.properties.id = resolved.id;\n\n        if (!feature.geometry.coordinates.length || !feature.properties.area) {\n          console.warn(`buildLocationIndex: locationSet ${resolved.id} for ${item.id} resolves to an empty feature:`);\n          console.warn(JSON.stringify(feature));\n          return;\n        }\n\n        that.locationSets.set(resolved.id, feature);\n      });\n    });\n\n    that.locationIndex = whichPolygon({ type: 'FeatureCollection', features: [...that.locationSets.values()] });\n\n    function _cloneDeep(obj) {\n      return JSON.parse(JSON.stringify(obj));\n    }\n  }\n\n\n  //\n  // `match()`\n  // Pass parts and return an Array of matches.\n  // `k` - key\n  // `v` - value\n  // `n` - namelike\n  // `loc` - optional - [lon,lat] location to search\n  //\n  // 1. If the [k,v,n] tuple matches a canonical item…\n  // Return an Array of match results.\n  // Each result will include the area in km² that the item is valid.\n  //\n  // Order of results:\n  // Primary ordering will be on the \"match\" column:\n  //   \"primary\" - where the query matches the `name` tag, followed by\n  //   \"alternate\" - where the query matches an alternate name tag (e.g. short_name, brand, operator, etc)\n  // Secondary ordering will be on the \"area\" column:\n  //   \"area descending\" if no location was provided, (worldwide before local)\n  //   \"area ascending\" if location was provided (local before worldwide)\n  //\n  // [\n  //   { match: 'primary',   itemID: String,  area: Number,  kv: String,  nsimple: String },\n  //   { match: 'primary',   itemID: String,  area: Number,  kv: String,  nsimple: String },\n  //   { match: 'alternate', itemID: String,  area: Number,  kv: String,  nsimple: String },\n  //   { match: 'alternate', itemID: String,  area: Number,  kv: String,  nsimple: String },\n  //   …\n  // ]\n  //\n  // -or-\n  //\n  // 2. If the [k,v,n] tuple matches an exclude pattern…\n  // Return an Array with a single exclude result, either\n  //\n  // [ { match: 'excludeGeneric', pattern: String,  kv: String } ]  // \"generic\" e.g. \"Food Court\"\n  //   or\n  // [ { match: 'excludeNamed', pattern: String,  kv: String } ]    // \"named\", e.g. \"Kebabai\"\n  //\n  // About results\n  //   \"generic\" - a generic word that is probably not really a name.\n  //     For these, iD should warn the user \"Hey don't put 'food court' in the name tag\".\n  //   \"named\" - a real name like \"Kebabai\" that is just common, but not a brand.\n  //     For these, iD should just let it be. We don't include these in NSI, but we don't want to nag users about it either.\n  //\n  // -or-\n  //\n  // 3. If the [k,v,n] tuple matches nothing of any kind, return `null`\n  //\n  //\n  match(k: string, v: string, n: string, loc?: Vec2): Array<Hit> | null {\n    const that = this;\n    if (!that.matchIndex) {\n      throw new Error('match:  matchIndex not built.');\n    }\n\n    // If we were supplied a location, and a that.locationIndex has been set up,\n    // get the locationSets that are valid there so we can filter results.\n    let matchLocations;\n    if (Array.isArray(loc) && that.locationIndex) {\n      // which-polygon query returns an array of GeoJSON properties, pass true to return all results\n      matchLocations = that.locationIndex([loc[0], loc[1], loc[0], loc[1]], true);\n    }\n\n    const nsimple = simplify(n);\n\n    const seen = new Set();\n    const results: Array<Hit> = [];\n    gatherResults('primary');\n    gatherResults('alternate');\n    if (results.length) return results;\n\n    gatherResults('exclude');\n    return results.length ? results : null;\n\n\n    function gatherResults(which: string): void {\n      // First try an exact match on k/v\n      const kv = `${k}/${v}`;\n      let didMatch = tryMatch(which, kv);\n      if (didMatch) return;\n\n      // If that didn't work, look in match groups for other pairs considered equivalent to k/v..\n      for (const mg in matchGroups) {\n        const matchGroup = matchGroups[mg];\n        const inGroup = matchGroup.some(otherkv => otherkv === kv);\n        if (!inGroup) continue;\n\n        for (const otherkv of matchGroup) {\n          if (otherkv === kv) continue;  // skip self\n          didMatch = tryMatch(which, otherkv);\n          if (didMatch) return;\n        }\n      }\n\n      // If finished 'exclude' pass and still haven't matched anything, try the global `genericWords.json` patterns\n      if (which === 'exclude') {\n        const regex = [...that.genericWords.values()].find(regex => regex.test(n));\n        if (regex) {\n          results.push({ match: 'excludeGeneric', pattern: String(regex) });  // note no `branch`, no `kv`\n          return;\n        }\n      }\n    }\n\n    function tryMatch(which: string, kv: string): boolean {\n      const branch = that.matchIndex.get(kv);\n      if (!branch) return false;\n\n      if (which === 'exclude') {  // Test name `n` against named and generic exclude patterns\n        let regex = [...branch.excludeNamed.values()].find(regex => regex.test(n));\n        if (regex) {\n          results.push({ match: 'excludeNamed', pattern: String(regex), kv: kv });\n          return false;\n        }\n        regex = [...branch.excludeGeneric.values()].find(regex => regex.test(n));\n        if (regex) {\n          results.push({ match: 'excludeGeneric', pattern: String(regex), kv: kv });\n          return false;\n        }\n        return false;\n      }\n\n      const leaf = branch[which].get(nsimple);\n      if (!leaf || !leaf.size) return false;\n      if (!(which === 'primary' || which === 'alternate')) return false;\n\n      // If we get here, we matched something..\n      // Prepare the results, calculate areas (if location index was set up)\n      let hits: Array<Hit> = [];\n      for (const itemID of [...leaf]) {\n        let area = Infinity;\n        if (that.itemLocation && that.locationSets) {\n          const location = that.locationSets.get(that.itemLocation.get(itemID));\n          area = (location && location.properties.area) || Infinity;\n        }\n        hits.push({ match: which, itemID: itemID, area: area, kv: kv, nsimple: nsimple });\n      }\n\n      let sortFn = byAreaDescending;\n\n      // Filter the match to include only results valid in the requested `loc`..\n      if (matchLocations) {\n        hits = hits.filter(isValidLocation);\n        sortFn = byAreaAscending;\n      }\n\n      if (!hits.length) return false;\n\n      // push results\n      hits.sort(sortFn).forEach(hit => {\n        if (seen.has(hit.itemID)) return;\n        seen.add(hit.itemID);\n        results.push(hit);\n      });\n\n      return true;\n\n\n      function isValidLocation(hit: Hit): boolean {\n        if (!that.itemLocation) return true;\n        return matchLocations.find(props => props.id === that.itemLocation.get(hit.itemID));\n      }\n      // Sort smaller (more local) locations first.\n      function byAreaAscending(hitA: Hit, hitB: Hit): number {\n        const areaA = hitA.area || 0;\n        const areaB = hitB.area || 0;\n        return areaA - areaB;\n      }\n      // Sort larger (more worldwide) locations first.\n      function byAreaDescending(hitA: Hit, hitB: Hit): number {\n        const areaA = hitA.area || 0;\n        const areaB = hitB.area || 0;\n        return areaB - areaA;\n      }\n    }\n  }\n\n\n  //\n  // `getWarnings()`\n  // Return any warnings discovered when buiding the index.\n  // (currently this does nothing)\n  //\n  getWarnings(): Array<string> {\n    return this.warnings;\n  }\n}\n",
    "// External\nimport diacritics from 'diacritics';\n\n// remove spaces, punctuation, diacritics\n// for punction see https://stackoverflow.com/a/21224179\nexport function simplify(str?: string): string {\n  if (typeof str !== 'string') return '';\n\n  return diacritics.remove(\n    str\n      .replace(/&/g, 'and')\n      .replace(/(İ|i̇)/ig, 'i')   // for BİM, İşbank - #5017, #8261\n      .replace(/[\\s\\-=_!\"#%'*{},.\\/:;?\\(\\)\\[\\]@\\\\$\\^*+<>«»~`’\\u00a1\\u00a7\\u00b6\\u00b7\\u00bf\\u037e\\u0387\\u055a-\\u055f\\u0589\\u05c0\\u05c3\\u05c6\\u05f3\\u05f4\\u0609\\u060a\\u060c\\u060d\\u061b\\u061e\\u061f\\u066a-\\u066d\\u06d4\\u0700-\\u070d\\u07f7-\\u07f9\\u0830-\\u083e\\u085e\\u0964\\u0965\\u0970\\u0af0\\u0df4\\u0e4f\\u0e5a\\u0e5b\\u0f04-\\u0f12\\u0f14\\u0f85\\u0fd0-\\u0fd4\\u0fd9\\u0fda\\u104a-\\u104f\\u10fb\\u1360-\\u1368\\u166d\\u166e\\u16eb-\\u16ed\\u1735\\u1736\\u17d4-\\u17d6\\u17d8-\\u17da\\u1800-\\u1805\\u1807-\\u180a\\u1944\\u1945\\u1a1e\\u1a1f\\u1aa0-\\u1aa6\\u1aa8-\\u1aad\\u1b5a-\\u1b60\\u1bfc-\\u1bff\\u1c3b-\\u1c3f\\u1c7e\\u1c7f\\u1cc0-\\u1cc7\\u1cd3\\u2000-\\u206f\\u2cf9-\\u2cfc\\u2cfe\\u2cff\\u2d70\\u2e00-\\u2e7f\\u3001-\\u3003\\u303d\\u30fb\\ua4fe\\ua4ff\\ua60d-\\ua60f\\ua673\\ua67e\\ua6f2-\\ua6f7\\ua874-\\ua877\\ua8ce\\ua8cf\\ua8f8-\\ua8fa\\ua92e\\ua92f\\ua95f\\ua9c1-\\ua9cd\\ua9de\\ua9df\\uaa5c-\\uaa5f\\uaade\\uaadf\\uaaf0\\uaaf1\\uabeb\\ufe10-\\ufe16\\ufe19\\ufe30\\ufe45\\ufe46\\ufe49-\\ufe4c\\ufe50-\\ufe52\\ufe54-\\ufe57\\ufe5f-\\ufe61\\ufe68\\ufe6a\\ufe6b\\ufeff\\uff01-\\uff03\\uff05-\\uff07\\uff0a\\uff0c\\uff0e\\uff0f\\uff1a\\uff1b\\uff1f\\uff20\\uff3c\\uff61\\uff64\\uff65]+/g,'')\n      .toLowerCase()\n  );\n}\n",
    "// Internal\nimport { simplify } from './simplify.ts';\n\n// Removes noise from the name so that we can compare\n// similar names for catching duplicates.\nexport function stemmer(str?: string): string {\n  if (typeof str !== 'string') return '';\n\n  const noise = [\n    /ban(k|c)(a|o)?/ig,\n    /банк/ig,\n    /coop/ig,\n    /express/ig,\n    /(gas|fuel)/ig,\n    /wireless/ig,\n    /(shop|store)/ig\n  ];\n\n  str = noise.reduce((acc, regex) => acc.replace(regex, ''), str);\n  return simplify(str);\n}\n"
  ],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACyB,IAAzB;;;ACAuB,IAAvB;AAIO,SAAS,QAAQ,CAAC,KAAsB;AAAA,EAC7C,IAAI,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EAEpC,OAAO,0BAAW,OAChB,IACG,QAAQ,MAAM,KAAK,EACnB,QAAQ,YAAW,GAAG,EACtB,QAAQ,+hCAA6hC,EAAE,EACviC,YAAY,CACjB;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADJF,IAAM,cAAc,oBAAgB;AACpC,IAAM,QAAQ,cAAU;AAAA;AA8BjB,MAAM,QAAQ;AAAA,EACX;AAAA,EACA,eAAe,IAAI;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAA0B,CAAC;AAAA,EAKnC,WAAW,GAAG;AAAA,IAyCZ,KAAK,aAAa;AAAA,IAIlB,KAAK,eAAe,IAAI;AAAA,KACvB,qBAAiB,gBAAgB,CAAC,GAAG,QAAQ,OAAK,KAAK,aAAa,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC,CAAC;AAAA,IAU/F,KAAK,eAAe;AAAA,IAUpB,KAAK,eAAe;AAAA,IAGpB,KAAK,gBAAgB;AAAA,IAGrB,KAAK,WAAW,CAAC;AAAA;AAAA,EAgBnB,eAAe,CAAC,MAAiC;AAAA,IAC/C,MAAM,OAAO;AAAA,IACb,IAAI,KAAK;AAAA,MAAY;AAAA,IACrB,KAAK,aAAa,IAAI;AAAA,IAEtB,MAAM,WAAW,IAAI;AAAA,IAErB,OAAO,KAAK,IAAI,EAAE,QAAQ,SAAO;AAAA,MAC/B,MAAM,WAAW,KAAK;AAAA,MACtB,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAC;AAAA,MAC9B,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,SAAS,GAAG,KAAK;AAAA,MACvB,MAAM,OAAO,MAAM;AAAA,MAEnB,IAAI,SAAS,KAAK,WAAW,IAAI,MAAM;AAAA,MACvC,IAAI,CAAC,QAAQ;AAAA,QACX,SAAS;AAAA,UACP,SAAS,IAAI;AAAA,UACb,WAAW,IAAI;AAAA,UACf,gBAAgB,IAAI;AAAA,UACpB,cAAc,IAAI;AAAA,QACpB;AAAA,QACA,KAAK,WAAW,IAAI,QAAQ,MAAM;AAAA,MACpC;AAAA,MAGA,MAAM,aAAa,SAAS,cAAc,CAAC;AAAA,MAC3C,MAAM,UAAU,WAAW,WAAW,CAAC;AAAA,OACtC,QAAQ,WAAW,CAAC,GAAG,QAAQ,OAAK,OAAO,eAAe,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC,CAAC;AAAA,OACpF,QAAQ,SAAS,CAAC,GAAG,QAAQ,OAAK,OAAO,aAAa,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC,CAAC;AAAA,MACjF,MAAM,iBAAiB,CAAC,GAAG,OAAO,eAAe,OAAO,GAAG,GAAG,OAAO,aAAa,OAAO,CAAC;AAAA,MAI1F,MAAM,QAAQ,SAAS;AAAA,MACvB,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM;AAAA,QAAQ;AAAA,MAK5C,MAAM,cAAc,IAAI,OAAO,KAAK,SAAS,SAAS,GAAG;AAAA,MAIzD,MAAM,gBAAgB,IAAI,OAAO,KAAK,SAAS,WAAW,GAAG;AAAA,MAK7D,MAAM,UAAU;AAAA,MAGhB,MAAM,gBAAgB,qBAAqB,GAAG,GAAG,CAAC;AAAA,MAGlD,MAAM,YAAY,IAAI,IAAI,CAAC,GAAG,SAAS,cAAc,CAAC;AAAA,MAItD,MAAM,eAAe,IAAI;AAAA,MACzB,OAAO,OAAO,WAAW,EAAE,QAAQ,gBAAc;AAAA,QAC/C,MAAM,UAAU,WAAW,KAAK,aAAW,YAAY,MAAM;AAAA,QAC7D,IAAI,CAAC;AAAA,UAAS;AAAA,QAEd,WAAW,QAAQ,aAAW;AAAA,UAC5B,IAAI,YAAY;AAAA,YAAQ;AAAA,UACxB,aAAa,IAAI,OAAO;AAAA,UAExB,MAAM,SAAS,QAAQ,MAAM,KAAK,CAAC,EAAE;AAAA,UACrC,UAAU,IAAI,GAAG,YAAY;AAAA,SAC9B;AAAA,OACF;AAAA,MAGD,MAAM,QAAQ,UAAQ;AAAA,QACpB,IAAI,CAAC,KAAK;AAAA,UAAI;AAAA,QAKd,IAAI,MAAM,QAAQ,KAAK,SAAS,KAAK,KAAK,UAAU,QAAQ;AAAA,UAC1D,KAAK,YAAY,KAAK,UACnB,OAAO,cAAY,CAAC,aAAa,IAAI,QAAQ,KAAM,aAAa,UAAW,CAAC,UAAU,IAAI,QAAQ,CAAC;AAAA,UAEtG,IAAI,CAAC,KAAK,UAAU;AAAA,YAAQ,OAAO,KAAK;AAAA,QAC1C;AAAA,QAGA,IAAI,SAAS,CAAC,GAAG,QAAQ,EACtB,OAAO,KAAK,aAAa,CAAC,CAAC;AAAA,QAE9B,IAAI,CAAC,eAAe;AAAA,UAClB,SAAS,OACN,OAAO,MAAM,KAAK,SAAS,CAAC;AAAA,QACjC;AAAA,QAGA,OAAO,KAAK,KAAK,IAAI,EAAE,QAAQ,YAAU;AAAA,UACvC,IAAI,QAAQ,KAAK,MAAM;AAAA,YAAG;AAAA,UAC1B,MAAM,WAAW,KAAK,KAAK;AAAA,UAC3B,IAAI,CAAC,YAAY,eAAe,KAAK,WAAS,MAAM,KAAK,QAAQ,CAAC;AAAA,YAAG;AAAA,UAErE,IAAI,YAAY,KAAK,MAAM,GAAG;AAAA,YAC5B,OAAO,QAAQ,QAAM,WAAW,WAAW,GAAG,IAAI,SAAS,QAAQ,GAAG,KAAK,EAAE,CAAC;AAAA,UAChF,EAAO,SAAI,cAAc,KAAK,MAAM,GAAG;AAAA,YACrC,OAAO,QAAQ,QAAM,WAAW,aAAa,GAAG,IAAI,SAAS,QAAQ,GAAG,KAAK,EAAE,CAAC;AAAA,UAClF;AAAA,SACD;AAAA,QAGD,MAAM,iBAAiB,IAAI;AAAA,SAC1B,KAAK,cAAc,CAAC,GAAG,QAAQ,eAAa;AAAA,UAE3C,MAAM,UAAU,SAAS,SAAS;AAAA,UAClC,OAAO,QAAQ,QAAM;AAAA,YACnB,MAAM,UAAS,KAAK,WAAW,IAAI,EAAE;AAAA,YACrC,MAAM,cAAc,WAAU,QAAO,QAAQ,IAAI,OAAO;AAAA,YACxD,MAAM,gBAAgB,WAAU,QAAO,UAAU,IAAI,OAAO;AAAA,YAC5D,MAAM,YAAY,eAAe,YAAY,IAAI,KAAK,EAAE;AAAA,YACxD,MAAM,cAAc,iBAAiB,cAAc,IAAI,KAAK,EAAE;AAAA,YAE9D,IAAI,CAAC,aAAa,CAAC,aAAa;AAAA,cAC9B,WAAW,aAAa,GAAG,IAAI,SAAS,KAAK,EAAE;AAAA,cAC/C,eAAe,IAAI,SAAS;AAAA,YAC9B;AAAA,WACD;AAAA,SACF;AAAA,QAID,IAAI,eAAe,MAAM;AAAA,UACvB,KAAK,aAAa,MAAM,KAAK,cAAc;AAAA,QAC7C,EAAO;AAAA,UACL,OAAO,KAAK;AAAA;AAAA,OAGf;AAAA,KACF;AAAA,IAID,SAAS,UAAU,CAAC,OAAe,GAAW,IAAY,SAAiB,QAAgB;AAAA,MACzF,IAAI,CAAC,SAAS;AAAA,QACZ,KAAK,SAAS,KAAK,2BAA2B,uBAAuB,KAAK,OAAO,QAAQ;AAAA,QACzF;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,KAAK,WAAW,IAAI,EAAE;AAAA,MACnC,IAAI,CAAC,QAAQ;AAAA,QACX,SAAS;AAAA,UACP,SAAS,IAAI;AAAA,UACb,WAAW,IAAI;AAAA,UACf,gBAAgB,IAAI;AAAA,UACpB,cAAc,IAAI;AAAA,QACpB;AAAA,QACA,KAAK,WAAW,IAAI,IAAI,MAAM;AAAA,MAChC;AAAA,MAEA,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO;AAAA,MACpC,IAAI,CAAC,MAAM;AAAA,QACT,OAAO,IAAI;AAAA,QACX,OAAO,OAAO,IAAI,SAAS,IAAI;AAAA,MACjC;AAAA,MAEA,KAAK,IAAI,MAAM;AAAA,MAGf,IAAI,CAAC,OAAO,KAAK,EAAE,GAAG;AAAA,QACpB,MAAM,YAAY,GAAG,MAAM;AAAA,QAC3B,MAAM,WAAW,SAAS,IAAI,SAAS;AAAA,QACvC,IAAI,YAAY,aAAa,GAAG;AAAA,UAC9B,MAAM,QAAQ,MAAM,KAAK,IAAI;AAAA,UAC7B,KAAK,SAAS,KAAK,wBAAwB,wBAAwB,WAAW,2BAA2B,OAAO;AAAA,UAChH;AAAA,QACF;AAAA,QACA,SAAS,IAAI,WAAW,CAAC;AAAA,MAC3B;AAAA;AAAA,IAIF,SAAS,oBAAoB,CAAC,GAAW,GAAW,GAAoB;AAAA,MACtE,OACE,MAAM,WACN,MAAM,aACN,MAAM,aACN,MAAM,SACN,MAAM,qBACN,MAAM,iBACN,MAAM,kBACN,MAAM,sBACN,MAAM,cACN,MAAM,aACN,MAAM,WACN,MAAM,gBACN,MAAM,cACN,MAAM,qBACN,MAAM,eACN,MAAM;AAAA;AAAA;AAAA,EAoBZ,kBAAkB,CAAC,MAA2B,MAAgC;AAAA,IAC5E,MAAM,OAAO;AAAA,IACb,IAAI,KAAK;AAAA,MAAe;AAAA,IAExB,KAAK,eAAe,IAAI;AAAA,IACxB,KAAK,eAAe,IAAI;AAAA,IAExB,OAAO,KAAK,IAAI,EAAE,QAAQ,SAAO;AAAA,MAC/B,MAAM,QAAQ,KAAK,KAAK;AAAA,MACxB,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM;AAAA,QAAQ;AAAA,MAE5C,MAAM,QAAQ,UAAQ;AAAA,QACpB,IAAI,KAAK,aAAa,IAAI,KAAK,EAAE;AAAA,UAAG;AAAA,QAEpC,IAAI;AAAA,QACJ,IAAI;AAAA,UACF,WAAW,KAAK,mBAAmB,KAAK,WAAW;AAAA,UACnD,OAAO,KAAc;AAAA,UACrB,MAAM,UAAW,eAAe,QAAS,IAAI,UAAU;AAAA,UACvD,QAAQ,KAAK,uBAAuB,SAAS;AAAA;AAAA,QAE/C,IAAI,CAAC,YAAY,CAAC,SAAS;AAAA,UAAI;AAAA,QAE/B,KAAK,aAAa,IAAI,KAAK,IAAI,SAAS,EAAE;AAAA,QAC1C,IAAI,KAAK,aAAa,IAAI,SAAS,EAAE;AAAA,UAAG;AAAA,QAGxC,MAAM,UAAU,WAAW,SAAS,OAAO;AAAA,QAC3C,QAAQ,KAAK,SAAS;AAAA,QACtB,QAAQ,WAAW,KAAK,SAAS;AAAA,QAEjC,IAAI,CAAC,QAAQ,SAAS,YAAY,UAAU,CAAC,QAAQ,WAAW,MAAM;AAAA,UACpE,QAAQ,KAAK,mCAAmC,SAAS,UAAU,KAAK,kCAAkC;AAAA,UAC1G,QAAQ,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,UACpC;AAAA,QACF;AAAA,QAEA,KAAK,aAAa,IAAI,SAAS,IAAI,OAAO;AAAA,OAC3C;AAAA,KACF;AAAA,IAED,KAAK,gBAAgB,6BAAa,EAAE,MAAM,qBAAqB,UAAU,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,EAAE,CAAC;AAAA,IAE1G,SAAS,UAAU,CAAC,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;AAAA;AAAA;AAAA,EAqDzC,KAAK,CAAC,GAAW,GAAW,GAAW,KAA+B;AAAA,IACpE,MAAM,OAAO;AAAA,IACb,IAAI,CAAC,KAAK,YAAY;AAAA,MACpB,MAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAAA,IAIA,IAAI;AAAA,IACJ,IAAI,MAAM,QAAQ,GAAG,KAAK,KAAK,eAAe;AAAA,MAE5C,iBAAiB,KAAK,cAAc,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,GAAG,IAAI;AAAA,IAC5E;AAAA,IAEA,MAAM,UAAU,SAAS,CAAC;AAAA,IAE1B,MAAM,OAAO,IAAI;AAAA,IACjB,MAAM,UAAsB,CAAC;AAAA,IAC7B,cAAc,SAAS;AAAA,IACvB,cAAc,WAAW;AAAA,IACzB,IAAI,QAAQ;AAAA,MAAQ,OAAO;AAAA,IAE3B,cAAc,SAAS;AAAA,IACvB,OAAO,QAAQ,SAAS,UAAU;AAAA,IAGlC,SAAS,aAAa,CAAC,OAAqB;AAAA,MAE1C,MAAM,KAAK,GAAG,KAAK;AAAA,MACnB,IAAI,WAAW,SAAS,OAAO,EAAE;AAAA,MACjC,IAAI;AAAA,QAAU;AAAA,MAGd,WAAW,MAAM,aAAa;AAAA,QAC5B,MAAM,aAAa,YAAY;AAAA,QAC/B,MAAM,UAAU,WAAW,KAAK,aAAW,YAAY,EAAE;AAAA,QACzD,IAAI,CAAC;AAAA,UAAS;AAAA,QAEd,WAAW,WAAW,YAAY;AAAA,UAChC,IAAI,YAAY;AAAA,YAAI;AAAA,UACpB,WAAW,SAAS,OAAO,OAAO;AAAA,UAClC,IAAI;AAAA,YAAU;AAAA,QAChB;AAAA,MACF;AAAA,MAGA,IAAI,UAAU,WAAW;AAAA,QACvB,MAAM,QAAQ,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,EAAE,KAAK,YAAS,OAAM,KAAK,CAAC,CAAC;AAAA,QACzE,IAAI,OAAO;AAAA,UACT,QAAQ,KAAK,EAAE,OAAO,kBAAkB,SAAS,OAAO,KAAK,EAAE,CAAC;AAAA,UAChE;AAAA,QACF;AAAA,MACF;AAAA;AAAA,IAGF,SAAS,QAAQ,CAAC,OAAe,IAAqB;AAAA,MACpD,MAAM,SAAS,KAAK,WAAW,IAAI,EAAE;AAAA,MACrC,IAAI,CAAC;AAAA,QAAQ,OAAO;AAAA,MAEpB,IAAI,UAAU,WAAW;AAAA,QACvB,IAAI,QAAQ,CAAC,GAAG,OAAO,aAAa,OAAO,CAAC,EAAE,KAAK,YAAS,OAAM,KAAK,CAAC,CAAC;AAAA,QACzE,IAAI,OAAO;AAAA,UACT,QAAQ,KAAK,EAAE,OAAO,gBAAgB,SAAS,OAAO,KAAK,GAAG,GAAO,CAAC;AAAA,UACtE,OAAO;AAAA,QACT;AAAA,QACA,QAAQ,CAAC,GAAG,OAAO,eAAe,OAAO,CAAC,EAAE,KAAK,YAAS,OAAM,KAAK,CAAC,CAAC;AAAA,QACvE,IAAI,OAAO;AAAA,UACT,QAAQ,KAAK,EAAE,OAAO,kBAAkB,SAAS,OAAO,KAAK,GAAG,GAAO,CAAC;AAAA,UACxE,OAAO;AAAA,QACT;AAAA,QACA,OAAO;AAAA,MACT;AAAA,MAEA,MAAM,OAAO,OAAO,OAAO,IAAI,OAAO;AAAA,MACtC,IAAI,CAAC,QAAQ,CAAC,KAAK;AAAA,QAAM,OAAO;AAAA,MAChC,IAAI,EAAE,UAAU,aAAa,UAAU;AAAA,QAAc,OAAO;AAAA,MAI5D,IAAI,OAAmB,CAAC;AAAA,MACxB,WAAW,UAAU,CAAC,GAAG,IAAI,GAAG;AAAA,QAC9B,IAAI,OAAO;AAAA,QACX,IAAI,KAAK,gBAAgB,KAAK,cAAc;AAAA,UAC1C,MAAM,WAAW,KAAK,aAAa,IAAI,KAAK,aAAa,IAAI,MAAM,CAAC;AAAA,UACpE,OAAQ,YAAY,SAAS,WAAW,QAAS;AAAA,QACnD;AAAA,QACA,KAAK,KAAK,EAAE,OAAO,OAAO,QAAgB,MAAY,IAAQ,QAAiB,CAAC;AAAA,MAClF;AAAA,MAEA,IAAI,SAAS;AAAA,MAGb,IAAI,gBAAgB;AAAA,QAClB,OAAO,KAAK,OAAO,eAAe;AAAA,QAClC,SAAS;AAAA,MACX;AAAA,MAEA,IAAI,CAAC,KAAK;AAAA,QAAQ,OAAO;AAAA,MAGzB,KAAK,KAAK,MAAM,EAAE,QAAQ,SAAO;AAAA,QAC/B,IAAI,KAAK,IAAI,IAAI,MAAM;AAAA,UAAG;AAAA,QAC1B,KAAK,IAAI,IAAI,MAAM;AAAA,QACnB,QAAQ,KAAK,GAAG;AAAA,OACjB;AAAA,MAED,OAAO;AAAA,MAGP,SAAS,eAAe,CAAC,KAAmB;AAAA,QAC1C,IAAI,CAAC,KAAK;AAAA,UAAc,OAAO;AAAA,QAC/B,OAAO,eAAe,KAAK,WAAS,MAAM,OAAO,KAAK,aAAa,IAAI,IAAI,MAAM,CAAC;AAAA;AAAA,MAGpF,SAAS,eAAe,CAAC,MAAW,MAAmB;AAAA,QACrD,MAAM,QAAQ,KAAK,QAAQ;AAAA,QAC3B,MAAM,QAAQ,KAAK,QAAQ;AAAA,QAC3B,OAAO,QAAQ;AAAA;AAAA,MAGjB,SAAS,gBAAgB,CAAC,MAAW,MAAmB;AAAA,QACtD,MAAM,QAAQ,KAAK,QAAQ;AAAA,QAC3B,MAAM,QAAQ,KAAK,QAAQ;AAAA,QAC3B,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,EAWrB,WAAW,GAAkB;AAAA,IAC3B,OAAO,KAAK;AAAA;AAEhB;;AE5kBO,SAAS,OAAO,CAAC,KAAsB;AAAA,EAC5C,IAAI,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EAEpC,MAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,OAAO,CAAC,KAAK,UAAU,IAAI,QAAQ,OAAO,EAAE,GAAG,GAAG;AAAA,EAC9D,OAAO,SAAS,GAAG;AAAA;",
  "debugId": "CC2169D6119855B264756E2164756E21",
  "names": []
}