From e37cd8be67c12ebb597350d00d9c93826525dc7a Mon Sep 17 00:00:00 2001 From: babayaga Date: Fri, 21 Nov 2025 23:29:34 +0100 Subject: [PATCH] search | registry esm --- packages/search/dist-in/lib/googlemaps.d.ts | 251 +------------ packages/search/dist-in/lib/googlemaps.js | 236 +++++------- packages/search/dist-in/lib/index.d.ts | 1 - packages/search/dist-in/lib/index.js | 3 +- packages/search/dist-in/lib/map_types.d.ts | 40 +- packages/search/dist-in/lib/types.d.ts | 1 + packages/search/src/commands/options-zod.ts | 2 +- packages/search/src/commands/options.ts | 2 +- packages/search/src/lib/googlemaps.ts | 393 +++++++++----------- packages/search/src/lib/index.ts | 1 - packages/search/src/lib/map_types.ts | 37 +- packages/search/src/lib/types-googlemaps.ts | 78 ---- packages/search/src/lib/types.ts | 5 +- 13 files changed, 276 insertions(+), 774 deletions(-) delete mode 100644 packages/search/src/lib/types-googlemaps.ts diff --git a/packages/search/dist-in/lib/googlemaps.d.ts b/packages/search/dist-in/lib/googlemaps.d.ts index 69827c76..f0bf1798 100644 --- a/packages/search/dist-in/lib/googlemaps.d.ts +++ b/packages/search/dist-in/lib/googlemaps.d.ts @@ -1,254 +1,14 @@ -import * as CLI from 'yargs'; -export type ParsedURL = { - scheme: string; - host?: string; - path?: string; - query?: Record; - fragment?: string; -}; -export declare const escapeFirstUrlSegment: (url: string) => string; -export declare const handleFs: (path: string) => Promise; -export declare const schemeHandlers: Record Promise>; -export declare const parseCustomUrl: (url: string) => Promise; -import { z } from 'zod'; +import { zodSchema, zodSchemaEach, yargsOptions, yargsOptionsEach, IOptionsGoogleMaps, IOptionsGoogleMapsEach } from './googlemaps-zod.js'; +export { zodSchema, zodSchemaEach, yargsOptions, yargsOptionsEach, IOptionsGoogleMaps, IOptionsGoogleMapsEach }; import type { GoogleParameters } from "serpapi"; import { IScaleserpSearch } from './types.js'; -import { IOptionsGoogleMaps, IOptionsGoogleMapsEach } from './types-googlemaps.js'; +import { LocalResult } from './map_types.js'; export declare enum SearchQueriesES { INJECTION = "inyecci\u00F3n de plastico" } -export declare const home: () => string; export declare const locationString: (coords: string, zoom?: number) => string; export declare const store: (storePath: string, ns?: string) => Promise; export declare const getStored: (title: string, storePath: string, ns?: string) => Promise; -export declare const zodSchema: () => z.ZodObject<{ - api_key: z.ZodOptional; - cache: z.ZodDefault; - category: z.ZodDefault>; - dst: z.ZodDefault; - dump: z.ZodOptional; - engine: z.ZodDefault; - env_key: z.ZodDefault; - filterCity: z.ZodOptional; - filterCountry: z.ZodOptional; - filterType: z.ZodOptional; - findEMail: z.ZodDefault; - geocode_key: z.ZodOptional; - google_domain: z.ZodDefault; - headless: z.ZodDefault; - language: z.ZodDefault; - limit: z.ZodDefault; - logLevel: z.ZodDefault; - meta: z.ZodDefault; - searchCache: z.ZodDefault; - query: z.ZodDefault; - searchCoord: z.ZodOptional; - searchFrom: z.ZodDefault>; - source: z.ZodOptional; - type: z.ZodDefault>; - zoom: z.ZodDefault>; - index: z.ZodDefault; - store: z.ZodDefault; -}, "strip", z.ZodTypeAny, { - api_key?: string; - cache?: boolean; - category?: string; - dst?: string; - dump?: string; - engine?: string; - env_key?: string; - filterCity?: string; - filterCountry?: string; - filterType?: string; - findEMail?: boolean; - geocode_key?: string; - google_domain?: string; - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string; - searchFrom?: string; - source?: string; - type?: string; - zoom?: number; - index?: string; - store?: string; -}, { - api_key?: string; - cache?: boolean; - category?: string; - dst?: string; - dump?: string; - engine?: string; - env_key?: string; - filterCity?: string; - filterCountry?: string; - filterType?: string; - findEMail?: boolean; - geocode_key?: string; - google_domain?: string; - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string; - searchFrom?: string; - source?: string; - type?: string; - zoom?: number; - index?: string; - store?: string; -}>; -export declare const zodSchemaEachExtras: () => z.ZodObject<{ - logLevel: z.ZodDefault; - log: z.ZodOptional; - country: z.ZodString; - area: z.ZodString; - list: z.ZodString; - cwd: z.ZodDefault>; - env: z.ZodDefault; - profile: z.ZodDefault; - migrate: z.ZodDefault; -}, "strip", z.ZodTypeAny, { - logLevel?: string; - log?: string; - country?: string; - area?: string; - list?: string; - cwd?: string; - env?: string; - profile?: string; - migrate?: boolean; -}, { - logLevel?: string; - log?: string; - country?: string; - area?: string; - list?: string; - cwd?: string; - env?: string; - profile?: string; - migrate?: boolean; -}>; -export declare const zodSchemaEach: () => z.ZodObject<{ - api_key: z.ZodOptional; - cache: z.ZodDefault; - category: z.ZodDefault>; - dst: z.ZodDefault; - dump: z.ZodOptional; - engine: z.ZodDefault; - env_key: z.ZodDefault; - filterCity: z.ZodOptional; - filterCountry: z.ZodOptional; - filterType: z.ZodOptional; - findEMail: z.ZodDefault; - geocode_key: z.ZodOptional; - google_domain: z.ZodDefault; - headless: z.ZodDefault; - language: z.ZodDefault; - limit: z.ZodDefault; - meta: z.ZodDefault; - searchCache: z.ZodDefault; - query: z.ZodDefault; - searchCoord: z.ZodOptional; - searchFrom: z.ZodDefault>; - source: z.ZodOptional; - type: z.ZodDefault>; - zoom: z.ZodDefault>; - index: z.ZodDefault; - store: z.ZodDefault; -} & { - logLevel: z.ZodDefault; - log: z.ZodOptional; - country: z.ZodString; - area: z.ZodString; - list: z.ZodString; - cwd: z.ZodDefault>; - env: z.ZodDefault; - profile: z.ZodDefault; - migrate: z.ZodDefault; -}, "strip", z.ZodTypeAny, { - api_key?: string; - cache?: boolean; - category?: string; - dst?: string; - dump?: string; - engine?: string; - env_key?: string; - filterCity?: string; - filterCountry?: string; - filterType?: string; - findEMail?: boolean; - geocode_key?: string; - google_domain?: string; - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string; - searchFrom?: string; - source?: string; - type?: string; - zoom?: number; - index?: string; - store?: string; - log?: string; - country?: string; - area?: string; - list?: string; - cwd?: string; - env?: string; - profile?: string; - migrate?: boolean; -}, { - api_key?: string; - cache?: boolean; - category?: string; - dst?: string; - dump?: string; - engine?: string; - env_key?: string; - filterCity?: string; - filterCountry?: string; - filterType?: string; - findEMail?: boolean; - geocode_key?: string; - google_domain?: string; - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string; - searchFrom?: string; - source?: string; - type?: string; - zoom?: number; - index?: string; - store?: string; - log?: string; - country?: string; - area?: string; - list?: string; - cwd?: string; - env?: string; - profile?: string; - migrate?: boolean; -}>; -export declare const yargsOptions: (yargs: CLI.Argv) => CLI.Argv; -export declare const yargsOptionsEach: (yargs: CLI.Argv) => CLI.Argv; export declare const searchVendor: (name: string, dst: string, opts: IScaleserpSearch) => Promise; export declare const defaultParamsGoogleES: (query: any, mixin: any) => any; export declare const defaultSearchParamsMapsES: (query: any, zoom: any, mixin?: {}) => { @@ -260,9 +20,8 @@ export declare const defaultSearchParamsMapsES: (query: any, zoom: any, mixin?: hl: string; }; export declare const searchVendorSA: (query: string, location: string, key: string, opts: GoogleParameters) => Promise>; -export declare const searchGoogleMap: (query: string, key: string, opts: any) => Promise; -export declare const parse: (argv: any) => any; -export declare const resolvePath: (str: string, query: any, category: any, opts: any) => string; +export declare const searchGoogleMap: (query: string, key: string, opts: IOptionsGoogleMaps) => Promise; +export declare const parse: (argv: IOptionsGoogleMaps) => IOptionsGoogleMaps; export declare const googleMaps: (opts: IOptionsGoogleMaps) => Promise; export declare const migrate: (opts: IOptionsGoogleMapsEach) => Promise; export declare const each: (opts: IOptionsGoogleMapsEach) => Promise; diff --git a/packages/search/dist-in/lib/googlemaps.js b/packages/search/dist-in/lib/googlemaps.js index cc8c889f..162210f0 100644 --- a/packages/search/dist-in/lib/googlemaps.js +++ b/packages/search/dist-in/lib/googlemaps.js @@ -1,54 +1,12 @@ import * as path from 'path'; -import { URL } from 'url'; -import { CONFIG_DEFAULT, DEFAULT_ROOTS, filesEx, pathInfo } from '@polymech/commons'; +import { CONFIG_DEFAULT, DEFAULT_ROOTS, pathInfo, filesEx } from '@polymech/commons'; +import { cleanObjectStrings } from './googlemaps-utils.js'; import { parse as parseProfile } from '@polymech/commons/profile'; import { isFile, resolve, substitute } from '@polymech/commons'; -import { toYargs } from '@polymech/commons'; -export const escapeFirstUrlSegment = (url) => { - const schemeEndIndex = url.indexOf('://') + 3; - const restOfUrl = url.slice(schemeEndIndex); - const questionMarkIndex = restOfUrl.indexOf('?'); - if (questionMarkIndex !== -1) { - const firstSegment = restOfUrl.slice(0, questionMarkIndex); - const escapedFirstSegment = encodeURIComponent(firstSegment); - return url.slice(0, schemeEndIndex) + escapedFirstSegment + restOfUrl.slice(questionMarkIndex); - } - else { - const escapedFirstSegment = encodeURIComponent(restOfUrl); - return url.slice(0, schemeEndIndex) + escapedFirstSegment; - } -}; -export const handleFs = async (path) => { - return read(path); -}; -export const schemeHandlers = { - // 'osr-ai': handleOsrAi, - 'fs': handleFs, - 'default': handleFs -}; -export const parseCustomUrl = async (url) => { - if (!url.includes('://')) { - const _path = path.resolve(resolve(url)); - if (exists(_path) && isFile(_path)) { - return read(_path, 'json'); - } - } - const parsedUrl = new URL(escapeFirstUrlSegment(url)); - let scheme = parsedUrl.protocol.replace(':', '') || 'default'; - const handler = schemeHandlers[scheme]; - let result = null; - if (handler) { - if (scheme === 'osr-ai') { - result = await handler(parsedUrl.hostname, parsedUrl.searchParams); - } - else { - result = await handler(parsedUrl.pathname); - } - } - return result || url; -}; +import { zodSchema, zodSchemaEach, yargsOptions, yargsOptionsEach, } from './googlemaps-zod.js'; +import { parseCustomUrl, resolvePath } from './googlemaps-utils.js'; +export { zodSchema, zodSchemaEach, yargsOptions, yargsOptionsEach }; import { clone } from '../options.js'; -import { z } from 'zod'; import { sync as write } from '@polymech/fs/write'; import { sync as read } from '@polymech/fs/read'; import { sync as exists } from '@polymech/fs/exists'; @@ -67,66 +25,21 @@ import { geocode_forward } from './geo.js'; import { store as getStore } from '@polymech/registry'; const MODULE_NAME = 'osr-search'; const queryExtras = ''; -const blUrls = ['bazar.preciousplastic.com']; export var SearchQueriesES; (function (SearchQueriesES) { SearchQueriesES["INJECTION"] = "inyecci\u00F3n de plastico"; })(SearchQueriesES || (SearchQueriesES = {})); -export const home = () => "41.6911354,2.1652746"; export const locationString = (coords, zoom = 13) => `@${coords},${zoom}z`; export const store = async (storePath, ns = 'osr-search') => getStore(storePath, ns); export const getStored = async (title, storePath, ns = 'osr-search') => getStore(storePath, ns).get(title); -export const zodSchema = () => z.object({ - api_key: z.string().optional().describe('API Key'), - cache: z.boolean().default(false), - category: z.string().optional().default('category'), - dst: z.string().default('${POLYMECH_ROOT}/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-10.xls'), - dump: z.string().optional(), - engine: z.string().default('google_maps'), - env_key: z.string().default('OSR-CONFIG'), - filterCity: z.string().optional(), - filterCountry: z.string().optional(), - filterType: z.string().optional(), - findEMail: z.boolean().default(false), - geocode_key: z.string().optional(), - google_domain: z.string().default('google.com'), - headless: z.boolean().default(true).describe('Headless mode'), - language: z.string().default('en'), - limit: z.number().default(5), - logLevel: z.string().default('info'), - meta: z.boolean().default(true), - searchCache: z.boolean().default(false).describe('Use search cache'), - query: z.string().default('plastichub'), - searchCoord: z.string().optional(), - searchFrom: z.string().optional().default('barcelona, spain'), - source: z.string().optional(), - type: z.string().optional().default('search'), - zoom: z.number().optional().default(13), - index: z.string().default('${OSR_ROOT}/osr-directory/meta/index.json').describe('Index file'), - store: z.string().default('${OSR_ROOT}/osr-directory/meta/index.db').describe('Index store'), -}, { description: 'IOptionsGoogleMaps' }); -export const zodSchemaEachExtras = () => z.object({ - logLevel: z.string().default('info'), - log: z.string().optional(), - country: z.string().describe('The country to search in, variable ${COUNTRY}'), - area: z.string().describe('The city to search in, variable ${AREA}'), - list: z.string().describe('List of items to process, FILE|GLOB|AI-Query, provided as ${TOWN}'), - cwd: z.string().optional().default('./').describe('the current working directory to use, otherwise . is being assumed'), - env: z.string().default(''), - profile: z.string().default('${OSR_ROOT}/osr-templates/osrl/.osrl.json'), - migrate: z.boolean().default(false), -}); -export const zodSchemaEach = () => zodSchema().merge(zodSchemaEachExtras()).describe('IOptionsGoogleMapsEach'); -export const yargsOptions = (yargs) => toYargs(yargs, zodSchema()); -export const yargsOptionsEach = (yargs) => toYargs(yargs, zodSchemaEach()); export const searchVendor = async (name, dst, opts) => { let q = name; let ret = await SearchProviders.scaleserp({ api_key: opts.api_key, - q: q + queryExtras + q: q + queryExtras, }); let urls = ret.organic_results.filter((u) => { - return !blUrls.includes(new URL(u.link).hostname); + return !opts.blacklist.includes(new URL(u.link).hostname); }); urls = urls.map((u) => u.link); dst && write(dst, urls); @@ -144,13 +57,13 @@ export const defaultParamsGoogleES = (query, mixin) => { }; export const defaultSearchParamsMapsES = (query, zoom, mixin = {}) => { return { - "engine": defaultEngine, - "type": "search", - "q": query, - "ll": locationString(home(), zoom), - "google_domain": defaultGoogleDomain, - "hl": defaultLanguage, - ...mixin + engine: defaultEngine, + type: 'search', + q: query, + ll: locationString('41.6911354,2.1652746', zoom), + google_domain: defaultGoogleDomain, + hl: defaultLanguage, + ...mixin, }; }; export const searchVendorSA = async (query, location, key, opts) => { @@ -166,6 +79,15 @@ export const searchVendorSA = async (query, location, key, opts) => { return await SearchProviders.serpApi("google", googleParams); }; export const searchGoogleMap = async (query, key, opts) => { + const roundCoords = (coords, decimals = 3) => { + const [latitude, longitude, zoom] = coords.split(',').map((part, index) => { + if (index < 2) { + return parseFloat(parseFloat(part).toFixed(decimals)); + } + return part; + }); + return `@${latitude},${longitude},${zoom}`; + }; const googleParams = { ...opts, api_key: key, @@ -188,15 +110,6 @@ export const searchGoogleMap = async (query, key, opts) => { limit: params.limit }; if (opts.searchCache && OSR_CACHE()) { - const roundCoords = (coords, decimals = 3) => { - const [latitude, longitude, zoom] = coords.split(',').map((part, index) => { - if (index < 2) { - return parseFloat(parseFloat(part).toFixed(decimals)); - } - return part; - }); - return `@${latitude},${longitude},${zoom}`; - }; cached = await get_cached_object(cache_key, MODULE_NAME); } let page = cached || await SearchProviders.serpApi(googleParams.engine, { @@ -230,22 +143,8 @@ export const searchGoogleMap = async (query, key, opts) => { } let idx = 0; //const cachedLoc = async (title: string) => getStored(title, opts.store, MODULE_NAME) - await pMap(results, async (entry) => { - idx++; - entry.position = entry.page * PAGE_SIZE + idx; - try { - if (index[entry.title] && index[entry.title].geo) { - entry.geo = index[entry.title].geo; - return; - } - return reverse(entry, opts); - } - catch (e) { - logger.error(`Error reverse geocoding ${entry.title}`); - entry.geo = REVERSE_DEFAULT; - } - }, { concurrency: 3 }); - logger.debug(`search ${query} with ${params.ll} / ${params.searchFrom} @ ${opts.zoom} : ${results.length} items`); + await enrichResults(results, index, opts); + logger.debug(`search ${query} with ${params.ll} / ${params.searchFrom} @ ${opts.zoom} | ${results.length} results before filters`); if (opts.filterCity) { results = results.filter((r) => r.geo.city.toLowerCase() === opts.filterCity.toLowerCase()); } @@ -260,11 +159,31 @@ export const searchGoogleMap = async (query, key, opts) => { } results = results.filter((r) => r.gps_coordinates); const beforeCached = results.length; - results = results.filter((r) => { + const newResults = results.filter((r) => { return index[r.title] == null || !index[r.title].geo || !index[r.title].meta; }); - logger.info(`search ${query} with ${params.ll} / ${params.searchFrom} : ${results.length} items | ${beforeCached} before cache`); - results = results.slice(0, opts.limit); + logger.info(`found ${newResults.length} new items for "${query}" from "${params.searchFrom}" | ${beforeCached} total before cache filtering`); + const processedResults = newResults.slice(0, opts.limit); + await enrichResults(processedResults, index, opts); + return results; +}; +const enrichResults = async (results, index, opts) => { + let idx = 0; + await pMap(results, async (entry) => { + idx++; + entry.position = entry.page * PAGE_SIZE + idx; + try { + if (index[entry.title] && index[entry.title].geo) { + entry.geo = index[entry.title].geo; + return; + } + return reverse(entry, opts); + } + catch (e) { + logger.error(`Error reverse geocoding ${entry.title}`); + entry.geo = REVERSE_DEFAULT; + } + }, { concurrency: opts.concurrency }); if (opts.meta) { await pMap(results, (entry) => { if (entry.meta || !entry.website || entry.rejected) { @@ -283,14 +202,14 @@ export const searchGoogleMap = async (query, key, opts) => { }, { concurrency: 1 }); } if (opts.findEMail && opts.meta) { - const emails = await pMap(results, async (entry) => { + await pMap(results, async (entry) => { if (index[entry.title] && index[entry.title].email) { entry.email = index[entry.title].email; return; } if (entry.meta && entry.website && !entry.email) { try { - //logger.debug(`searching email for ${entry.website}`) + logger.debug(`searching email for ${entry.website}`); return findEMail(SEARCH_AI_PROMPTS.GET_EMAIL, entry.website, opts, entry); } catch (e) { @@ -357,19 +276,6 @@ export const parse = (argv) => { } return opts; }; -export const resolvePath = (str, query, category, opts) => { - return path.resolve(resolve(str, false, { - QUERY: query, - FROM: opts.searchFrom ? opts.searchFrom.split(',').map((s) => s.trim()).join('/') : 'barcelona, spain', - ENGINE: opts.engine, - DOMAIN: opts.google_domain, - LANG: opts.language, - COUNTRY: opts.country, - AREA: opts.area, - CATEGORY: category || 'unknown', - ...opts.variables || {} - })); -}; export const googleMaps = async (opts) => { opts = parse(opts); if (!opts) { @@ -384,17 +290,18 @@ export const googleMaps = async (opts) => { opts.searchCoord = locationString(coords, opts.zoom); } else { - logger.error('Error geocoding', searchFrom); + logger.error(`Error geocoding "${searchFrom}"`); } } } catch (error) { - logger.error('Error geocoding', error, error.stack); + logger.error(`Error geocoding "${opts.searchFrom}"`, error, error.stack); } let ret = []; const search = async (query, category, opts) => { opts = clone(opts); opts.dst = resolvePath(path.join(opts.cwd || '', opts.dst || ''), query, category, opts); + logger.debug(`output destination --dst "${opts.dst}"`); if (opts.cache !== false && exists(opts.dst + '.json')) { const cachedPath = opts.dst + '.json'; const cached = read(cachedPath, 'json') || []; @@ -432,12 +339,35 @@ export const googleMaps = async (opts) => { }); if (opts.dst) { opts.dst = resolvePath(opts.dst, 'all', 'all', opts); + logger.debug(`final output destination --dst "${opts.dst}"`); + let existingResults = []; if (exists(opts.dst + '.json')) { - const last = (read(opts.dst + '.json', 'json') || []); - ret = [...last, ...ret]; + existingResults = read(opts.dst + '.json', 'json') || []; } - write(opts.dst + '.json', ret); - writeReport(ret, opts.dst, opts); + // Combine, deduplicate, clean, and process URLs in a single chain + const finalResults = Array.from([...existingResults, ...ret].reduce((map, obj) => { + if (obj.place_id) { + map.set(obj.place_id, obj); + } + return map; + }, new Map()).values()) + .map(cleanObjectStrings) + .map((r) => { + if (r.website && typeof r.website === 'string' && r.website.startsWith('/url?q=')) { + try { + const urlString = r.website.substring('/url?q='.length); + const decodedUrl = decodeURIComponent(urlString); + const urlParts = decodedUrl.split('&'); + r.website = urlParts[0]; + } + catch (e) { + logger.warn(`Could not parse website URL: ${r.website}`); + } + } + return r; + }); + write(opts.dst + '.json', finalResults); + writeReport(finalResults, opts.dst, opts); } if (opts.index) { let index = read(opts.index, 'json') || {}; @@ -473,6 +403,10 @@ export const migrate = async (opts) => { export const each = async (opts) => { logger.settings.minLevel = opts.logLevel || 2; let items = []; + if (!opts.list) { + logger.error('No list provided for each command'); + return; + } let listPath = path.resolve(resolve(opts.list)); const profile = parseProfile(opts.profile, { variables: { @@ -525,4 +459,4 @@ export const each = async (opts) => { opts.log && write(path.resolve(resolve(opts.log)), all); return all; }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlbWFwcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvZ29vZ2xlbWFwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUM1QixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBR3pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBWSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUU5RixPQUFPLEVBQUMsS0FBSyxJQUFJLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBRWhFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRS9ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQVMzQyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFO0lBQ3pELE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDNUMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRWpELElBQUksaUJBQWlCLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzQixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQzNELE1BQU0sbUJBQW1CLEdBQUcsa0JBQWtCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDN0QsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsR0FBRyxtQkFBbUIsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDbkcsQ0FBQztTQUFNLENBQUM7UUFDSixNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFELE9BQU8sR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLEdBQUcsbUJBQW1CLENBQUM7SUFDOUQsQ0FBQztBQUNMLENBQUMsQ0FBQTtBQUdELE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxLQUFLLEVBQUUsSUFBWSxFQUE0QixFQUFFO0lBQ3JFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQ3JCLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBdUY7SUFDOUcsNEJBQTRCO0lBQ3hCLElBQUksRUFBRSxRQUFRO0lBQ2QsU0FBUyxFQUFFLFFBQVE7Q0FDdEIsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxLQUFLLEVBQUUsR0FBVyxFQUE0QixFQUFFO0lBQzFFLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUN4QyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDOUIsQ0FBQztJQUNMLENBQUM7SUFDRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQ3JELElBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxTQUFTLENBQUE7SUFDN0QsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3RDLElBQUksTUFBTSxHQUFvQixJQUFJLENBQUE7SUFDbEMsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNWLElBQUksTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUN0RSxDQUFDO2FBQU0sQ0FBQztZQUNKLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDOUMsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLE1BQU0sSUFBSSxHQUFHLENBQUE7QUFDeEIsQ0FBQyxDQUFBO0FBRUwsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUVyQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXZCLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDbEQsT0FBTyxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsSUFBSSxJQUFJLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3ZFLE9BQU8sSUFBSSxNQUFNLE9BQU8sQ0FBQTtBQUN4QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUMxRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFN0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUUxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3ZJLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFHMUMsT0FBTyxFQUFFLEtBQUssSUFBSSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUV0RCxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUE7QUFDaEMsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFBO0FBRXRCLE1BQU0sTUFBTSxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUM1QyxNQUFNLENBQU4sSUFBWSxlQUF1RDtBQUFuRSxXQUFZLGVBQWU7SUFBRywyREFBbUMsQ0FBQTtBQUFDLENBQUMsRUFBdkQsZUFBZSxLQUFmLGVBQWUsUUFBd0M7QUFDbkUsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLHNCQUFzQixDQUFBO0FBQ2hELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLE1BQWMsRUFBRSxPQUFlLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxNQUFNLElBQUksSUFBSSxHQUFHLENBQUE7QUFFMUYsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLEtBQUssRUFBRSxTQUFpQixFQUFFLEtBQWEsWUFBWSxFQUFFLEVBQUUsQ0FDeEUsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQVEsQ0FBQTtBQUVsQyxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsS0FBSyxFQUFFLEtBQVksRUFBRSxTQUFpQixFQUFFLEtBQWEsWUFBWSxFQUFFLEVBQUUsQ0FDMUYsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7QUFHdEMsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDcEMsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO0lBQ2xELEtBQUssRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUNqQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7SUFDbkQsR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsb0VBQW9FLENBQUM7SUFDN0YsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDM0IsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO0lBQ3pDLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztJQUN6QyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNwQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDckMsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDbEMsYUFBYSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO0lBQy9DLFFBQVEsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7SUFDN0QsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ2xDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM1QixRQUFRLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDcEMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQy9CLFdBQVcsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztJQUNwRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7SUFDdkMsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDbEMsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFDN0QsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQzdDLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztJQUN2QyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUM7SUFDN0YsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMseUNBQXlDLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO0NBQy9GLEVBQUUsRUFBRSxXQUFXLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFBO0FBRXpDLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDOUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQ3BDLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzFCLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLCtDQUErQyxDQUFDO0lBQzdFLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLHlDQUF5QyxDQUFDO0lBQ3BFLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLG1FQUFtRSxDQUFDO0lBQzlGLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxvRUFBb0UsQ0FBQztJQUN2SCxHQUFHLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7SUFDM0IsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsMkNBQTJDLENBQUM7SUFDeEUsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0NBQ3RDLENBQUMsQ0FBQTtBQUVGLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFBO0FBQzlHLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQVksRUFBRSxTQUFTLEVBQVMsQ0FBQyxDQUFBO0FBQzFGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBWSxFQUFFLGFBQWEsRUFBUyxDQUFDLENBQUE7QUFFbEcsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxJQUFZLEVBQUUsR0FBVyxFQUFFLElBQXNCLEVBQUUsRUFBRTtJQUVwRixJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDYixJQUFJLEdBQUcsR0FBRyxNQUFNLGVBQWUsQ0FBQyxTQUFTLENBQUM7UUFDdEMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1FBQ3JCLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVztLQUNyQixDQUFDLENBQUE7SUFFRixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNyRCxDQUFDLENBQUMsQ0FBQTtJQUVGLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFRLENBQUE7SUFDckMsR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDdkIsT0FBTyxJQUFJLENBQUE7QUFDZixDQUFDLENBQUE7QUFDRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRTtJQUNsRCxPQUFPO1FBQ0gsUUFBUSxFQUFFLG1CQUFtQjtRQUM3QixFQUFFLEVBQUUsZUFBZTtRQUNuQixFQUFFLEVBQUUsZUFBZTtRQUNuQixhQUFhLEVBQUUsbUJBQW1CO1FBQ2xDLENBQUMsRUFBRSxLQUFLO1FBQ1IsR0FBRyxLQUFLO0tBQ1gsQ0FBQTtBQUNMLENBQUMsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEdBQUcsRUFBRSxFQUFFLEVBQUU7SUFDakUsT0FBTztRQUNILFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLEdBQUcsRUFBRSxLQUFLO1FBQ1YsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUM7UUFDbEMsZUFBZSxFQUFFLG1CQUFtQjtRQUNwQyxJQUFJLEVBQUUsZUFBZTtRQUNyQixHQUFHLEtBQUs7S0FDWCxDQUFBO0FBQ0wsQ0FBQyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLEtBQUssRUFDL0IsS0FBYSxFQUNiLFFBQWdCLEVBQ2hCLEdBQVcsRUFDWCxJQUFzQixFQUN4QixFQUFFO0lBRUEsTUFBTSxZQUFZLEdBQUc7UUFDakIsT0FBTyxFQUFFLEdBQUc7UUFDWixRQUFRLEVBQUUsUUFBUTtRQUNsQixFQUFFLEVBQUUsSUFBSTtRQUNSLEVBQUUsRUFBRSxJQUFJO1FBQ1IsYUFBYSxFQUFFLFlBQVk7UUFDM0IsR0FBRyxJQUFJO1FBQ1AsQ0FBQyxFQUFFLEtBQUssR0FBRyxXQUFXO0tBQ3pCLENBQUE7SUFDRCxPQUFPLE1BQU0sZUFBZSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsWUFBZ0MsQ0FBQyxDQUFBO0FBQ3BGLENBQUMsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxLQUFLLEVBQ2hDLEtBQWEsRUFDYixHQUFXLEVBQ1gsSUFBUyxFQUNYLEVBQUU7SUFDQSxNQUFNLFlBQVksR0FBRztRQUNqQixHQUFHLElBQUk7UUFDUCxPQUFPLEVBQUUsR0FBRztRQUNaLENBQUMsRUFBRSxLQUFLLEdBQUcsV0FBVztRQUN0QixFQUFFLEVBQUUsSUFBSSxDQUFDLFdBQVc7S0FDQyxDQUFBO0lBRXpCLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQTtJQUNoQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUE7SUFDZixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUNuRSxNQUFNLE1BQU0sR0FBUSxZQUFZLENBQUE7SUFDaEMsSUFBSSxNQUFZLENBQUE7SUFDaEIsTUFBTSxTQUFTLEdBQUc7UUFDZCxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07UUFDckIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1FBQ2pCLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNYLGFBQWEsRUFBRSxNQUFNLENBQUMsYUFBYTtRQUNuQyxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7UUFDYixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7UUFDakIsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztLQUN0QixDQUFBO0lBRUQsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFDbEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFjLEVBQUUsV0FBbUIsQ0FBQyxFQUFVLEVBQUU7WUFDakUsTUFBTSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ3RFLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUNaLE9BQU8sVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQTtnQkFDekQsQ0FBQztnQkFDRCxPQUFPLElBQUksQ0FBQTtZQUNmLENBQUMsQ0FBQyxDQUFBO1lBQ0YsT0FBTyxJQUFJLFFBQVEsSUFBSSxTQUFTLElBQUksSUFBSSxFQUFFLENBQUM7UUFDL0MsQ0FBQyxDQUFBO1FBQ0QsTUFBTSxHQUFHLE1BQU0saUJBQWlCLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFBO0lBQzVELENBQUM7SUFFRCxJQUFJLElBQUksR0FBRyxNQUFNLElBQUksTUFBTSxlQUFlLENBQUMsT0FBTyxDQUFFLFlBQW9CLENBQUMsTUFBTSxFQUFFO1FBQzdFLEdBQUcsWUFBWTtLQUNsQixDQUFDLENBQUE7SUFHRixPQUFPLElBQUksSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUM3QixDQUFDLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQTtRQUNwQixDQUFDLENBQUMsQ0FBQTtRQUNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDcEMsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBSztRQUN2QyxPQUFPLEVBQUUsQ0FBQTtRQUNULElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFBO0lBQzlCLENBQUM7SUFFRCxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1FBQzdELElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDN0MsQ0FBQztJQUVELE9BQU8sSUFBSSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQzdCLENBQUMsQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFBO1FBQ3BCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNwQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEtBQUs7WUFBRSxNQUFLO1FBQ3ZDLE9BQU8sRUFBRSxDQUFBO1FBQ1QsSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUE7SUFDOUIsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxTQUFTLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdEQsQ0FBQztJQUVELElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQTtJQUNYLHNGQUFzRjtJQUV0RixNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQVUsRUFBRSxFQUFFO1FBQ3JDLEdBQUcsRUFBRSxDQUFBO1FBQ0wsS0FBSyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUE7UUFDN0MsSUFBSSxDQUFDO1lBQ0QsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQy9DLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUE7Z0JBQ2xDLE9BQU07WUFDVixDQUFDO1lBQ0QsT0FBTyxPQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQy9CLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7WUFDdEQsS0FBSyxDQUFDLEdBQUcsR0FBRyxlQUFlLENBQUE7UUFDL0IsQ0FBQztJQUNMLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRXRCLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLFNBQVMsTUFBTSxDQUFDLEVBQUUsTUFBTSxNQUFNLENBQUMsVUFBVSxNQUFNLElBQUksQ0FBQyxJQUFJLE1BQU0sT0FBTyxDQUFDLE1BQU0sUUFBUSxDQUFDLENBQUE7SUFFakgsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtJQUMvRixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtJQUN6RyxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtJQUN6RyxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3JFLENBQUM7SUFFRCxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQ2xELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUE7SUFDbkMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUMzQixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUNoRixDQUFDLENBQUMsQ0FBQTtJQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVMsTUFBTSxDQUFDLEVBQUUsTUFBTSxNQUFNLENBQUMsVUFBVSxNQUFNLE9BQU8sQ0FBQyxNQUFNLFlBQVksWUFBWSxlQUFlLENBQUMsQ0FBQTtJQUNoSSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3RDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1osTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDL0IsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2pELE9BQU07WUFDVixDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNELElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNoRCxLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFBO29CQUNwQyxPQUFNO2dCQUNWLENBQUM7Z0JBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFBO1lBQzVCLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNULGtCQUFrQjtZQUN0QixDQUFDO1FBQ0wsQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFVLEVBQUUsRUFBRTtZQUNwRCxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDakQsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQTtnQkFDdEMsT0FBTTtZQUNWLENBQUM7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxDQUFDO29CQUNELHNEQUFzRDtvQkFDdEQsT0FBTyxTQUFTLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFBO2dCQUM3RSxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1QsTUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7Z0JBQzlELENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDMUIsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFBO0FBQ2xCLENBQUMsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLElBQVMsRUFBTyxFQUFFO0lBQ3BDLE1BQU0sSUFBSSxHQUFRLElBQUksQ0FBQTtJQUN0QixNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBZSxJQUFJLENBQUMsQ0FBQTtJQUNwRCxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBUSxDQUFBO0lBQ2xELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUMvQixPQUFNO0lBQ1YsQ0FBQztJQUNELElBQUksTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUE7UUFDOUMsT0FBTTtJQUNWLENBQUM7SUFDRCxNQUFNLElBQUksR0FBRztRQUNULEtBQUssRUFBRSxJQUFJLENBQUMsS0FBZTtRQUMzQixHQUFHLHlCQUF5QixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQztRQUNuRCxHQUFHLElBQUk7UUFDUCxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUc7UUFDM0MsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHO1FBQ3BELE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtRQUNyQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO1FBQ3RDLE9BQU8sRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRTtLQUNoQyxDQUFBO0lBRVIsSUFBSSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUN4QixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQzNDLENBQUM7YUFBTSxDQUFDO1lBQ0osTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksQ0FBQyxNQUFNLGdCQUFnQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQTtZQUNyRSxPQUFNO1FBQ1YsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5QixNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUE7UUFDdkMsT0FBTTtJQUNWLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0lBQ3pELENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0lBQ3pELENBQUM7SUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUE7UUFDaEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDN0MsQ0FBQztJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFBO1FBQzFELE9BQU07SUFDVixDQUFDO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtRQUNsQyxPQUFPO0lBQ1gsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFBO0FBQ2YsQ0FBQyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBVyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBUyxFQUFFLEVBQUU7SUFDbkUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUNsQztRQUNJLEtBQUssRUFBRSxLQUFLO1FBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0I7UUFDdEcsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1FBQ25CLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYTtRQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVE7UUFDbkIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1FBQ3JCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtRQUNmLFFBQVEsRUFBRSxRQUFRLElBQUksU0FBUztRQUMvQixHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRTtLQUMxQixDQUFDLENBQUMsQ0FBQTtBQUNYLENBQUMsQ0FBQTtBQUNELE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsSUFBd0IsRUFBRSxFQUFFO0lBQ3pELElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbEIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUNyQyxPQUFNO0lBQ1YsQ0FBQztJQUNELElBQUksQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRyxJQUFZLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDOUUsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0RCxNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQ2xFLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUN4RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxVQUFVLENBQUMsQ0FBQTtZQUMvQyxDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3ZELENBQUM7SUFFRCxJQUFJLEdBQUcsR0FBVSxFQUFFLENBQUE7SUFDbkIsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLEtBQWEsRUFBRSxRQUFRLEVBQUUsSUFBUyxFQUFFLEVBQUU7UUFDeEQsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNsQixJQUFJLENBQUMsR0FBRyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUN4RixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDckQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUE7WUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQVEsSUFBSSxFQUFFLENBQUE7WUFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLElBQUksQ0FBQyxLQUFLLFNBQVMsSUFBSSxDQUFDLFVBQVUsd0JBQXdCLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1lBQ3BHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUE7WUFDekIsT0FBTyxNQUFNLENBQUE7UUFDakIsQ0FBQztRQUNELElBQUksQ0FBQztZQUNELE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxJQUFJLENBQUMsS0FBSyxTQUFTLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFBO1lBQy9ELE1BQU0sRUFBRSxHQUFHLE1BQU0sZUFBZSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFBO1lBQ2xFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2pDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQTtnQkFDN0IsV0FBVyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFBO2dCQUMvQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDbEMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxHQUFHLGVBQWUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO2dCQUM3RSwwREFBMEQ7WUFDOUQsQ0FBQztZQUNELEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7WUFDckIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLElBQUksQ0FBQyxLQUFLLFNBQVMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUE7WUFDL0QsT0FBTyxHQUFHLENBQUE7UUFDZCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNiLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLEdBQUcsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3JGLENBQUM7SUFDTCxDQUFDLENBQUE7SUFDRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQU0sRUFBRSxFQUFFO1FBQ3hELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFNLEVBQUUsRUFBRTtZQUNuQyxPQUFPLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQzdCLENBQUMsRUFBRTtZQUNDLFdBQVcsRUFBRSxDQUFDO1NBQ2pCLENBQUMsQ0FBQTtJQUNOLENBQUMsRUFBRTtRQUNDLFdBQVcsRUFBRSxDQUFDO0tBQ2pCLENBQUMsQ0FBQTtJQUVGLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1gsSUFBSSxDQUFDLEdBQUcsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ3BELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sRUFBRSxNQUFNLENBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQTtZQUM1RCxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFBO1FBQzNCLENBQUM7UUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDOUIsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFBO0lBQ3BDLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBUSxJQUFJLEVBQUUsQ0FBQTtRQUNqRCxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNsQixLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUN0QixDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUE7UUFDRixLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUM1QixDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUE7QUFDZCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLElBQTRCLEVBQUUsRUFBRTtJQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ2pDLE9BQU07SUFDVixDQUFDO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtRQUNqQyxPQUFNO0lBQ1YsQ0FBQztJQUNELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBUSxJQUFJLEVBQUUsQ0FBQTtJQUNqRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3JDLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDbkQsQ0FBQztJQUNELE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQTtJQUN2QixJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNsQyxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQWMsRUFBRSxFQUFFO1FBQ3BELGdDQUFnQztJQUNuQyxDQUFDLENBQUMsQ0FBQTtJQUVGLE9BQU8sR0FBRyxDQUFBO0FBQ2QsQ0FBQyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxJQUE0QixFQUFFLEVBQUU7SUFDdkQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQWUsSUFBSSxDQUFDLENBQUE7SUFDcEQsSUFBSSxLQUFLLEdBQWEsRUFBRSxDQUFBO0lBQ3hCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBRS9DLE1BQU0sT0FBTyxHQUFhLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUMvQztRQUNJLFNBQVMsRUFBRTtZQUNQLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixHQUFHLGFBQWE7U0FDbkIsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFO0tBQzNCLEVBQUUsRUFBQyxHQUFHLEVBQUMsSUFBSSxDQUFDLEdBQUcsRUFBQyxDQUFDLENBQUE7SUFFdEIsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNsQixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixNQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ3JDLE9BQU07SUFDVixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN4QixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxjQUFjLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFBO0lBRWxGLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDaEIsS0FBSyxHQUFHLElBQUksQ0FBQTtJQUNoQixDQUFDO1NBQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3RGLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUM5QyxDQUFDO1NBQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JDLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQU8sSUFBSSxFQUFFLENBQUE7SUFDbkYsQ0FBQztJQUNELElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUE7UUFDekQsT0FBTTtJQUNWLENBQUM7SUFDRCxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3RDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUMsQ0FBQTtJQUNyQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNyRSxNQUFNLEdBQUcsR0FBVSxNQUFNLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtRQUN6QyxNQUFNLFNBQVMsR0FBRztZQUNkLEdBQUc7WUFDSCxJQUFJLEVBQUUsR0FBRztZQUNULEdBQUcsT0FBTyxDQUFDLFNBQVM7U0FDdkIsQ0FBQTtRQUNELE1BQU0sVUFBVSxHQUFHO1lBQ2YsR0FBRyxJQUFJO1lBQ1AsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUM7WUFDL0MsR0FBRyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUM7WUFDM0MsVUFBVSxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUM7WUFDekQsU0FBUztTQUNaLENBQUE7UUFDRCxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDbEMsT0FBTyxHQUFHLENBQUE7SUFDZCxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUN0QixJQUFJLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUN2RCxPQUFPLEdBQUcsQ0FBQTtBQUNkLENBQUMsQ0FBQSJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlbWFwcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvZ29vZ2xlbWFwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUU1QixPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBWSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDOUYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFMUQsT0FBTyxFQUFDLEtBQUssSUFBSSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUVoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUUvRCxPQUFPLEVBQ0gsU0FBUyxFQUNULGFBQWEsRUFDYixZQUFZLEVBQ1osZ0JBQWdCLEdBR25CLE1BQU0scUJBQXFCLENBQUE7QUFDNUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUNuRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQThDLENBQUE7QUFFL0csT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUVyQyxPQUFPLEVBQUUsSUFBSSxJQUFJLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDaEQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUN2RSxPQUFPLElBQUksTUFBTSxPQUFPLENBQUE7QUFDeEIsT0FBTyxFQUFFLGlCQUFpQixFQUFF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SyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDO1lBQy9DLEdBQUcsRUFBRSxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDO1lBQzNDLFVBQVUsRUFBRSxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDO1lBQ3pELFNBQVM7U0FDWixDQUFBO1FBQ0QsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ2xDLE9BQU8sR0FBRyxDQUFBO0lBQ2QsQ0FBQyxFQUNELEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUNyQixDQUFBO0lBQ0QsSUFBSSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDdkQsT0FBTyxHQUFHLENBQUE7QUFDZCxDQUFDLENBQUEifQ== \ No newline at end of file diff --git a/packages/search/dist-in/lib/index.d.ts b/packages/search/dist-in/lib/index.d.ts index d7ff6524..5ebda1b3 100644 --- a/packages/search/dist-in/lib/index.d.ts +++ b/packages/search/dist-in/lib/index.d.ts @@ -1,6 +1,5 @@ export * from './types.js'; export * from './googlemaps.js'; -export * from './types-googlemaps.js'; import { getJson as searchSerpAPI } from "serpapi"; export declare const SearchProviders: { scaleserp: (params: any) => Promise; diff --git a/packages/search/dist-in/lib/index.js b/packages/search/dist-in/lib/index.js index fefb8bf9..b66d9902 100644 --- a/packages/search/dist-in/lib/index.js +++ b/packages/search/dist-in/lib/index.js @@ -1,6 +1,5 @@ export * from './types.js'; export * from './googlemaps.js'; -export * from './types-googlemaps.js'; import { generate_interfaces } from '@polymech/commons'; import { getJson as searchSerpAPI } from "serpapi"; import { search as searchScaleserp } from './scalesep.js'; @@ -22,4 +21,4 @@ export const types = () => generate_interfaces([ zodSchemaGoogleMaps(), zodSchemaEach(), ], 'src/lib/types-googlemaps.ts'); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsWUFBWSxDQUFBO0FBQzFCLGNBQWMsaUJBQWlCLENBQUE7QUFDL0IsY0FBYyx1QkFBdUIsQ0FBQTtBQUNyQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsT0FBTyxJQUFJLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsTUFBTSxJQUFJLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN6RCxPQUFPLEVBQUUsU0FBUyxJQUFJLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBRWpGLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRztJQUMzQixTQUFTLEVBQUUsZUFBZTtJQUMxQixPQUFPLEVBQUUsYUFBYTtDQUN6QixDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBUyxFQUFFLEVBQUU7SUFDdEMsT0FBTztRQUNILEdBQUcsSUFBSTtRQUNQLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLE9BQU8sRUFBRSxRQUFRO1FBQ2pCLE9BQU8sRUFBRSxRQUFRO1FBQ2pCLFdBQVcsRUFBRSxRQUFRO0tBQ3hCLENBQUE7QUFDTCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsR0FBRyxFQUFFLENBQUMsbUJBQW1CLENBQUM7SUFDM0MsbUJBQW1CLEVBQVM7SUFDNUIsYUFBYSxFQUFTO0NBQ3pCLEVBQUUsNkJBQTZCLENBQUMsQ0FBQSJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsWUFBWSxDQUFBO0FBQzFCLGNBQWMsaUJBQWlCLENBQUE7QUFDL0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdkQsT0FBTyxFQUFFLE9BQU8sSUFBSSxhQUFhLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDbEQsT0FBTyxFQUFFLE1BQU0sSUFBSSxlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDekQsT0FBTyxFQUFFLFNBQVMsSUFBSSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUVqRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUc7SUFDM0IsU0FBUyxFQUFFLGVBQWU7SUFDMUIsT0FBTyxFQUFFLGFBQWE7Q0FDekIsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxDQUFDLElBQVMsRUFBRSxFQUFFO0lBQ3RDLE9BQU87UUFDSCxHQUFHLElBQUk7UUFDUCxNQUFNLEVBQUUsUUFBUTtRQUNoQixPQUFPLEVBQUUsUUFBUTtRQUNqQixPQUFPLEVBQUUsUUFBUTtRQUNqQixXQUFXLEVBQUUsUUFBUTtLQUN4QixDQUFBO0FBQ0wsQ0FBQyxDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLEdBQUcsRUFBRSxDQUFDLG1CQUFtQixDQUFDO0lBQzNDLG1CQUFtQixFQUFTO0lBQzVCLGFBQWEsRUFBUztDQUN6QixFQUFFLDZCQUE2QixDQUFDLENBQUEifQ== \ No newline at end of file diff --git a/packages/search/dist-in/lib/map_types.d.ts b/packages/search/dist-in/lib/map_types.d.ts index 9be6d513..8522e3c5 100644 --- a/packages/search/dist-in/lib/map_types.d.ts +++ b/packages/search/dist-in/lib/map_types.d.ts @@ -1,4 +1,3 @@ -import { IGeo } from '@polymech/commons/types'; export interface SearchMetadata { id: string; status: string; @@ -26,41 +25,10 @@ export interface OperatingHours { miércoles: string; jueves: string; } -export interface LocalResult { - position: number; - title: string; - place_id: string; - data_id: string; - data_cid: string; - reviews_link: string; - photos_link: string; - gps_coordinates: GpsCoordinates; - place_id_search: string; - provider_id: string; - rating: number; - reviews: number; - type: string; - types: string[]; - address: string; - open_state: string; - hours: string; - operating_hours: OperatingHours; - phone: string; - website: string; - email: string; - emails: string[]; - thumbnail: string; - meta: any; - links?: string[]; - allLinks?: string[]; - instagram?: string; - facebook?: string; - youtube?: string; - linkedin?: string; - twitter?: string; - geo?: IGeo; - rejected?: boolean; -} +export type LocalResult = { + [key: string]: any; + filterType?: string; +}; export interface SearchParameters { engine: string; type: string; diff --git a/packages/search/dist-in/lib/types.d.ts b/packages/search/dist-in/lib/types.d.ts index 0d4fc7d4..e060051c 100644 --- a/packages/search/dist-in/lib/types.d.ts +++ b/packages/search/dist-in/lib/types.d.ts @@ -141,4 +141,5 @@ export interface IScaleserpResponse { export interface IScaleserpSearch { api_key: string; q: string; + blacklist?: string[]; } diff --git a/packages/search/src/commands/options-zod.ts b/packages/search/src/commands/options-zod.ts index fba9422f..b7d517b7 100644 --- a/packages/search/src/commands/options-zod.ts +++ b/packages/search/src/commands/options-zod.ts @@ -6,7 +6,7 @@ export const defaultOptionsSchema = z.object({ cache: z.boolean().default(true), category: z.string().optional(), debug: z.boolean().default(false), - dst: z.string().default('${POLYMECH_ROOT}/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-10.xls'), + dst: z.string().default('./test/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-10.xls'), dump: z.string().optional(), engine: z.string().default('google'), env_key: z.string().default('OSR-CONFIG'), diff --git a/packages/search/src/commands/options.ts b/packages/search/src/commands/options.ts index 19870fc4..ed225fc2 100644 --- a/packages/search/src/commands/options.ts +++ b/packages/search/src/commands/options.ts @@ -44,7 +44,7 @@ export const defaultOptions = (yargs: CLI.Argv) => { default: 50 }).option('dst', { description: 'dst output path, supports XLS|CSV|HTML', - default: '${POLYMECH_ROOT}/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-${MM}.xls' + default: './test/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-${MM}.xls' }).option('filterCountry', { description: ' by this country', }).option('filterCity', { diff --git a/packages/search/src/lib/googlemaps.ts b/packages/search/src/lib/googlemaps.ts index e6628819..7efe4a86 100644 --- a/packages/search/src/lib/googlemaps.ts +++ b/packages/search/src/lib/googlemaps.ts @@ -1,71 +1,24 @@ import * as path from 'path' -import { URL } from 'url' -import * as CLI from 'yargs' -import { CONFIG_DEFAULT, DEFAULT_ROOTS, filesEx, IProfile, pathInfo } from '@polymech/commons' +import { CONFIG_DEFAULT, DEFAULT_ROOTS, IProfile, pathInfo, filesEx } from '@polymech/commons' +import { cleanObjectStrings } from './googlemaps-utils.js' import {parse as parseProfile } from '@polymech/commons/profile' import { isFile, resolve, substitute } from '@polymech/commons' -import { toYargs } from '@polymech/commons' - -export type ParsedURL = { - scheme: string - host?: string - path?: string - query?: Record - fragment?: string -} -export const escapeFirstUrlSegment = (url: string): string => { - const schemeEndIndex = url.indexOf('://') + 3; - const restOfUrl = url.slice(schemeEndIndex); - const questionMarkIndex = restOfUrl.indexOf('?'); - - if (questionMarkIndex !== -1) { - const firstSegment = restOfUrl.slice(0, questionMarkIndex); - const escapedFirstSegment = encodeURIComponent(firstSegment); - return url.slice(0, schemeEndIndex) + escapedFirstSegment + restOfUrl.slice(questionMarkIndex); - } else { - const escapedFirstSegment = encodeURIComponent(restOfUrl); - return url.slice(0, schemeEndIndex) + escapedFirstSegment; - } -} - - -export const handleFs = async (path: string): Promise => { - return read(path) -} - -export const schemeHandlers: Record Promise> = { - // 'osr-ai': handleOsrAi, - 'fs': handleFs, - 'default': handleFs - } - export const parseCustomUrl = async (url: string): Promise => { - if (!url.includes('://')) { - const _path = path.resolve(resolve(url)) - if (exists(_path) && isFile(_path)) { - return read(_path, 'json') - } - } - const parsedUrl = new URL(escapeFirstUrlSegment(url)) - let scheme = parsedUrl.protocol.replace(':', '') || 'default' - const handler = schemeHandlers[scheme] - let result: string | object = null - if (handler) { - if (scheme === 'osr-ai') { - result = await handler(parsedUrl.hostname, parsedUrl.searchParams) - } else { - result = await handler(parsedUrl.pathname) - } - } - return result || url - } +import { + zodSchema, + zodSchemaEach, + yargsOptions, + yargsOptionsEach, + IOptionsGoogleMaps, + IOptionsGoogleMapsEach, +} from './googlemaps-zod.js' +import { parseCustomUrl, resolvePath } from './googlemaps-utils.js' +export { zodSchema, zodSchemaEach, yargsOptions, yargsOptionsEach, IOptionsGoogleMaps, IOptionsGoogleMapsEach } import { clone } from '../options.js' - -import { z } from 'zod' import type { GoogleMapsParameters, GoogleParameters } from "serpapi" import { sync as write } from '@polymech/fs/write' import { sync as read } from '@polymech/fs/read' @@ -82,7 +35,6 @@ import { findEMail } from './email.js' import { defaultEngine, defaultFromLocation, defaultGoogleDomain, defaultLanguage, PAGE_SIZE, SEARCH_AI_PROMPTS } from './constants.js' import { meta } from './html.js' import { reverse, REVERSE_DEFAULT } from './geo.js' -import { IOptionsGoogleMaps, IOptionsGoogleMapsEach } from './types-googlemaps.js' import { writeReport } from '../lib/report_map.js' import { geocode_forward } from './geo.js' import { LocalResult } from './map_types.js' @@ -92,74 +44,25 @@ import { store as getStore } from '@polymech/registry' const MODULE_NAME = 'osr-search' const queryExtras = '' -const blUrls = ['bazar.preciousplastic.com'] -export enum SearchQueriesES { INJECTION = "inyección de plastico" } -export const home = () => "41.6911354,2.1652746" +export enum SearchQueriesES { + INJECTION = 'inyección de plastico', +} export const locationString = (coords: string, zoom: number = 13) => `@${coords},${zoom}z` -export const store = async (storePath: string, ns: string = 'osr-search') => - getStore(storePath, ns) as any +export const store = async (storePath: string, ns: string = 'osr-search') => getStore(storePath, ns) as any -export const getStored = async (title:string, storePath: string, ns: string = 'osr-search') => +export const getStored = async (title: string, storePath: string, ns: string = 'osr-search') => getStore(storePath, ns).get(title) - -export const zodSchema = () => z.object({ - api_key: z.string().optional().describe('API Key'), - cache: z.boolean().default(false), - category: z.string().optional().default('category'), - dst: z.string().default('${POLYMECH_ROOT}/campaign/maps/${FROM}/${CATEGORY}/${QUERY}-10.xls'), - dump: z.string().optional(), - engine: z.string().default('google_maps'), - env_key: z.string().default('OSR-CONFIG'), - filterCity: z.string().optional(), - filterCountry: z.string().optional(), - filterType: z.string().optional(), - findEMail: z.boolean().default(false), - geocode_key: z.string().optional(), - google_domain: z.string().default('google.com'), - headless: z.boolean().default(true).describe('Headless mode'), - language: z.string().default('en'), - limit: z.number().default(5), - logLevel: z.string().default('info'), - meta: z.boolean().default(true), - searchCache: z.boolean().default(false).describe('Use search cache'), - query: z.string().default('plastichub'), - searchCoord: z.string().optional(), - searchFrom: z.string().optional().default('barcelona, spain'), - source: z.string().optional(), - type: z.string().optional().default('search'), - zoom: z.number().optional().default(13), - index: z.string().default('${OSR_ROOT}/osr-directory/meta/index.json').describe('Index file'), - store: z.string().default('${OSR_ROOT}/osr-directory/meta/index.db').describe('Index store'), -}, { description: 'IOptionsGoogleMaps' }) - -export const zodSchemaEachExtras = () => z.object({ - logLevel: z.string().default('info'), - log: z.string().optional(), - country: z.string().describe('The country to search in, variable ${COUNTRY}'), - area: z.string().describe('The city to search in, variable ${AREA}'), - list: z.string().describe('List of items to process, FILE|GLOB|AI-Query, provided as ${TOWN}'), - cwd: z.string().optional().default('./').describe('the current working directory to use, otherwise . is being assumed'), - env: z.string().default(''), - profile: z.string().default('${OSR_ROOT}/osr-templates/osrl/.osrl.json'), - migrate: z.boolean().default(false), -}) - -export const zodSchemaEach = () => zodSchema().merge(zodSchemaEachExtras()).describe('IOptionsGoogleMapsEach') -export const yargsOptions = (yargs: CLI.Argv) => toYargs(yargs as any, zodSchema() as any) -export const yargsOptionsEach = (yargs: CLI.Argv) => toYargs(yargs as any, zodSchemaEach() as any) - export const searchVendor = async (name: string, dst: string, opts: IScaleserpSearch) => { - - let q = name; + let q = name let ret = await SearchProviders.scaleserp({ api_key: opts.api_key, - q: q + queryExtras + q: q + queryExtras, }) let urls = ret.organic_results.filter((u) => { - return !blUrls.includes(new URL(u.link).hostname) + return !opts.blacklist.includes(new URL(u.link).hostname) }) urls = urls.map((u) => u.link) as any @@ -178,13 +81,13 @@ export const defaultParamsGoogleES = (query, mixin) => { } export const defaultSearchParamsMapsES = (query, zoom, mixin = {}) => { return { - "engine": defaultEngine, - "type": "search", - "q": query, - "ll": locationString(home(), zoom), - "google_domain": defaultGoogleDomain, - "hl": defaultLanguage, - ...mixin + engine: defaultEngine, + type: 'search', + q: query, + ll: locationString('41.6911354,2.1652746', zoom), + google_domain: defaultGoogleDomain, + hl: defaultLanguage, + ...mixin, } } export const searchVendorSA = async ( @@ -208,8 +111,18 @@ export const searchVendorSA = async ( export const searchGoogleMap = async ( query: string, key: string, - opts: any + opts: IOptionsGoogleMaps, ) => { + const roundCoords = (coords: string, decimals: number = 3): string => { + const [latitude, longitude, zoom] = coords.split(',').map((part, index) => { + if (index < 2) { + return parseFloat(parseFloat(part).toFixed(decimals)) + } + return part + }) + return `@${latitude},${longitude},${zoom}`; + } + const googleParams = { ...opts, api_key: key, @@ -217,9 +130,9 @@ export const searchGoogleMap = async ( ll: opts.searchCoord } as GoogleMapsParameters - let results = [] + let results: LocalResult[] = [] let pageIdx = 0 - let index = opts.index ? read(opts.index, 'json') as any || {} : {} + let index = opts.index ? (read(opts.index, 'json') as any) || {} : {} const params: any = googleParams let cached: null const cache_key = { @@ -234,15 +147,6 @@ export const searchGoogleMap = async ( } if (opts.searchCache && OSR_CACHE()) { - const roundCoords = (coords: string, decimals: number = 3): string => { - const [latitude, longitude, zoom] = coords.split(',').map((part, index) => { - if (index < 2) { - return parseFloat(parseFloat(part).toFixed(decimals)) - } - return part - }) - return `@${latitude},${longitude},${zoom}`; - } cached = await get_cached_object(cache_key, MODULE_NAME) } @@ -255,7 +159,7 @@ export const searchGoogleMap = async ( page.local_results.forEach((r) => { r.page = pageIdx }) - results.push(...page.local_results); + results.push(...page.local_results) if (results.length >= opts.limit) break pageIdx++ page = await page.next?.() @@ -269,7 +173,7 @@ export const searchGoogleMap = async ( page.place_results.forEach((r) => { r.page = pageIdx }) - results.push(...page.place_results); + results.push(...page.place_results) if (results.length >= opts.limit) break pageIdx++ page = await page.next?.() @@ -278,26 +182,15 @@ export const searchGoogleMap = async ( if (opts.searchCache && OSR_CACHE()) { set_cached_object(cache_key, MODULE_NAME, results) } - + let idx = 0 //const cachedLoc = async (title: string) => getStored(title, opts.store, MODULE_NAME) - await pMap(results, async (entry: any) => { - idx++ - entry.position = entry.page * PAGE_SIZE + idx - try { - if (index[entry.title] && index[entry.title].geo) { - entry.geo = index[entry.title].geo - return - } - return reverse(entry, opts) - } catch (e) { - logger.error(`Error reverse geocoding ${entry.title}`) - entry.geo = REVERSE_DEFAULT - } - }, { concurrency: 3 }) + await enrichResults(results, index, opts) - logger.debug(`search ${query} with ${params.ll} / ${params.searchFrom} @ ${opts.zoom} : ${results.length} items`) + logger.debug( + `search ${query} with ${params.ll} / ${params.searchFrom} @ ${opts.zoom} | ${results.length} results before filters`, + ) if (opts.filterCity) { results = results.filter((r) => r.geo.city.toLowerCase() === opts.filterCity.toLowerCase()) @@ -314,49 +207,85 @@ export const searchGoogleMap = async ( results = results.filter((r) => r.gps_coordinates) const beforeCached = results.length - results = results.filter((r) => { + const newResults = results.filter((r) => { return index[r.title] == null || !index[r.title].geo || !index[r.title].meta }) - logger.info(`search ${query} with ${params.ll} / ${params.searchFrom} : ${results.length} items | ${beforeCached} before cache`) - results = results.slice(0, opts.limit) - if (opts.meta) { - await pMap(results, (entry: any) => { - if (entry.meta || !entry.website || entry.rejected) { - return - } + logger.info( + `found ${newResults.length} new items for "${query}" from "${params.searchFrom}" | ${beforeCached} total before cache filtering`, + ) + const processedResults = newResults.slice(0, opts.limit) + await enrichResults(processedResults, index, opts) + return results +} + +const enrichResults = async (results: LocalResult[], index: any, opts: IOptionsGoogleMaps) => { + let idx = 0 + await pMap( + results, + async (entry: any) => { + idx++ + entry.position = entry.page * PAGE_SIZE + idx try { - if (index[entry.title] && index[entry.title].meta) { - entry.meta = index[entry.title].meta + if (index[entry.title] && index[entry.title].geo) { + entry.geo = index[entry.title].geo return } - return meta(entry, opts) + return reverse(entry, opts) } catch (e) { - // entry.meta = {} + logger.error(`Error reverse geocoding ${entry.title}`) + entry.geo = REVERSE_DEFAULT } - }, { concurrency: 1 }) + }, + { concurrency: opts.concurrency }, + ) + if (opts.meta) { + await pMap( + results, + (entry: any) => { + if (entry.meta || !entry.website || entry.rejected) { + return + } + try { + if (index[entry.title] && index[entry.title].meta) { + entry.meta = index[entry.title].meta + return + } + return meta(entry, opts) + } catch (e) { + // entry.meta = {} + } + }, + { concurrency: 1 }, + ) } if (opts.findEMail && opts.meta) { - const emails = await pMap(results, async (entry: any) => { - if (index[entry.title] && index[entry.title].email) { - entry.email = index[entry.title].email - return - } - if (entry.meta && entry.website && !entry.email) { - try { - //logger.debug(`searching email for ${entry.website}`) - return findEMail(SEARCH_AI_PROMPTS.GET_EMAIL, entry.website, opts, entry) - } catch (e) { - logger.error(`Error retrieving EMail data ${entry.title}`) + await pMap( + results, + async (entry: any) => { + if (index[entry.title] && index[entry.title].email) { + entry.email = index[entry.title].email + return } - } - }, { concurrency: 1 }) + if (entry.meta && entry.website && !entry.email) { + try { + logger.debug(`searching email for ${entry.website}`) + return findEMail(SEARCH_AI_PROMPTS.GET_EMAIL, entry.website, opts, entry) + } catch (e) { + logger.error(`Error retrieving EMail data ${entry.title}`) + } + } + }, + { concurrency: 1 }, + ) } + return results } -export const parse = (argv: any): any => { - const args: any = argv - logger.settings.minLevel = args.logLevel as any || 2 + +export const parse = (argv: IOptionsGoogleMaps): IOptionsGoogleMaps => { + const args: IOptionsGoogleMaps = argv + logger.settings.minLevel = (args.logLevel as any) || 2 const config = CONFIG_DEFAULT(args.env_key) as any if (!config) { logger.warn('No config found!') @@ -411,20 +340,7 @@ export const parse = (argv: any): any => { } return opts } -export const resolvePath = (str: string, query, category, opts: any) => { - return path.resolve(resolve(str, false, - { - QUERY: query, - FROM: opts.searchFrom ? opts.searchFrom.split(',').map((s) => s.trim()).join('/') : 'barcelona, spain', - ENGINE: opts.engine, - DOMAIN: opts.google_domain, - LANG: opts.language, - COUNTRY: opts.country, - AREA: opts.area, - CATEGORY: category || 'unknown', - ...opts.variables || {} - })) -} + export const googleMaps = async (opts: IOptionsGoogleMaps) => { opts = parse(opts) if (!opts) { @@ -438,17 +354,18 @@ export const googleMaps = async (opts: IOptionsGoogleMaps) => { if (coords) { opts.searchCoord = locationString(coords, opts.zoom) } else { - logger.error('Error geocoding', searchFrom) + logger.error(`Error geocoding "${searchFrom}"`) } } } catch (error) { - logger.error('Error geocoding', error, error.stack) + logger.error(`Error geocoding "${opts.searchFrom}"`, error, error.stack) } let ret: any[] = [] const search = async (query: string, category, opts: any) => { opts = clone(opts) opts.dst = resolvePath(path.join(opts.cwd || '', opts.dst || ''), query, category, opts) + logger.debug(`output destination --dst "${opts.dst}"`) if (opts.cache !== false && exists(opts.dst + '.json')) { const cachedPath = opts.dst + '.json' const cached = read(cachedPath, 'json') as any || [] @@ -486,16 +403,42 @@ export const googleMaps = async (opts: IOptionsGoogleMaps) => { if (opts.dst) { opts.dst = resolvePath(opts.dst, 'all', 'all', opts) + logger.debug(`final output destination --dst "${opts.dst}"`) + let existingResults: LocalResult[] = [] if (exists(opts.dst + '.json')) { - const last = (read(opts.dst + '.json', 'json') as any || []) - ret = [...last, ...ret] + existingResults = (read(opts.dst + '.json', 'json') as LocalResult[]) || [] } - write(opts.dst + '.json', ret) - writeReport(ret, opts.dst, opts) + + // Combine, deduplicate, clean, and process URLs in a single chain + const finalResults = Array.from( + [...existingResults, ...ret].reduce((map, obj) => { + if (obj.place_id) { + map.set(obj.place_id, obj) + } + return map + }, new Map()).values(), + ) + .map(cleanObjectStrings) + .map((r: any) => { + if (r.website && typeof r.website === 'string' && r.website.startsWith('/url?q=')) { + try { + const urlString = r.website.substring('/url?q='.length) + const decodedUrl = decodeURIComponent(urlString) + const urlParts = decodedUrl.split('&') + r.website = urlParts[0] + } catch (e) { + logger.warn(`Could not parse website URL: ${r.website}`) + } + } + return r + }) + + write(opts.dst + '.json', finalResults) + writeReport(finalResults, opts.dst, opts) } if (opts.index) { - let index = read(opts.index, 'json') as any || {} + let index = (read(opts.index, 'json') as any) || {} ret.forEach((r) => { if (!index[r.title]) { index[r.title] = r @@ -528,8 +471,12 @@ export const migrate = async (opts: IOptionsGoogleMapsEach) => { return ret } export const each = async (opts: IOptionsGoogleMapsEach) => { - logger.settings.minLevel = opts.logLevel as any || 2 + logger.settings.minLevel = (opts.logLevel as any) || 2 let items: string[] = [] + if (!opts.list) { + logger.error('No list provided for each command') + return + } let listPath = path.resolve(resolve(opts.list)) const profile: IProfile = parseProfile(opts.profile, @@ -565,22 +512,26 @@ export const each = async (opts: IOptionsGoogleMapsEach) => { items = items.filter((item) => !!item) logger.debug(`${items.length} items`) write(path.join(path.resolve(resolve(opts.cwd), 'list.json')), items) - const all: any[] = await pMap(items, (KEY) => { - const variables = { - KEY, - TOWN: KEY, - ...profile.variables - } - const googleOpts = { - ...opts, - query: substitute(false, opts.query, variables), - dst: substitute(false, opts.dst, variables), - searchFrom: substitute(false, opts.searchFrom, variables), - variables - } - const ret = googleMaps(googleOpts) - return ret - }, { concurrency: 1 }) + const all: any[] = await pMap( + items, + (KEY) => { + const variables = { + KEY, + TOWN: KEY, + ...profile.variables + } + const googleOpts: IOptionsGoogleMaps = { + ...opts, + query: substitute(false, opts.query, variables), + dst: substitute(false, opts.dst, variables), + searchFrom: substitute(false, opts.searchFrom, variables), + variables + } + const ret = googleMaps(googleOpts) + return ret + }, + { concurrency: 1 }, + ) opts.log && write(path.resolve(resolve(opts.log)), all) return all } diff --git a/packages/search/src/lib/index.ts b/packages/search/src/lib/index.ts index aad2c6b0..87f66d27 100644 --- a/packages/search/src/lib/index.ts +++ b/packages/search/src/lib/index.ts @@ -1,6 +1,5 @@ export * from './types.js' export * from './googlemaps.js' -export * from './types-googlemaps.js' import { generate_interfaces } from '@polymech/commons' import { getJson as searchSerpAPI } from "serpapi" import { search as searchScaleserp } from './scalesep.js' diff --git a/packages/search/src/lib/map_types.ts b/packages/search/src/lib/map_types.ts index 2b4569f9..358b2ca8 100644 --- a/packages/search/src/lib/map_types.ts +++ b/packages/search/src/lib/map_types.ts @@ -31,40 +31,9 @@ export interface OperatingHours { jueves: string; } -export interface LocalResult { - position: number; - title: string; - place_id: string; - data_id: string; - data_cid: string; - reviews_link: string; - photos_link: string; - gps_coordinates: GpsCoordinates; - place_id_search: string; - provider_id: string; - rating: number; - reviews: number; - type: string; - types: string[]; - address: string; - open_state: string; - hours: string; - operating_hours: OperatingHours; - phone: string; - website: string; - email: string; - emails: string[]; - thumbnail: string; - meta:any; - links?: string[]; - allLinks?: string[]; - instagram?: string; - facebook?: string; - youtube?: string; - linkedin?: string; - twitter?: string; - geo?: IGeo; - rejected?: boolean; +export type LocalResult = { + [key: string]: any + filterType?: string } export interface SearchParameters { diff --git a/packages/search/src/lib/types-googlemaps.ts b/packages/search/src/lib/types-googlemaps.ts deleted file mode 100644 index ec16caeb..00000000 --- a/packages/search/src/lib/types-googlemaps.ts +++ /dev/null @@ -1,78 +0,0 @@ -export interface IOptionsGoogleMaps { - /** API Key */ - api_key?: string | undefined; - cache?: boolean; - category?: string; - dst?: string; - dump?: string | undefined; - engine?: string; - env_key?: string; - filterCity?: string | undefined; - filterCountry?: string | undefined; - filterType?: string | undefined; - findEMail?: boolean; - geocode_key?: string | undefined; - google_domain?: string; - /** Headless mode */ - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string | undefined; - searchFrom?: string | undefined; - source?: string | undefined; - type?: string; - zoom?: number; - /** Index file */ - index?: string; - /** Index store */ - store?: string; -} -export interface IOptionsGoogleMapsEach { - /** API Key */ - api_key?: string | undefined; - cache?: boolean; - category?: string; - dst?: string; - dump?: string | undefined; - engine?: string; - env_key?: string; - filterCity?: string | undefined; - filterCountry?: string | undefined; - filterType?: string | undefined; - findEMail?: boolean; - geocode_key?: string | undefined; - google_domain?: string; - /** Headless mode */ - headless?: boolean; - language?: string; - limit?: number; - logLevel?: string; - meta?: boolean; - searchCache?: boolean; - query?: string; - searchCoord?: string | undefined; - searchFrom?: string | undefined; - source?: string | undefined; - type?: string; - zoom?: number; - /** Index file */ - index?: string; - /** Index store */ - store?: string; - log?: string | undefined; - /** The country to search in, variable ${COUNTRY} */ - country: string; - /** The city to search in, variable ${AREA} */ - area: string; - /** List of items to process, FILE|GLOB|AI-Query, provided as ${TOWN} */ - list: string; - /** the current working directory to use, otherwise . is being assumed */ - cwd?: string; - env?: string; - profile?: string; - migrate?: boolean; -} \ No newline at end of file diff --git a/packages/search/src/lib/types.ts b/packages/search/src/lib/types.ts index 0574ac4b..d46d09d0 100644 --- a/packages/search/src/lib/types.ts +++ b/packages/search/src/lib/types.ts @@ -163,6 +163,7 @@ export interface IScaleserpResponse { } export interface IScaleserpSearch { - api_key:string - q:string + api_key: string + q: string + blacklist?: string[] }