diff --git a/.babelrc b/.babelrc index e93edff6..d30aedd0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,7 @@ { "plugins": [ - "@babel/plugin-proposal-optional-chaining" + "@babel/plugin-proposal-optional-chaining", + "@babel/plugin-transform-runtime" ], "presets": [ ["@babel/preset-env", { diff --git a/.prettierrc b/.prettierrc index 15f8ea92..ed5f6174 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,7 +1,7 @@ { "arrowParens": "avoid", "bracketSpacing": true, - "printWidth": 180, + "printWidth": 100, "semi": true, "singleQuote": true, "tabWidth": 4, diff --git a/README.md b/README.md index 8d85f6c5..535def46 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,86 @@ # Web Scraper -Web Scraper is a chrome browser extension built for data extraction from web -pages. Using this extension you can create a plan (sitemap) how a web site -should be traversed and what should be extracted. Using these sitemaps the -Web Scraper will navigate the site accordingly and extract all data. Scraped -data later can be exported as CSV. + +Web Scraper is a chrome browser extension built for data extraction from web +pages. Using this extension you can create a plan (sitemap) how a web site +should be traversed and what should be extracted. Using these sitemaps the +Web Scraper will navigate the site accordingly and extract all data. Scraped +data later can be exported as CSV or JSON Lines. #### Latest Version -To run the latest version you need to [download the project][latest-releases] to your system and [follow the description on Google][get-started-chrome]) (select the `extension` folder). - + +Read about installation process on [installation page](./docs/Installation.md). + ## Changelog +### v0.3.6 + +- Updated support for Tables (update vertical tables support and added complex headers and data rows) +- Added export and import sitemap from file +- Added Russian translations and support of i18n that make possible to add every language translation +- Added Rest Api CRUD storage for sitemaps +- Moved to webpack bundler +- Added id hints from predefined model +- Added selectors for Constants and Documents +- Refactored preview data and added search in scraped data +- Refactored returned items model to JSON +- Added saving in JSON lines + ### v0.3 - * Enabled pasting of multible start URLs (by [@jwillmer](https://github.com/jwillmer)) - * Added scraping of dynamic table columns (by [@jwillmer](https://github.com/jwillmer)) - * Added style extraction type (by [@jwillmer](https://github.com/jwillmer)) - * Added text manipulation (trim, replace, prefix, suffix, remove HTML) (by [@jwillmer](https://github.com/jwillmer)) - * Added image improvements to find images in div background (by [@jwillmer](https://github.com/jwillmer)) - * Added support for vertical tables (by [@jwillmer](https://github.com/jwillmer)) - * Added random delay function between requests (by [@Euphorbium](https://github.com/Euphorbium)) - * Start URL can now also be a local URL (by [@3flex](https://github.com/3flex)) - * Added CSV export options (by [@mohamnag](https://github.com/mohamnag)) - * Added Regex group for select (by [@RuneHL](https://github.com/RuneHL)) - * JSON export/import of settings (by [@haisi](https://github.com/haisi)) - * Added date and number pattern in URL (by [@codoff](https://github.com/codoff)) - * Added pagination selector limit (by [@codoff](https://github.com/codoff)) - * Improved CSV export (by [@haisi](https://github.com/haisi)) - * Added click limit option (by [@panna-ahmed](https://github.com/panna-ahmed)) + +- Enabled pasting of multiple start URLs (by [@jwillmer](https://github.com/jwillmer)) +- Added scraping of dynamic table columns (by [@jwillmer](https://github.com/jwillmer)) +- Added style extraction type (by [@jwillmer](https://github.com/jwillmer)) +- Added text manipulation (trim, replace, prefix, suffix, remove HTML) (by [@jwillmer](https://github.com/jwillmer)) +- Added image improvements to find images in div background (by [@jwillmer](https://github.com/jwillmer)) +- Added support for vertical tables (by [@jwillmer](https://github.com/jwillmer)) +- Added random delay function between requests (by [@Euphorbium](https://github.com/Euphorbium)) +- Start URL can now also be a local URL (by [@3flex](https://github.com/3flex)) +- Added CSV export options (by [@mohamnag](https://github.com/mohamnag)) +- Added Regex group for select (by [@RuneHL](https://github.com/RuneHL)) +- JSON export/import of settings (by [@haisi](https://github.com/haisi)) +- Added date and number pattern in URL (by [@codoff](https://github.com/codoff)) +- Added pagination selector limit (by [@codoff](https://github.com/codoff)) +- Improved CSV export (by [@haisi](https://github.com/haisi)) +- Added click limit option (by [@panna-ahmed](https://github.com/panna-ahmed)) ### v0.2 - * Added Element click selector - * Added Element scroll down selector - * Added Link popup selector - * Improved table selector to work with any html markup - * Added Image download - * Added keyboard shortcuts when selecting elements - * Added configurable delay before using selector - * Added configurable delay between page visiting - * Added multiple start url configuration - * Added form field validation - * Fixed a lot of bugs + +- Added Element click selector +- Added Element scroll down selector +- Added Link popup selector +- Improved table selector to work with any html markup +- Added Image download +- Added keyboard shortcuts when selecting elements +- Added configurable delay before using selector +- Added configurable delay between page visiting +- Added multiple start url configuration +- Added form field validation +- Fixed a lot of bugs ### v0.1.3 - * Added Table selector - * Added HTML selector - * Added HTML attribute selector - * Added data preview - * Added ranged start urls - * Fixed bug which made selector tree not to show on some operating systems + +- Added Table selector +- Added HTML selector +- Added HTML attribute selector +- Added data preview +- Added ranged start urls +- Fixed bug which made selector tree not to show on some operating systems #### Bugs + When submitting a bug please attach an exported sitemap if possible. #### Development + Read the [Development Instructions](/docs/Development.md) before you start. ## License + LGPLv3 - [chrome-store]: https://chrome.google.com/webstore/detail/web-scraper/jnhgnonknehpejjnehehllkliplmbmhn - [webscraper.io]: http://webscraper.io/ - [google-groups]: https://groups.google.com/forum/#!forum/web-scraper - [github-issues]: https://github.com/martinsbalodis/web-scraper-chrome-extension/issues - [get-started-chrome]: https://developer.chrome.com/extensions/getstarted#unpacked - [issue-14]: https://github.com/jwillmer/web-scraper-chrome-extension/issues/14 - [latest-releases]: https://github.com/jwillmer/web-scraper-chrome-extension/releases +[chrome-store]: https://chrome.google.com/webstore/detail/web-scraper/jnhgnonknehpejjnehehllkliplmbmhn +[webscraper.io]: http://webscraper.io/ +[google-groups]: https://groups.google.com/forum/#!forum/web-scraper +[github-issues]: https://github.com/martinsbalodis/web-scraper-chrome-extension/issues +[get-started-chrome]: https://developer.chrome.com/extensions/getstarted#unpacked +[latest-releases]: https://github.com/ispras/web-scraper-chrome-extension/releases diff --git a/docs/Installation.md b/docs/Installation.md index 554006ea..8276ece9 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -1,12 +1,44 @@ # Installation -You can install the extension from [Chrome store] [1]. After installing it you -should restart chrome to make sure the extension is fully loaded. If you don't -want to restart Chrome then use the extension only in tabs that are -created after installing it. - ## Requirements -The extension requires Chrome 31+ . There are no OS limitations. +This extension supports different browsers at least Chrome and Mozilla Firefox. Opera is also possible browser fo use. + +# Install Chrome + +To install the program, you must perform the following actions: + +1. Unzip the file with the plugin "web-scraper-chrome-extension-v .zip" downloaded from [release page][latest-realease]. +2. Go to the extensions page in the Google Chrome browser - [chrome://extensions/](chrome://extensions/). +3. Enable developer mode using the switch in the upper right corner (if not enabled). (You can read more here https://developer.chrome.com/extensions/getstarted#unpacked). +4. You can add an extension to the browser in the following ways: + 1. Using the drag and drop system, move the folder `web-scraper-chrome-extension-v` obtained from the unzipped file to the extensions page; + 2. Download the unpacked extension from the folder `web-scraper-chrome-extension-v` obtained from the unzipped file. As a result of the actions performed, a new Web Scraper extension should appear in the list of Google Chrome browser extensions: +5. For the extension to work correctly, after installing it, restart chrome so that the extension works properly. + ![Fig. Installing the program in Google Chrome][install-chrome] + +# Install Mozilla Firefox + +To install the program, you must perform the following actions: + +1. Go to the Mozilla Firefox browser settings page. about: config. +2. In the search bar, enter the xpinstall.signatures.required setting and press Enter. +3. Set the value of this setting to false (double-click on the settings line). + ![Fig. Modifying Mozilla Firefox][change-config] +4. Go to the add-ons page (extensions) of the Mozilla Firefox browser. about: addons +5. Open the settings menu by clicking on the corresponding icon. +6. Select the menu item "install addon from file" in the drop-down list. + ![Fig. Install Add-on][install-addon] +7. Select the file with the plugin "web-scraper-chrome-extension-v .zip" provided on the disk with the distribution package of the program. +8. Click on the file selection confirmation button. + ![Fig. Selecting a program distribution file][choose-addon-file] +9. Confirm the installation of the extension in the pop-up window. + + ![Fig. Confirm install extension][confirm-install] - [1]: https://chrome.google.com/webstore/detail/web-scraper/jnhgnonknehpejjnehehllkliplmbmhn "Install web scraper from Chrome store" \ No newline at end of file +[install-chrome]: images/installation/chrome_scraper_1.png +[change-config]: images/installation/Firefox_scraper_1.png +[install-addon]: images/installation/Firefox_scraper_2.png +[choose-addon-file]: images/installation/Firefox_scraper_3.png +[confirm-install]: images/installation/Firefox_scraper_4.png +[latest-releases]: https://github.com/ispras/web-scraper-chrome-extension/releases diff --git a/docs/Open Web Scraper.md b/docs/Open Web Scraper.md index cc326121..8cb74eee 100644 --- a/docs/Open Web Scraper.md +++ b/docs/Open Web Scraper.md @@ -1,14 +1,14 @@ # Open Web Scraper -Web Scraper is integrated into chrome Developer tools. Figure 1 shows how you +Web Scraper is integrated into Developer tools. Figure 1 shows how you can open it. You can also use these shortcuts to open Developer tools. After -opening Developer tools open *Web Scraper* tab. +opening Developer tools open _Web Scraper_ tab. -Shourtcuts: +Shortcuts: - * windows, linux: `Ctrl+Shift+I`, `f12`, open `Tools / Developer tools` - * mac `Cmd+Opt+I`, open `Tools / Developer tools` +- windows, linux: `Ctrl+Shift+I`, `f12`, open `Tools / Developer tools` +- mac `Cmd+Opt+I`, open `Tools / Developer tools` ![Fig. 1: Open Web Scraper][open-web-scraper] - [open-web-scraper]: images/open-web-scraper/open-web-scraper.png?raw=true \ No newline at end of file +[open-web-scraper]: images/open-web-scraper/open-web-scraper.png?raw=true diff --git a/docs/Scraping a site.md b/docs/Scraping a site.md index d333a22e..5ef08d5c 100644 --- a/docs/Scraping a site.md +++ b/docs/Scraping a site.md @@ -4,7 +4,7 @@ Open the site that you want to scrape. ## Create Sitemap -The first thing you need to do when creating a *sitemap* is specifying the +The first thing you need to do when creating a _sitemap_ is specifying the start url. This is the url from which the scraping will start. You can also specify multiple start urls if the scraping should start from multiple places. For example if you want to scrape multiple search results then you could create @@ -13,7 +13,7 @@ a separate start url for each search result. ### Specify multiple urls with ranges In cases where a site uses numbering in pages URLs it is much simpler to create -a range start url than creating *Link selectors* that would navigate the site. +a range start url than creating _Link selectors_ that would navigate the site. To specify a range url replace the numeric part of start url with a range definition - `[1-100]`. If the site uses zero padding in urls then add zero padding to the range definition - `[001-100]`. If you want to skip some urls @@ -21,28 +21,28 @@ then you can also specify incremental like this `[0-100:10]`. Use range url like this `http://example.com/page/[1-3]` for links like these: - * `http://example.com/page/1` - * `http://example.com/page/2` - * `http://example.com/page/3` +- `http://example.com/page/1` +- `http://example.com/page/2` +- `http://example.com/page/3` Use range url with zero padding like this `http://example.com/page/[001-100]` for links like these: - * `http://example.com/page/001` - * `http://example.com/page/002` - * `http://example.com/page/003` +- `http://example.com/page/001` +- `http://example.com/page/002` +- `http://example.com/page/003` Use range url with increment like this `http://example.com/page/[0-100:10]` for links like these: - * `http://example.com/page/0` - * `http://example.com/page/10` - * `http://example.com/page/20` +- `http://example.com/page/0` +- `http://example.com/page/10` +- `http://example.com/page/20` ## Create selectors -After you have created the *sitemap* you can add selectors to it. In the -*Selectors* panel you can add new selectors, modify them and navigate the +After you have created the _sitemap_ you can add selectors to it. In the +_Selectors_ panel you can add new selectors, modify them and navigate the selector tree. The selectors can be added in a tree type structure. The web scraper will execute the selectors in the order how they are organized in the tree @@ -52,10 +52,10 @@ example site. ![Fig. 1: News site][image-news-site] -To scrape this site you can create a *Link selector* which will extract all +To scrape this site you can create a _Link selector_ which will extract all article links in the first page. Then as a child selector you can add a -*Text selector* that will extract articles from the article pages that the -*Link selector* found links to. Image below illustrates how the *sitemap* +_Text selector_ that will extract articles from the article pages that the +_Link selector_ found links to. Image below illustrates how the _sitemap_ should be built for the news site. ![Fig. 2: News site sitemap][image-news-site-sitemap] @@ -66,13 +66,13 @@ to ensure that you have selected the correct elements with the correct data. More information about selector tree building is available in selector documentation. You should atleast read about these core selectors: - * [Text selector][text-selector] - * [Link selector][link-selector] - * [Element selector][element-selector] +- [Text selector][text-selector] +- [Link selector][link-selector] +- [Element selector][element-selector] ### Inspect selector tree -After you have created selectors for the *sitemap* you can inspect the tree +After you have created selectors for the _sitemap_ you can inspect the tree structure of selectors in the Selector graph panel. Image below shows an example selector graph. @@ -80,17 +80,16 @@ example selector graph. ## Scrape the site -After you have created selectors for the *sitemap* you can start scraping. Open -*Scrape* panel and start scraping. A new popup window will open in which the +After you have created selectors for the _sitemap_ you can start scraping. Open +_Scrape_ panel and start scraping. A new popup window will open in which the scraper will load pages and extract data from them. After the scraping is done the popup window will close and you will be notified with a popup message. You can view -the scraped data by opening *Browse* panel and export it by opening the -*Export data as CSV* panel. - +the scraped data by opening _Browse_ panel and export it by opening the +_Export data_ panel. [image-news-site]: images/scraping-a-site/news-site.png?raw=true [image-news-site-sitemap]: images/scraping-a-site/news-site-sitemap.png?raw=true [image-news-site-selector-graph]: images/scraping-a-site/news-site-selector-graph.png?raw=true [text-selector]: Selectors/Text%20selector.md [link-selector]: Selectors/Link%20selector.md -[element-selector]: Selectors/Element%20selector.md \ No newline at end of file +[element-selector]: Selectors/Element%20selector.md diff --git a/docs/Selectors.md b/docs/Selectors.md index fa90e24b..a37a98d3 100644 --- a/docs/Selectors.md +++ b/docs/Selectors.md @@ -4,50 +4,59 @@ Web scraper has multiple selectors that can be used for different type data extraction and for different interaction with the website. The selectors can be divided in three groups: - * Data extraction selectors for data extraction. - * Link selectors for site navigation. - * Element selectors for element selection that separate multiple records +- Data extraction selectors for data extraction. +- Link selectors for site navigation. +- Element selectors for element selection that separate multiple records ### Data extraction selectors -Data extraction selectors simply return data from the selected element. -For example [Text selector] [text-selector] extracts text from +Data extraction selectors simply return data from the selected element. +For example [Text selector][text-selector] extracts text from selected element. These selectors can be used as data extraction selectors: - * [Text selector] [text-selector] - * [Link selector] [link-selector] - * [Link popup selector] [link-popup-selector] - * [Image selector] [image-selector] - * [Table selector] [table-selector] - * [Element attribute selector] [element-attribute-selector] - * [HTML selector] [html-selector] - * [Grouped selector] [grouped-selector] +- [Text selector][text-selector] +- [Link selector][link-selector] +- [Link popup selector][link-popup-selector] +- [Image selector][image-selector] +- [Document selector][document-selector] +- [Constant Value][constant-value] +- [Table selector][table-selector] +- [Element attribute selector][element-attribute-selector] +- [Element style selector][element-style-selector] +- [HTML selector][html-selector] +- [Grouped selector][grouped-selector] ### Link selectors Link selectors extract URLs from links that can be later opened for data -extraction. For example if in a sitemap tree there is a *Link selector* that has -3 child text selectors then the Web Scraper extract all urls with the *Link -selector* and then open each link and use those child data extraction selectors -to extract data. Of course a link selector might have *Link selectors* as child -selectors then these child *Link selectors* would be used for further page -navigation. These are currently available *Link selectors*: +extraction. For example if in a sitemap tree there is a _Link selector_ that has +3 child text selectors then the Web Scraper extract all urls with the _Link +selector_ and then open each link and use those child data extraction selectors +to extract data. Of course a link selector might have _Link selectors_ as child +selectors then these child _Link selectors_ would be used for further page +navigation. These are currently available _Link selectors_: - * [Link selector] [link-selector] - * [Link popup selector] [link-popup-selector] +- [Link selector][link-selector] +- [Link popup selector][link-popup-selector] ### Element selectors Element selectors are for element selection that contain multiple data elements. For example an element selector might be used to select a list of items in an e-commerce site. The selector will return each selected element as a parent -element to its child selectors. Element selectors child selectors will +element to its child selectors. Element selectors child selectors will extract data only within the element that the element selector gave them. These are currently available Element selectors: - * [Element selector] [element-selector] - * [Element scroll down selector] [element-scroll-selector] - * [Element click selector] [element-click-selector] +- [Element selector][element-selector] +- [Element scroll down selector][element-scroll-selector] +- [Element click selector][element-click-selector] + +### Input Value + +This selector is used to interact with page. For example input value in search form. + +- [Input Value][input-value] ## Selector configuration options @@ -55,14 +64,14 @@ Each selector has configuration options. Here you can see the most common ones. Configuration options that are specific to a selector are described in selectors documentation. - * selector - CSS selector that selects an element the selector will be working - on. - * multiple - should be checked when multiple records (data rows) are going to - be extracted with this selector. Data extracted from two or more selectors with - multiple checked wont be merged in a single record. - * delay - delay before selector is being used. - * parent selectors - configure parent selectors for this selector to make the -selector tree. +- selector - CSS selector that selects an element the selector will be working + on. +- multiple - should be checked when multiple records (data rows) are going to + be extracted with this selector. Data extracted from two or more selectors with + multiple checked wont be merged in a single record. +- delay - delay before selector is being used. +- parent selectors - configure parent selectors for this selector to make the + selector tree. Note! A common mistake when using multiple configuration option is to create two selectors alongside with multiple checked and expect that the scraper will @@ -71,14 +80,18 @@ navigation links these links couldn't be logically joined in pairs. The correct way is to select a wrapper element with Element selector and add data selectors as child selectors to the element selector with multiple option not checked. - [text-selector]: Selectors/Text%20selector.md - [link-selector]: Selectors/Link%20Selector.md - [link-popup-selector]: Selectors/Link%20Popup%20Selector.md - [image-selector]: Selectors/Image%20selector.md - [element-attribute-selector]: Selectors/Table%20selector.md - [table-selector]: Selectors/Table%20selector.md - [grouped-selector]: Selectors/Grouped%20selector.md - [html-selector]: Selectors/HTML%20selector.md - [element-selector]: Selectors/Element%20selector.md - [element-click-selector]: Selectors/Element%20click%20selector.md - [element-scroll-selector]: Selectors/Element%20scroll%20down%20selector.md +[text-selector]: Selectors/Text%20selector.md +[link-selector]: Selectors/Link%20selector.md +[link-popup-selector]: Selectors/Link%20popup%20selector.md +[image-selector]: Selectors/Image%20selector.md +[element-attribute-selector]: Selectors/Element%20attribute%20selector.md +[element-style-selector]: Selectors/Element%20style%20selector.md +[table-selector]: Selectors/Table%20selector.md +[grouped-selector]: Selectors/Grouped%20selector.md +[html-selector]: Selectors/HTML%20selector.md +[element-selector]: Selectors/Element%20selector.md +[element-click-selector]: Selectors/Element%20click%20selector.md +[element-scroll-selector]: Selectors/Element%20scroll%20down%20selector.md +[document-selector]: Selectors/Document%20selector%20.md +[constant-value]: Selectors/Constant%20value.md +[input-value]: Selectors/Input%20value.md diff --git a/docs/Selectors/Constant value.md b/docs/Selectors/Constant value.md index 9736f116..d06d1cb0 100644 --- a/docs/Selectors/Constant value.md +++ b/docs/Selectors/Constant value.md @@ -1,6 +1,8 @@ # Constant value -Value selector is input constant wich will be added to parent selector, like column with name selector "Id" and contain "Value" + +Value selector is input constant which will be added to parent selector, like column with selector named "id" and extracted "value" ## Configuration options - * "Id" - name of colomn and selector - * "Value" - value will be inserted + +- id - name of column and selector +- value - value that will be inserted diff --git a/docs/Selectors/Document selector .md b/docs/Selectors/Document selector .md index 1033ef52..a97c4b8c 100644 --- a/docs/Selectors/Document selector .md +++ b/docs/Selectors/Document selector .md @@ -1,5 +1,6 @@ # SelectorDocument -Document selector can extract attribute (URL) of a document. + +Document selector can extract attribute (URL) of a document. Optionally you can also store the document. The document will be stored in your downloads directory. @@ -7,10 +8,9 @@ Note! Document selector works only with `` tags with `href` attribute.If the download selector is not working for you then you can look at Link selector. ## Configuration options - * selector - [CSS selector] [css-selector] for the document element. - * multiple - multiple records are being extracted. - * Download document - downloads and store document on local drive. When CouchDB - storage back end is used the document is also stored locally. - * delay - delay the extraction - +- selector - [CSS selector][css-selector] for the document element. +- multiple - multiple records are being extracted. +- Download document - downloads and store document on local drive. When CouchDB + storage back end is used the document is also stored locally. +- delay - delay the extraction diff --git a/docs/Selectors/Element click selector.md b/docs/Selectors/Element click selector.md index 04daa4e1..778f3988 100644 --- a/docs/Selectors/Element click selector.md +++ b/docs/Selectors/Element click selector.md @@ -1,9 +1,9 @@ # Element click selector Element click selector works similarly to -[Element selector] [element-selector]. It's main purpose also is element +[Element selector][element-selector]. It's main purpose also is element selection that could be given as parent elements to its child selectors. The only -difference is that *Element click selector* can interact with the web page by +difference is that _Element click selector_ can interact with the web page by clicking on buttons to load new elements. For example a page might use JavaScript and AJAX for pagination or item loading. @@ -12,26 +12,28 @@ mouse over the element and pressing "S". This kind of selection will avoid events triggered by the button. ## Configuration options - * selector - [CSS selector] [css-selector] for the wrapper elements that will - be used as parent elements for child selectors. - * click selector - [CSS selector] [css-selector] for the buttons that need to - be clicked to load more elements. - * click type - type of how the selector knows when there will be no new - elements and clicking should stop. - * pagination limit - the number of clicks you want the selector to perform. - * click element uniqueness - type of how selector knows which buttons are - already clicked. - * multiple - multiple records are being extracted (almost always should be - checked). Multiple option for child selectors usually should not be checked. - * delay - delay before element selection and delay between clicking. This - should usually be specified because the data won't be loaded immediately from - the server. More than 2000 ms might be a good choice if you you don't want to - loose data because the server didn't respond fast enough. - * Discard initial elements - the selector will not return the elements that - were available before clicking for the first time. This might be useful for - duplicate removal. + +- selector - [CSS selector][css-selector] for the wrapper elements that will + be used as parent elements for child selectors. +- click selector - [CSS selector][css-selector] for the buttons that need to + be clicked to load more elements. +- click type - type of how the selector knows when there will be no new + elements and clicking should stop. +- pagination limit - the number of clicks you want the selector to perform. +- click element uniqueness - type of how selector knows which buttons are + already clicked. +- multiple - multiple records are being extracted (almost always should be + checked). Multiple option for child selectors usually should not be checked. +- delay - delay before element selection and delay between clicking. This + should usually be specified because the data won't be loaded immediately from + the server. More than 2000 ms might be a good choice if you you don't want to + loose data because the server didn't respond fast enough. +- Discard initial elements - the selector will not return the elements that + were available before clicking for the first time. This might be useful for + duplicate removal. ### Click type + #### Click Once Click Once type will click on the buttons only once. If a new button appears @@ -47,15 +49,15 @@ element that has unique text content. ### Click element uniqueness -When using *Click Once* only unique buttons will be clicked. When using -*Click More* this helps to ignore buttons that don't generate more elements. - - * Unique Text - buttons with identical text content are considered equal - * Unique HTML+Text - buttons with identical HTML and text content are - considered equal - * Unique HTML - buttons with identical HTML and stripped text content are - considered equal - * Unique CSS Selector - buttons with identical CSS Selector are considered equal +When using _Click Once_ only unique buttons will be clicked. When using +_Click More_ this helps to ignore buttons that don't generate more elements. + +- Unique Text - buttons with identical text content are considered equal +- Unique HTML+Text - buttons with identical HTML and text content are + considered equal +- Unique HTML - buttons with identical HTML and stripped text content are + considered equal +- Unique CSS Selector - buttons with identical CSS Selector are considered equal ## Use cases @@ -63,26 +65,26 @@ When using *Click Once* only unique buttons will be clicked. When using For example there is a site that displays a list of items and there are some pagination buttons that reload these items dynamically (after clicking a button -the url doesn't change. changes after hash tag # doesn't count). Using *Element -click selector* you can select these items and buttons that need to be clicked. +the url doesn't change. changes after hash tag # doesn't count). Using _Element +click selector_ you can select these items and buttons that need to be clicked. The scraper during scraping phase will click these buttons to extract all -elements. Also you need to add child selectors for the *Element click selector* +elements. Also you need to add child selectors for the _Element click selector_ that select data within each element. In figure 1 you can see how to configure -the *Element click selector* to extract data from the described site. +the _Element click selector_ to extract data from the described site. - ![Fig. 1: Sitemap when using Click once type][image-click-once] +![Fig. 1: Sitemap when using Click once type][image-click-once] #### Load more items in an e-commerce site by clicking "More" button This example is similar to the one above. The only difference is that in this site items are loaded by clicking a single button multiple times. In this case -the *Element click selector* should be configured to use "Click more" click -type. In figure 2 you can see how to configure the *Element click selector* +the _Element click selector_ should be configured to use "Click more" click +type. In figure 2 you can see how to configure the _Element click selector_ to extract data from this site. - ![Fig. 2: Sitemap when using Click more type][image-click-more] +![Fig. 2: Sitemap when using Click more type][image-click-more] - [image-click-more]: ../images/selectors/element-click/click-more.png?raw=true - [image-click-once]: ../images/selectors/element-click/click-once.png?raw=true - [element-selector]: Element%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +[image-click-more]: ../images/selectors/element-click/click-more.png?raw=true +[image-click-once]: ../images/selectors/element-click/click-once.png?raw=true +[element-selector]: Element%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Element scroll down selector.md b/docs/Selectors/Element scroll down selector.md index 1bb62b42..9d36606a 100644 --- a/docs/Selectors/Element scroll down selector.md +++ b/docs/Selectors/Element scroll down selector.md @@ -9,17 +9,18 @@ infinitely then this selector will be stuck in an infinite loop. ## Configuration options - * selector - [CSS selector] [css-selector] for the element. - * multiple - multiple records are being extracted (almost always should be - checked). Multiple option for child selectors usually should not be checked. - * delay - delay before element selection and delay between scrolling. This - should usually be specified because the data won't be loaded immediately from - the server after scrolling down. More than 2000 ms might be a good choice if - you you don't want to loose data because the server didn't respond fast enough. - * pagination limit - the number of clicks you want the selector to perform. +- selector - [CSS selector][css-selector] for the element. +- multiple - multiple records are being extracted (almost always should be + checked). Multiple option for child selectors usually should not be checked. +- delay - delay before element selection and delay between scrolling. This + should usually be specified because the data won't be loaded immediately from + the server after scrolling down. More than 2000 ms might be a good choice if + you you don't want to loose data because the server didn't respond fast enough. +- pagination limit - the number of clicks you want the selector to perform. ## Use cases -See [Element selector] [element-selector] use cases. - [element-selector]: Element%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +See [Element selector][element-selector] use cases. + +[element-selector]: Element%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Element selector.md b/docs/Selectors/Element selector.md index 092bcfc2..a0138685 100644 --- a/docs/Selectors/Element selector.md +++ b/docs/Selectors/Element selector.md @@ -9,15 +9,16 @@ extracting data only within the element that the element selector gave them. Note! If the page dynamically loads new items after scrolling down or clicking on a button then you should try these selectors: - * [Element scroll down selector] [element-scroll-selector] - * [Element click selector] [element-click-selector] +- [Element scroll down selector][element-scroll-selector] +- [Element click selector][element-click-selector] ## Configuration options - * selector - [CSS selector] [css-selector] for the wrapper elements that will - be used as parent elements for child selectors. - * multiple - multiple records are being extracted (almost always should be - checked). Multiple option for child selectors usually should not be checked. - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the wrapper elements that will + be used as parent elements for child selectors. +- multiple - multiple records are being extracted (almost always should be + checked). Multiple option for child selectors usually should not be checked. +- delay - delay the extraction ## Use cases @@ -25,20 +26,20 @@ on a button then you should try these selectors: For example an e-commerce site has a page with a list of items. With element selector you can select the elements that wrap these items and then add -multiple child selectors to it to extract data within the items wrapper +multiple child selectors to it to extract data within the items wrapper element. Figure 1 shows how an element selector could be used in this situation. -![Fig. 1: Multiple items selected with element selector] [multiple-elements-with-text-selectors] +![Fig. 1: Multiple items selected with element selector][multiple-elements-with-text-selectors] #### Extract data from tables Similarly to e-commerce item selection you can also select table rows and add child selectors for data extraction from table cells. -Though [Table selector] [table-selector] might be much better solution. +Though [Table selector][table-selector] might be much better solution. - [css-selector]: ../CSS%20selector.md - [element-scroll-selector]: Element%20scroll%20down%20selector.md - [element-click-selector]: Element%20click%20selector.md - [table-selector]: Table%20selector.md - [multiple-elements-with-text-selectors]: ../images/selectors/text/text-selector-multiple-elements-with-text-selectors.png?raw=true \ No newline at end of file +[css-selector]: ../CSS%20selector.md +[element-scroll-selector]: Element%20scroll%20down%20selector.md +[element-click-selector]: Element%20click%20selector.md +[table-selector]: Table%20selector.md +[multiple-elements-with-text-selectors]: ../images/selectors/text/text-selector-multiple-elements-with-text-selectors.png?raw=true diff --git a/docs/Selectors/Element style selector.md b/docs/Selectors/Element style selector.md index fc178161..c2e31c25 100644 --- a/docs/Selectors/Element style selector.md +++ b/docs/Selectors/Element style selector.md @@ -1,21 +1,24 @@ # Element style selector + Element style selector can extract an style value of an HTML element. For example you could use this selector to extract the with attribute from this div: `
`. ## Configuration options - * selector - [CSS selector] [css-selector] for the element. - * multiple - multiple records are being extracted. - * style name - the attribute that is going to be extracted. For example - `width`, `background-image`. - * remove HTML - * trim text - * replace text - regular expression in the replace field possible - * text prefix/suffix - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the element. +- multiple - multiple records are being extracted. +- style name - the attribute that is going to be extracted. For example + `width`, `background-image`. +- remove HTML +- trim text +- replace text - regular expression in the replace field possible +- text prefix/suffix +- delay - delay the extraction ## Use cases -See [Text selector] [text-selector] use cases. - [text-selector]: Text%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +See [Text selector][text-selector] use cases. + +[text-selector]: Text%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Grouped selector.md b/docs/Selectors/Grouped selector.md index 1573b73e..899e9fe7 100644 --- a/docs/Selectors/Grouped selector.md +++ b/docs/Selectors/Grouped selector.md @@ -4,16 +4,17 @@ Grouped selector can group text data from multiple elements into one record. The extracted data will be stored as JSON. ## Configuration options - * selector - [CSS selector] [css-selector] for the elements whose text will be - extracted and stored in JSON format. - * attribute name - optionally this selector can extract an attribute of the - selected element. If specified the extractor will also add this attribute to - the resulting JSON. - * remove HTML - * trim text - * replace text - regular expression in the replace field possible - * text prefix/suffix - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the elements whose text will be + extracted and stored in JSON format. +- attribute name - optionally this selector can extract an attribute of the + selected element. If specified the extractor will also add this attribute to + the resulting JSON. +- remove HTML +- trim text +- replace text - regular expression in the replace field possible +- text prefix/suffix +- delay - delay the extraction ## Use cases @@ -27,4 +28,4 @@ serialize all these reference links into one record. To do that select all reference links and set attribute name to `href` to also extract links to these sites. - [css-selector]: ../CSS%20selector.md \ No newline at end of file +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/HTML selector.md b/docs/Selectors/HTML selector.md index 749b9b0d..c250f8d7 100644 --- a/docs/Selectors/HTML selector.md +++ b/docs/Selectors/HTML selector.md @@ -1,19 +1,22 @@ # HTML selector + HMTL selector can extract HTML and text within the selected element. Only the inner HTML of the element will be extracted. ## Configuration options - * selector - [CSS selector] [css-selector] for the element whose inner HTML - will be extracted. - * multiple - multiple records are being extracted. - * remove HTML - * trim text - * replace text - regular expression in the replace field possible - * text prefix/suffix - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the element whose inner HTML + will be extracted. +- multiple - multiple records are being extracted. +- remove HTML +- trim text +- replace text - regular expression in the replace field possible +- text prefix/suffix +- delay - delay the extraction ## Use cases -See [Text selector] [text-selector] use cases. - [text-selector]: Text%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +See [Text selector][text-selector] use cases. + +[text-selector]: Text%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Image selector.md b/docs/Selectors/Image selector.md index a65a076d..ebb38a84 100644 --- a/docs/Selectors/Image selector.md +++ b/docs/Selectors/Image selector.md @@ -1,24 +1,27 @@ # Image selector -Image selector can extract `src` attribute (URL) of an image. + +Image selector can extract `src` attribute (URL) of an image. Optionally you can also store the images. The images will be stored in your downloads directory: -`Downloads///` +`~/Downloads///` Note! When selecting CSS selector for image selector all the images within the site are moved to the top. If this feature somehow breaks sites layout please report it as a bug. ## Configuration options - * selector - [CSS selector] [css-selector] for the image element. - * multiple - multiple records are being extracted. Usually should not be - checked for Image selector. - * download image - downloads and store images on local drive. When CouchDB - storage back end is used the image is also stored locally. - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the image element. +- multiple - multiple records are being extracted. Usually should not be + checked for Image selector. +- download image - downloads and store images on local drive. When CouchDB + storage back end is used the image is also stored locally. +- delay - delay the extraction ## Use cases -See [Text selector] [text-selector] use cases. - [text-selector]: Text%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +See [Text selector][text-selector] use cases. + +[text-selector]: Text%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Input value.md b/docs/Selectors/Input value.md index ebdf091d..a09caf3b 100644 --- a/docs/Selectors/Input value.md +++ b/docs/Selectors/Input value.md @@ -1,6 +1,10 @@ # Value input + Value input is insert custom value into page element, e.g. search form ## Configuration options - * "selector" [CSS selector] [css-selector] to insert a value - * "value" - value will be inserted + +- "selector" [CSS selector][css-selector] to insert a value +- "value" - value will be inserted + +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Link popup selector.md b/docs/Selectors/Link popup selector.md index 0ede9de8..c9e3ead9 100644 --- a/docs/Selectors/Link popup selector.md +++ b/docs/Selectors/Link popup selector.md @@ -1,18 +1,19 @@ # Link popup selector -*Link popup selector* works similarly as [Link selector] [link-selector]. It can +_Link popup selector_ works similarly as [Link selector][link-selector]. It can be used for url extraction and site navigation. The only difference is that -*Link popup selector* should be used when clicking on a link the site opens a new +_Link popup selector_ should be used when clicking on a link the site opens a new window (popup) instead of loading the URL in the same tab or opening it in a new tab. This selector will catch the popup creation event and extract the URL. If the site creates a visual popup but not a real window then you should try -[Element click selector] [element-click-selector] +[Element click selector][element-click-selector] -Note! when selecting these link elements you can move the mouse over the +Note! when selecting these link elements you can move the mouse over the element and press "S" to select it to prevent it from opening a popup. ## Use cases -See [Link selector] [link-selector] use cases. - [link-selector]: Link%20selector.md - [element-click-selector]: Element%20click%20selector.md \ No newline at end of file +See [Link selector][link-selector] use cases. + +[link-selector]: Link%20selector.md +[element-click-selector]: Element%20click%20selector.md diff --git a/docs/Selectors/Link selector.md b/docs/Selectors/Link selector.md index d1ab32c4..76e9eabf 100644 --- a/docs/Selectors/Link selector.md +++ b/docs/Selectors/Link selector.md @@ -1,29 +1,29 @@ # Link selector Link selector is used for link selection and website navigation. If you use -*Link selector* without any child selectors then it will extract the link and -the href attribute of the link. If you add child selectors to *Link selector* +_Link selector_ without any child selectors then it will extract the link and +the href attribute of the link. If you add child selectors to _Link selector_ then these child selectors will be used in the page that this link was leading -to. If you are selecting multiple links then check *multiple* property. +to. If you are selecting multiple links then check _multiple_ property. Note! Link selector works only with `` tags with `href` attribute. If the link selector is not working for you then you can try these workarounds: - 1. Check that the link in the url bar changes after clicking an item (changes - only after hash tag doesn't count). If the link doesn't change then the site - is probably using ajax for data loading. Instead of using link selector you - should use [Element click selector] [element-click]. - 2. If the site opens a popup then you should use - [Link popup selector] [link-popup] - 3. The site might be using JavaScript `window.location` to change the URL. Web - Scraper cannot handle this kind of navigation right now. +1. Check that the link in the url bar changes after clicking an item (changes + only after hash tag doesn't count). If the link doesn't change then the site + is probably using ajax for data loading. Instead of using link selector you + should use [Element click selector][element-click]. +2. If the site opens a popup then you should use + [Link popup selector][link-popup] +3. The site might be using JavaScript `window.location` to change the URL. Web + Scraper cannot handle this kind of navigation right now. ## Configuration options - * selector - [CSS selector] [css-selector] for the link element from which the - link for navigation will be extracted. - * multiple - multiple records are being extracted. Usually should be checked. - * delay - delay the extraction +- selector - [CSS selector][css-selector] for the link element from which the + link for navigation will be extracted. +- multiple - multiple records are being extracted. Usually should be checked. +- delay - delay the extraction ## Use cases @@ -31,10 +31,10 @@ link selector is not working for you then you can try these workarounds: For example an e-commerce site has multi level navigation - `categories -> subcategories`. To scrape data from all categories and -subcategories you can create two *Link selectors*. One selector would select +subcategories you can create two _Link selectors_. One selector would select category links and the other selector would select subcategory links that are -available in the category pages. The subcategory *Link selector* should be made -as a child of the category *Link selector*. The selectors for data extraction +available in the category pages. The subcategory _Link selector_ should be made +as a child of the category _Link selector_. The selectors for data extraction from subcategory pages should be made as a child selectors to the subcategory selector. @@ -49,7 +49,7 @@ pagination links 1-5, but not 6-8). You can start by building a sitemap that visits each category and extract items from category page. This sitemap will extract items only from the first pagination page. To extract items from all of the pagination links including the ones that are not visible at the beginning -you need to create another *Link selector* that selects the pagination links. +you need to create another _Link selector_ that selects the pagination links. Figure 2 shows how the link selector should be created in the sitemap. When the scraper opens a category link it will extract items that are available in the page. After that it will find the pagination links and also visit those. If @@ -60,9 +60,9 @@ see how pagination links discover more pagination links and more data. ![Fig. 2: Sitemap with Link selector for pagination][pagination-link-selectors] ![Fig. 3: Selector graph with pagination][pagination-selector-graph] - [multiple-level-link-selectors]: ../images/selectors/link/multiple-level-link-selectors.png?raw=true - [pagination-link-selectors]: ../images/selectors/link/pagination-link-selectors.png?raw=true - [pagination-selector-graph]: ../images/selectors/link/pagination-selector-graph.png?raw=true - [element-click]: Element%20click%20selector.md - [link-popup]: Link%20popup%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +[multiple-level-link-selectors]: ../images/selectors/link/multiple-level-link-selectors.png?raw=true +[pagination-link-selectors]: ../images/selectors/link/pagination-link-selectors.png?raw=true +[pagination-selector-graph]: ../images/selectors/link/pagination-selector-graph.png?raw=true +[element-click]: Element%20click%20selector.md +[link-popup]: Link%20popup%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Selectors/Table selector.md b/docs/Selectors/Table selector.md index bfb8eb17..59d22f9e 100644 --- a/docs/Selectors/Table selector.md +++ b/docs/Selectors/Table selector.md @@ -1,27 +1,55 @@ # Table selector -Table selector can extract data from tables. *Table selector* has 3 -configurable CSS selectors. The selector is for table selection. After you have -selected the selector the *Table selector* will try to guess selectors -for header row and data rows. You can click Element preview on those selectors -to see whether the *Table selector* found table header and data rows correctly. -The header row selector is used to identify table columns when data is -extracted from multiple pages. Also you can rename table columns. Figure 1 -shows what you should select when extracting data from a table. +Table selector can extract data from tables. _Table selector_ has 3 configurable CSS selectors. +The selector is for table selection. +If header is a column you can choose vertical table type with using _This is vertical table_ hint. -![Fig. 1: Selectors for table selector] [table-selector-selectors] +You can extract data from complex headers (consisting of multiple rows and substrings), as well as from complex rows(whose cells may +contain substrings). +After you have selected the selector the _Table selector_ scraper will automatically suggest you the CSS of the header +and rows based on table HTML. +If the table header is defined by th or tbody tag - the type of table is automatically determined (vertical or horizontal). + +You can click Element preview on those selectors to see whether the _Table selector_ found table header and data rows correctly. +If automatic detection failed you can select header and data rows selector by yourself like you do it with table selector. +The header row selector is used to identify table columns when data is extracted from multiple pages. + +Also you can rename table columns in extracted data and include only columns that you need in output data. +If new columns are found during data extraction, they could be added to the extracted data as well. + +Figure 1 shows what you should select when extracting data from a table. +![Fig. 1: Selectors for table selector][table-selector-selectors] + +Figure 2 shows example of complex header. + +![Fig. 2: Header for table selector][table-selector-complex-header] + +Figure 3 shows example of complex rows. + +![Fig. 3: Rows for table selector][table-selector-complex-rows] + +Figure 4 shows example of column headers renaming and excluding from final data. + +![Fig. 4: Column headers renaming][table-selector-column-headers] ## Configuration options - * selector - [CSS selector] [css-selector] for the table element. - * header row selector - [CSS selector] [css-selector] for table header row. - * data rows selector - [CSS selector] [css-selector] for table data rows. - * multiple - multiple records are being extracted. Usually should be - checked for Table selector because you are extracting multiple rows. - * delay - delay the extraction + +- selector - [CSS selector][css-selector] for the table element. +- header row selector - [CSS selector][css-selector] for table header row. +- data rows selector - [CSS selector][css-selector] for table data rows. +- This is vertical table - hint that this table is vertical (with vertical header and rows) +- Extract missing columns - new columns that was not extracted during sitemap creation will be added to the extracted data +- multiple - multiple records are being extracted. Usually should be + checked for Table selector because you are extracting multiple rows. +- delay - delay the extraction ## Use cases -See [Text selector] [text-selector] use cases. - [table-selector-selectors]: ../images/selectors/table/selectors.png?raw=true - [text-selector]: Text%20selector.md - [css-selector]: ../CSS%20selector.md \ No newline at end of file +See [Text selector][text-selector] use cases. + +[table-selector-selectors]: ../images/selectors/table/selectors.png?raw=true +[text-selector]: Text%20selector.md +[css-selector]: ../CSS%20selector.md +[table-selector-complex-rows]: ../images/selectors/table/ComplexRows.png?raw=true +[table-selector-complex-header]: ../images/selectors/table/ComplexHeader.png?raw=true +[table-selector-column-headers]: ../images/selectors/table/ColumnsHeaders.png?raw=true diff --git a/docs/Selectors/Text selector.md b/docs/Selectors/Text selector.md index 4b62d1cc..122b0c75 100644 --- a/docs/Selectors/Text selector.md +++ b/docs/Selectors/Text selector.md @@ -9,42 +9,43 @@ resulting data. ## Configuration options - * selector - [CSS selector] [css-selector] for the element from which data - will be extracted. - * multiple - multiple records are being extracted. Usually should not be - checked. If you want to use multiple text selectors within one page with - multiple checked then you might actually need - [Element selector] [element-selector]. - * regex - regular expression to extract a substring from the result. - * remove HTML - * trim text - * replace text - regular expression in the replace field possible - * text prefix/suffix - * delay - delay the extraction +- selector - [CSS selector][css-selector] for the element from which data + will be extracted. +- multiple - multiple records are being extracted. Usually should not be + checked. If you want to use multiple text selectors within one page with + multiple checked then you might actually need + [Element selector][element-selector]. +- regex - regular expression to extract a substring from the result. +- remove HTML +- trim text +- replace text - regular expression in the replace field possible +- text prefix/suffix +- delay - delay the extraction ### Regex The regular expression attribute can be used to extract a substring of the text that the selector extracts. When a regular expression is used the whole match -(group 0) will be returned as a result [www.regexr.com] [regex-site] is a +(group 0) will be returned as a result [www.regexr.com][regex-site] is a great site where you can learn about regular expressions and try them out. Here are some examples that you might find useful: -| text | regex | result | -|------------------ |-------------------------------- |------------ | -| price: 14.99$ | `[0-9]+\.[0-9]+` | 14.99 | -| id: H83JKDX4 | `[A-Z0-9]{8}` | H83JKDX4 | -| date: 2014-08-20 | `[0-9]{4}\-[0-9]{2}\-[0-9]{2}` | 2014-08-20 | +| text | regex | result | +| ---------------- | ------------------------------ | ---------- | +| price: 14.99\$ | `[0-9]+\.[0-9]+` | 14.99 | +| id: H83JKDX4 | `[A-Z0-9]{8}` | H83JKDX4 | +| date: 2014-08-20 | `[0-9]{4}\-[0-9]{2}\-[0-9]{2}` | 2014-08-20 | ## Use cases + **Extract one record per page with multiple text selectors** For example you are scraping news site that has one article per page. The page might contain the article, its title, date published and the author. A -*Link selector* can navigate the scraper to each of these article pages. +_Link selector_ can navigate the scraper to each of these article pages. Multiple text selectors can extract the title, date, author and article. -*Multiple* option should be left unchecked for text selectors because each page +_Multiple_ option should be left unchecked for text selectors because each page is extracting only one record. ![Fig. 1: Multiple text selectors per page][text-selector-multiple-single-text-selectors-in-one-page] @@ -52,7 +53,7 @@ is extracting only one record. **Extract multiple items with multiple text selectors per page** E-commerce sites usually have multiple items per page. If you want to scrape -these items you will need an *Element selector* that selects item wrapper +these items you will need an _Element selector_ that selects item wrapper elements and multiple text selectors that select data within each item wrapper element. @@ -63,15 +64,14 @@ element. For example you want to extract comments for an article. There are multiple comments in a single page and you only need the comment text (If you would need other comment attributes then see the example above). You can use -*Text selector* to extract these comments. The *Text selectors* multiple +_Text selector_ to extract these comments. The _Text selectors_ multiple attribute should be checked because you will be extracting multiple records. ![Fig. 3: Text selector selects multiple comments][text-selector-multiple-per-page] - - [regex-site]: http://www.regexr.com/ - [text-selector-multiple-single-text-selectors-in-one-page]: ../images/selectors/text/text-selector-multiple-single-text-selectors-in-one-page.png?raw=true - [text-selector-multiple-elements-with-text-selectors]: ../images/selectors/text/text-selector-multiple-elements-with-text-selectors.png?raw=true - [text-selector-multiple-per-page]: ../images/selectors/text/text-selector-multiple-per-page.png?raw=true - [element-selector]: Element%20selector.md - [css-selector]: ../CSS%20selector.md +[regex-site]: http://www.regexr.com/ +[text-selector-multiple-single-text-selectors-in-one-page]: ../images/selectors/text/text-selector-multiple-single-text-selectors-in-one-page.png?raw=true +[text-selector-multiple-elements-with-text-selectors]: ../images/selectors/text/text-selector-multiple-elements-with-text-selectors.png?raw=true +[text-selector-multiple-per-page]: ../images/selectors/text/text-selector-multiple-per-page.png?raw=true +[element-selector]: Element%20selector.md +[css-selector]: ../CSS%20selector.md diff --git a/docs/Storage backends.md b/docs/Storage backends.md index b59289ee..2b20d173 100644 --- a/docs/Storage backends.md +++ b/docs/Storage backends.md @@ -10,7 +10,7 @@ is not replicated from one chrome instance to another. ## CouchDB -[CouchDB] [couchdb] is a RESTful NoSQL JavaScript database. You can configure +[CouchDB][couchdb] is a RESTful NoSQL JavaScript database. You can configure the extension to store sitemaps and scraped data in this database. The data then could be accessible from all your chrome instances. To do that you need to configure it in the options page. You can open it by right clicking @@ -19,7 +19,17 @@ backends. For CouchDB you need to add configure the database where sitemaps will be storend and the couchdb db server where scraped data will be stored. For example you can configure it like this: - * sitemap db - http://localhost:5984/scraper-sitemaps - * data db - http://localhost:5984/ +- sitemap db - http://localhost:5984/scraper-sitemaps +- data db - http://localhost:5984/ - [couchdb]: http://couchdb.apache.org/ +[couchdb]: http://couchdb.apache.org/ + +## Rest Api + +This storage is used if you want to implement sitemap storage in your own rest api with your own database. +Simply implement this methods in your API: + +- `GET /sitemaps/` - Which returns list of available in storage sitemaps JSONs. +- `POST /sitemaps/` (With Sitemap JSON in body) - Create new sitemap in storage. +- `PUT /sitemaps/:sitemap_id` (With Sitemap JSON in body) - Updates existing sitemap in storage. +- `DELETE /sitemaps/:sitemap_id` - Deletes sitemap from storage. diff --git a/docs/images/installation/Firefox_scraper_1.png b/docs/images/installation/Firefox_scraper_1.png new file mode 100644 index 00000000..7b32d5d3 Binary files /dev/null and b/docs/images/installation/Firefox_scraper_1.png differ diff --git a/docs/images/installation/Firefox_scraper_2.png b/docs/images/installation/Firefox_scraper_2.png new file mode 100644 index 00000000..f83478c5 Binary files /dev/null and b/docs/images/installation/Firefox_scraper_2.png differ diff --git a/docs/images/installation/Firefox_scraper_3.png b/docs/images/installation/Firefox_scraper_3.png new file mode 100644 index 00000000..387840e9 Binary files /dev/null and b/docs/images/installation/Firefox_scraper_3.png differ diff --git a/docs/images/installation/Firefox_scraper_4.png b/docs/images/installation/Firefox_scraper_4.png new file mode 100644 index 00000000..2b655b03 Binary files /dev/null and b/docs/images/installation/Firefox_scraper_4.png differ diff --git a/docs/images/installation/chrome_scraper_1.png b/docs/images/installation/chrome_scraper_1.png new file mode 100644 index 00000000..4da55e05 Binary files /dev/null and b/docs/images/installation/chrome_scraper_1.png differ diff --git a/docs/images/selectors/table/ColumnsHeaders.png b/docs/images/selectors/table/ColumnsHeaders.png new file mode 100644 index 00000000..441c1190 Binary files /dev/null and b/docs/images/selectors/table/ColumnsHeaders.png differ diff --git a/docs/images/selectors/table/ComplexHeader.png b/docs/images/selectors/table/ComplexHeader.png new file mode 100644 index 00000000..0e3993c5 Binary files /dev/null and b/docs/images/selectors/table/ComplexHeader.png differ diff --git a/docs/images/selectors/table/ComplexRows.png b/docs/images/selectors/table/ComplexRows.png new file mode 100644 index 00000000..5c2429b3 Binary files /dev/null and b/docs/images/selectors/table/ComplexRows.png differ diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 93f9e332..00000000 --- a/package-lock.json +++ /dev/null @@ -1,3447 +0,0 @@ -{ - "name": "web-scraper-chrome-extension", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "abstract-leveldown": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.0.3.tgz", - "integrity": "sha512-jzewKKpZbaYUa6HTThnrl+GrJhzjEAeuc7hTVpZdzg7kupXZFoqQDFwyOwLNbmJKJlmzw8yiipMPkDiuKkT06Q==", - "requires": { - "level-concat-iterator": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "argsarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", - "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "optional": true - }, - "ast-types": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", - "dev": true - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true, - "optional": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "optional": true - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" - }, - "dependencies": { - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "optional": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "optional": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "optional": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "optional": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "optional": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "optional": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "optional": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "optional": true - }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "optional": true - }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.2.tgz", - "integrity": "sha512-/a+Iwj0rn//CX0EJOasNyZJd2o8xur8Ce9C57Sznti/Ilt/cb6Qd8/k98A4ZOklXgTG+iAYYUs1OTG0s1eH+zQ==", - "requires": { - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.2.tgz", - "integrity": "sha512-/a+Iwj0rn//CX0EJOasNyZJd2o8xur8Ce9C57Sznti/Ilt/cb6Qd8/k98A4ZOklXgTG+iAYYUs1OTG0s1eH+zQ==", - "requires": { - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, - "end-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz", - "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", - "requires": { - "write-stream": "~0.4.3" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "es6-denodeify": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-denodeify/-/es6-denodeify-0.1.5.tgz", - "integrity": "sha1-MdTV/pxVA+ElRgQ5MQ4WoqPznB8=" - }, - "es6-templates": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", - "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=", - "dev": true, - "requires": { - "recast": "~0.11.12", - "through": "~2.3.6" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "optional": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "optional": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-future": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", - "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" - }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, - "fetch-cookie": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.7.0.tgz", - "integrity": "sha512-Mm5pGlT3agW6t71xVM7vMZPIvI7T4FaTuFW4jari6dVzYHFDb3WZZsGpN22r/o3XMdkM0E7sPd1EGeyVbH2Tgg==", - "requires": { - "es6-denodeify": "^0.1.1", - "tough-cookie": "^2.3.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "optional": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "optional": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "optional": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "optional": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "html-loader": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", - "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==", - "dev": true, - "requires": { - "es6-templates": "^0.2.3", - "fastparse": "^1.1.1", - "html-minifier": "^3.5.8", - "loader-utils": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - } - }, - "icanhaz": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/icanhaz/-/icanhaz-0.10.3.tgz", - "integrity": "sha1-sIDiz7MDX34okiC6BSRfKIPk9Lo=" - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "optional": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "optional": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true, - "optional": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true - }, - "level": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level/-/level-5.0.1.tgz", - "integrity": "sha512-wcak5OQeA4rURGacqS62R/xNHjCYnJSQDBOlm4KNUGJVE9bWv2B04TclqReYejN+oD65PzD4FsqeWoI5wNC5Lg==", - "requires": { - "level-js": "^4.0.0", - "level-packager": "^5.0.0", - "leveldown": "^5.0.0", - "opencollective-postinstall": "^2.0.0" - } - }, - "level-codec": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.1.tgz", - "integrity": "sha512-ajFP0kJ+nyq4i6kptSM+mAvJKLOg1X5FiFPtLG9M5gCEZyBmgDi3FkDrvlMkEzrUn1cWxtvVmrvoS4ASyO/q+Q==" - }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" - }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - } - } - }, - "level-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-js/-/level-js-4.0.1.tgz", - "integrity": "sha512-m5JRIyHZn5VnCCFeRegJkn5bQd3MJK5qZX12zg3Oivc8+BUIS2yFS6ANMMeHX2ieGxucNvEn6/ZnyjmZQLLUWw==", - "requires": { - "abstract-leveldown": "~6.0.1", - "immediate": "~3.2.3", - "inherits": "^2.0.3", - "ltgt": "^2.1.2", - "typedarray-to-buffer": "~3.1.5" - }, - "dependencies": { - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - } - } - }, - "level-packager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.0.tgz", - "integrity": "sha512-3pbJmDgGvp/lUQNULPoYQZtUbhMI8KoViYDw7Sa0kWl1mPeHWWJF7T/9upWI/NTMuEikkEE/cd6wBvmrW1+ZnQ==", - "requires": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - }, - "dependencies": { - "levelup": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.3.2.tgz", - "integrity": "sha512-cRTjU4ktWo59wf13PHEiOayHC3n0dOh4i5+FHr4tv4MX9+l7mqETicNq3Aj07HKlLdk0z5muVoDL2RD+ovgiyA==", - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, - "level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "requires": { - "xtend": "^4.0.2" - }, - "dependencies": { - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - } - } - }, - "level-write-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz", - "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", - "requires": { - "end-stream": "~0.1.0" - } - }, - "leveldown": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.0.2.tgz", - "integrity": "sha512-Ib6ygFYBleS8x2gh3C1AkVsdrUShqXpe6jSTnZ6sRycEXKhqVf+xOSkhgSnjidpPzyv0d95LJVFrYQ4NuXAqHA==", - "requires": { - "abstract-leveldown": "~6.0.0", - "fast-future": "~1.0.2", - "napi-macros": "~1.8.1", - "node-gyp-build": "~3.8.0" - } - }, - "levelup": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.0.2.tgz", - "integrity": "sha512-cx9PmLENwbGA3svWBEbeO2HazpOSOYSXH4VA+ahVpYyurvD+SDSfURl29VBY2qgyk+Vfy2dJd71SBRckj/EZVA==", - "requires": { - "deferred-leveldown": "~5.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "deferred-leveldown": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.0.1.tgz", - "integrity": "sha512-BXohsvTedWOLkj2n/TY+yqVlrCWa2Zs8LSxh3uCAgFOru7/pjxKyZAexGa1j83BaKloER4PqUyQ9rGPJLt9bqA==", - "requires": { - "abstract-leveldown": "~6.0.0", - "inherits": "^2.0.3" - } - } - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "optional": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "optional": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true, - "optional": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "optional": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "optional": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "napi-macros": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-1.8.2.tgz", - "integrity": "sha512-Tr0DNY4RzTaBG2W2m3l7ZtFuJChTH6VZhXVhkGGjF/4cZTt+i8GcM9ozD+30Lmr4mDoZ5Xx34t2o4GJqYWDGcg==" - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-fetch": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.4.1.tgz", - "integrity": "sha512-P9UbpFK87NyqBZzUuDBDz4f6Yiys8xm8j7ACDbi6usvFm6KItklQUKjeoqTrYS/S1k6I8oaOC2YLLDr/gg26Mw==" - }, - "node-gyp-build": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.8.0.tgz", - "integrity": "sha512-bYbpIHyRqZ7sVWXxGpz8QIRug5JZc/hzZH4GbdT9HTZi6WmKCZ8GLvP8OZ9TTiIBvwPFKgtGrlWQSXDAvYdsPw==" - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "optional": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "optional": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" - } - }, - "papaparse": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.1.0.tgz", - "integrity": "sha1-csia+3gKFezGt2v+ryrqOFeCMDI=" - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "optional": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "optional": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "optional": true - }, - "pouchdb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-7.1.1.tgz", - "integrity": "sha512-8bXWclixNJZqokvxGHRsG19zehSJiaZaz4dVYlhXhhUctz7gMcNTElHjPBzBdZlKKvt9aFDndmXN1VVE53Co8g==", - "requires": { - "argsarray": "0.0.1", - "buffer-from": "1.1.0", - "clone-buffer": "1.0.0", - "double-ended-queue": "2.1.0-0", - "fetch-cookie": "0.7.0", - "immediate": "3.0.6", - "inherits": "2.0.3", - "level": "5.0.1", - "level-codec": "9.0.1", - "level-write-stream": "1.0.0", - "leveldown": "5.0.2", - "levelup": "4.0.2", - "ltgt": "2.2.1", - "node-fetch": "2.4.1", - "readable-stream": "1.0.33", - "spark-md5": "3.0.0", - "through2": "3.0.1", - "uuid": "3.2.1", - "vuvuzela": "1.0.3" - }, - "dependencies": { - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", - "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "requires": { - "readable-stream": "2 || 3" - }, - "dependencies": { - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" - } - } - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "recast": { - "version": "0.11.23", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", - "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", - "dev": true, - "requires": { - "ast-types": "0.9.6", - "esprima": "~3.1.0", - "private": "~0.1.5", - "source-map": "~0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "optional": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true, - "optional": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true, - "optional": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true, - "optional": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "optional": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "optional": true, - "requires": { - "ret": "~0.1.10" - } - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "optional": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "optional": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "optional": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true, - "optional": true - }, - "spark-md5": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.0.tgz", - "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "optional": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "optional": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "optional": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - } - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "optional": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "optional": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "optional": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "optional": true - } - } - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true, - "optional": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "optional": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "^1.1.1" - } - }, - "vuvuzela": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", - "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-stream": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz", - "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", - "requires": { - "readable-stream": "~0.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", - "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" - } - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - } - } -} diff --git a/package.json b/package.json index 6d9e6be3..e6ebf6a4 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "web-scraper-chrome-extension", - "version": "0.3.5.00", + "version": "0.3.508", "description": "Web data extraction tool implemented as chrome extension", "scripts": { - "lint": "eslint --ext .js,.vue src", - "prettier": "prettier \"src/**/*.{js,vue}\"", + "lint": "eslint --ext .js src", + "prettier": "prettier \"src/**/*.{js}\"", "prettier:write": "npm run prettier -- --write", "build": "cross-env NODE_ENV=production webpack --hide-modules", "build:dev": "cross-env NODE_ENV=development webpack --hide-modules", @@ -18,14 +18,20 @@ } }, "dependencies": { + "axios": "^0.19.2", + "bootstrap": "3.1.1", + "d3": "^3.3.8", "icanhaz": "0.10.3", + "jquery": "^3.4.1", + "jquery-flexdatalist": "^2.2.4", + "jquery-searcher": "^0.3.0", + "nanoid": "^2.1.11", "papaparse": "^4.1.0", "pouchdb": "^7.1.1", + "renderjson": "^1.4.0", "sugar": "^1.4.1", - "d3": "^3.3.8", - "bootstrap": "3.1.1", - "jquery": "^3.4.1", - "jquery-flexdatalist": "^2.2.4", + "spark-md5": "^3.0.1", + "@babel/runtime": "^7.8.4", "webextension-polyfill": "^0.6.0" }, "devDependencies": { @@ -33,6 +39,7 @@ "@babel/plugin-proposal-optional-chaining": "^7.0.0", "@babel/preset-env": "^7.1.0", "@babel/runtime-corejs3": "^7.4.0", + "@babel/plugin-transform-runtime": "^7.8.3", "archiver": "^3.0.0", "babel-eslint": "^10.0.1", "core-js": "^3.0.1", @@ -44,10 +51,14 @@ "eslint-config-prettier": "^4.3.0", "eslint-friendly-formatter": "^4.0.1", "eslint-import-resolver-webpack": "^0.10.1", - "eslint-plugin-import": "^2.16.0", - "eslint-plugin-prettier": "^3.1.0", + "eslint-plugin-json": "^2.1.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-prettier": "^3.1.3", + "eslint-plugin-simple-import-sort": "^5.0.2", "husky": "^2.4.0", - "prettier": "^1.17.1", + "prettier": "^2.0.4", "pretty-quick": "^1.8.0", "web-ext-types": "^2.1.0", "webpack": "^4.20.2", diff --git a/playgrounds/extension/tables.html b/playgrounds/extension/tables.html index 4cfb46a3..74efe69f 100644 --- a/playgrounds/extension/tables.html +++ b/playgrounds/extension/tables.html @@ -2,86 +2,125 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+

Table with thead and tbody

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
YearFinal decisionScoreBest student
First examinerSecond examinerKolyaVasyaAlexRoma
IIIIII
2019GoodGoodGoodGood5638Roma
2018ExcellentExcellentGoodGood8796Alex
2017SatisfactorySatisfactoryBadBad4235Roma
2016GoodGoodGoodGood53108Alex
+
+
+
+

Table with complicated rows

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StudentTestClassMark
RomaMath9-AGooD
ProgaExcellent
AlexMath10-BExcellent
DenisProga12-BExcellent
+ +
+
+

Table in table

@@ -161,6 +200,42 @@

Table with thead and tbody



+

Table with th and td inside tbody

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
+ +
+
+
+

Table with vertical headers

@@ -265,8 +340,8 @@

Table without headers

- - + + @@ -283,6 +358,66 @@

Table without headers

flowersnameparameter
color 30
+ +
+
+
+ +

Table with thead and tbody

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
YearFinal decisionScoreBest student
KolyaVasyaAlexRoma
2019Good5663Roma
2018Good8769Alex
2017Bad4235Roma
2016Good53610Alex
diff --git a/playgrounds/extension/webpage.css b/playgrounds/extension/webpage.css index 589b2e5b..23c2a49e 100644 --- a/playgrounds/extension/webpage.css +++ b/playgrounds/extension/webpage.css @@ -1,9 +1,8 @@ #webpage { - height:400px; border-radius: 5px; - border:3px #ccc solid; - margin:10px; - overflow-y:scroll; + border: 3px #ccc solid; + margin: 10px; + overflow-y: scroll; } #webpage { @@ -16,6 +15,6 @@ } .productImage { - background-image: url("../../docs/images/chrome-store-logo.png"); - height: 375px; -} \ No newline at end of file + background-image: url('../../docs/images/chrome-store-logo.png'); + height: 375px; +} diff --git a/playgrounds/sitemap-tree/index.html b/playgrounds/sitemap-tree/index.html index c6c23ccf..0bf154de 100644 --- a/playgrounds/sitemap-tree/index.html +++ b/playgrounds/sitemap-tree/index.html @@ -13,7 +13,7 @@
+ -

- Open Developer tools where you will find Web Scraper tab: -

+

    -
  • - Windows, Linux: Ctrl+Shift+I or F12 -
  • -
  • - Mac: Cmd+Opt+I -
  • -
  • - Any OS: open Tools / Developer tools -
  • +
  • +
  • +
-

Documentation is available on webscraper.io

+

webscraper.io

diff --git a/src/popup/popup.js b/src/popup/popup.js new file mode 100644 index 00000000..b0dcc237 --- /dev/null +++ b/src/popup/popup.js @@ -0,0 +1,6 @@ +import * as $ from 'jquery'; +import Translator from '../scripts/Translator'; + +$(() => { + Translator.translatePage(); +}); diff --git a/src/scripts/Base64.js b/src/scripts/Base64.js new file mode 100644 index 00000000..0d248aea --- /dev/null +++ b/src/scripts/Base64.js @@ -0,0 +1,29 @@ +/** + * @url http://jsperf.com/blob-base64-conversion + */ +export default class Base64 { + static blobToBase64(blob) { + return new Promise((resolve, reject) => { + let reader = new FileReader(); + reader.onload = () => { + let dataUrl = reader.result; + let base64 = dataUrl.split(',')[1]; + resolve(base64); + }; + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + } + + static base64ToBlob(base64, mimeType) { + return new Promise(resolve => { + let binary = atob(base64); + let blobPart = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + blobPart[i] = binary.charCodeAt(i); + } + let blob = new Blob([blobPart], { type: mimeType }); + resolve(blob); + }); + } +} diff --git a/src/scripts/ChromePopupBrowser.js b/src/scripts/ChromePopupBrowser.js index 7d2ff761..e361b57a 100644 --- a/src/scripts/ChromePopupBrowser.js +++ b/src/scripts/ChromePopupBrowser.js @@ -20,7 +20,6 @@ export default class ChromePopupBrowser { callback.call(scope); return; } - let createWindowOptions = { type: 'popup', width: 1042, @@ -89,4 +88,11 @@ export default class ChromePopupBrowser { ); }, this); } + + downloadFile(url, savePath) { + return browser.downloads.download({ + url: url, + filename: savePath, + }); + } } diff --git a/src/scripts/Config.js b/src/scripts/Config.js index 08341133..35d6f4af 100644 --- a/src/scripts/Config.js +++ b/src/scripts/Config.js @@ -5,6 +5,7 @@ export default class Config { this.sitemapDb = ''; this.dataDb = ''; this.restUrl = ''; + this.locale = ''; this.defaults = { storageType: 'local', // this is where sitemap documents are stored @@ -13,6 +14,7 @@ export default class Config { // empty for local storage dataDb: '', restUrl: '', + locale: 'en', }; } @@ -21,10 +23,10 @@ export default class Config { */ loadConfiguration(callback) { return new Promise(resolve => { - browser.storage.sync.get(['sitemapDb', 'dataDb', 'storageType', 'restUrl']).then( + browser.storage.sync.get(['sitemapDb', 'dataDb', 'storageType', 'restUrl', 'locale']).then( function(items) { this.storageType = items.storageType || this.defaults.storageType; - + this.locale = items.locale || this.defaults.locale; this.sitemapDb = this.defaults.sitemapDb; this.dataDb = this.defaults.dataDb; this.restUrl = this.defaults.restUrl; diff --git a/src/scripts/ContentScript.js b/src/scripts/ContentScript.js index 12c7ac7f..69277eea 100644 --- a/src/scripts/ContentScript.js +++ b/src/scripts/ContentScript.js @@ -45,7 +45,7 @@ let ContentScript = { * @param request.allowedElements */ selectSelector: function(request) { - let deferredResponse = $.Deferred(); + const deferredResponse = $.Deferred(); this.removeCurrentContentSelector().done( function() { @@ -55,7 +55,7 @@ let ContentScript = { }); window.cs = contentSelector; - let deferredCSSSelector = contentSelector.getCSSSelector(); + const deferredCSSSelector = contentSelector.getCSSSelector(); deferredCSSSelector .done( function(response) { diff --git a/src/scripts/ContentSelector.js b/src/scripts/ContentSelector.js index ee1b3b40..d99b08b8 100644 --- a/src/scripts/ContentSelector.js +++ b/src/scripts/ContentSelector.js @@ -1,5 +1,7 @@ +import * as browser from 'webextension-polyfill'; import CssSelector from '../libs/css-selector/lib/CssSelector'; import ElementQuery from './ElementQuery'; +import Translator from './Translator'; export default class ContentSelector { /** @@ -15,7 +17,7 @@ export default class ContentSelector { this.parentCSSSelector = options.parentCSSSelector.trim(); this.alert = options.alert || - function(txt) { + function (txt) { alert(txt); }; @@ -44,7 +46,6 @@ export default class ContentSelector { // initialize css selector this.initCssSelector(false); - this.initGUI(); } @@ -59,10 +60,13 @@ export default class ContentSelector { if (this.isParentSelected()) { if (this.selectedElements.length === 1) { cssSelector = '_parent_'; - } else if ($('#-selector-toolbar [name=diferentElementSelection]').prop('checked')) { + } else if ( + $('#-selector-toolbar [name=diferentElementSelection]').prop('checked') + ) { var selectedElements = this.selectedElements.clone(); selectedElements.splice(selectedElements.indexOf(this.parent), 1); - cssSelector = '_parent_, ' + this.cssSelector.getCssSelector(selectedElements, this.top); + cssSelector = + '_parent_, ' + this.cssSelector.getCssSelector(selectedElements, this.top); } else { // will trigger error where multiple selections are not allowed cssSelector = this.cssSelector.getCssSelector(this.selectedElements, this.top); @@ -89,7 +93,13 @@ export default class ContentSelector { enableSmartTableSelector: true, parent: this.parent, allowMultipleSelectors: allowMultipleSelectors, - ignoredClasses: ['-sitemap-select-item-selected', '-sitemap-select-item-hover', '-sitemap-parent', '-web-scraper-img-on-top', '-web-scraper-selection-active'], + ignoredClasses: [ + '-sitemap-select-item-selected', + '-sitemap-select-item-hover', + '-sitemap-parent', + '-web-scraper-img-on-top', + '-web-scraper-selection-active', + ], query: jQuery, }); } @@ -97,18 +107,23 @@ export default class ContentSelector { previewSelector(elementCSSSelector) { if (this.deferredCSSSelectorResponse.state() !== 'rejected') { this.highlightParent(); - $(ElementQuery(elementCSSSelector, this.parent)).addClass('-sitemap-select-item-selected'); + $(ElementQuery(elementCSSSelector, this.parent)).addClass( + '-sitemap-select-item-selected' + ); this.deferredCSSSelectorResponse.resolve(); } return this.deferredCSSSelectorResponse.promise(); } - initGUI() { + async initGUI() { this.highlightParent(); // all elements except toolbar - this.$allElements = $(this.allowedElements + ':not(#-selector-toolbar):not(#-selector-toolbar *)', this.parent); + this.$allElements = $( + this.allowedElements + ':not(#-selector-toolbar):not(#-selector-toolbar *)', + this.parent + ); // allow selecting parent also if (this.parent !== document.body) { this.$allElements.push(this.parent); @@ -117,16 +132,17 @@ export default class ContentSelector { this.bindElementHighlight(); this.bindElementSelection(); this.bindKeyboardSelectionManipulations(); - this.attachToolbar(); + await this.attachToolbar(); this.bindMultipleGroupCheckbox(); this.bindMultipleGroupPopupHide(); this.bindMoveImagesToTop(); + Translator.translatePage(); } bindElementSelection() { this.$allElements.bind( 'click.elementSelector', - function(e) { + function (e) { var element = e.currentTarget; if (this.selectedElements.indexOf(element) === -1) { this.selectedElements.push(element); @@ -154,7 +170,7 @@ export default class ContentSelector { $(this.$allElements) .bind( 'mouseover.elementSelector', - function(e) { + function (e) { // allow event bubbling for other event listeners but not for web scraper. if (e.target !== e.currentTarget) { return; @@ -167,7 +183,7 @@ export default class ContentSelector { ) .bind( 'mouseout.elementSelector', - function(e) { + function (e) { // allow event bubbling for other event listeners but not for web scraper. if (e.target !== e.currentTarget) { return; @@ -186,7 +202,7 @@ export default class ContentSelector { // do this only when selecting images if (this.allowedElements === 'img') { $('img') - .filter(function(i, element) { + .filter(function (i, element) { return $(element).css('position') === 'static'; }) .addClass('-web-scraper-img-on-top'); @@ -214,7 +230,7 @@ export default class ContentSelector { // check for focus var lastFocusStatus; this.keyPressFocusInterval = setInterval( - function() { + function () { var focus = document.hasFocus(); if (focus === lastFocusStatus) return; lastFocusStatus = focus; @@ -229,7 +245,7 @@ export default class ContentSelector { // selected element $(document).bind( 'keydown.selectionManipulation', - function(event) { + function (event) { // select child C if (event.keyCode === 67) { this.animateClickedKey($('#-selector-toolbar .key-button-child')); @@ -252,12 +268,10 @@ export default class ContentSelector { } animateClickedKey(element) { - $(element) - .removeClass('clicked') - .removeClass('clicked-animation'); - setTimeout(function() { + $(element).removeClass('clicked').removeClass('clicked-animation'); + setTimeout(function () { $(element).addClass('clicked'); - setTimeout(function() { + setTimeout(function () { $(element).addClass('clicked-animation'); }, 100); }, 1); @@ -270,7 +284,9 @@ export default class ContentSelector { $('body #-selector-toolbar .selector').text(resultCssSelector); // highlight selected elements $('.-sitemap-select-item-selected').removeClass('-sitemap-select-item-selected'); - $(ElementQuery(resultCssSelector, this.parent)).addClass('-sitemap-select-item-selected'); + $(ElementQuery(resultCssSelector, this.parent)).addClass( + '-sitemap-select-item-selected' + ); } catch (err) { if (err === 'found multiple element groups, but allowMultipleSelectors disabled') { console.log('multiple different element selection disabled'); @@ -301,7 +317,7 @@ export default class ContentSelector { bindMultipleGroupCheckbox() { $('#-selector-toolbar [name=diferentElementSelection]').change( - function(e) { + function (e) { if ($(e.currentTarget).is(':checked')) { this.initCssSelector(true); } else { @@ -314,38 +330,14 @@ export default class ContentSelector { $('#-selector-toolbar .diferentElementSelection').unbind('change'); } - attachToolbar() { - var $toolbar = - '
' + - '
' + - '
' + - '' + - '
' + - '
×
' + - '
' + - '
' + - '
' + - 'Different type element selection is disabled. If the element ' + - 'you clicked should also be included then enable this and ' + - 'click on the element again. Usually this is not needed.' + - '
' + - '
' + - '
' + - '
' + - '
Enable key events
' + - '
S
' + - '
P
' + - '
C
' + - '
Done selecting!
' + - '
'; + async attachToolbar() { + const toolbarUrl = browser.runtime.getURL('content_script/AttachedToolbar.html'); + const toolbarFile = await fetch(toolbarUrl); + const $toolbar = await toolbarFile.text(); $('body').append($toolbar); - - $('body #-selector-toolbar .done-selecting-button').click( - function() { - this.selectionFinished(); - }.bind(this) - ); + $('body #-selector-toolbar .done-selecting-button').click(() => this.selectionFinished()); } + highlightParent() { // do not highlight parent if its the body if (!$(this.parent).is('body') && !$(this.parent).is('#webpage')) { @@ -363,9 +355,7 @@ export default class ContentSelector { $('.-sitemap-parent').removeClass('-sitemap-parent'); } unbindElementHighlight() { - $(this.$allElements) - .unbind('mouseover.elementSelector') - .unbind('mouseout.elementSelector'); + $(this.$allElements).unbind('mouseover.elementSelector').unbind('mouseout.elementSelector'); } unbindKeyboardSelectionMaipulatios() { $(document).unbind('keydown.selectionManipulation'); diff --git a/src/scripts/Controller.js b/src/scripts/Controller.js index 4f7d9eca..e2d43c86 100644 --- a/src/scripts/Controller.js +++ b/src/scripts/Controller.js @@ -1,97 +1,111 @@ -import getBackgroundScript from './BackgroundScript'; +import * as $ from 'jquery'; +import * as ich from 'icanhaz/ICanHaz'; +import * as browser from 'webextension-polyfill'; +import * as renderjson from 'renderjson/renderjson'; +import 'jquery-searcher/dist/jquery.searcher.min'; +import 'jquery-flexdatalist/jquery.flexdatalist'; +import '../libs/jquery.bootstrapvalidator/bootstrapValidator'; +import 'sugar'; +import * as Papa from 'papaparse'; + import getContentScript from './ContentScript'; import Sitemap from './Sitemap'; import SelectorGraphv2 from './SelectorGraphv2'; import SelectorList from './SelectorList'; import SelectorTable from './Selector/SelectorTable'; import Model from './Model'; -import * as ich from 'icanhaz/ICanHaz'; -import 'jquery-flexdatalist/jquery.flexdatalist'; -import '../libs/jquery.bootstrapvalidator/bootstrapValidator'; -import * as browser from 'webextension-polyfill'; +import Translator from './Translator'; export default class SitemapController { constructor(store, templateDir) { this.store = store; this.templateDir = templateDir; - this.backgroundScript = getBackgroundScript('DevTools'); this.contentScript = getContentScript('DevTools'); + this.selectorTypes = [ { type: 'SelectorText', - title: 'Text', }, { type: 'ConstantValue', - title: 'Constant value', }, { type: 'SelectorInputValue', - title: 'Input value', }, { type: 'SelectorLink', - title: 'Link', }, { type: 'SelectorPopupLink', - title: 'Popup Link', }, { type: 'SelectorImage', - title: 'Image', }, { type: 'SelectorDocument', - title: 'Document', }, { type: 'SelectorTable', - title: 'Table', }, { type: 'SelectorElementAttribute', - title: 'Element attribute', }, { type: 'SelectorElementStyle', - title: 'Element style', }, { type: 'SelectorHTML', - title: 'HTML', }, { type: 'SelectorElement', - title: 'Element', }, { type: 'SelectorElementScroll', - title: 'Element scroll down', }, { type: 'SelectorElementClick', - title: 'Element click', }, { type: 'SelectorGroup', - title: 'Grouped', }, ]; - this.init(); + + this.selectorTypes = this.selectorTypes.map(typeObj => { + typeObj.title = Translator.getTranslationByKey(typeObj.type); + return typeObj; + }); + + this.jsonRenderer = renderjson + .set_icons('+', '-') + .set_show_to_level('all') + .set_max_string_length(80) + .set_replacer((key, value) => { + if (typeof value === 'string') { + return value + .replace(/(\r\n|\n|\r)/gm, ' ') + .replace(/\s+/g, ' ') + .trim(); + } + return value; + }) + .set_sort_objects(true); + return this.init(); } control(controls) { - let controller = this; + const controller = this; - for (let selector in controls) { - for (let event in controls[selector]) { + for (const selector in controls) { + for (const event in controls[selector]) { $(document).on( event, selector, - (function(selector, event) { - return function() { - let continueBubbling = controls[selector][event].call(controller, this); + (function (selector, event) { + return function () { + const continueBubbling = controls[selector][event].call( + controller, + this + ); if (continueBubbling !== true) { return false; } @@ -105,8 +119,8 @@ export default class SitemapController { /** * Loads templates for ICanHaz */ - loadTemplates(cbAllTemplatesLoaded) { - let templateIds = [ + async loadTemplates() { + const templateIds = [ 'Viewport', 'SitemapList', 'SitemapListItem', @@ -115,7 +129,7 @@ export default class SitemapController { 'SitemapExport', 'SitemapBrowseData', 'SitemapScrapeConfig', - 'SitemapExportDataCSV', + 'SitemapExportData', 'SitemapEditMetadata', 'SelectorList', 'SelectorListItem', @@ -123,163 +137,161 @@ export default class SitemapController { 'SelectorEditTableColumn', 'SitemapSelectorGraph', 'DataPreview', + 'ItemCard', ]; - let templatesLoaded = 0; - let cbLoaded = function(templateId, template) { - templatesLoaded++; - ich.addTemplate(templateId, template); - if (templatesLoaded === templateIds.length) { - cbAllTemplatesLoaded(); - } - }; - templateIds.forEach( - function(templateId) { - $.get(this.templateDir + templateId + '.html', cbLoaded.bind(this, templateId)); - }.bind(this) + return Promise.all( + templateIds.map(templateId => { + return $.get(`${this.templateDir + templateId}.html`) + .promise() + .then(template => { + ich.addTemplate(templateId, template); + }); + }) ); } - init() { - this.loadTemplates( - function() { - // currently viewed objects - this.clearState(); + async init() { + await this.loadTemplates(); + // function() { + // currently viewed objects + this.clearState(); - // render main viewport - ich.Viewport().appendTo('body'); + // render main viewport + ich.Viewport().appendTo('body'); - // cancel all form submits - $('form').bind('submit', function() { - return false; - }); + // cancel all form submits + $('form').bind('submit', () => { + return false; + }); - this.control({ - '#sitemaps-nav-button': { - click: this.showSitemaps, - }, - '#create-sitemap-create-nav-button': { - click: this.showCreateSitemap, - }, - '#create-sitemap-import-nav-button': { - click: this.showImportSitemapPanel, - }, - '#sitemap-export-nav-button': { - click: this.showSitemapExportPanel, - }, - '#sitemap-export-data-csv-nav-button': { - click: this.showSitemapExportDataCsvPanel, - }, - '#submit-create-sitemap': { - click: this.createSitemap, - }, - '#submit-import-sitemap': { - click: this.importSitemap, - }, - '#sitemap-edit-metadata-nav-button': { - click: this.editSitemapMetadata, - }, - '#sitemap-selector-list-nav-button': { - click: this.showSitemapSelectorList, - }, - '#sitemap-selector-graph-nav-button': { - click: this.showSitemapSelectorGraph, - }, - '#sitemap-browse-nav-button': { - click: this.browseSitemapData, - }, - 'button#submit-edit-sitemap': { - click: this.editSitemapMetadataSave, - }, - '#edit-sitemap-metadata-form': { - submit: function() { - return false; - }, - }, - '#sitemaps tr': { - click: this.editSitemap, - }, - '#sitemaps button[action=delete-sitemap]': { - click: this.deleteSitemap, - }, - '#sitemap-scrape-nav-button': { - click: this.showScrapeSitemapConfigPanel, - }, - '#submit-scrape-sitemap-form': { - submit: function() { - return false; - }, - }, - '#submit-scrape-sitemap': { - click: this.scrapeSitemap, - }, - '#sitemaps button[action=browse-sitemap-data]': { - click: this.sitemapListBrowseSitemapData, - }, - // @TODO move to tr - '#selector-tree tbody tr': { - click: this.showChildSelectors, - }, - '#selector-tree .breadcrumb a': { - click: this.treeNavigationshowSitemapSelectorList, - }, - '#selector-tree tr button[action=edit-selector]': { - click: this.editSelector, - }, - '#edit-selector select[name=type]': { - change: function() { - this.selectorTypeChanged(true); - }.bind(this), - }, - '#edit-selector button[action=save-selector]': { - click: this.saveSelector, - }, - '#edit-selector button[action=cancel-selector-editing]': { - click: this.cancelSelectorEditing, - }, - '#edit-selector #selectorId': { - keyup: this.updateSelectorParentListOnIdChange, - }, - '#selector-tree button[action=add-selector]': { - click: this.addSelector, - }, - '#selector-tree tr button[action=delete-selector]': { - click: this.deleteSelector, - }, - '#selector-tree tr button[action=preview-selector]': { - click: this.previewSelectorFromSelectorTree, - }, - '#selector-tree tr button[action=data-preview-selector]': { - click: this.previewSelectorDataFromSelectorTree, - }, - '#edit-selector button[action=select-selector]': { - click: this.selectSelector, - }, - '#edit-selector button[action=select-table-header-row-selector]': { - click: this.selectTableHeaderRowSelector, - }, - '#edit-selector button[action=refresh-header-row-selector]': { - click: this.refreshTableHeaderRowSelector, - }, - '#edit-selector button[action=select-table-data-row-selector]': { - click: this.selectTableDataRowSelector, - }, - '#edit-selector button[action=preview-selector]': { - click: this.previewSelector, - }, - '#edit-selector button[action=preview-click-element-selector]': { - click: this.previewClickElementSelector, - }, - '#edit-selector button[action=preview-table-row-selector]': { - click: this.previewTableRowSelector, - }, - '#edit-selector button[action=preview-selector-data]': { - click: this.previewSelectorDataFromSelectorEditing, - }, - }); - this.showSitemaps(); - }.bind(this) - ); + this.control({ + '#sitemapFiles': { + change: this.readBlob, + }, + '#sitemaps-nav-button': { + click: this.showSitemaps, + }, + '#create-sitemap-create-nav-button': { + click: this.showCreateSitemap, + }, + '#create-sitemap-import-nav-button': { + click: this.showImportSitemapPanel, + }, + '#sitemap-export-nav-button': { + click: this.showSitemapExportPanel, + }, + '#sitemap-export-data-nav-button': { + click: this.showSitemapExportDataPanel, + }, + '#submit-create-sitemap': { + click: this.createSitemap, + }, + '#submit-import-sitemap': { + click: this.importSitemap, + }, + '#sitemap-edit-metadata-nav-button': { + click: this.editSitemapMetadata, + }, + '#sitemap-selector-list-nav-button': { + click: this.showSitemapSelectorList, + }, + '#sitemap-selector-graph-nav-button': { + click: this.showSitemapSelectorGraph, + }, + '#sitemap-browse-nav-button': { + click: this.browseSitemapData, + }, + 'button#submit-edit-sitemap': { + click: this.editSitemapMetadataSave, + }, + '#edit-sitemap-metadata-form': { + submit: () => false, + }, + '#sitemaps tr td:nth-of-type(1)': { + click: this.editSitemap, + }, + '#sitemaps button[action=delete-sitemap]': { + click: this.deleteSitemap, + }, + '#sitemap-scrape-nav-button': { + click: this.showScrapeSitemapConfigPanel, + }, + '#submit-scrape-sitemap-form': { + submit: () => false, + }, + '#submit-scrape-sitemap': { + click: this.scrapeSitemap, + }, + '#sitemaps button[action=browse-sitemap-data]': { + click: this.sitemapListBrowseSitemapData, + }, + // @TODO move to tr + '#selector-tree tbody tr': { + click: this.showChildSelectors, + }, + '#selector-tree .breadcrumb a': { + click: this.treeNavigationShowSitemapSelectorList, + }, + '#selector-tree tr button[action=edit-selector]': { + click: this.editSelector, + }, + '#edit-selector select[name=type]': { + change: () => this.selectorTypeChanged(true), + }, + '#edit-selector button[action=save-selector]': { + click: this.saveSelector, + }, + '#edit-selector button[action=cancel-selector-editing]': { + click: this.cancelSelectorEditing, + }, + '#edit-selector #selectorId': { + keyup: this.updateSelectorParentListOnIdChange, + }, + '#selector-tree button[action=add-selector]': { + click: this.addSelector, + }, + '#selector-tree tr button[action=delete-selector]': { + click: this.deleteSelector, + }, + '#selector-tree tr button[action=preview-selector]': { + click: this.previewSelectorFromSelectorTree, + }, + '#selector-tree tr button[action=data-preview-selector]': { + click: this.previewSelectorDataFromSelectorTree, + }, + '#edit-selector button[action=select-selector]': { + click: this.selectSelector, + }, + '#edit-selector button[action=select-table-header-row-selector]': { + click: this.selectTableHeaderRowSelector, + }, + '#edit-selector button[action=refresh-header-row-selector]': { + click: this.refreshTableColumns, + }, + '#edit-selector button[action=select-table-data-row-selector]': { + click: this.selectTableDataRowSelector, + }, + '#edit-selector button[action=preview-selector]': { + click: this.previewSelector, + }, + '#edit-selector button[action=preview-click-element-selector]': { + click: this.previewClickElementSelector, + }, + '#edit-selector button[action=preview-table-row-selector]': { + click: this.previewTableRowSelector, + }, + '#edit-selector button[action=preview-selector-data]': { + click: this.previewSelectorDataFromSelectorEditing, + }, + '#data-export-form .data-export-control': { + input: this.sitemapExportDataFormChanged, + }, + '#data-export-generate-file': { + click: this.sitemapExportData, + }, + }); + await this.showSitemaps(); } clearState() { @@ -301,25 +313,20 @@ export default class SitemapController { setActiveNavigationButton(navigationId) { $('.nav .active').removeClass('active'); - $('#' + navigationId + '-nav-button') - .closest('li') - .addClass('active'); + $(`#${navigationId}-nav-button`).closest('li').addClass('active'); if (navigationId.match(/^sitemap-/)) { - $('#sitemap-nav-button').removeClass('disabled'); - $('#sitemap-nav-button') - .closest('li') - .addClass('active'); - $('#navbar-active-sitemap-id').text('(' + this.state.currentSitemap._id + ')'); + const navButton = $('#sitemap-nav-button'); + navButton.removeClass('disabled'); + navButton.closest('li').addClass('active'); + $('#navbar-active-sitemap-id').text(`(${this.state.currentSitemap._id})`); } else { $('#sitemap-nav-button').addClass('disabled'); $('#navbar-active-sitemap-id').text(''); } if (navigationId.match(/^create-sitemap-/)) { - $('#create-sitemap-nav-button') - .closest('li') - .addClass('active'); + $('#create-sitemap-nav-button').closest('li').addClass('active'); } } @@ -335,11 +342,10 @@ export default class SitemapController { * @returns {Boolean} */ isValidForm() { - let validator = this.getFormValidator(); - - //validator.validate(); + const validator = this.getFormValidator(); + // validator.validate(); // validate method calls submit which is not needed in this case. - for (let field in validator.options.fields) { + for (const field in validator.options.fields) { validator.validateField(field); } @@ -355,20 +361,20 @@ export default class SitemapController { _id: { validators: { notEmpty: { - message: 'The sitemap id is required and cannot be empty', + message: Translator.getTranslationByKey('sitemapid_empty_message'), }, stringLength: { min: 3, - message: 'The sitemap id should be at least 3 characters long', + message: Translator.getTranslationByKey('sitemapid_short_message'), }, regexp: { regexp: /^[a-z][a-z0-9_\$\(\)\+\-/]+$/, - message: 'Only lowercase characters (a-z), digits (0-9), or any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.', + message: Translator.getTranslationByKey('sitemapid_invalid_char'), }, // placeholder for sitemap id existance validation callback: { - message: 'Sitemap with this id already exists', - callback: function() { + message: Translator.getTranslationByKey('sitemapid_repeated_id'), + callback() { return true; }, }, @@ -377,11 +383,11 @@ export default class SitemapController { startUrls: { validators: { notEmpty: { - message: 'The start URL is required and cannot be empty', + message: Translator.getTranslationByKey('sitemapurl_empty_message'), }, callback: { - message: 'The start URLs are not valid. Please use "," as a seperator.', - callback: function(value) { + message: Translator.getTranslationByKey('sitemapurl_invalid_message'), + callback(value) { return Sitemap.validateStartUrls(value.split(',')); }, }, @@ -390,10 +396,12 @@ export default class SitemapController { model: { validators: { callback: { - callback: function(value) { + callback(value) { if (!value) { return { - message: 'Empty value is possible model', + message: Translator.getTranslationByKey( + 'sitemapmodel_empty_message' + ), valid: true, }; } @@ -402,10 +410,12 @@ export default class SitemapController { } catch (e) { return { valid: false, - message: 'JSON is not valid', + message: Translator.getTranslationByKey( + 'sitemapjson_invalid_message' + ), }; } - }.bind(this), + }, }, }, }, @@ -415,14 +425,10 @@ export default class SitemapController { showCreateSitemap() { this.setActiveNavigationButton('create-sitemap-create'); - let sitemapForm = ich.SitemapCreate(); + const sitemapForm = ich.SitemapCreate(); $('#viewport').html(sitemapForm); this.initSitemapValidation(); - - // //XXX quickFix for new sitemap creation bug - let validator = this.getFormValidator(); - validator.updateStatus('model', 'VALID', 'callback'); - + Translator.translatePage(); return true; } @@ -433,85 +439,100 @@ export default class SitemapController { validators: { stringLength: { min: 3, - message: 'The sitemap id should be at least 3 characters long', + message: Translator.getTranslationByKey('sitemapid_short_message'), }, regexp: { regexp: /^[a-z][a-z0-9_\$\(\)\+\-/]+$/, - message: 'Only lowercase characters (a-z), digits (0-9), or any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.', + message: Translator.getTranslationByKey('sitemapid_invalid_char'), }, // placeholder for sitemap id existance validation callback: { - message: 'Sitemap with this id already exists', - callback: function(value, validator) { + message: Translator.getTranslationByKey('sitemapid_repeated_id'), + callback(value, validator) { validator.revalidateField('sitemapJSON'); return true; - }.bind(this), + }, }, }, }, sitemapJSON: { validators: { notEmpty: { - message: 'Sitemap JSON is required and cannot be empty', + message: Translator.getTranslationByKey('sitemapjson_empty_message'), }, callback: { - message: 'JSON is not valid', - callback: function(value, validator) { + message: Translator.getTranslationByKey('sitemapjson_invalid_message'), + callback(value, validator) { try { - let sitemap = JSON.parse(value); + const sitemap = JSON.parse(value); - let renameId = $('#viewport form [name="_id"]').val(); + const renameId = $('#viewport form [name="_id"]').val(); if (!renameId) { if (!sitemap.hasOwnProperty('_id')) { return { valid: false, - message: 'The sitemap id is required and cannot be empty', + message: Translator.getTranslationByKey( + 'sitemapid_empty_message' + ), }; } if (sitemap._id.length < 3) { return { valid: false, - message: 'The sitemap id should be at least 3 characters long', + message: Translator.getTranslationByKey( + 'sitemapid_short_message' + ), }; } - if (!sitemap._id.match('^[a-z][a-z0-9_\\$\\(\\)\\+\\-/]+$')) { + if ( + !sitemap._id.match('^[a-z][a-z0-9_\\$\\(\\)\\+\\-/]+$') + ) { return { valid: false, - message: - 'Only lowercase characters (a-z), digits (0-9), or any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.', + message: Translator.getTranslationByKey( + 'sitemapid_invalid_char' + ), }; } } - //check for start urls + // check for start urls if (!sitemap.hasOwnProperty('startUrls')) { return { valid: false, - message: 'The start URL is required and cannot be empty', + message: Translator.getTranslationByKey( + 'sitemapurl_empty_message' + ), }; } if (!Sitemap.validateStartUrls(sitemap.startUrls)) { return { valid: false, - message: 'The start URLs are not valid', + message: Translator.getTranslationByKey( + 'sitemapurl_invalid_message' + ), }; } - let result = Model.validateModel(sitemap.model); + const result = Model.validateModel(sitemap.model); if (!result.valid) { return result; } } catch (e) { return { valid: false, - message: 'JSON is not valid', + message: Translator.getTranslationByKey( + 'sitemapjson_invalid_message' + ), }; } return { - message: 'Valid sitemap', + message: Translator.getTranslationByKey( + 'sitemap_valid_message' + ), valid: true, }; - }.bind(this), + }, }, }, }, @@ -519,141 +540,153 @@ export default class SitemapController { }); } + readBlob() { + const { files } = $('#sitemapFiles')[0]; + if (!files.length) { + alert(Translator.getTranslationByKey('selecting_file_error')); + return; + } + const file = files[0]; + const validator = this.getFormValidator(); + const blob = file.slice(0, file.size); + blob.text().then(text => { + $('#sitemapJSON').val(text); + validator.revalidateField('_id'); + validator.revalidateField('sitemapJSON'); + }); + return true; + } + showImportSitemapPanel() { this.setActiveNavigationButton('create-sitemap-import'); - let sitemapForm = ich.SitemapImport(); + const sitemapForm = ich.SitemapImport(); $('#viewport').html(sitemapForm); this.initImportSitemapValidation(); + Translator.translatePage(); return true; } showSitemapExportPanel() { this.setActiveNavigationButton('sitemap-export'); - let sitemap = this.state.currentSitemap; - let sitemapJSON = sitemap.exportSitemap(); - let sitemapExportForm = ich.SitemapExport({ - sitemapJSON: sitemapJSON, + const sitemap = this.state.currentSitemap; + const sitemapJSON = sitemap.exportSitemap(); + + const sitemapExportForm = ich.SitemapExport({ + sitemapJSON, }); + + const blob = new Blob([sitemapJSON], { type: 'text/json' }); + $('#viewport').html(sitemapExportForm); + Translator.translatePage(); + const downloadButton = $('#download-button'); + downloadButton.attr('href', window.URL.createObjectURL(blob)); + downloadButton.attr('download', `${sitemap._id}.json`); + return true; } - showSitemaps() { + async showSitemaps() { this.clearState(); this.setActiveNavigationButton('sitemaps'); - this.store.getAllSitemaps().then(function(sitemaps) { - var $sitemapListPanel = ich.SitemapList(); - sitemaps.forEach(function(sitemap) { - var $sitemap = ich.SitemapListItem(sitemap); - $sitemap.data('sitemap', sitemap); - $sitemapListPanel.find('tbody').append($sitemap); - }); - $('#viewport').html($sitemapListPanel); + const sitemaps = await this.store.getAllSitemaps(); + const $sitemapListPanel = ich.SitemapList(); + + sitemaps.forEach(sitemap => { + const $sitemap = ich.SitemapListItem(sitemap); + $sitemap.data('sitemap', sitemap); + $sitemapListPanel.find('tbody').append($sitemap); }); + $('#viewport').html($sitemapListPanel); + Translator.translatePage(); } getSitemapFromMetadataForm() { - let id = $('#viewport form input[name=_id]').val(); - let $startUrlInputs = $('#viewport form .input-start-url'); - let startUrls = $startUrlInputs + const id = $('#viewport form input[name=_id]').val(); + const $startUrlInputs = $('#viewport form .input-start-url'); + const startUrls = $startUrlInputs .val() .split(',') .map(item => item.trim()); - let model = $('#viewport .input-model').val(); - if (model) { - return { - id: id, - startUrls: startUrls, - model: JSON.parse(model), - }; - } else { - return { - id: id, - startUrls: startUrls, - }; - } + const modelStr = $('#viewport .input-model').val(); + return { + id, + startUrls, + model: modelStr ? JSON.parse(modelStr) : undefined, + }; } - createSitemap() { + async createSitemap() { // cancel submit if invalid form + if (!this.isValidForm()) { return false; } - let sitemapData = this.getSitemapFromMetadataForm(); + const sitemapData = this.getSitemapFromMetadataForm(); // check whether sitemap with this id already exist - this.store.sitemapExists(sitemapData.id).then( - function(sitemapExists) { - if (sitemapExists) { - let validator = this.getFormValidator(); - validator.updateStatus('_id', 'INVALID', 'callback'); - } else { - let sitemap = new Sitemap({ - _id: sitemapData.id, - startUrls: sitemapData.startUrls, - model: sitemapData.model, - selectors: [], - }); - this.store.createSitemap(sitemap).then( - function(sitemap) { - this._editSitemap(sitemap, ['_root']); - }.bind(this, sitemap) - ); - } - }.bind(this) - ); + const sitemapExists = await this.store.sitemapExists(sitemapData.id); + if (sitemapExists) { + const validator = this.getFormValidator(); + validator.updateStatus('_id', 'INVALID', 'callback'); + } else { + let sitemap = new Sitemap(sitemapData.id, sitemapData.startUrls, sitemapData.model, []); + sitemap = await this.store.createSitemap(sitemap); + this._editSitemap(sitemap, ['_root']); + } } - importSitemap() { + async importSitemap() { // cancel submit if invalid form + if (!this.isValidForm()) { return false; } - // load data from form - let sitemapJSON = $('[name=sitemapJSON]').val(); + const sitemapJSON = $('[name=sitemapJSON]').val(); + const sitemapObj = JSON.parse(sitemapJSON); + let id = $('input[name=_id]').val(); - let sitemap = new Sitemap(); - sitemap.importSitemap(sitemapJSON); - if (id.length) { - sitemap._id = id; + if (!id) { + id = sitemapObj._id; } + // check whether sitemap with this id already exist - this.store.sitemapExists(sitemap._id).then( - function(sitemapExists) { - if (sitemapExists) { - let validator = this.getFormValidator(); - validator.updateStatus('_id', 'INVALID', 'callback'); - } else { - this.store.createSitemap(sitemap).then( - function(sitemap) { - this._editSitemap(sitemap, ['_root']); - }.bind(this) - ); - } - }.bind(this) - ); + const sitemapExists = await this.store.sitemapExists(id); + if (sitemapExists) { + const validator = this.getFormValidator(); + validator.updateStatus('_id', 'INVALID', 'callback'); + } else { + let sitemap = new Sitemap( + id, + sitemapObj.startUrls, + sitemapObj.model, + sitemapObj.selectors + ); + sitemap = await this.store.createSitemap(sitemap); + this._editSitemap(sitemap, ['_root']); + } } - editSitemapMetadata(button) { + editSitemapMetadata() { this.setActiveNavigationButton('sitemap-edit-metadata'); - let sitemap = this.state.currentSitemap; + const sitemap = this.state.currentSitemap.clone(); if (sitemap.model) { - sitemap.model = JSON.stringify(sitemap.model, null, 4); + sitemap.model = sitemap.model.toString(); } - let $sitemapMetadataForm = ich.SitemapEditMetadata(sitemap); + const $sitemapMetadataForm = ich.SitemapEditMetadata(sitemap); $('#viewport').html($sitemapMetadataForm); this.initSitemapValidation(); - + Translator.translatePage(); return true; } - editSitemapMetadataSave(button) { - let sitemap = this.state.currentSitemap; - let sitemapData = this.getSitemapFromMetadataForm(); + async editSitemapMetadataSave() { + const sitemap = this.state.currentSitemap; + const sitemapData = this.getSitemapFromMetadataForm(); // cancel submit if invalid form if (!this.isValidForm()) { @@ -661,54 +694,44 @@ export default class SitemapController { } // check whether sitemap with this id already exist - this.store.sitemapExists(sitemapData.id).then( - function(sitemapExists) { - if (sitemap._id !== sitemapData.id && sitemapExists) { - let validator = this.getFormValidator(); - validator.updateStatus('_id', 'INVALID', 'callback'); - return; - } + const sitemapExists = await this.store.sitemapExists(sitemapData.id); - // change data - sitemap.startUrls = sitemapData.startUrls; - sitemap.model = sitemapData.model; - - // just change sitemaps url - if (sitemapData.id === sitemap._id) { - this.store.saveSitemap(sitemap).then( - function(sitemap) { - this.showSitemapSelectorList(); - }.bind(this) - ); - } - // id changed. we need to delete the old one and create a new one - else { - let newSitemap = new Sitemap(sitemap); - let oldSitemap = sitemap; - newSitemap._id = sitemapData.id; - if (newSitemap._rev) { - delete newSitemap._rev; - } - this.store.createSitemap(newSitemap).then( - function(newSitemap) { - this.store.deleteSitemap(oldSitemap).then( - function() { - this.state.currentSitemap = newSitemap; - this.showSitemapSelectorList(); - }.bind(this) - ); - }.bind(this) - ); - } - }.bind(this) - ); + if (sitemap._id !== sitemapData.id && sitemapExists) { + const validator = this.getFormValidator(); + validator.updateStatus('_id', 'INVALID', 'callback'); + return false; + } + + // just change sitemaps url + if (sitemapData.id === sitemap._id) { + // change data + sitemap.startUrls = sitemapData.startUrls; + sitemap.model = new Model(sitemapData.model); + await this.store.saveSitemap(sitemap); + } else { + // id changed. we need to delete the old one and create a new one + const oldSitemap = sitemap; + const newSitemap = new Sitemap( + sitemapData.id, + sitemapData.startUrls, + sitemapData.model, + sitemap.selectors + ); + if (newSitemap._rev) { + delete newSitemap._rev; + } + await this.store.createSitemap(newSitemap); + await this.store.deleteSitemap(oldSitemap); + this.state.currentSitemap = newSitemap; + } + this.showSitemapSelectorList(); } /** * Callback when sitemap edit button is clicked in sitemap grid */ - editSitemap(tr) { - let sitemap = $(tr).data('sitemap'); + editSitemap(td) { + const sitemap = $(td).parent().data('sitemap'); this._editSitemap(sitemap); } @@ -722,48 +745,49 @@ export default class SitemapController { showSitemapSelectorList() { this.setActiveNavigationButton('sitemap-selector-list'); - let sitemap = this.state.currentSitemap; - let parentSelectors = this.state.editSitemapBreadcumbsSelectors; - let parentSelectorId = this.state.currentParentSelectorId; + const sitemap = this.state.currentSitemap; + const parentSelectors = this.state.editSitemapBreadcumbsSelectors; + const parentSelectorId = this.state.currentParentSelectorId; - let $selectorListPanel = ich.SelectorList({ - parentSelectors: parentSelectors, + const $selectorListPanel = ich.SelectorList({ + parentSelectors, }); - let selectors = sitemap.getDirectChildSelectors(parentSelectorId); - selectors.forEach(function(selector) { - let $selector = ich.SelectorListItem(selector); + const selectors = sitemap.getDirectChildSelectors(parentSelectorId); + selectors.forEach(selector => { + const selectorType = this.selectorTypes.find(selType => selType.type === selector.type); + const $selector = ich.SelectorListItem({ ...selector, title: selectorType.title }); $selector.data('selector', selector); $selectorListPanel.find('tbody').append($selector); }); $('#viewport').html($selectorListPanel); - + Translator.translatePage(); return true; } showSitemapSelectorGraph() { this.setActiveNavigationButton('sitemap-selector-graph'); - let sitemap = this.state.currentSitemap; - let $selectorGraphPanel = ich.SitemapSelectorGraph(); + const sitemap = this.state.currentSitemap; + const $selectorGraphPanel = ich.SitemapSelectorGraph(); $('#viewport').html($selectorGraphPanel); - let graphDiv = $('#selector-graph')[0]; - let graph = new SelectorGraphv2(sitemap); + const graphDiv = $('#selector-graph')[0]; + const graph = new SelectorGraphv2(sitemap); graph.draw(graphDiv, $(document).width(), 200); return true; } showChildSelectors(tr) { - let selector = $(tr).data('selector'); - let parentSelectors = this.state.editSitemapBreadcumbsSelectors; + const selector = $(tr).data('selector'); + const parentSelectors = this.state.editSitemapBreadcumbsSelectors; this.state.currentParentSelectorId = selector.id; parentSelectors.push(selector); this.showSitemapSelectorList(); } - treeNavigationshowSitemapSelectorList(button) { - let parentSelectors = this.state.editSitemapBreadcumbsSelectors; - let controller = this; - $('#selector-tree .breadcrumb li a').each(function(i, parentSelectorButton) { + treeNavigationShowSitemapSelectorList(button) { + const parentSelectors = this.state.editSitemapBreadcumbsSelectors; + const controller = this; + $('#selector-tree .breadcrumb li a').each(function (i, parentSelectorButton) { if (parentSelectorButton === button) { parentSelectors.splice(i + 1); controller.state.currentParentSelectorId = parentSelectors[i].id; @@ -778,37 +802,39 @@ export default class SitemapController { id: { validators: { notEmpty: { - message: 'Sitemap id required and cannot be empty', + message: Translator.getTranslationByKey('sitemapid_empty_message'), }, stringLength: { min: 3, - message: 'The sitemap id should be atleast 3 characters long', + message: Translator.getTranslationByKey('sitemapid_short_message'), }, regexp: { regexp: /^[^_].*$/, - message: 'Selector id cannot start with an underscore _', + message: Translator.getTranslationByKey('selectorid_underscore'), }, }, }, selector: { validators: { notEmpty: { - message: 'Selector is required and cannot be empty', + message: Translator.getTranslationByKey('selector_empty_message'), }, }, }, regex: { validators: { callback: { - message: 'JavaScript does not support regular expressions that can match 0 characters.', - callback: function(value, validator) { + message: Translator.getTranslationByKey( + 'regex_regular_expressions_error_message' + ), + callback(value, validator) { // allow no regex if (!value) { return true; } try { - let matches = ''.match(new RegExp(value)); + const matches = ''.match(new RegExp(value)); return !(matches !== null && matches[0] === ''); } catch (e) { return false; @@ -820,8 +846,10 @@ export default class SitemapController { regexgroup: { validators: { callback: { - message: 'Regex group must be numeric', - callback: function(value, validator) { + message: Translator.getTranslationByKey( + 'regex_group_numeric_error_message' + ), + callback(value, validator) { if (value === '') { return true; } @@ -833,39 +861,47 @@ export default class SitemapController { clickElementSelector: { validators: { notEmpty: { - message: 'Click selector is required and cannot be empty', + message: Translator.getTranslationByKey('selector_click_empty_message'), }, }, }, tableHeaderRowSelector: { validators: { notEmpty: { - message: 'Header row selector is required and cannot be empty', + message: Translator.getTranslationByKey( + 'selector_header_empty_message' + ), }, }, }, tableDataRowSelector: { validators: { notEmpty: { - message: 'Data row selector is required and cannot be empty', + message: Translator.getTranslationByKey( + 'selector_data_row_empty_message' + ), }, }, }, delay: { validators: { numeric: { - message: 'Delay must be numeric', + message: Translator.getTranslationByKey('delay_numeric_message'), }, }, }, paginationLimit: { validators: { numeric: { - message: 'Pagination limit must be numeric or empty', + message: Translator.getTranslationByKey( + 'pagination_limit_numeric_message' + ), }, callback: { - message: 'Pagination limit must be 1 at least', - callback: function(value, validator) { + message: Translator.getTranslationByKey( + 'pagination_limit_small_message' + ), + callback(value, validator) { if (!value) { return true; } @@ -877,12 +913,16 @@ export default class SitemapController { parentSelectors: { validators: { notEmpty: { - message: 'You must choose at least one parent selector', + message: Translator.getTranslationByKey( + 'parent_selector_empty_message' + ), }, callback: { - message: 'Cannot handle recursive element selectors', - callback: function(value, validator, $field) { - let sitemap = this.getCurrentlyEditedSelectorSitemap(); + message: Translator.getTranslationByKey( + 'handle_recursive_error_message' + ), + callback: function (value, validator, $field) { + const sitemap = this.getCurrentlyEditedSelectorSitemap(); return !sitemap.selectors.hasRecursiveElementSelectors(); }.bind(this), }, @@ -893,50 +933,31 @@ export default class SitemapController { } editSelector(button) { - let selector = $(button) - .closest('tr') - .data('selector'); + const selector = $(button).closest('tr').data('selector'); this._editSelector(selector); } updateSelectorParentListOnIdChange() { - let selector = this.getCurrentlyEditedSelector(); - $('.currently-edited') - .val(selector.id) - .text(selector.id); + const selector = this.getCurrentlyEditedSelector(); + $('.currently-edited').val(selector.id).text(selector.id); } _editSelector(selector) { - let sitemap = this.state.currentSitemap; - let selectorIds = sitemap.getPossibleParentSelectorIds(); + const sitemap = this.state.currentSitemap; + const selectorIds = sitemap.getPossibleParentSelectorIds(); - let $editSelectorForm = ich.SelectorEdit({ - selector: selector, - selectorIds: selectorIds, + const $editSelectorForm = ich.SelectorEdit({ + selector, + selectorIds, selectorTypes: this.selectorTypes, }); $('#viewport').html($editSelectorForm); - //TODO move this check to Model class - let data = []; - let idInData = false; - if (sitemap.model) { - for (let field of sitemap.model) { - data.push(field); - if (field.field_name === selector.id) { - idInData = true; - } - } - } - if (!idInData && selector.id) { - data.push({ field: '', entity: '', field_name: selector.id }); - } - $('#selectorId').flexdatalist({ init: this.initSelectorValidation(), - textProperty: '{field_name}', - valueProperty: 'field_name', - data: data, + textProperty: '{fieldName}', + valueProperty: 'fieldName', + data: [...sitemap.model, { entity: '', field: '', fieldName: selector.id }], searchIn: ['entity', 'field'], visibleProperties: ['entity', 'field'], groupBy: 'entity', @@ -946,7 +967,7 @@ export default class SitemapController { }); // mark initially opened selector as currently edited - $('#edit-selector #parentSelectors option').each(function(i, element) { + $('#edit-selector #parentSelectors option').each((_, element) => { if ($(element).val() === selector.id) { $(element).addClass('currently-edited'); } @@ -959,28 +980,33 @@ export default class SitemapController { // set clickElementUniquenessType if (selector.clickElementUniquenessType) { - $editSelectorForm.find('[name=clickElementUniquenessType]').val(selector.clickElementUniquenessType); + $editSelectorForm + .find('[name=clickElementUniquenessType]') + .val(selector.clickElementUniquenessType); } // handle selects seperately $editSelectorForm.find('[name=type]').val(selector.type); - selector.parentSelectors.forEach(function(parentSelectorId) { - $editSelectorForm.find("#parentSelectors [value='" + parentSelectorId + "']").attr('selected', 'selected'); + selector.parentSelectors.forEach(parentSelectorId => { + $editSelectorForm + .find(`#parentSelectors [value='${parentSelectorId}']`) + .attr('selected', 'selected'); }); this.state.currentSelector = selector; this.selectorTypeChanged(false); + Translator.translatePage(); } selectorTypeChanged(changeTrigger) { // let type = $('#edit-selector select[name=type]').val(); // add this selector to possible parent selector - let selector = this.getCurrentlyEditedSelector(); + const selector = this.getCurrentlyEditedSelector(); // this.state.currentSelector = selector; - let features = selector.getFeatures(); + const features = selector.getFeatures(); $('#edit-selector .feature').hide(); - features.forEach(function(feature) { - $('#edit-selector .feature-' + feature).show(); + features.forEach(function (feature) { + $(`#edit-selector .feature-${feature}`).show(); }); if (changeTrigger && selector.type === 'SelectorLink') { @@ -989,7 +1015,7 @@ export default class SitemapController { if (selector.canHaveChildSelectors()) { if ($('#edit-selector #parentSelectors .currently-edited').length === 0) { - let $option = $(''); + const $option = $(''); $option.text(selector.id).val(selector.id); $('#edit-selector #parentSelectors').append($option); } @@ -1001,10 +1027,11 @@ export default class SitemapController { } saveSelector(button) { - let sitemap = this.state.currentSitemap; - let selector = this.state.currentSelector; - let newSelector = this.getCurrentlyEditedSelector(); - + const sitemap = this.state.currentSitemap; + const selector = this.state.currentSelector; + const newSelector = this.getCurrentlyEditedSelector(); + const validator = this.getFormValidator(); + validator.revalidateField('id'); // cancel submit if invalid form if (!this.isValidForm()) { return false; @@ -1012,10 +1039,10 @@ export default class SitemapController { // cancel possible element selection this.contentScript.removeCurrentContentSelector().done( - function() { + function () { sitemap.updateSelector(selector, newSelector); this.store.saveSitemap(sitemap).then( - function() { + function () { this.showSitemapSelectorList(); }.bind(this) ); @@ -1027,36 +1054,42 @@ export default class SitemapController { * Get selector from selector editing form */ getCurrentlyEditedSelector() { - let id = $('#edit-selector [name=id]').val(); - let selectorsSelector = $('#edit-selector [name=selector]').val(); - let tableDataRowSelector = $('#edit-selector [name=tableDataRowSelector]').val(); - let tableHeaderRowSelector = $('#edit-selector [name=tableHeaderRowSelector]').val(); - let tableAddMissingColumns = $('#edit-selector [name=tableAddMissingColumns]').is(':checked'); - let verticalTable = $('#edit-selector [name=verticalTable]').is(':checked'); - let clickElementSelector = $('#edit-selector [name=clickElementSelector]').val(); - let type = $('#edit-selector [name=type]').val(); - let clickElementUniquenessType = $('#edit-selector [name=clickElementUniquenessType]').val(); - let clickType = $('#edit-selector [name=clickType]').val(); - let paginationLimit = $('#edit-selector [name=paginationLimit]').val(); - let discardInitialElements = $('#edit-selector [name=discardInitialElements]').is(':checked'); - let multiple = $('#edit-selector [name=multiple]').is(':checked'); - let downloadImage = $('#edit-selector [name=downloadImage]').is(':checked'); - let downloadDocument = $('#edit-selector [name=downloadDocument]').is(':checked'); - let clickPopup = $('#edit-selector [name=clickPopup]').is(':checked'); - let delay = $('#edit-selector [name=delay]').val(); - let extractAttribute = $('#edit-selector [name=extractAttribute]').val(); - let extractStyle = $('#edit-selector [name=extractStyle]').val(); - let value = $('#edit-selector [name=value]').val(); - let parentSelectors = $('#edit-selector [name=parentSelectors]').val(); - let columns = []; - let $columnHeaders = $('#edit-selector .column-header'); - let $columnNames = $('#edit-selector .column-name'); - let $columnExtracts = $('#edit-selector .column-extract'); - let stringReplacement = { + const id = $('#edit-selector [name=id]').val(); + const selectorsSelector = $('#edit-selector [name=selector]').val(); + const tableDataRowSelector = $('#edit-selector [name=tableDataRowSelector]').val(); + const tableHeaderRowSelector = $('#edit-selector [name=tableHeaderRowSelector]').val(); + const tableAddMissingColumns = $('#edit-selector [name=tableAddMissingColumns]').is( + ':checked' + ); + const verticalTable = $('#edit-selector [name=verticalTable]').is(':checked'); + const clickElementSelector = $('#edit-selector [name=clickElementSelector]').val(); + const type = $('#edit-selector [name=type]').val(); + const clickElementUniquenessType = $( + '#edit-selector [name=clickElementUniquenessType]' + ).val(); + const clickType = $('#edit-selector [name=clickType]').val(); + const paginationLimit = $('#edit-selector [name=paginationLimit]').val(); + const discardInitialElements = $('#edit-selector [name=discardInitialElements]').is( + ':checked' + ); + const multiple = $('#edit-selector [name=multiple]').is(':checked'); + const downloadImage = $('#edit-selector [name=downloadImage]').is(':checked'); + const downloadDocument = $('#edit-selector [name=downloadDocument]').is(':checked'); + const clickPopup = $('#edit-selector [name=clickPopup]').is(':checked'); + const delay = $('#edit-selector [name=delay]').val(); + const extractAttribute = $('#edit-selector [name=extractAttribute]').val(); + const extractStyle = $('#edit-selector [name=extractStyle]').val(); + const value = $('#edit-selector [name=value]').val(); + const parentSelectors = $('#edit-selector [name=parentSelectors]').val(); + const columns = []; + const $columnHeaders = $('#edit-selector .column-header'); + const $columnNames = $('#edit-selector .column-name'); + const $columnExtracts = $('#edit-selector .column-extract'); + const stringReplacement = { replaceString: $('#edit-selector [name=replaceString]').val(), replacementString: $('#edit-selector [name=replacementString]').val(), }; - let textmanipulation = { + const textmanipulation = { removeHtml: $('#edit-selector [name=removeHtml]').is(':checked'), trimText: $('#edit-selector [name=trimText]').is(':checked'), replaceText: $('#edit-selector [name=replaceText]').val(), @@ -1067,42 +1100,42 @@ export default class SitemapController { regexgroup: $('#edit-selector [name=regexgroup]').val(), }; - $columnHeaders.each(function(i) { - let header = $($columnHeaders[i]).val(); - let name = $($columnNames[i]).val(); - let extract = $($columnExtracts[i]).is(':checked'); + $columnHeaders.each(function (i) { + const header = $($columnHeaders[i]).val(); + const name = $($columnNames[i]).val(); + const extract = $($columnExtracts[i]).is(':checked'); columns.push({ - header: header, - name: name, - extract: extract, + header, + name, + extract, }); }); return SelectorList.createSelector({ - id: id, + id, selector: selectorsSelector, - tableHeaderRowSelector: tableHeaderRowSelector, - tableAddMissingColumns: tableAddMissingColumns, - verticalTable: verticalTable, - tableDataRowSelector: tableDataRowSelector, - clickElementSelector: clickElementSelector, - clickElementUniquenessType: clickElementUniquenessType, - clickType: clickType, - paginationLimit: paginationLimit, - discardInitialElements: discardInitialElements, - type: type, - multiple: multiple, - downloadImage: downloadImage, - downloadDocument: downloadDocument, - clickPopup: clickPopup, - extractAttribute: extractAttribute, - extractStyle: extractStyle, - value: value, - parentSelectors: parentSelectors, - columns: columns, - delay: delay, - textmanipulation: textmanipulation, - stringReplacement: stringReplacement, + tableHeaderRowSelector, + tableAddMissingColumns, + verticalTable, + tableDataRowSelector, + clickElementSelector, + clickElementUniquenessType, + clickType, + paginationLimit, + discardInitialElements, + type, + multiple, + downloadImage, + downloadDocument, + clickPopup, + extractAttribute, + extractStyle, + value, + parentSelectors, + columns, + delay, + textmanipulation, + stringReplacement, }); } @@ -1110,9 +1143,9 @@ export default class SitemapController { * @returns {Sitemap|*} Cloned Sitemap with currently edited selector */ getCurrentlyEditedSelectorSitemap() { - let sitemap = this.state.currentSitemap.clone(); - let selector = sitemap.getSelectorById(this.state.currentSelector.id); - let newSelector = this.getCurrentlyEditedSelector(); + const sitemap = this.state.currentSitemap.clone(); + const selector = sitemap.getSelectorById(this.state.currentSelector.id); + const newSelector = this.getCurrentlyEditedSelector(); sitemap.updateSelector(selector, newSelector); return sitemap; } @@ -1120,17 +1153,17 @@ export default class SitemapController { cancelSelectorEditing(button) { // cancel possible element selection this.contentScript.removeCurrentContentSelector().done( - function() { + function () { this.showSitemapSelectorList(); }.bind(this) ); } addSelector() { - let parentSelectorId = this.state.currentParentSelectorId; - let sitemap = this.state.currentSitemap; + const parentSelectorId = this.state.currentParentSelectorId; + const sitemap = this.state.currentSitemap; - let selector = SelectorList.createSelector({ + const selector = SelectorList.createSelector({ parentSelectors: [parentSelectorId], type: 'SelectorText', multiple: false, @@ -1140,25 +1173,21 @@ export default class SitemapController { } deleteSelector(button) { - let sitemap = this.state.currentSitemap; - let selector = $(button) - .closest('tr') - .data('selector'); + const sitemap = this.state.currentSitemap; + const selector = $(button).closest('tr').data('selector'); sitemap.deleteSelector(selector); this.store.saveSitemap(sitemap).then( - function() { + function () { this.showSitemapSelectorList(); }.bind(this) ); } deleteSitemap(button) { - let sitemap = $(button) - .closest('tr') - .data('sitemap'); - let controller = this; - this.store.deleteSitemap(sitemap).then(function() { + const sitemap = $(button).closest('tr').data('sitemap'); + const controller = this; + this.store.deleteSitemap(sitemap).then(function () { controller.showSitemaps(); }); } @@ -1169,14 +1198,20 @@ export default class SitemapController { requestInterval: { validators: { notEmpty: { - message: 'The request interval is required and cannot be empty', + message: Translator.getTranslationByKey( + 'request_interval_empty_message' + ), }, numeric: { - message: 'The request interval must be numeric', + message: Translator.getTranslationByKey( + 'request_interval_numeric_message' + ), }, callback: { - message: 'The request interval must be atleast 2000 milliseconds', - callback: function(value, validator) { + message: Translator.getTranslationByKey( + 'request_interval_short_message' + ), + callback(value, validator) { return value >= 2000; }, }, @@ -1185,24 +1220,34 @@ export default class SitemapController { requestIntervalRandomness: { validators: { notEmpty: { - message: 'The request interval randomness is required and cannot be empty', + message: Translator.getTranslationByKey( + 'request_interval_randomness_empty_message' + ), }, numeric: { - message: 'The request interval randomness must be numeric', + message: Translator.getTranslationByKey( + 'request_interval_randomness_numeric_message' + ), }, }, }, pageLoadDelay: { validators: { notEmpty: { - message: 'The page load delay is required and cannot be empty', + message: Translator.getTranslationByKey( + 'page_load_delay_empty_message' + ), }, numeric: { - message: 'The page laod delay must be numeric', + message: Translator.getTranslationByKey( + 'page_load_delay_numeric_message' + ), }, callback: { - message: 'The page load delay must be atleast 500 milliseconds', - callback: function(value, validator) { + message: Translator.getTranslationByKey( + 'page_load_delay_short_message' + ), + callback(value, validator) { return value >= 500; }, }, @@ -1214,9 +1259,10 @@ export default class SitemapController { showScrapeSitemapConfigPanel() { this.setActiveNavigationButton('sitemap-scrape'); - let scrapeConfigPanel = ich.SitemapScrapeConfig(); + const scrapeConfigPanel = ich.SitemapScrapeConfig(); $('#viewport').html(scrapeConfigPanel); this.initScrapeSitemapConfigValidation(); + Translator.translatePage(); return true; } @@ -1225,29 +1271,27 @@ export default class SitemapController { return false; } - let requestInterval = $('input[name=requestInterval]').val(); - let pageLoadDelay = $('input[name=pageLoadDelay]').val(); - let intervalRandomness = $('input[name=requestIntervalRandomness]').val(); + const requestInterval = $('input[name=requestInterval]').val(); + const pageLoadDelay = $('input[name=pageLoadDelay]').val(); + const intervalRandomness = $('input[name=requestIntervalRandomness]').val(); - let sitemap = this.state.currentSitemap; - let request = { + const sitemap = this.state.currentSitemap; + const request = { scrapeSitemap: true, sitemap: JSON.parse(JSON.stringify(sitemap)), - requestInterval: requestInterval, - pageLoadDelay: pageLoadDelay, + requestInterval, + pageLoadDelay, requestIntervalRandomness: intervalRandomness, }; // show sitemap scraping panel this.getFormValidator().destroy(); $('.scraping-in-progress').removeClass('hide'); - $('#submit-scrape-sitemap') - .closest('.form-group') - .hide(); + $('#submit-scrape-sitemap').closest('.form-group').hide(); $('#scrape-sitemap-config input').prop('disabled', true); browser.runtime.sendMessage(request).then( - function(selectors) { + function (selectors) { // table selector can dynamically add columns // replace current selector (columns) with the dynamicly created once sitemap.selectors = new SelectorList(selectors); @@ -1258,215 +1302,336 @@ export default class SitemapController { } sitemapListBrowseSitemapData(button) { - let sitemap = $(button) - .closest('tr') - .data('sitemap'); + const sitemap = $(button).closest('tr').data('sitemap'); this.setStateEditSitemap(sitemap); this.browseSitemapData(); } browseSitemapData() { this.setActiveNavigationButton('sitemap-browse'); - let sitemap = this.state.currentSitemap; - this.store.getSitemapData(sitemap).then( - function(data) { - let dataColumns = sitemap.getDataColumns(); + const sitemap = this.state.currentSitemap; + this.store.getSitemapData(sitemap).then(data => { + const $dataPanel = ich.SitemapBrowseData(); + $('#viewport').html($dataPanel); + Translator.translatePage(); - let dataPanel = ich.SitemapBrowseData({ - columns: dataColumns, - }); - $('#viewport').html(dataPanel); - - // display data - // Doing this the long way so there aren't xss vulnerubilites - // while working with data or with the selector titles - let $tbody = $('#sitemap-data tbody'); - data.forEach(function(row) { - let $tr = $(''); - dataColumns.forEach(function(column) { - let $td = $(''); - let cellData = row[column]; - if (typeof cellData === 'object') { - cellData = JSON.stringify(cellData); - } - $td.text(cellData); - $tr.append($td); - }); - $tbody.append($tr); + // display data + // Doing this the long way so there aren't xss vulnerubilites + // while working with data or with the selector titles + + const $accordion = $('#sitemap-data'); + for (let rowNum = 0; rowNum < data.length; rowNum++) { + const $card = ich.ItemCard({ + id: rowNum, + url: data[rowNum]._url || `Item${rowNum}`, }); - }.bind(this) - ); + $accordion.append($card); + } + + for (let rowNum = 0; rowNum < data.length; rowNum++) { + const row = data[rowNum]; + if (row.hasOwnProperty('_id')) { + delete row._id; + } + if (row.hasOwnProperty('_rev')) { + delete row._rev; + } + $(`#json-${rowNum}`).html(this.jsonRenderer(row)); + } + + $accordion.searcher({ + itemSelector: '.panel', // jQuery selector for the data item element + textSelector: '.panel-body', // jQuery selector for the element which contains the text + inputSelector: '#search-input', // jQuery selector for the input element + }); + + $('.collapse').collapse('show'); + }); return true; } - showSitemapExportDataCsvPanel() { - this.setActiveNavigationButton('sitemap-export-data-csv'); + initSitemapExportDataValidation() { + $('#viewport form').bootstrapValidator({ + fields: { + delimiter: { + validators: { + callback: { + message: Translator.getTranslationByKey('data_export_empty_delimiter'), + callback: value => $('#export-format').val() !== 'csv' || !!value, + }, + }, + }, + }, + }); + } - let sitemap = this.state.currentSitemap; - let exportPanel = ich.SitemapExportDataCSV(sitemap); + showSitemapExportDataPanel() { + this.setActiveNavigationButton('sitemap-export-data'); + const sitemap = this.state.currentSitemap; + const exportPanel = ich.SitemapExportData(sitemap); $('#viewport').html(exportPanel); + this.initSitemapExportDataValidation(); + Translator.translatePage(); + return true; + } - $('.result').hide(); - $('.download-button').hide(); - - // generate data - $('#generate-csv').click( - function() { - $('.result').show(); - $('.download-button').hide(); - - let options = { - delimiter: $('#delimiter').val(), - newline: $('#newline').prop('checked'), - containBom: $('#utf-bom').prop('checked'), - }; - - this.store.getSitemapData(sitemap).then( - function(data) { - let blob = sitemap.getDataExportCsvBlob(data, options); - let button_a = $('.download-button a'); - button_a.attr('href', window.URL.createObjectURL(blob)); - button_a.attr('download', sitemap._id + '.csv'); - $('.download-button').show(); - $('.result').hide(); - }.bind(this) - ); - }.bind(this) - ); - + sitemapExportDataFormChanged(element) { + if (element.id === 'export-format') { + if (element.value === 'csv') { + $('#delimiter-option').show(); + } else { + $('#delimiter-option').hide(); + } + } + $('#wait-message').hide(); + $('#data-export-download-file').hide(); return true; } - selectSelector(button) { - let input = $(button) - .closest('.form-group') - .find('input.selector-value'); - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage(currentStateParentSelectorIds); + sitemapExportData() { + if (!this.isValidForm()) { + return false; + } + + const downloadButton = $('#data-export-download-file'); + const waitMessage = $('#wait-message'); + downloadButton.hide(); - let deferredSelector = this.contentScript.selectSelector({ - parentCSSSelector: parentCSSSelector, - allowedElements: selector.getItemCSSSelector(), + // displaying alert immediately looks annoying + const waitMessageTimeout = setTimeout(() => waitMessage.show(), 100); + + const sitemap = this.state.currentSitemap; + const format = $('#export-format').val(); + const options = { + delimiter: $('#delimiter').val(), + newline: $('#newline').prop('checked'), + containBom: $('#utf-bom').prop('checked'), + }; + + const dataPromise = + format === 'csv' + ? this.getDataExportCsvBlob(sitemap, options) + : this.getDataExportJsonLinesBlob(sitemap, options); + dataPromise.then(blob => { + clearTimeout(waitMessageTimeout); + waitMessage.hide(); + downloadButton.attr('href', window.URL.createObjectURL(blob)); + downloadButton.attr('download', `${sitemap._id}.${format}`); + downloadButton.show(); }); - deferredSelector.done( - function(result) { - $(input).val(result.CSSSelector); - - // update validation for selector field - let validator = this.getFormValidator(); - validator.revalidateField(input); - - // @TODO how could this be encapsulated? - // update header row, data row selectors after selecting the table. selectors are updated based on tables - // inner html - if (selector.type === 'SelectorTable') { - this.getSelectorHTML().done( - function(html) { - let verticalTable = this.getCurrentlyEditedSelector().verticalTable; - let tableHeaderRowSelector = SelectorTable.getTableHeaderRowSelectorFromTableHTML(html, verticalTable); - let tableDataRowSelector = SelectorTable.getTableDataRowSelectorFromTableHTML(html, verticalTable); - $('input[name=tableHeaderRowSelector]').val(tableHeaderRowSelector); - $('input[name=tableDataRowSelector]').val(tableDataRowSelector); - - let headerColumns = SelectorTable.getTableHeaderColumnsFromHTML(tableHeaderRowSelector, html, verticalTable); - this.renderTableHeaderColumns(headerColumns); - }.bind(this) - ); + return true; + } + + async getDataExportCsvBlob(sitemap, options) { + function mergeAttachments(obj, attachmentsSelectors) { + const { _attachments, ...data } = obj; + if (!_attachments) { + return data; + } + const attachments = new Map( + _attachments.map(attachment => { + const { url, ...rest } = attachment; + return [url, rest]; + }) + ); + const toAttachment = (selector, url) => { + if (url && attachments.has(url)) { + const attachment = { [selector.getUrlColumn()]: url }; + Object.entries(attachments.get(url)).forEach(([key, value]) => { + attachment[`${selector.id}-${key}`] = value; + }); + return attachment; } - }.bind(this) + return url; + }; + attachmentsSelectors.forEach(selector => { + const urlKey = selector.getUrlColumn(); + if (urlKey in data) { + const urlData = data[urlKey]; + if (Array.isArray(urlData)) { + data[urlKey] = urlData.map(url => toAttachment(selector, url)); + } else { + data[urlKey] = toAttachment(selector, urlData); + } + } + }); + return data; + } + + function splitProps(obj) { + const commonProps = {}; + const listProps = {}; + Object.entries(obj).forEach(([key, value]) => { + if (Array.isArray(value)) { + listProps[key] = value; + } else if (Object.isObject(value)) { + const [valueCommonProps, valueListProps] = splitProps(value); + Object.assign(commonProps, valueCommonProps); + Object.assign(listProps, valueListProps); + } else { + commonProps[key] = value; + } + }); + return [commonProps, listProps]; + } + + function flatten(obj) { + const [commonProps, listProps] = splitProps(obj); + const results = Object.entries(listProps).flatMap(([key, values]) => + values.flatMap(value => flatten({ ...commonProps, [key]: value })) + ); + return results.length ? results : commonProps; + } + + function addMissingProps(obj, columns) { + const objCopy = { ...obj }; + columns.forEach(column => { + if (!(column in obj)) { + objCopy[column] = ''; + } + }); + return objCopy; + } + + // default delimiter is comma + const delimiter = options.delimiter || ','; + // per default, utf8 BOM is included at the beginning + const prepend = 'containBom' in options && !options.containBom ? '' : '\ufeff'; + // per default, new line is included at end of lines + const append = 'newline' in options && !options.newline ? '' : '\r\n'; + + const data = await this.store.getSitemapData(sitemap); + const attachmentsSelectors = sitemap.selectors.filter(selector => + selector.downloadsAttachments() ); + const columns = sitemap.getDataColumns(); + const jsonData = data + .map(dataObj => mergeAttachments(dataObj, attachmentsSelectors)) + .flatMap(flatten) + .map(dataObj => addMissingProps(dataObj, columns)); + + const csvConfig = { + delimiter, + quotes: false, + quoteChar: '"', + header: true, + newline: '\r\n', // between value rows + }; + const csvData = prepend + Papa.unparse(jsonData, csvConfig) + append; + return new Blob([csvData], { type: 'text/csv' }); } - getCurrentStateParentSelectorIds() { - let parentSelectorIds = this.state.editSitemapBreadcumbsSelectors.map(function(selector) { - return selector.id; - }); + async getDataExportJsonLinesBlob(sitemap, options) { + // per default, utf8 BOM is NOT included at the beginning + const prepend = options.containBom ? '\ufeff' : ''; + // per default, new line is included at end of lines + const append = 'newline' in options && !options.newline ? '' : '\r\n'; - return parentSelectorIds; + const data = await this.store.getSitemapData(sitemap); + const jsonlData = prepend + data.map(JSON.stringify).join('\r\n') + append; + return new Blob([jsonlData], { type: 'application/x-jsonlines' }); } - refreshTableHeaderRowSelector(button) { - let input = $(button) - .closest('.form-group') - .find('input.selector-value'); - let value = input.val(); - - this.getSelectorHTML().done( - function(html) { - // let verticalTable = this.getCurrentlyEditedSelector().verticalTable; - // let tableHeaderRowSelector = SelectorTable.getTableHeaderRowSelectorFromTableHTML(html, verticalTable); - // let tableDataRowSelector = SelectorTable.getTableDataRowSelectorFromTableHTML(html, verticalTable); - // $('input[name=tableHeaderRowSelector]').val(tableHeaderRowSelector); - // $('input[name=tableDataRowSelector]').val(tableDataRowSelector); - let headerColumns = SelectorTable.getTableHeaderColumnsFromHTML(value, html); - this.renderTableHeaderColumns(headerColumns); - }.bind(this) + async selectSelector(button) { + const input = $(button).closest('.form-group').find('input.selector-value'); + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + let selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage( + currentStateParentSelectorIds ); - let validator = this.getFormValidator(); + const result = await this.contentScript + .selectSelector({ + parentCSSSelector, + allowedElements: selector.getItemCSSSelector(), + }) + .promise(); + + selector = this.getCurrentlyEditedSelector(); + await selector.afterSelect(result.CSSSelector, this); + + // update validation for selector field + const validator = this.getFormValidator(); validator.revalidateField(input); } - selectTableHeaderRowSelector(button) { - let input = $(button) - .closest('.form-group') - .find('input.selector-value'); - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage(selector.id, currentStateParentSelectorIds); + getCurrentStateParentSelectorIds() { + return this.state.editSitemapBreadcumbsSelectors.map(selector => selector.id); + } - let deferredSelector = this.contentScript.selectSelector({ - parentCSSSelector: parentCSSSelector, - allowedElements: 'tr', - }); + async refreshTableColumns() { + const selector = this.getCurrentlyEditedSelector(); - deferredSelector.done( - function(result) { - let tableHeaderRowSelector = result.CSSSelector; - $(input).val(tableHeaderRowSelector); + if (!(selector instanceof SelectorTable)) { + // wrong selector triggered this event + return false; + } - this.getSelectorHTML().done( - function(html) { - let headerColumns = SelectorTable.getTableHeaderColumnsFromHTML(tableHeaderRowSelector, html); - this.renderTableHeaderColumns(headerColumns); - }.bind(this) - ); + const html = await this.getSelectorHTML().promise(); + selector.getTableHeaderColumnsFromHTML(html); + this.renderTableHeaderColumns(selector.headerColumns); + } - // update validation for selector field - let validator = this.getFormValidator(); - validator.revalidateField(input); - }.bind(this) + async selectTableHeaderRowSelector(button) { + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + const selector = this.getCurrentlyEditedSelector(); + + if (!(selector instanceof SelectorTable)) { + // wrong selector triggered this event + return false; + } + + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage( + selector.id, + currentStateParentSelectorIds ); - } - selectTableDataRowSelector(button) { - let input = $(button) - .closest('.form-group') - .find('input.selector-value'); - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage(selector.id, currentStateParentSelectorIds); + const result = await this.contentScript + .selectSelector({ + parentCSSSelector, + allowedElements: 'tr', + }) + .promise(); - let deferredSelector = this.contentScript.selectSelector({ - parentCSSSelector: parentCSSSelector, - allowedElements: 'tr', - }); + const tableHeaderRowSelector = result.CSSSelector; + selector.tableHeaderRowSelector = tableHeaderRowSelector; - deferredSelector.done( - function(result) { - $(input).val(result.CSSSelector); + const html = this.getSelectorHTML().promise(); + selector.getTableHeaderColumnsFromHTML(html); + this.renderTableHeaderColumns(selector.headerColumns); - // update validation for selector field - let validator = this.getFormValidator(); - validator.revalidateField(input); - }.bind(this) + // update validation for selector field + const input = $(button).closest('.form-group').find('input.selector-value'); + $(input).val(tableHeaderRowSelector); + const validator = this.getFormValidator(); + validator.revalidateField(input); + } + + async selectTableDataRowSelector(button) { + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + const selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage( + selector.id, + currentStateParentSelectorIds ); + + const result = await this.contentScript + .selectSelector({ + parentCSSSelector, + allowedElements: 'tr', + }) + .promise(); + + // update validation for selector field + const input = $(button).closest('.form-group').find('input.selector-value'); + $(input).val(result.CSSSelector); + const validator = this.getFormValidator(); + validator.revalidateField(input); } /** @@ -1474,10 +1639,10 @@ export default class SitemapController { */ renderTableHeaderColumns(headerColumns) { // reset previous columns - let $tbody = $('.feature-columns table tbody'); + const $tbody = $('.feature-columns table tbody'); $tbody.html(''); - headerColumns.forEach(function(column) { - let $row = ich.SelectorEditTableColumn(column); + headerColumns.forEach(function (column) { + const $row = ich.SelectorEditTableColumn(column); $tbody.append($row); }); } @@ -1486,27 +1651,30 @@ export default class SitemapController { * Returns HTML that the current selector would select */ getSelectorHTML() { - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let CSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage(selector.id, currentStateParentSelectorIds); - let deferredHTML = this.contentScript.getHTML({ CSSSelector: CSSSelector }); - - return deferredHTML; + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + const selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const CSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage( + selector.id, + currentStateParentSelectorIds + ); + return this.contentScript.getHTML({ CSSSelector }).promise(); } previewSelector(button) { if (!$(button).hasClass('preview')) { - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage(currentStateParentSelectorIds); - let deferredSelectorPreview = this.contentScript.previewSelector({ - parentCSSSelector: parentCSSSelector, + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + const selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage( + currentStateParentSelectorIds + ); + const deferredSelectorPreview = this.contentScript.previewSelector({ + parentCSSSelector, elementCSSSelector: selector.selector, }); - deferredSelectorPreview.done(function() { + deferredSelectorPreview.done(function () { $(button).addClass('preview'); }); } else { @@ -1517,17 +1685,19 @@ export default class SitemapController { previewClickElementSelector(button) { if (!$(button).hasClass('preview')) { - let sitemap = this.state.currentSitemap; - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage(currentStateParentSelectorIds); - - let deferredSelectorPreview = this.contentScript.previewSelector({ - parentCSSSelector: parentCSSSelector, + const sitemap = this.state.currentSitemap; + const selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage( + currentStateParentSelectorIds + ); + + const deferredSelectorPreview = this.contentScript.previewSelector({ + parentCSSSelector, elementCSSSelector: selector.clickElementSelector, }); - deferredSelectorPreview.done(function() { + deferredSelectorPreview.done(function () { $(button).addClass('preview'); }); } else { @@ -1538,21 +1708,21 @@ export default class SitemapController { previewTableRowSelector(button) { if (!$(button).hasClass('preview')) { - let sitemap = this.getCurrentlyEditedSelectorSitemap(); - let selector = this.getCurrentlyEditedSelector(); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage(selector.id, currentStateParentSelectorIds); - let rowSelector = $(button) - .closest('.form-group') - .find('input') - .val(); - - let deferredSelectorPreview = this.contentScript.previewSelector({ - parentCSSSelector: parentCSSSelector, + const sitemap = this.getCurrentlyEditedSelectorSitemap(); + const selector = this.getCurrentlyEditedSelector(); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getCSSSelectorWithinOnePage( + selector.id, + currentStateParentSelectorIds + ); + const rowSelector = $(button).closest('.form-group').find('input').val(); + + const deferredSelectorPreview = this.contentScript.previewSelector({ + parentCSSSelector, elementCSSSelector: rowSelector, }); - deferredSelectorPreview.done(function() { + deferredSelectorPreview.done(function () { $(button).addClass('preview'); }); } else { @@ -1563,18 +1733,18 @@ export default class SitemapController { previewSelectorFromSelectorTree(button) { if (!$(button).hasClass('preview')) { - let sitemap = this.state.currentSitemap; - let selector = $(button) - .closest('tr') - .data('selector'); - let currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); - let parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage(currentStateParentSelectorIds); - let deferredSelectorPreview = this.contentScript.previewSelector({ - parentCSSSelector: parentCSSSelector, + const sitemap = this.state.currentSitemap; + const selector = $(button).closest('tr').data('selector'); + const currentStateParentSelectorIds = this.getCurrentStateParentSelectorIds(); + const parentCSSSelector = sitemap.selectors.getParentCSSSelectorWithinOnePage( + currentStateParentSelectorIds + ); + const deferredSelectorPreview = this.contentScript.previewSelector({ + parentCSSSelector, elementCSSSelector: selector.selector, }); - deferredSelectorPreview.done(function() { + deferredSelectorPreview.done(function () { $(button).addClass('preview'); }); } else { @@ -1584,17 +1754,15 @@ export default class SitemapController { } previewSelectorDataFromSelectorTree(button) { - let sitemap = this.state.currentSitemap; - let selector = $(button) - .closest('tr') - .data('selector'); + const sitemap = this.state.currentSitemap; + const selector = $(button).closest('tr').data('selector'); this.previewSelectorData(sitemap, selector.id); } previewSelectorDataFromSelectorEditing() { - let sitemap = this.state.currentSitemap.clone(); - let selector = sitemap.getSelectorById(this.state.currentSelector.id); - let newSelector = this.getCurrentlyEditedSelector(); + const sitemap = this.state.currentSitemap.clone(); + const selector = sitemap.getSelectorById(this.state.currentSelector.id); + const newSelector = this.getCurrentlyEditedSelector(); sitemap.updateSelector(selector, newSelector); this.previewSelectorData(sitemap, newSelector.id); } @@ -1604,8 +1772,8 @@ export default class SitemapController { * @returns {Array} */ getStateParentSelectorIds() { - let parentSelectorIds = []; - this.state.editSitemapBreadcumbsSelectors.forEach(function(selector) { + const parentSelectorIds = []; + this.state.editSitemapBreadcumbsSelectors.forEach(function (selector) { parentSelectorIds.push(selector.id); }); return parentSelectorIds; @@ -1613,51 +1781,47 @@ export default class SitemapController { previewSelectorData(sitemap, selectorId) { // data preview will be base on how the selector tree is opened - let parentSelectorIds = this.getStateParentSelectorIds(); + const parentSelectorIds = this.getStateParentSelectorIds(); - let request = { + const request = { previewSelectorData: true, sitemap: JSON.parse(JSON.stringify(sitemap)), - parentSelectorIds: parentSelectorIds, - selectorId: selectorId, + parentSelectorIds, + selectorId, }; - browser.runtime.sendMessage(request).then(function(response) { + + browser.runtime.sendMessage(request).then(response => { if (response.length === 0) { return; } - let dataColumns = Object.keys(response[0]); - console.log(dataColumns); + const $dataPreviewPanel = ich.DataPreview(); - let $dataPreviewPanel = ich.DataPreview({ - columns: dataColumns, - }); $('#viewport').append($dataPreviewPanel); $dataPreviewPanel.modal('show'); + Translator.translatePage(); // display data // Doing this the long way so there aren't xss vulnerubilites // while working with data or with the selector titles - let $tbody = $('tbody', $dataPreviewPanel); - response.forEach(function(row) { - let $tr = $(''); - dataColumns.forEach(function(column) { - let $td = $(''); - let cellData = row[column]; - if (typeof cellData === 'object') { - cellData = JSON.stringify(cellData); - } - $td.text(cellData); - $tr.append($td); + const $accordion = $('#data-preview', $dataPreviewPanel); + for (let rowNum = 0; rowNum < response.length; rowNum++) { + const $card = ich.ItemCard({ + id: rowNum, + url: response[rowNum]._url || `Item${rowNum}`, }); - $tbody.append($tr); - }); + $accordion.append($card); + } - let windowHeight = $(window).height(); + const windowHeight = $(window).height(); + for (let rowNum = 0; rowNum < response.length; rowNum++) { + $(`#json-${rowNum}`).html(this.jsonRenderer(response[rowNum])); + } + $('.collapse').collapse('show'); $('.data-preview-modal .modal-body').height(windowHeight - 130); // remove modal from dom after it is closed - $dataPreviewPanel.on('hidden.bs.modal', function() { + $dataPreviewPanel.on('hidden.bs.modal', function () { $(this).remove(); }); }); diff --git a/src/scripts/DataExtractor.js b/src/scripts/DataExtractor.js index f860f780..eff398a3 100644 --- a/src/scripts/DataExtractor.js +++ b/src/scripts/DataExtractor.js @@ -8,7 +8,7 @@ export default class DataExtractor { if (options.sitemap instanceof Sitemap) { this.sitemap = options.sitemap; } else { - this.sitemap = new Sitemap(options.sitemap); + this.sitemap = Sitemap.sitemapFromObj(options.sitemap); } this.parentSelectorId = options.parentSelectorId; @@ -38,7 +38,10 @@ export default class DataExtractor { // Link selectors which will follow to a new page also cannot be common // to all selectors - if (selector.canCreateNewJobs() && this.sitemap.getDirectChildSelectors(selector.id).length > 0) { + if ( + selector.canCreateNewJobs() && + this.sitemap.getDirectChildSelectors(selector.id).length > 0 + ) { return false; } @@ -58,13 +61,13 @@ export default class DataExtractor { let childSelectors = this.sitemap.getDirectChildSelectors(parentSelectorId); childSelectors.forEach( - function(childSelector) { + function (childSelector) { if (this.selectorIsCommonToAllTrees(childSelector)) { commonSelectors.push(childSelector); // also add all child selectors which. Child selectors were also checked let selectorChildSelectors = this.sitemap.getAllSelectors(childSelector.id); - selectorChildSelectors.forEach(function(selector) { + selectorChildSelectors.forEach(function (selector) { if (commonSelectors.indexOf(selector) === -1) { commonSelectors.push(selector); } @@ -77,13 +80,15 @@ export default class DataExtractor { } _findSelectorTrees(parentSelectorId, commonSelectorsFromParent) { - let commonSelectors = commonSelectorsFromParent.concat(this.getSelectorsCommonToAllTrees(parentSelectorId)); + let commonSelectors = commonSelectorsFromParent.concat( + this.getSelectorsCommonToAllTrees(parentSelectorId) + ); // find selectors that will be making a selector tree let selectorTrees = []; let childSelectors = this.sitemap.getDirectChildSelectors(parentSelectorId); childSelectors.forEach( - function(selector) { + function (selector) { if (!this.selectorIsCommonToAllTrees(selector)) { // this selector will be making a new selector tree. But this selector might contain some child // selectors that are making more trees so here should be a some kind of seperation for that @@ -93,7 +98,10 @@ export default class DataExtractor { } else { // find selector tree within this selector let commonSelectorsFromParent = commonSelectors.concat([selector]); - let childSelectorTrees = this._findSelectorTrees(selector.id, commonSelectorsFromParent); + let childSelectorTrees = this._findSelectorTrees( + selector.id, + commonSelectorsFromParent + ); selectorTrees = selectorTrees.concat(childSelectorTrees); } } @@ -112,17 +120,19 @@ export default class DataExtractor { let childSelectors = selectors.getDirectChildSelectors(parentSelectorId); let deferredDataCalls = []; childSelectors.forEach( - function(selector) { + function (selector) { if (!selectors.willReturnMultipleRecords(selector.id)) { - deferredDataCalls.push(this.getSelectorCommonData.bind(this, selectors, selector, parentElement)); + deferredDataCalls.push( + this.getSelectorCommonData.bind(this, selectors, selector, parentElement) + ); } }.bind(this) ); let deferredResponse = $.Deferred(); - $.whenCallSequentially(deferredDataCalls).done(function(responses) { + $.whenCallSequentially(deferredDataCalls).done(function (responses) { let commonData = {}; - responses.forEach(function(data) { + responses.forEach(function (data) { commonData = Object.merge(commonData, data); }); deferredResponse.resolve(commonData); @@ -134,12 +144,16 @@ export default class DataExtractor { getSelectorCommonData(selectors, selector, parentElement) { let d = $.Deferred(); let deferredData = selector.getData(parentElement); - deferredData.done( - function(data) { + deferredData.then( + function (data) { if (selector.willReturnElements()) { let newParentElement = data[0]; - let deferredChildCommonData = this.getSelectorTreeCommonData(selectors, selector.id, newParentElement); - deferredChildCommonData.done(function(data) { + let deferredChildCommonData = this.getSelectorTreeCommonData( + selectors, + selector.id, + newParentElement + ); + deferredChildCommonData.done(function (data) { d.resolve(data); }); } else { @@ -160,13 +174,13 @@ export default class DataExtractor { // if the selector is not an Element selector then its fetched data is the result. if (!selector.willReturnElements()) { let deferredData = selector.getData(parentElement); - deferredData.done( - function(selectorData) { + deferredData.then( + function (selectorData) { let newCommonData = Object.clone(commonData, true); let resultData = []; selectorData.forEach( - function(record) { + function (record) { Object.merge(record, newCommonData, true); resultData.push(record); }.bind(this) @@ -179,23 +193,29 @@ export default class DataExtractor { // handle situation when this selector is an elementSelector let deferredData = selector.getData(parentElement); - deferredData.done( - function(selectorData) { + deferredData.then( + function (selectorData) { let deferredDataCalls = []; selectorData.forEach( - function(element) { + function (element) { let newCommonData = Object.clone(commonData, true); - let childRecordDeferredCall = this.getSelectorTreeData.bind(this, selectors, selector.id, element, newCommonData); + let childRecordDeferredCall = this.getSelectorTreeData.bind( + this, + selectors, + selector.id, + element, + newCommonData + ); deferredDataCalls.push(childRecordDeferredCall); }.bind(this) ); $.whenCallSequentially(deferredDataCalls).done( - function(responses) { + function (responses) { let resultData = []; - responses.forEach(function(childRecordList) { - childRecordList.forEach(function(childRecord) { + responses.forEach(function (childRecordList) { + childRecordList.forEach(function (childRecord) { let rec = {}; Object.merge(rec, childRecord, true); resultData.push(rec); @@ -212,20 +232,30 @@ export default class DataExtractor { getSelectorTreeData(selectors, parentSelectorId, parentElement, commonData) { let childSelectors = selectors.getDirectChildSelectors(parentSelectorId); - let childCommonDataDeferred = this.getSelectorTreeCommonData(selectors, parentSelectorId, parentElement); + let childCommonDataDeferred = this.getSelectorTreeCommonData( + selectors, + parentSelectorId, + parentElement + ); let deferredResponse = $.Deferred(); childCommonDataDeferred.done( - function(childCommonData) { + function (childCommonData) { commonData = Object.merge(commonData, childCommonData); let dataDeferredCalls = []; childSelectors.forEach( - function(selector) { + function (selector) { if (selectors.willReturnMultipleRecords(selector.id)) { let newCommonData = Object.clone(commonData, true); - let dataDeferredCall = this.getMultiSelectorData.bind(this, selectors, selector, parentElement, newCommonData); + let dataDeferredCall = this.getMultiSelectorData.bind( + this, + selectors, + selector, + parentElement, + newCommonData + ); dataDeferredCalls.push(dataDeferredCall); } }.bind(this) @@ -233,10 +263,10 @@ export default class DataExtractor { // merge all data records together $.whenCallSequentially(dataDeferredCalls).done( - function(responses) { + function (responses) { let resultData = []; - responses.forEach(function(childRecords) { - childRecords.forEach(function(childRecord) { + responses.forEach(function (childRecords) { + childRecords.forEach(function (childRecord) { let rec = {}; Object.merge(rec, childRecord, true); resultData.push(rec); @@ -262,26 +292,72 @@ export default class DataExtractor { return deferredResponse; } + /** + * Extracts '_attachments-XXX' properties and merges them into single top-level + * '_attachments' property. + */ + manageAttachments(dataObject) { + function popAttachments(data) { + if (Array.isArray(data)) { + return data.flatMap(popAttachments); + } + if (Object.isObject(data)) { + return Object.entries(data).flatMap(([key, value]) => { + if (key.startsWith('_attachments-')) { + delete data[key]; + return value; + } + return popAttachments(value); + }); + } + return []; + } + + const attachments = popAttachments(dataObject); + const uniqueAttachments = new Map(); + attachments.forEach(attachment => { + const { url } = attachment; + if (!uniqueAttachments.has(url)) { + uniqueAttachments.set(url, attachment); + } + }); + + if (uniqueAttachments.size) { + dataObject._attachments = [...uniqueAttachments.values()]; + } + } + getData() { let selectorTrees = this.findSelectorTrees(); let dataDeferredCalls = []; selectorTrees.forEach( - function(selectorTree) { - let deferredTreeDataCall = this.getSelectorTreeData.bind(this, selectorTree, this.parentSelectorId, this.parentElement, {}); + function (selectorTree) { + let deferredTreeDataCall = this.getSelectorTreeData.bind( + this, + selectorTree, + this.parentSelectorId, + this.parentElement, + {} + ); dataDeferredCalls.push(deferredTreeDataCall); }.bind(this) ); let responseDeferred = $.Deferred(); $.whenCallSequentially(dataDeferredCalls).done( - function(responses) { + function (responses) { let results = []; responses.forEach( - function(dataResults) { + function (dataResults) { results = results.concat(dataResults); }.bind(this) ); + results.forEach(this.manageAttachments); + results.forEach(dataObject => { + dataObject._url = window.location.href; + dataObject._timestamp = Date.now(); + }); responseDeferred.resolve(results); }.bind(this) ); diff --git a/src/scripts/Model.js b/src/scripts/Model.js index 8dfd1f9d..ea501991 100644 --- a/src/scripts/Model.js +++ b/src/scripts/Model.js @@ -1,28 +1,55 @@ -export default class Model { +import Translator from './Translator'; + + +class Field { + constructor(entity, field, fieldName) { + this.entity = entity; + this.field = field; + this.fieldName = fieldName; + } +} + +export default class Model extends Array { + constructor(fields) { + super(); + const fieldsArray = fields || []; + fieldsArray.forEach(fieldObj => { + this.push(new Field(fieldObj.entity, fieldObj.field, fieldObj.fieldName)); + }); + } + static validateModel(model) { if (model === undefined) { return { - message: 'Empty value is possible model', + message: Translator.getTranslationByKey('model_empty_message'), valid: true, }; } if (!Array.isArray(model)) { return { valid: false, - message: 'JSON must be array', + message: Translator.getTranslationByKey('model_json_array_message'), }; } - for (let field_rule of model) { - if (!('entity' in field_rule) || !('field' in field_rule) || !('field_name' in field_rule)) { - return { - valid: false, - message: 'Each object in JSON array must contain keys entity, field, field_name.', - }; - } + if ( + !model.every( + fieldRule => + 'entity' in fieldRule && 'field' in fieldRule && 'fieldName' in fieldRule + ) + ) { + return { + valid: false, + message: Translator.getTranslationByKey('model_json_error_message'), + }; } + return { - message: 'Valid model', + message: Translator.getTranslationByKey('model_correct_message'), valid: true, }; } + + toString() { + return this.length ? JSON.stringify(this, null, 4) : ''; + } } diff --git a/src/scripts/Scraper.js b/src/scripts/Scraper.js index d61b967e..cc64b0dd 100644 --- a/src/scripts/Scraper.js +++ b/src/scripts/Scraper.js @@ -1,5 +1,7 @@ import Job from './Job'; import '../libs/jquery.whencallsequentially'; +import Base64 from './Base64'; +import * as nanoid from 'nanoid'; export default class Scraper { /** @@ -16,28 +18,29 @@ export default class Scraper { this.requestInterval = parseInt(options.requestInterval); this.requestIntervalRandomness = parseInt(options.requestIntervalRandomness); this.pageLoadDelay = parseInt(options.pageLoadDelay); + this.downloadPaths = new Map(); // url -> local path } initFirstJobs() { - var urls = this.sitemap.getStartUrls(); + const urls = this.sitemap.getStartUrls(); urls.forEach( - function(url) { - var firstJob = new Job(url, '_root', this); + function (url) { + const firstJob = new Job(url, '_root', this); this.queue.add(firstJob); }.bind(this) ); } run(executionCallback) { - var scraper = this; + const scraper = this; // callback when scraping is finished this.executionCallback = executionCallback; this.initFirstJobs(); - this.store.initSitemapDataDb(this.sitemap._id).then(function(resultWriter) { + this.store.initSitemapDataDb(this.sitemap._id).then(function (resultWriter) { scraper.resultWriter = resultWriter; scraper._run(); }); @@ -48,23 +51,28 @@ export default class Scraper { return false; } - var selectorId = record._followSelectorId; - var childSelectors = this.sitemap.getDirectChildSelectors(selectorId); + const selectorId = record._followSelectorId; + const childSelectors = this.sitemap.getDirectChildSelectors(selectorId); if (childSelectors.length === 0) { return false; - } else { - return true; } + return true; } - getFileFilename(url) { - var parts = url.split('/'); - var filename = parts[parts.length - 1]; - filename = filename.replace(/\?/g, ''); - if (filename.length > 130) { - filename = filename.substr(0, 130); + generateDownloadPath(filename, maxLength = 100) { + // TODO consider using URL-based hash + const path = `${this.sitemap._id}/${nanoid(8)}--${filename}`; + if (path.length <= maxLength) { + return path; } - return filename; + const extensionMatch = /\.[^/]*$/.exec(path); + if (extensionMatch) { + const [extension] = extensionMatch; + if (extension.length <= maxLength) { + return path.substr(0, maxLength - extension.length) + extension; + } + } + return path.substr(0, maxLength); } /** @@ -72,71 +80,40 @@ export default class Scraper { * @param record */ saveFile(record) { - let deferredResponse = $.Deferred(); - let deferredFileStoreCalls = []; - let prefixLength = '_fileBase64-'.length; - - for (let attr in record) { - if (attr.substr(0, prefixLength) === '_fileBase64-') { - var selectorId = attr.substring(prefixLength, attr.length); - deferredFileStoreCalls.push( - function(selectorId) { - var fileBase64 = record['_fileBase64-' + selectorId]; - var documentFilename = record['_filename' + selectorId]; - - var deferredDownloadDone = $.Deferred(); - var deferredBlob = Base64.base64ToBlob(fileBase64, record['_fileMimeType-' + selectorId]); - - delete record['_fileMimeType-' + selectorId]; - delete record['_fileBase64-' + selectorId]; - delete record['_filename' + selectorId]; - - deferredBlob.done( - function(blob) { - var downloadUrl = window.URL.createObjectURL(blob); - var fileSavePath = this.sitemap._id + '/' + selectorId + '/' + documentFilename; - - // download file using chrome api - var downloadRequest = { - url: downloadUrl, - filename: fileSavePath, - }; - - // wait for the download to finish - chrome.downloads.download(downloadRequest, function(downloadId) { - var cbDownloaded = function(downloadItem) { - if (downloadItem.id === downloadId && downloadItem.state) { - if (downloadItem.state.current === 'complete') { - deferredDownloadDone.resolve(); - chrome.downloads.onChanged.removeListener(cbDownloaded); - } else if (downloadItem.state.current === 'interrupted') { - deferredDownloadDone.reject('download failed'); - chrome.downloads.onChanged.removeListener(cbDownloaded); - } - } - }; - - chrome.downloads.onChanged.addListener(cbDownloaded); - }); - }.bind(this) - ); - - return deferredDownloadDone.promise(); - }.bind(this, selectorId) - ); - } + const deferredResponse = $.Deferred(); + if (!('_attachments' in record)) { + deferredResponse.resolve(); + return deferredResponse.promise(); } - $.whenCallSequentially(deferredFileStoreCalls).done(function() { - deferredResponse.resolve(); + const downloads = record._attachments.map(async attachment => { + const { url, mimeType, fileBase64, checksum, filename } = attachment; + if (this.downloadPaths.has(url)) { + return { url, filename, checksum, path: this.downloadPaths.get(url) }; + } + const downloadPath = this.generateDownloadPath(filename); + try { + const blob = await Base64.base64ToBlob(fileBase64, mimeType); + const downloadUrl = window.URL.createObjectURL(blob); + await this.browser.downloadFile(downloadUrl, downloadPath); + this.downloadPaths.set(url, downloadPath); + return { url, filename, checksum, path: downloadPath }; + } catch (e) { + console.error(`Failed to save attachment for url ${url}`, e); + return attachment; + } }); + Promise.all(downloads).then(attachments => { + record._attachments = attachments; + deferredResponse.resolve(); + }); return deferredResponse.promise(); } // @TODO remove recursion and add an iterative way to run these jobs. _run() { - var job = this.queue.getNextJob(); + const job = this.queue.getNextJob(); if (job === false) { console.log('Scraper execution is finished'); this.executionCallback(); @@ -145,25 +122,25 @@ export default class Scraper { job.execute( this.browser, - function(job) { - var scrapedRecords = []; - var deferredDatamanipulations = []; + function (job) { + const scrapedRecords = []; + const deferredDatamanipulations = []; - var records = job.getResults(); + const records = job.getResults(); records.forEach( - function(record) { - //var record = JSON.parse(JSON.stringify(rec)); + function (record) { + // var record = JSON.parse(JSON.stringify(rec)); deferredDatamanipulations.push(this.saveFile.bind(this, record)); // @TODO refactor job exstraction to a seperate method if (this.recordCanHaveChildJobs(record)) { // var followSelectorId = record._followSelectorId; - var followURL = record['_follow']; - var followSelectorId = record['_followSelectorId']; - delete record['_follow']; - delete record['_followSelectorId']; - var newJob = new Job(followURL, followSelectorId, this, job, record); + const followURL = record._follow; + const followSelectorId = record._followSelectorId; + delete record._follow; + delete record._followSelectorId; + const newJob = new Job(followURL, followSelectorId, this, job, record); if (this.queue.canBeAdded(newJob)) { this.queue.add(newJob); } @@ -175,8 +152,8 @@ export default class Scraper { } } else { if (record._follow !== undefined) { - delete record['_follow']; - delete record['_followSelectorId']; + delete record._follow; + delete record._followSelectorId; } scrapedRecords.push(record); } @@ -184,27 +161,27 @@ export default class Scraper { ); $.whenCallSequentially(deferredDatamanipulations).done( - function() { - this.store.saveSitemap(this.sitemap, function() {}); - this.resultWriter.writeDocs( - scrapedRecords, - function() { - var now = new Date().getTime(); - // delay next job if needed - this._timeNextScrapeAvailable = now + this.requestInterval + Math.random() * this.requestIntervalRandomness; - if (now >= this._timeNextScrapeAvailable) { - this._run(); - } else { - var delay = this._timeNextScrapeAvailable - now; - setTimeout( - function() { - this._run(); - }.bind(this), - delay - ); - } - }.bind(this) - ); + function () { + this.store.saveSitemap(this.sitemap, function () {}); + this.resultWriter.writeDocs(scrapedRecords).then(() => { + const now = new Date().getTime(); + // delay next job if needed + this._timeNextScrapeAvailable = + now + + this.requestInterval + + Math.random() * this.requestIntervalRandomness; + if (now >= this._timeNextScrapeAvailable) { + this._run(); + } else { + const delay = this._timeNextScrapeAvailable - now; + setTimeout( + function () { + this._run(); + }.bind(this), + delay + ); + } + }); }.bind(this) ); }.bind(this) diff --git a/src/scripts/Selector.js b/src/scripts/Selector.js index f893a0d2..e927d4af 100644 --- a/src/scripts/Selector.js +++ b/src/scripts/Selector.js @@ -1,21 +1,17 @@ +import SparkMD5 from 'spark-md5'; import ElementQuery from './ElementQuery'; +import Base64 from './Base64'; export default class Selector { - constructor(selector) { - // if (selector.type === 'ConstantValue'){ - // this = new ConstantValue(selector); - // } - // this.updateData(['id', 'type', 'selector', 'parentSelectors']); - // this.initType(); - } + constructor(selector) {} /** * Update current selector configuration * @param data + * @param features */ updateData(data, features) { let allowedKeys = ['id', 'type', 'selector', 'parentSelectors']; - //XXX no need in information from window allowedKeys = allowedKeys.concat(features); // update data @@ -33,18 +29,10 @@ export default class Selector { } } - /** - * override objects methods based on seletor type - */ - initType() { - // if (window[this.type] === undefined) { - // throw 'Selector type not defined ' + this.type; - // } - // - // // overrides objects methods - // for (let i in window[this.type]) { - // this[i] = window[this.type][i]; - // } + afterSelect(selector, controller) { + this.selector = selector; + controller._editSelector(this); + return Promise.resolve(); } /** @@ -52,7 +40,22 @@ export default class Selector { * @param data */ manipulateData(data) { - let regex = function(content, regex, regexgroup) { + let isTextManipulationDefined = + typeof this.textmanipulation != 'undefined' && this.textmanipulation !== ''; + if (!isTextManipulationDefined) { + return data; + } + + // TODO refactor + selector group semantics + if (Array.isArray(data)) { + return data.map(e => this.manipulateData(e)); + } + if (Object.isObject(data) && this.id in data) { + data[this.id] = this.manipulateData(data[this.id]); + return data; + } + + let regex = function (content, regex, regexgroup) { try { content = $.trim(content); let matches = content.match(new RegExp(regex, 'gm')), @@ -66,21 +69,22 @@ export default class Selector { return ''; } } catch (e) { - console.log('%c Skipping regular expression: ' + e.message, 'background: red; color: white;'); + console.log( + '%c Skipping regular expression: ' + e.message, + 'background: red; color: white;' + ); } }; - let removeHtml = function(content) { - return $('
') - .html(content) - .text(); + let removeHtml = function (content) { + return $('
').html(content).text(); }; - let trimText = function(content) { + let trimText = function (content) { return content.trim(); }; - let replaceText = function(content, replaceText, replacementText) { + let replaceText = function (content, replaceText, replacementText) { let replace; try { let regex = new RegExp(replaceText, 'gm'); @@ -92,85 +96,80 @@ export default class Selector { return content.replace(replace, replacementText); }; - let textPrefix = function(content, prefix) { + let textPrefix = function (content, prefix) { return (content = prefix + content); }; - let textSuffix = function(content, suffix) { + let textSuffix = function (content, suffix) { return (content += suffix); }; - $(data).each( - function(i, element) { - let content = element[this.id], - isString = typeof content === 'string' || content instanceof String, - isUnderlyingString = !isString && $(content).text() !== '', - isArray = Array.isArray(content), - isTextmManipulationDefined = typeof this.textmanipulation != 'undefined' && this.textmanipulation !== '', - textManipulationAvailable = (isString || isUnderlyingString) && isTextmManipulationDefined; - - if (textManipulationAvailable) { - content = isString ? content : $(content).text(); - - // use key in object since unit tests might not define each property - let keys = []; - for (let key in this.textmanipulation) { - if (!this.textmanipulation.hasOwnProperty(key)) { - continue; - } - keys.push(key); - } - - function propertyIsAvailable(key) { - return keys.indexOf(key) >= 0; - } - - if (propertyIsAvailable('regex')) { - let group = this.textmanipulation.regexgroup; - let value = this.textmanipulation.regex; - group = typeof group != 'undefined' ? group : ''; - if (value !== '') { - content = regex(content, value, group); - } - } - - if (propertyIsAvailable('removeHtml')) { - if (this.textmanipulation.removeHtml) { - content = removeHtml(content); - } - } - - if (propertyIsAvailable('trimText')) { - if (this.textmanipulation.trimText) { - content = trimText(content); - } - } - - if (propertyIsAvailable('replaceText')) { - let replacement = this.textmanipulation.replacementText; - replacement = typeof replacement != 'undefined' ? replacement : ''; - content = replaceText(content, this.textmanipulation.replaceText, replacement); - } - - if (propertyIsAvailable('textPrefix')) { - if (this.textmanipulation.textPrefix !== '') { - content = textPrefix(content, this.textmanipulation.textPrefix); - } - } - - if (propertyIsAvailable('textSuffix')) { - if (this.textmanipulation.textSuffix !== '') { - content = textSuffix(content, this.textmanipulation.textSuffix); - } - } - - element[this.id] = content; - } else if (isArray && isTextmManipulationDefined) { - element[this.id] = JSON.stringify(content); - this.manipulateData(element); + let applyTextManipulation = function (content) { + let isString = typeof content === 'string' || content instanceof String, + isUnderlyingString = !isString && $(content).text() !== ''; + + if (!isString && !isUnderlyingString) { + return content; + } + + content = isString ? content : $(content).text(); + + // use key in object since unit tests might not define each property + let keys = []; + for (let key in this.textmanipulation) { + if (!this.textmanipulation.hasOwnProperty(key)) { + continue; + } + keys.push(key); + } + + function propertyIsAvailable(key) { + return keys.indexOf(key) >= 0; + } + + if (propertyIsAvailable('regex')) { + let group = this.textmanipulation.regexgroup; + let value = this.textmanipulation.regex; + group = typeof group != 'undefined' ? group : ''; + if (value !== '') { + content = regex(content, value, group); + } + } + + if (propertyIsAvailable('removeHtml')) { + if (this.textmanipulation.removeHtml) { + content = removeHtml(content); + } + } + + if (propertyIsAvailable('trimText')) { + if (this.textmanipulation.trimText) { + content = trimText(content); + } + } + + if (propertyIsAvailable('replaceText')) { + let replacement = this.textmanipulation.replacementText; + replacement = typeof replacement != 'undefined' ? replacement : ''; + content = replaceText(content, this.textmanipulation.replaceText, replacement); + } + + if (propertyIsAvailable('textPrefix')) { + if (this.textmanipulation.textPrefix !== '') { + content = textPrefix(content, this.textmanipulation.textPrefix); } - }.bind(this) - ); + } + + if (propertyIsAvailable('textSuffix')) { + if (this.textmanipulation.textSuffix !== '') { + content = textSuffix(content, this.textmanipulation.textSuffix); + } + } + + return content; + }.bind(this); + + return applyTextManipulation(data); } /** @@ -240,74 +239,67 @@ export default class Selector { } } - getData(parentElement) { - let d = $.Deferred(); - let timeout = this.delay || 0; - - // this works much faster because $.whenCallSequentially isn't running next data extraction immediately - if (timeout === 0) { - let deferredData = this._getData(parentElement); - deferredData.done( - function(data) { - this.manipulateData(data); - d.resolve(data); - }.bind(this) - ); - } else { - setTimeout( - function() { - let deferredData = this._getData(parentElement); - deferredData.done( - function(data) { - this.manipulateData(data); - d.resolve(data); - }.bind(this) - ); - }.bind(this), - timeout - ); + getElementCSSSelector(element) { + function localCssSelector(element) { + const tagName = element.tagName.toLocaleLowerCase(); + if (tagName === 'html' || tagName === 'body') { + return tagName; + } + let nthChild = 1; + let prevSibling = element.previousElementSibling; + while (prevSibling) { + nthChild++; + prevSibling = prevSibling.previousElementSibling; + } + return `${tagName}:nth-child(${nthChild})`; } - return d.promise(); + let cssSelector = localCssSelector(element); + let parent = element.parentElement; + while (parent) { + cssSelector = `${localCssSelector(parent)}>${cssSelector}`; + parent = parent.parentElement; + } + + return cssSelector; + } + + async getData(parentElement) { + const timeout = parseInt(this.delay); + if (timeout) { + await new Promise(resolve => setTimeout(resolve, timeout)); + } + const data = await this._getData(parentElement); + return this.manipulateData(data); + } + + downloadsAttachments() { + return false; } getFilenameFromUrl(url) { - let parts = url.split('/'); + const parts = url.split('/'); let filename = parts[parts.length - 1]; - filename = filename.replace(/\?/g, ''); - if (filename.length > 130) { - filename = filename.substr(0, 130); - } + [filename] = filename.split('?', 1); + [filename] = filename.split('#', 1); return filename; } - downloadFileAsBase64(url) { - let deferredResponse = $.Deferred(); - let xhr = new XMLHttpRequest(); - let fileName = this.getFilenameFromUrl(url); - xhr.onreadystatechange = function() { - if (this.readyState == 4) { - if (this.status == 200) { - let blob = this.response; - let mimeType = blob.type; - let deferredBlob = Base64.blobToBase64(blob); - - deferredBlob.done(function(fileBase64) { - deferredResponse.resolve({ - mimeType: mimeType, - fileBase64: fileBase64, - filename: fileName, - }); - }); - } else { - deferredResponse.reject(xhr.statusText); - } + async downloadFileAsBase64(url) { + const response = await fetch(url); + const blob = await response.blob(); + const mimeType = blob.type; + const fileBase64 = await Base64.blobToBase64(blob); + const checksum = SparkMD5.ArrayBuffer.hash(await blob.arrayBuffer()); + const result = { url, mimeType, fileBase64, checksum }; + const contentDisposition = response.headers.get('Content-Disposition'); + if (contentDisposition) { + const filenameMatch = /filename="(.*?)"/.exec(contentDisposition); + if (filenameMatch) { + const [, filename] = filenameMatch; + result.filename = filename; } - }; - xhr.open('GET', url); - xhr.responseType = 'blob'; - xhr.send(); - - return deferredResponse.promise(); + } + return result; } } diff --git a/src/scripts/Selector/ConstantValue.js b/src/scripts/Selector/ConstantValue.js index 1b816786..1a28bdc2 100644 --- a/src/scripts/Selector/ConstantValue.js +++ b/src/scripts/Selector/ConstantValue.js @@ -26,13 +26,8 @@ export default class ConstantValue extends Selector { return false; } - _getData(parentElement) { - let dfd = $.Deferred(); - let data = {}; - data[this.id] = this.value; - - dfd.resolve([data]); - return dfd.promise(); + async _getData(parentElement) { + return [{ [this.id]: this.value }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorDocument.js b/src/scripts/Selector/SelectorDocument.js index 85131fd0..4c005b45 100644 --- a/src/scripts/Selector/SelectorDocument.js +++ b/src/scripts/Selector/SelectorDocument.js @@ -1,5 +1,4 @@ import Selector from '../Selector'; -import '../../libs/jquery.whencallsequentially'; export default class SelectorDocument extends Selector { constructor(options) { @@ -8,7 +7,7 @@ export default class SelectorDocument extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -27,76 +26,65 @@ export default class SelectorDocument extends Selector { return false; } - _getData(parentElement) { - var elements = this.getDataElements(parentElement); + downloadsAttachments() { + return !!this.downloadDocument; + } - var dfd = $.Deferred(); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement).filter(element => 'href' in element); + const urls = elements.map(element => + this.stringReplace(element.href, this.stringReplacement) + ); - // return empty record if not multiple type and no elements found - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id] = null; - dfd.resolve([data]); - return dfd; + const result = {}; + if (this.multiple) { + result[`${this.id}-href`] = urls; + } else { + result[`${this.id}-href`] = urls.length ? urls[0] : null; } - // extract links one by one - var deferredDataExtractionCalls = []; - $(elements).each( - function(k, element) { - deferredDataExtractionCalls.push( - function(element) { - var href = this.stringReplace(element.href, this.stringReplacement); - var deferredData = $.Deferred(); - var data = {}; - - data[this.id] = $(element).text(); - - data[this.id + '-href'] = href; - - if (!this.downloadDocument) { - deferredData.resolve(data); - } else if (href) { - var deferredFileBase64 = this.downloadFileAsBase64(href); - - deferredFileBase64 - .done( - function(base64Response) { - data['_fileBase64-' + this.id] = base64Response.fileBase64; - data['_fileMimeType-' + this.id] = base64Response.mimeType; - data['_filename' + this.id] = base64Response.filename; - - deferredData.resolve(data); - }.bind(this) - ) - .fail(function() { - deferredData.resolve(data); - }); - } else { - deferredData.resolve(data); + if (this.downloadDocument) { + const documents = []; + for (const [i, url] of urls.entries()) { + try { + if (url) { + const document = await this.downloadFileAsBase64(url); + if (!document.filename) { + // TODO consider $(elements[i]).text() for filename + document.filename = + elements[i].download || this.getFilenameFromUrl(url); } - return deferredData.promise(); - }.bind(this, element) - ); - }.bind(this) - ); - - $.whenCallSequentially(deferredDataExtractionCalls).done(function(responses) { - var result = []; - responses.forEach(function(dataResult) { - result.push(dataResult); - }); - dfd.resolve(result); - }); + documents.push(document); + } + } catch (e) { + console.warn(`Failed to download document by url ${url}`, e); + } + } + if (documents.length) { + result[`_attachments-${this.id}`] = documents; + } + } - return dfd.promise(); + return [result]; } getDataColumns() { - return [this.id, this.id + '-href']; + const dataColumns = [`${this.id}-href`]; + if (this.downloadDocument) { + dataColumns.push(`${this.id}-path`, `${this.id}-checksum`, `${this.id}-filename`); + } + return dataColumns; + } + + getUrlColumn() { + return `${this.id}-href`; } getFeatures() { return ['selector', 'multiple', 'delay', 'downloadDocument', 'stringReplacement']; } + + getItemCSSSelector() { + return 'a'; + } } diff --git a/src/scripts/Selector/SelectorElement.js b/src/scripts/Selector/SelectorElement.js index 2a968079..64ac90c7 100644 --- a/src/scripts/Selector/SelectorElement.js +++ b/src/scripts/Selector/SelectorElement.js @@ -26,13 +26,8 @@ export default class SelectorElement extends Selector { return true; } - _getData(parentElement) { - var dfd = $.Deferred(); - - var elements = this.getDataElements(parentElement); - dfd.resolve(jQuery.makeArray(elements)); - - return dfd.promise(); + async _getData(parentElement) { + return this.getDataElements(parentElement); } getDataColumns() { diff --git a/src/scripts/Selector/SelectorElementAttribute.js b/src/scripts/Selector/SelectorElementAttribute.js index a5fc66a2..4943ba75 100644 --- a/src/scripts/Selector/SelectorElementAttribute.js +++ b/src/scripts/Selector/SelectorElementAttribute.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorElementAttribute extends Selector { @@ -7,7 +8,7 @@ export default class SelectorElementAttribute extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -26,29 +27,13 @@ export default class SelectorElementAttribute extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); - - var elements = this.getDataElements(parentElement); - - var result = []; - $(elements).each( - function(k, element) { - var data = {}; - - data[this.id] = $(element).attr(this.extractAttribute); - result.push(data); - }.bind(this) - ); - - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id + '-src'] = null; - result.push(data); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + let attributes = elements.map(element => $(element).attr(this.extractAttribute)); + if (!this.multiple) { + attributes = attributes.length ? attributes[0] : null; } - dfd.resolve(result); - - return dfd.promise(); + return [{ [this.id]: attributes }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorElementClick.js b/src/scripts/Selector/SelectorElementClick.js index cbe1c768..448eb845 100644 --- a/src/scripts/Selector/SelectorElementClick.js +++ b/src/scripts/Selector/SelectorElementClick.js @@ -32,110 +32,66 @@ export default class SelectorElementClick extends Selector { return ElementQuery(this.clickElementSelector, parentElement); } - /** - * Check whether element is still reachable from html. Useful to check whether the element is removed from DOM. - * @param element - */ - isElementInHTML(element) { - return $(element).closest('html').length !== 0; - } - - getElementCSSSelector(element) { - let nthChild, prev; - for (nthChild = 1, prev = element.previousElementSibling; prev !== null; prev = prev.previousElementSibling, nthChild++) {} - let tagName = element.tagName.toLocaleLowerCase(); - let cssSelector = tagName + ':nth-child(' + nthChild + ')'; - - while (element.parentElement) { - element = element.parentElement; - let tagName = element.tagName.toLocaleLowerCase(); - if (tagName === 'body' || tagName === 'html') { - cssSelector = tagName + '>' + cssSelector; - } else { - for (nthChild = 1, prev = element.previousElementSibling; prev !== null; prev = prev.previousElementSibling, nthChild++) {} - cssSelector = tagName + ':nth-child(' + nthChild + ')>' + cssSelector; - } - } - - return cssSelector; - } - triggerButtonClick(clickElement) { - let cssSelector = this.getElementCSSSelector(clickElement); - + const cssSelector = this.getElementCSSSelector(clickElement); // this function will trigger the click from browser land - let script = document.createElement('script'); + // TODO do we really need to inject a script instead of document.querySelector(...).click()? + const script = document.createElement('script'); script.type = 'text/javascript'; - script.text = '' + '(function(){ ' + "let el = document.querySelectorAll('" + cssSelector + "')[0]; " + 'el.click(); ' + '})();'; + script.text = `{ document.querySelector('${cssSelector}').click(); }`; document.body.appendChild(script); } getClickElementUniquenessType() { if (this.clickElementUniquenessType === undefined) { return 'uniqueText'; - } else { - return this.clickElementUniquenessType; } + return this.clickElementUniquenessType; } - _getData(parentElement) { - let paginationLimit = parseInt(this.paginationLimit); + async _getData(parentElement) { + const delay = parseInt(this.delay) || 0; + const paginationLimit = parseInt(this.paginationLimit); let paginationCount = 1; - let delay = parseInt(this.delay) || 0; - let deferredResponse = $.Deferred(); - let foundElements = new UniqueElementList('uniqueHTMLText'); - let clickElements = this.getClickElements(parentElement); - let doneClickingElements = new UniqueElementList(this.getClickElementUniquenessType()); - - // add elements that are available before clicking - let elements = this.getDataElements(parentElement); - elements.forEach(foundElements.push.bind(foundElements)); - // discard initial elements - if (this.discardInitialElements) { - foundElements = new UniqueElementList('uniqueText'); + const foundDataElements = new UniqueElementList('uniqueHTMLText'); + if (!this.discardInitialElements) { + // add elements that are available before clicking + this.getDataElements(parentElement).forEach(foundDataElements.push); } - // no elements to click at the beginning - if (clickElements.length === 0) { - deferredResponse.resolve(foundElements); - return deferredResponse.promise(); + let clickElements = this.getClickElements(parentElement); + if (!clickElements.length) { + // no elements to click at the beginning + return foundDataElements; } + const doneClickingElements = new UniqueElementList(this.getClickElementUniquenessType()); + // initial click and wait - let currentClickElement = clickElements[0]; + let [currentClickElement] = clickElements; this.triggerButtonClick(currentClickElement); - let nextElementSelection = new Date().getTime() + delay; + let nextElementSelection = Date.now() + delay; - // infinitely scroll down and find all items - let interval = setInterval( - function() { + return new Promise(resolve => { + // repeatedly click and find new items + const interval = setInterval(() => { // find those click elements that are not in the black list - let allClickElements = this.getClickElements(parentElement); - clickElements = []; - allClickElements.forEach(function(element) { - if (!doneClickingElements.isAdded(element)) { - clickElements.push(element); - } - }); + clickElements = this.getClickElements(parentElement).filter( + element => !doneClickingElements.isAdded(element) + ); - let now = new Date().getTime(); - // sleep. wait when to extract next elements + const now = Date.now(); + // sleep and wait when to extract next elements if (now < nextElementSelection) { - //console.log("wait"); return; } - // add newly found elements to element foundElements array. - let elements = this.getDataElements(parentElement); - let addedAnElement = false; - elements.forEach(function(element) { - let added = foundElements.push(element); - if (added) { - addedAnElement = true; - } - }); - //console.log("added", addedAnElement); + // add newly found elements to foundDataElements array + const addedAnElement = this.getDataElements(parentElement).reduce( + (added, element) => foundDataElements.push(element) || added, + false + ); // no new elements found. Stop clicking this button if (!addedAnElement) { @@ -143,15 +99,13 @@ export default class SelectorElementClick extends Selector { } // continue clicking and add delay, but if there is nothing - // more to click the finish - //console.log("total buttons", clickElements.length) - if (clickElements.length === 0 || paginationCount >= paginationLimit) { + // more to click then finish + if (!clickElements.length || paginationCount >= paginationLimit) { clearInterval(interval); - deferredResponse.resolve(foundElements); + resolve(foundDataElements); } else { paginationCount++; - //console.log("click"); - currentClickElement = clickElements[0]; + [currentClickElement] = clickElements; // click on elements only once if the type is clickonce if (this.clickType === 'clickOnce') { doneClickingElements.push(currentClickElement); @@ -159,11 +113,8 @@ export default class SelectorElementClick extends Selector { this.triggerButtonClick(currentClickElement); nextElementSelection = now + delay; } - }.bind(this), - 50 - ); - - return deferredResponse.promise(); + }, 50); + }); } getDataColumns() { @@ -171,6 +122,15 @@ export default class SelectorElementClick extends Selector { } getFeatures() { - return ['selector', 'multiple', 'delay', 'clickElementSelector', 'clickType', 'discardInitialElements', 'clickElementUniquenessType', 'paginationLimit']; + return [ + 'selector', + 'multiple', + 'delay', + 'clickElementSelector', + 'clickType', + 'discardInitialElements', + 'clickElementUniquenessType', + 'paginationLimit', + ]; } } diff --git a/src/scripts/Selector/SelectorElementScroll.js b/src/scripts/Selector/SelectorElementScroll.js index 77c9c35a..403281c4 100644 --- a/src/scripts/Selector/SelectorElementScroll.js +++ b/src/scripts/Selector/SelectorElementScroll.js @@ -30,31 +30,33 @@ export default class SelectorElementScroll extends Selector { window.scrollTo(0, document.body.scrollHeight); } - _getData(parentElement) { - let paginationLimit = parseInt(this.paginationLimit); + async _getData(parentElement) { + const delay = parseInt(this.delay) || 0; + const paginationLimit = parseInt(this.paginationLimit); let paginationCount = 1; - let delay = parseInt(this.delay) || 0; - let deferredResponse = $.Deferred(); let foundElements = []; // initially scroll down and wait this.scrollToBottom(); - let nextElementSelection = new Date().getTime() + delay; + let nextElementSelection = Date.now() + delay; - // infinitely scroll down and find all items - let interval = setInterval( - function() { - let now = new Date().getTime(); - // sleep. wait when to extract next elements + return new Promise(resolve => { + // infinitely scroll down and find all items + const interval = setInterval(() => { + const now = Date.now(); + // sleep and wait when to extract next elements if (now < nextElementSelection) { return; } - let elements = this.getDataElements(parentElement); + const elements = this.getDataElements(parentElement); // no new elements found or pagination limit - if (elements.length === foundElements.length || paginationCount >= paginationLimit) { + if ( + elements.length === foundElements.length || + paginationCount >= paginationLimit + ) { clearInterval(interval); - deferredResponse.resolve($.makeArray(elements)); + resolve(elements); } else { paginationCount++; // continue scrolling and add delay @@ -62,11 +64,8 @@ export default class SelectorElementScroll extends Selector { this.scrollToBottom(); nextElementSelection = now + delay; } - }.bind(this), - 50 - ); - - return deferredResponse.promise(); + }, 50); + }); } getDataColumns() { diff --git a/src/scripts/Selector/SelectorElementStyle.js b/src/scripts/Selector/SelectorElementStyle.js index 3adce920..51b0eadd 100644 --- a/src/scripts/Selector/SelectorElementStyle.js +++ b/src/scripts/Selector/SelectorElementStyle.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorElementStyle extends Selector { @@ -7,7 +8,7 @@ export default class SelectorElementStyle extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -26,27 +27,13 @@ export default class SelectorElementStyle extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); - var elements = this.getDataElements(parentElement); - - var result = []; - $(elements).each( - function(k, element) { - var data = {}; - data[this.id] = $(element).css(this.extractStyle); - result.push(data); - }.bind(this) - ); - - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id + '-src'] = null; - result.push(data); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + let styles = elements.map(element => $(element).css(this.extractStyle)); + if (!this.multiple) { + styles = styles.length ? styles[0] : null; } - dfd.resolve(result); - - return dfd.promise(); + return [{ [this.id]: styles }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorGroup.js b/src/scripts/Selector/SelectorGroup.js index 44ad031f..aeb1b6e9 100644 --- a/src/scripts/Selector/SelectorGroup.js +++ b/src/scripts/Selector/SelectorGroup.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorGroup extends Selector { @@ -26,36 +27,28 @@ export default class SelectorGroup extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); + async getData(parentElement) { + const [{ [this.id]: records }] = await super.getData(parentElement); + return [{ [this.id]: JSON.stringify(records) }]; + } + async _getData(parentElement) { // cannot reuse this.getDataElements because it depends on *multiple* property - var elements = $(this.selector, parentElement); - - var records = []; - $(elements).each( - function(k, element) { - var data = {}; - - data[this.id] = $(element).text(); - - if (this.extractAttribute) { - data[this.id + '-' + this.extractAttribute] = $(element).attr(this.extractAttribute); - } - - if (this.extractStyle) { - data[this.id + '-' + this.extractStyle] = $(element).css(this.extractStyle); - } - - records.push(data); - }.bind(this) - ); - - var result = {}; - result[this.id] = records; - - dfd.resolve([result]); - return dfd.promise(); + const $elements = $(this.selector, parentElement); + const records = $.map($elements, element => { + const $element = $(element); + const record = { [this.id]: $element.text() }; + if (this.extractAttribute) { + record[`${this.id}-${this.extractAttribute}`] = $element.attr( + this.extractAttribute + ); + } + if (this.extractStyle) { + record[`${this.id}-${this.extractStyle}`] = $element.css(this.extractStyle); + } + return record; + }); + return [{ [this.id]: records }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorHTML.js b/src/scripts/Selector/SelectorHTML.js index 8aa33fad..ecb08aae 100644 --- a/src/scripts/Selector/SelectorHTML.js +++ b/src/scripts/Selector/SelectorHTML.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorHTML extends Selector { @@ -7,7 +8,7 @@ export default class SelectorHTML extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -26,33 +27,13 @@ export default class SelectorHTML extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); - - var elements = this.getDataElements(parentElement); - - var result = []; - $(elements).each( - function(k, element) { - var data = {}; - var html = $(element).html(); - - // do something - - data[this.id] = html; - - result.push(data); - }.bind(this) - ); - - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id] = null; - result.push(data); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + let htmls = elements.map(element => $(element).html()); + if (!this.multiple) { + htmls = htmls.length ? htmls[0] : null; } - - dfd.resolve(result); - return dfd.promise(); + return [{ [this.id]: htmls }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorImage.js b/src/scripts/Selector/SelectorImage.js index b2aaa6bc..3bf39264 100644 --- a/src/scripts/Selector/SelectorImage.js +++ b/src/scripts/Selector/SelectorImage.js @@ -1,5 +1,5 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; -import '../../libs/jquery.whencallsequentially'; export default class SelectorImage extends Selector { constructor(options) { @@ -8,7 +8,7 @@ export default class SelectorImage extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -27,75 +27,63 @@ export default class SelectorImage extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); - - var elements = this.getDataElements(parentElement); - - var deferredDataCalls = []; - $(elements).each( - function(i, element) { - deferredDataCalls.push( - function() { - var deferredData = $.Deferred(), - data = {}; - - src = element.src; - - // get url from style - if (src == null) { - src = $(element).css('background-image'); - src = /^url\((['"]?)(.*)\1\)$/.exec(src); - src = src ? src[2] : ''; - } - - src = this.stringReplace(src, this.stringReplacement); - - data[this.id + '-src'] = src; + downloadsAttachments() { + return !!this.downloadImage; + } - // download image if required - if (!this.downloadImage) { - deferredData.resolve(data); - } else { - var deferredFileBase64 = this.downloadFileAsBase64(src); - deferredFileBase64 - .done( - function(imageResponse) { - data['_fileBase64-' + this.id] = imageResponse.fileBase64; - data['_fileMimeType-' + this.id] = imageResponse.mimeType; - data['_filename' + this.id] = imageResponse.filename; + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + const urls = elements.map(element => { + let { src } = element; + // get url from style + if (src == null) { + src = $(element).css('background-image'); + src = /^url\((['"]?)(.*)\1\)$/.exec(src); + src = src ? src[2] : ''; + } + return this.stringReplace(src, this.stringReplacement); + }); - deferredData.resolve(data); - }.bind(this) - ) - .fail(function() { - // failed to download image continue. - // @TODO handle errror - deferredData.resolve(data); - }); + const result = {}; + if (this.multiple) { + result[`${this.id}-src`] = urls; + } else { + result[`${this.id}-src`] = urls.length ? urls[0] : null; + } + + if (this.downloadImage) { + const images = []; + for (const [i, url] of urls.entries()) { + try { + if (url) { + const image = await this.downloadFileAsBase64(url); + if (!image.filename) { + image.filename = this.getFilenameFromUrl(url); } - - return deferredData.promise(); - }.bind(this) - ); - }.bind(this) - ); - - $.whenCallSequentially(deferredDataCalls).done(function(dataResults) { - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id + '-src'] = null; - dataResults.push(data); + images.push(image); + } + } catch (e) { + console.warn(`Failed to download image by url ${url}`, e); + } } + if (images.length) { + result[`_attachments-${this.id}`] = images; + } + } - dfd.resolve(dataResults); - }); - - return dfd.promise(); + return [result]; } getDataColumns() { - return [this.id + '-src']; + const dataColumns = [`${this.id}-src`]; + if (this.downloadImage) { + dataColumns.push(`${this.id}-path`, `${this.id}-checksum`, `${this.id}-filename`); + } + return dataColumns; + } + + getUrlColumn() { + return `${this.id}-src`; } getFeatures() { diff --git a/src/scripts/Selector/SelectorInputValue.js b/src/scripts/Selector/SelectorInputValue.js index b30cf0f9..d91ee21a 100644 --- a/src/scripts/Selector/SelectorInputValue.js +++ b/src/scripts/Selector/SelectorInputValue.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorInputValue extends Selector { @@ -26,24 +27,10 @@ export default class SelectorInputValue extends Selector { return false; } - _getData(parentElement) { - var dfd = $.Deferred(); - - var elements = this.getDataElements(parentElement); - - var result = []; - $(elements).each( - function(k, element) { - $(element).val(this.value); - }.bind(this) - ); - - var data = {}; - data[this.id] = this.value; - result.push(data); - - dfd.resolve(result); - return dfd.promise(); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + elements.forEach(element => $(element).val(this.value)); + return [{ [this.id]: this.value }]; } getDataColumns() { diff --git a/src/scripts/Selector/SelectorLink.js b/src/scripts/Selector/SelectorLink.js index 6309fc1a..b4e15a35 100644 --- a/src/scripts/Selector/SelectorLink.js +++ b/src/scripts/Selector/SelectorLink.js @@ -1,5 +1,5 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; -import '../../libs/jquery.whencallsequentially'; export default class SelectorLink extends Selector { constructor(options) { @@ -27,61 +27,27 @@ export default class SelectorLink extends Selector { return false; } - _getData(parentElement) { - var elements = this.getDataElements(parentElement); - - var dfd = $.Deferred(); - - // return empty record if not multiple type and no elements found - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id] = null; - dfd.resolve([data]); - return dfd; + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + if (!this.multiple && !elements.length) { + return [{ [this.id]: null }]; } - - // extract links one by one - var deferredDataExtractionCalls = []; - $(elements).each( - function(k, element) { - deferredDataExtractionCalls.push( - function(element) { - var deferredData = $.Deferred(); - var data = {}; - - var extracted_value; - if (this.extractAttribute) { - extracted_value = element[this.extractAttribute]; - } else { - extracted_value = $(element).text(); - } - extracted_value = this.stringReplace(extracted_value, this.stringReplacement); - - data[this.id] = $(element).text(); - data[this.id + '-href'] = extracted_value; - data._followSelectorId = this.id; - data._follow = extracted_value; - deferredData.resolve(data); - - return deferredData; - }.bind(this, element) - ); - }.bind(this) - ); - - $.whenCallSequentially(deferredDataExtractionCalls).done(function(responses) { - var result = []; - responses.forEach(function(dataResult) { - result.push(dataResult); - }); - dfd.resolve(result); + return elements.map(element => { + const $element = $(element); + const text = $element.text(); + let url = this.extractAttribute ? $element.attr(this.extractAttribute) : text; + url = this.stringReplace(url, this.stringReplacement); + return { + [this.id]: text, + [`${this.id}-href`]: url, + _followSelectorId: this.id, + _follow: url, + }; }); - - return dfd.promise(); } getDataColumns() { - return [this.id, this.id + '-href']; + return [this.id, `${this.id}-href`]; } getFeatures() { diff --git a/src/scripts/Selector/SelectorPopupLink.js b/src/scripts/Selector/SelectorPopupLink.js index 1d5f34b8..d320dce4 100644 --- a/src/scripts/Selector/SelectorPopupLink.js +++ b/src/scripts/Selector/SelectorPopupLink.js @@ -1,5 +1,5 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; -import '../../libs/jquery.whencallsequentially'; export default class SelectorPopupLink extends Selector { constructor(options) { @@ -27,75 +27,23 @@ export default class SelectorPopupLink extends Selector { return false; } - _getData(parentElement) { - var elements = this.getDataElements(parentElement); - - var dfd = $.Deferred(); - - // return empty record if not multiple type and no elements found - if (this.multiple === false && elements.length === 0) { - var data = {}; - data[this.id] = null; - dfd.resolve([data]); - return dfd; + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + if (!this.multiple && !elements.length) { + return [{ [this.id]: null }]; } - - // extract links one by one - var deferredDataExtractionCalls = []; - $(elements).each( - function(k, element) { - deferredDataExtractionCalls.push( - function(element) { - var deferredData = $.Deferred(); - - var data = {}; - data[this.id] = $(element).text(); - data._followSelectorId = this.id; - - var deferredPopupURL = this.getPopupURL(element); - deferredPopupURL.done( - function(url) { - data[this.id + '-href'] = url; - data._follow = url; - deferredData.resolve(data); - }.bind(this) - ); - - return deferredData; - }.bind(this, element) - ); - }.bind(this) - ); - - $.whenCallSequentially(deferredDataExtractionCalls).done(function(responses) { - var result = []; - responses.forEach(function(dataResult) { - result.push(dataResult); + const links = []; + for (const element of elements) { + const text = $(element).text(); + const url = await this.getPopupURL(element); + links.push({ + [this.id]: text, + [`${this.id}-href`]: url, + _followSelectorId: this.id, + _follow: url, }); - dfd.resolve(result); - }); - - return dfd.promise(); - } - - getElementCSSSelector(element) { - var nthChild, prev; - for (nthChild = 1, prev = element.previousElementSibling; prev !== null; prev = prev.previousElementSibling, nthChild++); - var tagName = element.tagName.toLocaleLowerCase(); - var cssSelector = tagName + ':nth-child(' + nthChild + ')'; - - while (element.parentElement) { - element = element.parentElement; - var tagName = element.tagName.toLocaleLowerCase(); - if (tagName === 'body' || tagName === 'html') { - cssSelector = tagName + '>' + cssSelector; - } else { - for (nthChild = 1, prev = element.previousElementSibling; prev !== null; prev = prev.previousElementSibling, nthChild++); - cssSelector = tagName + ':nth-child(' + nthChild + ')>' + cssSelector; - } } - - return cssSelector; + return links; } /** @@ -106,50 +54,45 @@ export default class SelectorPopupLink extends Selector { getPopupURL(element) { // override window.open function. we need to execute this in page scope. // we need to know how to find this element from page scope. - var cssSelector = this.getElementCSSSelector(element); + const cssSelector = this.getElementCSSSelector(element); // this function will catch window.open call and place the requested url as the elements data attribute - var script = document.createElement('script'); + const script = document.createElement('script'); script.type = 'text/javascript'; - script.text = - '' + - '(function(){ ' + - 'var open = window.open; ' + - "var el = document.querySelectorAll('" + - cssSelector + - "')[0]; " + - 'var openNew = function() { ' + - 'var url = arguments[0]; ' + - 'el.dataset.webScraperExtractUrl = url; ' + - 'window.open = open; ' + - '};' + - 'window.open = openNew; ' + - 'el.click(); ' + - '})();'; + script.text = `{ + const { open } = window; + const el = document.querySelector('${cssSelector}'); + window.open = url => { + el.dataset.webScraperExtractUrl = url; + window.open = open; + }; + el.click(); + }`; document.body.appendChild(script); // wait for url to be available - var deferredURL = $.Deferred(); - var timeout = Math.abs(5000 / 30); // 5s timeout to generate an url for popup - var interval = setInterval(function() { - var url = $(element).data('web-scraper-extract-url'); - if (url) { - deferredURL.resolve(url); - clearInterval(interval); - script.remove(); - } - // timeout popup opening - if (timeout-- <= 0) { - clearInterval(interval); - script.remove(); - } - }, 30); - - return deferredURL.promise(); + const timeout = 5000; // 5s timeout to generate an url for popup + const intervalTickRate = 30; // check each 30 ms + let ticks = Math.ceil(timeout / intervalTickRate); + return new Promise(resolve => { + const interval = setInterval(() => { + const url = $(element).data('web-scraper-extract-url'); + if (url) { + clearInterval(interval); + script.remove(); + resolve(url); + } + // timeout popup opening + if (!--ticks) { + clearInterval(interval); + script.remove(); + } + }, intervalTickRate); + }); } getDataColumns() { - return [this.id, this.id + '-href']; + return [this.id, `${this.id}-href`]; } getFeatures() { diff --git a/src/scripts/Selector/SelectorTable.js b/src/scripts/Selector/SelectorTable.js index 9fb59e51..00881780 100644 --- a/src/scripts/Selector/SelectorTable.js +++ b/src/scripts/Selector/SelectorTable.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorTable extends Selector { @@ -27,161 +28,127 @@ export default class SelectorTable extends Selector { } getTableHeaderColumns($table) { - let columns = {}; - let headerRowSelector = this.getTableHeaderRowSelector(); - let $headerRow = $table.find(headerRowSelector); - - if ($headerRow.length > 0) { - if ($headerRow.length > 1) { - if ($headerRow[0].nodeName === 'TR') { - $headerRow = $headerRow.find('th:first-child'); - if ($headerRow.length === 0) { - console.log('%c Please specify row header cell selector ', 'background: red; color: white;'); - } + const headerRowSelector = this.getTableHeaderRowSelector(); + const columns = this.getHeaderColumnsIndices($table, headerRowSelector, this.verticalTable); + // add missing columns + if (this.tableAddMissingColumns) { + Object.keys(columns).forEach(header => { + const matchedColumn = this.columns.find(column => column.header === header); + if (!matchedColumn) { + this.columns.push({ + header, + name: header, + extract: true, + }); } - } else if ($headerRow.find('th').length) { - $headerRow = $headerRow.find('th'); - } else if ($headerRow.find('td').length) { - $headerRow = $headerRow.find('td'); - } - - $headerRow.each( - function(i, value) { - let header = $(value) - .text() - .trim(); - columns[header] = { - index: i + 1, - }; - }.bind(this) - ); - - this.addMissingColumns($headerRow); + }); } return columns; } - addMissingColumns(headerRow) { - headerRow.each( - function(i, value) { - if (this.tableAddMissingColumns) { - let header = $(value) - .text() - .trim(); - let column = $.grep(this.columns, function(h) { - return h.name === header; - }); - - if (column.length !== 1) { - this.columns.push({ - header: header, - extract: true, - }); - } - } - }.bind(this) - ); - } - - getVerticalDataCells(table, dataSelector) { - let selectors = $(table).find(dataSelector), - isRow = selectors[0].nodeName === 'TR', - result = []; + getVerticalDataCells(table) { + const columnIndices = this.getTableHeaderColumns($(table)); + const dataSelector = this.getTableDataRowSelector(); + const dataColumns = this.getDataColumns(); + const dataCells = $(table).find(dataSelector); + const isRow = dataCells[0].nodeName === 'TR'; + let result = []; if (isRow) { - console.log('%c Please specify row data cell selector ', 'background: red; color: white;'); - } else { - for (let i = 0; i < selectors.length; i++) { - result.push({}); - } - selectors.each( - function(i, dataCell) { - if (dataCell.cellIndex === 0) { - console.log("%c Vertical rows can't have first column as data cell ", 'background: red; color: white;'); - } else { - let headerCellName = $(dataCell) - .closest('tr') - .find('th, td')[0].innerText; - - let listDataColumnName = this.getDataColumnName(headerCellName); - let dataCellvalue = dataCell.innerText; - if (listDataColumnName) { - result[dataCell.cellIndex - 1][listDataColumnName] = dataCellvalue; - } - } - }.bind(this) + console.log( + '%c Please specify row data cell selector ', + 'background: red; color: white;' ); + return result; } - return result; - } - - _getData(parentElement) { - let dfd = $.Deferred(); - let verticalTable = this.verticalTable; - let tables = this.getDataElements(parentElement); - - let result = []; - $(tables).each( - function(k, table) { - let dataSelector = this.getTableDataRowSelector(); - if (verticalTable) { - let columnsList = this.getVerticalDataCells(table, dataSelector); - columnsList.forEach(function(column) { - if (!$.isEmptyObject(column)) { - result.push(column); - } - }); - } else { - let columnIndices = this.getTableHeaderColumns($(table)); - $(table) - .find(dataSelector) - .each( - function(i, dataCell) { - let data = {}; + result = Array.from({ + length: dataCells.length / Object.keys(columnIndices).length, + }).map(_ => Object()); + dataCells.each((rowNum, dataCell) => { + if (dataCell.cellIndex === 0) { + console.log( + "%c Vertical rows can't have first column as data cell ", + 'background: red; color: white;' + ); + } else { + const headerName = SelectorTable.trimHeader( + $(dataCell).closest('tr').find('th, td')[0].innerText + ); - this.columns.forEach(function(column) { - let header = columnIndices[column.header.trim()]; - let rowText = $(dataCell) - .find('>:nth-child(' + header.index + ')') - .text() - .trim(); - if (column.extract) { - data[column.name] = rowText; - } - }); - result.push(data); - }.bind(this) - ); + const column = dataColumns.find(column => column.header === headerName); + if (column) { + result[dataCell.cellIndex - 1][column.name] = dataCell.innerText; } - }.bind(this) - ); + } + }); - dfd.resolve(result); - return dfd.promise(); + return result.filter(column => !$.isEmptyObject(column)); } - getDataColumns() { - let dataColumns = []; - this.columns.forEach(function(column) { - if (column.extract) { - dataColumns.push(column.name); + getHorizontalDataCells(table) { + const columnIndices = this.getTableHeaderColumns($(table)); + const dataColumns = this.getDataColumns(); + const rows = $(table).find(this.getTableDataRowSelector()); + const result = Array.from({ length: rows.length }).map(_ => Object()); + rows.each((rowNum, row) => { + // helper function + function getColumnIndex(column) { + return columnIndices[column.header] - 1; } + + // count current row offsets + const rowOffsets = dataColumns.map(column => { + return dataColumns.filter(key => { + return ( + getColumnIndex(key) < getColumnIndex(column) && key.header in result[rowNum] + ); + }).length; + }); + + // extract data from row + dataColumns + .filter(column => !(column.header in result[rowNum])) + .forEach(column => { + const headerIndex = getColumnIndex(column); + const cell = $(row)[0].children[headerIndex - rowOffsets[headerIndex]]; + const cellText = cell.innerText.trim(); + result[rowNum][column.name] = cellText; + + // if we have rowSpan in cell push to further rows + if ('rowSpan' in cell && cell.rowSpan > 1) { + for (let i = rowNum; i < rowNum + cell.rowSpan; i++) { + result[i][column.name] = cellText; + } + } + }); }); - return dataColumns; + return result; } - getDataColumnName(header) { - let answer = this.columns.find(function(column) { - return column.extract && header === column.header.trim(); - }); - if (answer) { - return answer.name; - } + async _getData(parentElement) { + const tables = this.getDataElements(parentElement); + const getDataCells = this.verticalTable + ? this.getVerticalDataCells + : this.getHorizontalDataCells; + return tables.flatMap(getDataCells); + } + + getDataColumns() { + return this.columns.filter(column => column.extract); } getFeatures() { - return ['selector', 'multiple', 'columns', 'delay', 'tableDataRowSelector', 'tableHeaderRowSelector', 'tableAddMissingColumns', 'verticalTable']; + return [ + 'selector', + 'multiple', + 'columns', + 'delay', + 'tableDataRowSelector', + 'tableHeaderRowSelector', + 'tableAddMissingColumns', + 'verticalTable', + ]; } getItemCSSSelector() { @@ -190,108 +157,158 @@ export default class SelectorTable extends Selector { getTableHeaderRowSelector() { // handle legacy selectors - if (this.tableHeaderRowSelector === undefined) { - return 'thead tr'; - } else { - return this.tableHeaderRowSelector; - } + return this.tableHeaderRowSelector || 'thead tr'; } getTableDataRowSelector() { // handle legacy selectors - if (this.tableDataRowSelector === undefined) { - return 'tbody tr'; - } else { - return this.tableDataRowSelector; - } + return this.tableDataRowSelector || 'tbody tr'; } - static getTableHeaderRowSelectorFromTableHTML(html, verticalTable) { - let $table = $(html); - let firstRow = $table.find('tr:first-child'); - - if ($table.find('thead tr:has(td:not(:empty)), thead tr:has(th:not(:empty))').length) { - if ($table.find('thead tr').length === 1) { - return 'thead tr'; - } else { - let $rows = $table.find('thead tr'); - // first row with data - let rowIndex = $rows.index($rows.filter(':has(td:not(:empty)),:has(th:not(:empty))')[0]); - return 'thead tr:nth-of-type(' + (rowIndex + 1) + ')'; - } + // TODO split this method into two: one determines table orientation, second finds header row. + getTableHeaderRowSelectorFromTableHTML(html) { + const $table = $(html); + if ($table.find('thead tr:has(td:not(:empty)), thead tr:has(th:not(:empty))').length >= 1) { + // rows in thead + this.tableHeaderRowSelector = 'thead tr'; + this.verticalTable = false; } else { - if (!verticalTable) { + const firstRow = $table.find('tr:first-of-type'); + if (!this.verticalTable) { if (firstRow.find('th:not(:empty)').length > 1) { - return 'tr:nth-of-type(1)'; - } else if (firstRow.find('th:first-child:not(:empty)').length === 1 && firstRow.children().length > 1) { - return 'tr'; + // if we have more than one th in first row + // TODO find first row without th here and in data selector + this.tableHeaderRowSelector = 'tr:nth-of-type(1)'; + this.verticalTable = false; + } else if ( + firstRow.find('th:first-of-type:not(:empty)').length === 1 && + firstRow.children().length > 1 + ) { + // this is the case of vertical table with th on first cell + this.tableHeaderRowSelector = 'tr>th'; + this.verticalTable = true; } else if ($table.find('tr td:not(:empty), tr th:not(:empty)').length) { - let $rows = $table.find('tr'); - // first row with data - let rowIndex = $rows.index($rows.filter(':has(td:not(:empty)),:has(th:not(:empty))')[0]); - return 'tr:nth-of-type(' + (rowIndex + 1) + ')'; + const $rows = $table.find('tr'); + // first row with th or td + const rowIndex = $rows.index( + $rows.filter(':has(td:not(:empty)), :has(th:not(:empty))')[0] + ); + this.tableHeaderRowSelector = `tr:nth-of-type(${rowIndex + 1})`; + this.verticalTable = false; } else { - return ''; + this.tableHeaderRowSelector = ''; } + } else if (firstRow.find('th').length) { + // vertical table with th on first cell + this.tableHeaderRowSelector = 'tr>th'; + this.verticalTable = true; } else { - if (firstRow.find('th').length) { - return 'tr>th'; - } else { - return 'tr>td:nth-of-type(1)'; - } + // vertical table with only td + this.tableHeaderRowSelector = 'tr>td:nth-of-type(1)'; + this.verticalTable = true; } } } - static getTableDataRowSelectorFromTableHTML(html, verticalTable) { - let $table = $(html); + getTableDataRowSelectorFromTableHTML(html) { + const $table = $(html); if ($table.find('thead tr:has(td:not(:empty)), thead tr:has(th:not(:empty))').length) { - return 'tbody tr'; - } else { - if (!verticalTable) { - if ($table.find('tr td:not(:empty), tr th:not(:empty)').length) { - let $rows = $table.find('tr'); - // first row with data - let rowIndex = $rows.index($rows.filter(':has(td:not(:empty)),:has(th:not(:empty))')[0]); - return 'tr:nth-of-type(n+' + (rowIndex + 2) + ')'; - } - } else { - if ($table.find('th').length) return 'tr>td'; - else return 'tr>td:nth-of-type(n+2)'; + // rows in tbody + this.tableDataRowSelector = 'tbody tr'; + } else if (!this.verticalTable) { + if ($table.find('tr td:not(:empty), tr th:not(:empty)').length) { + const $rows = $table.find('tr'); + // first row with data + const rowIndex = $rows.index( + $rows.filter(':has(td:not(:empty)),:has(th:not(:empty))')[0] + ); + this.tableDataRowSelector = `tr:nth-of-type(n+${rowIndex + 2})`; } + } else if ($table.find('th').length) { + // vertical table with th on first cell + this.tableDataRowSelector = 'tr>td'; + } else { + // vertical table with only td + this.tableDataRowSelector = 'tr>td:nth-of-type(n+2)'; } } /** * Extract table header column info from html - * @param headerRowSelector - * @param html - * @param verticalTable + * @param $headerRow header's html */ - static getTableHeaderColumnsFromHTML(headerRowSelector, html, verticalTable) { - let $table = $(html); - let $headerRowColumns = $table.find(headerRowSelector); - - let columns = []; - if (!verticalTable) { - if ($headerRowColumns.length > 1) { - $headerRowColumns = $headerRowColumns.find('th:first-child'); - } else if ($headerRowColumns.find('th').length) { - $headerRowColumns = $headerRowColumns.find('th'); - } else if ($headerRowColumns.find('td').length) { - $headerRowColumns = $headerRowColumns.find('td'); + horizontalColumnsMaker($headerRow) { + const columns = {}; + const tableRowOffsets = {}; + /** + * @param tableRowNum - number of layer of our header + * @param nameAcc - accumulator for the name of our column + * @param maxSpanOffset - maximum number of columns to watch (-1 if no limits) + */ + function columnsMakerHelper(tableRowNum, nameAcc, maxSpanOffset) { + const startSpanOffset = + tableRowNum in tableRowOffsets ? tableRowOffsets[tableRowNum] : 0; + let colSpanOffset = 0; + for (const cell of $headerRow[tableRowNum].children) { + const colSpan = 'colSpan' in cell ? cell.colSpan : 1; + colSpanOffset += colSpan; + if (colSpanOffset < startSpanOffset + 1) { + continue; + } + const header = (nameAcc ? `${nameAcc} ` : '') + $(cell).text(); + if (colSpan < 2) { + columns[SelectorTable.trimHeader(header)] = Object.keys(columns).length + 1; + } else { + columnsMakerHelper(tableRowNum + 1, header, colSpan); + } + tableRowOffsets[tableRowNum] = colSpanOffset; + if (maxSpanOffset > 0 && colSpanOffset >= maxSpanOffset + startSpanOffset) { + return; + } } } - $headerRowColumns.each(function(i, columnEl) { - let header = columnEl.innerText; - if (header) { - columns.push({ - header: header, - name: header, - extract: true, - }); - } - }); + columnsMakerHelper(0, '', -1); return columns; } + + getHeaderColumnsIndices(tableHtml) { + const $table = $(tableHtml); + const $headerRowColumns = $table.find(this.tableHeaderRowSelector); + let columns; + if (!this.verticalTable) { + columns = this.horizontalColumnsMaker($headerRowColumns); + } else { + columns = {}; + $headerRowColumns.each((i, headerElement) => { + const header = SelectorTable.trimHeader($(headerElement).text()); + columns[header] = i + 1; + }); + } + return columns; + } + + getTableHeaderColumnsFromHTML(tableHtml) { + const columns = this.getHeaderColumnsIndices(tableHtml); + this.headerColumns = Object.keys(columns).map(header => { + return { + header: SelectorTable.trimHeader(header), + name: SelectorTable.trimHeader(header), + extract: true, + }; + }); + } + + static trimHeader(header) { + return header.trim().replace(/\s+/gm, ' '); + } + + async afterSelect(cssSelector, controller) { + await super.afterSelect(cssSelector, controller); + const html = await controller.getSelectorHTML(this); + this.getTableHeaderRowSelectorFromTableHTML(html); + this.getTableDataRowSelectorFromTableHTML(html); + this.getTableHeaderColumnsFromHTML(html); + controller._editSelector(this); + controller.renderTableHeaderColumns(this.headerColumns); + } } diff --git a/src/scripts/Selector/SelectorText.js b/src/scripts/Selector/SelectorText.js index c728d23e..bf365a40 100644 --- a/src/scripts/Selector/SelectorText.js +++ b/src/scripts/Selector/SelectorText.js @@ -1,3 +1,4 @@ +import * as $ from 'jquery'; import Selector from '../Selector'; export default class SelectorText extends Selector { @@ -7,7 +8,7 @@ export default class SelectorText extends Selector { } canReturnMultipleRecords() { - return true; + return false; } canHaveChildSelectors() { @@ -26,35 +27,20 @@ export default class SelectorText extends Selector { return false; } - _getData(parentElement) { - let dfd = $.Deferred(); - - let elements = this.getDataElements(parentElement); - - let result = []; - $(elements).each( - function(k, element) { - let data = {}; - - // remove script, style tag contents from text results - let $element_clone = $(element).clone(); - $element_clone.find('script, style').remove(); - //
replace br tags with newlines - $element_clone.find('br').after('\n'); - data[this.id] = $element_clone.text(); - - result.push(data); - }.bind(this) - ); - - if (this.multiple === false && elements.length === 0) { - let data = {}; - data[this.id] = null; - result.push(data); + async _getData(parentElement) { + const elements = this.getDataElements(parentElement); + let texts = elements.map(element => { + // remove script, style tag contents from text results + const $elementClone = $(element).clone(); + $elementClone.find('script, style').remove(); + //
replace br tags with newlines + $elementClone.find('br').after('\n'); + return $elementClone.text(); + }); + if (!this.multiple) { + texts = texts.length ? texts[0] : null; } - - dfd.resolve(result); - return dfd.promise(); + return [{ [this.id]: texts }]; } getDataColumns() { diff --git a/src/scripts/Sitemap.js b/src/scripts/Sitemap.js index 7bca1610..a40d1fe9 100644 --- a/src/scripts/Sitemap.js +++ b/src/scripts/Sitemap.js @@ -1,17 +1,27 @@ import DatePatternSupport from './DateUtils/DatePatternSupport'; import SelectorList from './SelectorList'; +import Model from './Model'; import * as Papa from 'papaparse'; export default class Sitemap { - constructor(sitemapObj) { - this.initData(sitemapObj); - } - - initData(sitemapObj) { - for (let key in sitemapObj) { - this[key] = sitemapObj[key]; + constructor(id, startUrls, model, selectors) { + this._id = id; + this.startUrls = startUrls; + this.model = new Model(model); + this.selectors = new SelectorList(selectors ? selectors : []); + } + + static sitemapFromObj(sitemapObj) { + let sitemap = new Sitemap( + sitemapObj._id, + sitemapObj.startUrls, + sitemapObj.model, + sitemapObj.selectors + ); + if (sitemapObj._rev) { + sitemap._rev = sitemapObj._rev; } - this.selectors = new SelectorList(this.selectors); + return sitemap; } static isUrlValid(url) { @@ -57,7 +67,7 @@ export default class Sitemap { */ getSelectorIds() { let ids = ['_root']; - this.selectors.forEach(function(selector) { + this.selectors.forEach(function (selector) { ids.push(selector.id); }); return ids; @@ -70,7 +80,7 @@ export default class Sitemap { getPossibleParentSelectorIds() { let ids = ['_root']; this.selectors.forEach( - function(selector) { + function (selector) { if (selector.canHaveChildSelectors()) { ids.push(selector.id); } @@ -83,9 +93,9 @@ export default class Sitemap { let startUrls = this.startUrls; startUrls = DatePatternSupport.expandUrl(startUrls); - let nextUrls = function(url) { + let nextUrls = function (url) { let urls = []; - let lpad = function(str, length) { + let lpad = function (str, length) { while (str.length < length) str = '0' + str; return str; }; @@ -112,7 +122,7 @@ export default class Sitemap { } else { current = matches[1] + i; } - nextSet.forEach(function(next) { + nextSet.forEach(function (next) { urls.push(current + next); }); } @@ -123,7 +133,7 @@ export default class Sitemap { }; let urls = []; - startUrls.forEach(function(startUrl) { + startUrls.forEach(function (startUrl) { urls = urls.concat(nextUrls(startUrl)); }); @@ -138,7 +148,7 @@ export default class Sitemap { // update child selectors if (selector.id !== undefined && selector.id !== selectorData.id) { - this.selectors.forEach(function(currentSelector) { + this.selectors.forEach(function (currentSelector) { currentSelector.renameParentSelector(selector.id, selectorData.id); }); @@ -161,7 +171,7 @@ export default class Sitemap { } deleteSelector(selectorToDelete) { this.selectors.forEach( - function(selector) { + function (selector) { if (selector.hasParentSelector(selectorToDelete.id)) { selector.removeParentSelector(selectorToDelete.id); if (selector.parentSelectors.length === 0) { @@ -183,7 +193,7 @@ export default class Sitemap { } exportSitemap() { function removeEmpty(obj) { - Object.keys(obj).forEach(function(key) { + Object.keys(obj).forEach(function (key) { if (obj[key] && typeof obj[key] === 'object') { removeEmpty(obj[key]); if (Object.keys(obj[key]).length === 0) { @@ -199,63 +209,22 @@ export default class Sitemap { removeEmpty(sitemapObj); return JSON.stringify(sitemapObj); } - importSitemap(sitemapJSON) { - let sitemapObj = JSON.parse(sitemapJSON); - this.initData(sitemapObj); - } + // return a list of columns than can be exported getDataColumns() { let columns = []; - this.selectors.forEach(function(selector) { + this.selectors.forEach(function (selector) { columns = columns.concat(selector.getDataColumns()); }); let uniqueColumns = []; - $.each(columns, function(i, e) { + $.each(columns, function (i, e) { if ($.inArray(e, uniqueColumns) == -1) uniqueColumns.push(e); }); return uniqueColumns; } - getDataExportCsvBlob(data, option) { - let delimiterKey = 'delimiter'; - let newlineKey = 'newline'; - let containBomKey = 'containBom'; - - let columns = this.getDataColumns(), - // default delimiter is comma - delimiter = option.hasOwnProperty(delimiterKey) ? option[delimiterKey] : ',', - // per default, new line is included at end of lines - newline = option.hasOwnProperty(newlineKey) ? (option[newlineKey] == true ? '\r\n' : '') : '\r\n', - // per default, utf8 BOM is included at the beginning. - prepend = option.hasOwnProperty(containBomKey) ? (option[containBomKey] == true ? '\ufeff' : '') : '\ufeff', // utf-8 bom char - options = { - quotes: false, - quoteChar: '"', - delimiter: delimiter, - header: true, - newline: '\r\n', // between value rows - }, - jsonData = []; - // data - data.forEach(function(row) { - let jsonRow = {}; - columns.forEach(function(column) { - let cellData = row[column]; - if (cellData === undefined) { - cellData = ''; - } else if (typeof cellData === 'object') { - cellData = JSON.stringify(cellData); - } - - jsonRow[column] = cellData; - }); - jsonData.push(jsonRow); - }); - - return new Blob([prepend + Papa.unparse(jsonData, options) + newline], { type: 'text/csv' }); - } getSelectorById(selectorId) { return this.selectors.getSelectorById(selectorId); } @@ -264,7 +233,12 @@ export default class Sitemap { * @returns {Sitemap} */ clone() { - let clonedJSON = JSON.parse(JSON.stringify(this)); - return new Sitemap(clonedJSON); + let clonedObj = JSON.parse(JSON.stringify(this)); + return new Sitemap( + clonedObj._id, + clonedObj.startUrls, + clonedObj.model, + clonedObj.selectors + ); } } diff --git a/src/scripts/StoreDevtools.js b/src/scripts/StoreDevtools.js index 3c9f39ca..57c425e8 100644 --- a/src/scripts/StoreDevtools.js +++ b/src/scripts/StoreDevtools.js @@ -1,5 +1,5 @@ -import Sitemap from './Sitemap'; import * as browser from 'webextension-polyfill'; +import Sitemap from './Sitemap'; /** * From devtools panel there is no possibility to execute XHR requests. So all requests to a remote CouchDb must be @@ -7,53 +7,48 @@ import * as browser from 'webextension-polyfill'; * @constructor */ export default class StoreDevtools { - createSitemap(sitemap) { - var request = { + async createSitemap(sitemap) { + const request = { createSitemap: true, sitemap: JSON.parse(JSON.stringify(sitemap)), }; - return new Promise(resolve => { - browser.runtime.sendMessage(request).then( - function(originalSitemap, newSitemap) { - originalSitemap._rev = newSitemap._rev; - resolve(originalSitemap); - }.bind(this, sitemap) - ); - }); + const newSitemap = await browser.runtime.sendMessage(request); + sitemap._rev = newSitemap._rev; + return sitemap; } - saveSitemap(sitemap) { - return this.createSitemap(sitemap); + async saveSitemap(sitemap) { + const request = { + saveSitemap: true, + sitemap: JSON.parse(JSON.stringify(sitemap)), + }; + + const newSitemap = await browser.runtime.sendMessage(request); + sitemap._rev = newSitemap._rev; + return sitemap; } deleteSitemap(sitemap) { - var request = { + const request = { deleteSitemap: true, sitemap: JSON.parse(JSON.stringify(sitemap)), }; return browser.runtime.sendMessage(request); } - getAllSitemaps() { - var request = { + async getAllSitemaps() { + const request = { getAllSitemaps: true, }; - - return new Promise(resolve => { - browser.runtime.sendMessage(request).then(function(response) { - var sitemaps = []; - - for (var i in response) { - sitemaps.push(new Sitemap(response[i])); - } - return resolve(sitemaps); - }); + const response = await browser.runtime.sendMessage(request); + return Array.from(response, sitemapObj => { + return Sitemap.sitemapFromObj(sitemapObj); }); } getSitemapData(sitemap) { - var request = { + const request = { getSitemapData: true, sitemap: JSON.parse(JSON.stringify(sitemap)), }; @@ -62,9 +57,9 @@ export default class StoreDevtools { } sitemapExists(sitemapId) { - var request = { + const request = { sitemapExists: true, - sitemapId: sitemapId, + sitemapId, }; return browser.runtime.sendMessage(request); diff --git a/src/scripts/StorePouchDB.js b/src/scripts/StorePouchDB.js index b02b0435..e944d0cb 100644 --- a/src/scripts/StorePouchDB.js +++ b/src/scripts/StorePouchDB.js @@ -1,50 +1,25 @@ import PouchDB from 'pouchdb'; import * as browser from 'webextension-polyfill'; import Sitemap from './Sitemap'; - -/** - * Make sure all obj have the same properties - * They can differe if table selector retrieves dynamic columns - */ -let normalizeProperties = function(docs) { - // get all keys of the objects - let keys = []; - docs.forEach(function(doc) { - for (let key in doc) { - if (doc.hasOwnProperty(key) && keys.indexOf(key) === -1) { - keys.push(key); - } - } - }); - - // add missing keys to objects - docs.forEach(function(doc) { - let objKeys = Object.keys(doc); - keys.forEach(function(key) { - if (!(key in doc)) { - doc[key] = ''; - } - }); - }); -}; +import 'sugar'; class StoreScrapeResultWriter { constructor(db) { this.db = db; } - writeDocs(docs, callback) { + writeDocs(docs) { if (docs.length === 0) { - callback(); - } else { - normalizeProperties(docs); - this.db.bulkDocs({ docs: docs }, function(err, response) { - if (err !== null) { - console.log('Error while persisting scraped data to db', err); - } - callback(); - }); + return Promise.resolve(); } + // Extra wrapping is added since PouchDB forbids identifiers starting + // with underscore. We use them for our attachments and meta information. + // TODO Consider moving custom properties from doc to wrapper level + return this.db.bulkDocs({ docs: docs.map(doc => ({ data: doc })) }).catch(err => { + if (err !== null) { + console.log('Error while persisting scraped data to db', err); + } + }); } } @@ -56,16 +31,16 @@ export default class StorePouchDB { } sanitizeSitemapDataDbName(dbName) { - return 'sitemap-data-' + dbName.replace(/[^a-z0-9_\$\(\)\+\-/]/gi, '_'); + return `sitemap-data-${dbName.replace(/[^a-z0-9_\$\(\)\+\-/]/gi, '_')}`; } getSitemapDataDbLocation(sitemapId) { - let dbName = this.sanitizeSitemapDataDbName(sitemapId); + const dbName = this.sanitizeSitemapDataDbName(sitemapId); return this.config.dataDb + dbName; } getSitemapDataDb(sitemapId) { - let dbLocation = this.getSitemapDataDbLocation(sitemapId); + const dbLocation = this.getSitemapDataDbLocation(sitemapId); return new PouchDB(dbLocation); } @@ -74,118 +49,73 @@ export default class StorePouchDB { * @param {type} sitemapId * @returns {undefined} */ - initSitemapDataDb(sitemapId) { - // let dbLocation = this.getSitemapDataDbLocation(sitemapId); - let store = this; + async initSitemapDataDb(sitemapId) { + const store = this; let db = this.getSitemapDataDb(sitemapId); - - return new Promise(resolve => { - db.destroy() - .then(() => { - let db = store.getSitemapDataDb(sitemapId); - let dbWriter = new StoreScrapeResultWriter(db); - resolve(dbWriter); - }) - .catch(reason => { - console.log(reason); - resolve(); - }); - }); + try { + await db.destroy(); + db = store.getSitemapDataDb(sitemapId); + return new StoreScrapeResultWriter(db); + } catch (reason) { + console.log(reason); + } } - createSitemap(sitemap) { - let sitemapJson = JSON.parse(JSON.stringify(sitemap)); + async createSitemap(sitemap) { + const sitemapJson = JSON.parse(JSON.stringify(sitemap)); if (!sitemap._id) { console.log('cannot save sitemap without an id', sitemap); } - return new Promise(resolve => { - this.sitemapDb.put( - sitemapJson, - function(sitemap, err, response) { - // @TODO handle err - if (response) { - sitemap._rev = response.rev; - } - // this.initSitemapDataDb(sitemap._id).then(function () { - resolve(sitemap); - // }); - }.bind(this, sitemap) - ); - }); + const response = await this.sitemapDb.put(sitemapJson); + sitemap._rev = response.rev; + return sitemap; } saveSitemap(sitemap) { - // @TODO remove return this.createSitemap(sitemap); } - deleteSitemap(sitemap) { - sitemap = JSON.parse(JSON.stringify(sitemap)); - return new Promise(resolve => { - this.sitemapDb.remove( - sitemap, - function(err, response) { - // @TODO handle err - - // delete sitemap data db - let dbLocation = this.getSitemapDataDbLocation(sitemap._id); - // PouchDB.destroy(dbLocation, function () { - resolve(); - // }.bind(this)); - }.bind(this) - ); - }); + async deleteSitemap(sitemap) { + const sitemapJson = JSON.parse(JSON.stringify(sitemap)); + await this.sitemapDb.remove(sitemapJson); + const db = this.getSitemapDataDb(sitemap._id); + await db.destroy(); } - getAllSitemaps() { - return new Promise(resolve => { - this.sitemapDb.allDocs({ include_docs: true }, function(err, response) { - let sitemaps = []; - for (let i in response.rows) { - let sitemap = response.rows[i].doc; - if (!browser.extension) { - sitemap = new Sitemap(sitemap); - } - - sitemaps.push(sitemap); - } - resolve(sitemaps); - }); + async getAllSitemaps() { + const result = await this.sitemapDb.allDocs({ include_docs: true }); + return Array.from(result.rows, row => { + const sitemapObj = row.doc; + if (browser.extension) { + return sitemapObj; + } + const sitemap = Sitemap.sitemapFromObj(sitemapObj); + if (sitemapObj._rev) { + sitemap._rev = sitemapObj._rev; + } + return sitemap; }); } - getSitemapData(sitemap) { - return new Promise(resolve => { - let db = this.getSitemapDataDb(sitemap._id); - db.allDocs( - { include_docs: true }, - function(err, response) { - let responseData = []; - for (let i in response.rows) { - let doc = response.rows[i].doc; - responseData.push(doc); - } - normalizeProperties(responseData); - resolve(responseData); - }.bind(this) - ); + async getSitemapData(sitemap) { + const db = this.getSitemapDataDb(sitemap._id); + const response = await db.allDocs({ include_docs: true }); + return Array.from(response.rows, row => { + const { doc } = row; + delete doc._id; + delete doc._rev; + const { data, ...rest } = doc; + // these conditions are included for backwards compatibility + return Object.isObject(data) && Object.isEmpty(rest) ? data : doc; }); } - // @TODO make this call lighter - sitemapExists(sitemapId) { - return new Promise(resolve => { - this.getAllSitemaps().then(function(sitemaps) { - let sitemapFound = false; - for (let i in sitemaps) { - if (sitemaps[i]._id === sitemapId) { - sitemapFound = true; - } - } - resolve(sitemapFound); - }); - }); + async sitemapExists(sitemapId) { + return this.sitemapDb + .get(sitemapId) + .then(() => true) + .catch(() => false); } } diff --git a/src/scripts/StoreRestApi.js b/src/scripts/StoreRestApi.js index 2f502e10..972e0915 100644 --- a/src/scripts/StoreRestApi.js +++ b/src/scripts/StoreRestApi.js @@ -1,109 +1,75 @@ +import axios from 'axios'; import Sitemap from './Sitemap'; import StorePouchDB from './StorePouchDB'; export default class StoreRestApi { constructor(config) { - this.base_uri = config.restUrl; this.localDataStore = new StorePouchDB(config); + this.axiosInstance = axios.create({ + baseURL: config.restUrl, + }); + this.axiosInstance.defaults.headers.post['Content-Type'] = 'application/json'; + this.axiosInstance.defaults.headers.put['Content-Type'] = 'application/json'; } createSitemap(sitemap) { - return this.saveSitemap(sitemap); + return this.axiosInstance + .post('/sitemaps/', Sitemap.sitemapFromObj(sitemap).exportSitemap()) + .then(() => { + return sitemap; + }) + .catch(() => { + alert('StoreApi: Error creating sitemap.'); + }); } - saveSitemap(sitemap) { - let base_uri = this.base_uri; - return new Promise(resolve => { - this.sitemapExists(sitemap._id).then(function(exists) { - if (exists) { - //update sitemap - $.ajax({ - type: 'PUT', - url: new URL('/sitemaps/' + sitemap._id, base_uri).href, - data: new Sitemap(sitemap).exportSitemap(), - success: function() { - resolve(sitemap); - }, - error: function(jqXHR, textStatus, errorThrown) { - alert('StoreApi: Error updating sitemap.'); - }, - contentType: 'application/json', - }); - } else { - //create new sitemap - $.ajax({ - type: 'POST', - url: new URL('/sitemaps/', base_uri).href, - data: new Sitemap(sitemap).exportSitemap(), - success: function() { - resolve(sitemap); - }, - error: function(jqXHR, textStatus, errorThrown) { - alert('StoreApi: Error creating sitemap.'); - }, - contentType: 'application/json', - }); - } - }); - }); + async saveSitemap(sitemap) { + const sitemapExists = await this.sitemapExists(sitemap._id); + if (sitemapExists) { + return this.axiosInstance + .put(`/sitemaps/${sitemap._id}`, Sitemap.sitemapFromObj(sitemap).exportSitemap()) + .then(() => { + return sitemap; + }) + .catch(response => { + if (response.statusCode() === 304) { + return sitemap; + } + alert('StoreApi: Error updating sitemap.'); + }); + } + return this.createSitemap(sitemap); } deleteSitemap(sitemap) { - return new Promise(resolve => { - $.ajax({ - type: 'DELETE', - url: new URL('/sitemaps/' + sitemap._id, this.base_uri).href, - success: function(response) { - resolve(response); - }, - error: function(jqXHR, textStatus, errorThrown) { - alert('StoreApi: Error deleting sitemap.'); - }, - contentType: 'application/json', + return this.axiosInstance + .delete(`/sitemaps/${sitemap._id}`) + .then(response => { + return response.data; + }) + .catch(() => { + alert('StoreApi: Error deleting sitemap.'); }); - }); } getAllSitemaps() { - return new Promise(resolve => { - $.ajax({ - type: 'GET', - url: new URL('/sitemaps/', this.base_uri).href, - success: function(data) { - let sitemaps = []; - for (let i in data) { - sitemaps.push(new Sitemap(data[i])); - } - resolve(sitemaps); - }, - error: function(jqXHR, textStatus, errorThrown) { - alert('StoreApi: Could not get all sitemaps.'); - }, - contentType: 'application/json', + return this.axiosInstance + .get('/sitemaps/') + .then(response => { + return Array.from(response.data, sitemapObj => { + return Sitemap.sitemapFromObj(sitemapObj); + }); + }) + .catch(() => { + alert('StoreApi: Could not get all sitemaps.'); }); - }); } - sitemapExists(sitemapId) { - return new Promise(resolve => { - $.ajax({ - type: 'GET', - url: new URL('/sitemaps/', this.base_uri).href, - success: function(data) { - let exists = false; - for (let i in data) { - if (data[i]._id === sitemapId) { - exists = true; - } - } - resolve(exists); - }, - error: function(jqXHR, textStatus, errorThrown) { - alert('StoreApi: Could not get all sitemaps.'); - }, - contentType: 'application/json', - }); + async sitemapExists(sitemapId) { + const sitemaps = await this.getAllSitemaps().catch(() => { + alert('StoreApi: Error checking sitemap exists.'); }); + return sitemaps.some(sitemap => sitemap._id === sitemapId); } initSitemapDataDb(sitemapId) { diff --git a/src/scripts/Translator.js b/src/scripts/Translator.js new file mode 100644 index 00000000..9675275c --- /dev/null +++ b/src/scripts/Translator.js @@ -0,0 +1,27 @@ +import * as browser from 'webextension-polyfill'; + +export default class Translator { + static translatePage() { + ['title', 'data-i18n', 'placeholder'].forEach(attribute => this.translateAttribute(attribute)); + } + + static translateAttribute(attribute = 'data-i18n') { + let selector = '[' + attribute + ']'; + $(selector).each((_, elem) => { + let messageKey = $(elem).attr(attribute); + try { + if (selector === '[data-i18n]') { + $(elem).html(this.getTranslationByKey(messageKey)); + } else { + $(elem).attr(attribute, this.getTranslationByKey(messageKey)); + } + } catch (e) { + $(elem).attr(attribute, messageKey); + } + }); + } + + static getTranslationByKey(element) { + return browser.i18n.getMessage(element); + } +} diff --git a/tests/spec/ChromePopupBrowserSpec.js b/tests/spec/ChromePopupBrowserSpec.js index 8e8e6325..42143586 100644 --- a/tests/spec/ChromePopupBrowserSpec.js +++ b/tests/spec/ChromePopupBrowserSpec.js @@ -37,7 +37,7 @@ describe("Chrome popup browser", function () { it("should sendMessage to popup contentscript when data extraction is needed", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: 'a', diff --git a/tests/spec/DataExtractSpec.js b/tests/spec/DataExtractSpec.js index 7df79825..0e89c69f 100644 --- a/tests/spec/DataExtractSpec.js +++ b/tests/spec/DataExtractSpec.js @@ -15,7 +15,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -38,7 +38,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -68,7 +68,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -100,7 +100,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); var extractor = new DataExtractor({ @@ -129,7 +129,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); var extractor = new DataExtractor({ @@ -185,7 +185,7 @@ describe("DataExtractor", function () { } ]); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); var extractor = new DataExtractor({ @@ -207,7 +207,7 @@ describe("DataExtractor", function () { parentSelectors: ['_root'] } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -239,7 +239,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -273,7 +273,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -311,7 +311,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -373,7 +373,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -444,7 +444,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -495,7 +495,7 @@ describe("DataExtractor", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -514,7 +514,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -552,7 +552,7 @@ describe("DataExtractor", function () { it("should be able to extract text data from head title", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "title", @@ -591,7 +591,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-element-text"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "e", @@ -639,7 +639,7 @@ describe("DataExtractor", function () { it("should be able to extract multiple text results", function () { var parentElement = $("#dataextract-get-data"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -681,7 +681,7 @@ describe("DataExtractor", function () { it("should be able to extract multiple text results with common data", function () { var parentElement = $("#dataextract-get-data"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -732,7 +732,7 @@ describe("DataExtractor", function () { it("should be able to extract multiple text results within elements", function () { var parentElement = $("#dataextract-get-element-text"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "div", @@ -781,7 +781,7 @@ describe("DataExtractor", function () { it("should be able to extract multiple text records within single element", function () { var parentElement = $("#dataextract-get-element-text"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "div", @@ -829,7 +829,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data-multiple-selectors"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "div", @@ -899,7 +899,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data-multiple-selectors"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "span", @@ -939,7 +939,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data-multiple-selectors"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "span", @@ -972,7 +972,7 @@ describe("DataExtractor", function () { }); it("should return one selector tree for this sitemap", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ "selectors": [ { "parentSelectors": [ @@ -1093,7 +1093,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -1131,7 +1131,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-get-data"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -1169,7 +1169,7 @@ describe("DataExtractor", function () { var parentElement = $("#dataextract-multiple-elements"); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "parent1", diff --git a/tests/spec/ScraperSpec.js b/tests/spec/ScraperSpec.js index 2f52cf86..050ee995 100644 --- a/tests/spec/ScraperSpec.js +++ b/tests/spec/ScraperSpec.js @@ -15,7 +15,7 @@ describe("Scraper", function () { it("should be able to scrape one page", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ id: 'test', startUrls: 'http://test.lv/', selectors: [ @@ -60,7 +60,7 @@ describe("Scraper", function () { it("should be able to scrape a child page", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ id: 'test', startUrls: 'http://test.lv/', selectors: [ @@ -114,7 +114,7 @@ describe("Scraper", function () { it("should be able to tell whether a data record can have child jobs", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ id: 'test', startUrls: 'http://test.lv/', selectors: [ @@ -164,7 +164,7 @@ describe("Scraper", function () { it("should be able to create multiple start jobs", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: 'http://test.lv/[1-100].html' }); @@ -180,7 +180,7 @@ describe("Scraper", function () { it("should create multiple start jobs if multiple urls provided", function(){ - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: ['http://example.com/1', 'http://example.com/2', 'http://example.com/3'] }); @@ -232,7 +232,7 @@ describe("Scraper", function () { "test-src": "http://images/image.png" }; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ id: 'test' }); @@ -263,7 +263,7 @@ describe("Scraper", function () { $el.append('
'); - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ id: 'test', startUrls: 'http://test.com/', selectors: [ diff --git a/tests/spec/SitemapSpec.js b/tests/spec/SitemapSpec.js index f2aba17d..f43f3464 100644 --- a/tests/spec/SitemapSpec.js +++ b/tests/spec/SitemapSpec.js @@ -23,7 +23,7 @@ describe("Sitemap", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -59,7 +59,7 @@ describe("Sitemap", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -97,7 +97,7 @@ describe("Sitemap", function () { } ]; - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: selectors }); @@ -124,7 +124,7 @@ describe("Sitemap", function () { it("should be able to change selector type", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -151,7 +151,7 @@ describe("Sitemap", function () { it("should be able to export as JSON", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ _id: 'id', _rev: 'rev', selectors: [ @@ -172,7 +172,7 @@ describe("Sitemap", function () { it("should be able to import from JSON", function () { - var expectedSitemap = new Sitemap({ + var expectedSitemap = Sitemap.sitemapFromObj({ _id: 'id', selectors: [ { @@ -186,14 +186,14 @@ describe("Sitemap", function () { }); var sitemapJSON = '{"_id":"id","selectors":[{"id":"a","type":"SelectorElement","parentSelectors":["a"]}]}'; - var sitemap = new Sitemap(); + var sitemap = Sitemap.sitemapFromObj(); sitemap.importSitemap(sitemapJSON); expect(sitemap).toEqual(expectedSitemap); }); it("should be able to export data as CSV", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -218,7 +218,7 @@ describe("Sitemap", function () { it("should know what data columns is it going to return", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -239,7 +239,7 @@ describe("Sitemap", function () { }); it("should be able to delete a selector", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -262,7 +262,7 @@ describe("Sitemap", function () { }); it("should be able to delete a selector with child selectors", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -284,7 +284,7 @@ describe("Sitemap", function () { }); it("should not delete selectors if they have multiple parent selectors when deleting one of their parent", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", @@ -318,7 +318,7 @@ describe("Sitemap", function () { }); it("Should return one start url", function(){ - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls:"http://example.com/" }); var expectedURLS = ["http://example.com/"]; @@ -326,7 +326,7 @@ describe("Sitemap", function () { }); it("Should return multiple start urls", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: "http://example.com/[1-3].html" }); var expectedURLS = [ @@ -338,7 +338,7 @@ describe("Sitemap", function () { }); it("Should return multiple start urls with id at the end", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: "http://example.com/?id=[1-3]" }); var expectedURLS = [ @@ -350,7 +350,7 @@ describe("Sitemap", function () { }); it("should return multiple start urls with specified incremental", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: "http://example.com/?id=[0-20:10]" }); var expectedURLS = [ @@ -362,7 +362,7 @@ describe("Sitemap", function () { }); it("Should return multiple start urls with padding", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: "http://example.com/[001-003].html" }); var expectedURLS = [ @@ -375,7 +375,7 @@ describe("Sitemap", function () { it("Should return multiple start urls when startUrl is an array", function(){ - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ startUrls: ["http://example.com/1.html", "http://example.com/2.html", "http://example.com/3.html"] }); var expectedURLS = [ @@ -387,7 +387,7 @@ describe("Sitemap", function () { }); it("Should return only selectors which can have child selectors", function () { - var sitemap = new Sitemap({ + var sitemap = Sitemap.sitemapFromObj({ selectors: [ { id: "a", diff --git a/webpack.config.js b/webpack.config.js index fde72601..7ea74bb9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,6 +20,7 @@ const config = { 'devtools/devtools': './devtools/devtools.js', 'devtools/app': './scripts/App.js', 'options/options': './options/options.js', + 'popup/popup': './popup/popup.js', 'content_script/content_script': './content_script/content_script.js', }, output: { @@ -82,11 +83,21 @@ const config = { }), new CopyWebpackPlugin([ { from: 'icons', to: 'icons', ignore: ['icon.xcf'] }, - { from: 'devtools/views', to: 'devtools/views/', transform: transformHtml }, + { from: '_locales', to: '_locales' }, { from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml }, { from: 'options/options.html', to: 'options/options.html', transform: transformHtml }, { from: 'devtools/panel.html', to: 'devtools/panel.html', transform: transformHtml }, - { from: 'devtools/devtools.html', to: 'devtools/devtools.html', transform: transformHtml }, + { from: 'devtools/views', to: 'devtools/views/', transform: transformHtml }, + { + from: 'content_script/AttachedToolbar.html', + to: 'content_script/AttachedToolbar.html', + transform: transformHtml, + }, + { + from: 'devtools/devtools.html', + to: 'devtools/devtools.html', + transform: transformHtml, + }, { from: 'manifest.json', to: 'manifest.json', @@ -95,7 +106,8 @@ const config = { jsonContent.version = version; if (config.mode === 'development') { - jsonContent.content_security_policy = "script-src 'self' 'unsafe-eval'; object-src 'self'"; + jsonContent.content_security_policy = + "script-src 'self' 'unsafe-eval'; object-src 'self'"; } return JSON.stringify(jsonContent, null, 2); diff --git a/yarn.lock b/yarn.lock index 47c7396f..b3c4a4a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,42 +9,43 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/compat-data@^7.8.4": - version "7.8.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.8.5.tgz#d28ce872778c23551cbb9432fc68d28495b613b9" - integrity sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg== +"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" + integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== dependencies: - browserslist "^4.8.5" + browserslist "^4.9.1" invariant "^2.2.4" semver "^5.5.0" "@babel/core@^7.1.2": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" - integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" - "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.4" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" - json5 "^2.1.0" + json5 "^2.1.2" lodash "^4.17.13" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" - integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA== +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== dependencies: - "@babel/types" "^7.8.3" + "@babel/types" "^7.9.5" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -64,33 +65,25 @@ "@babel/helper-explode-assignable-expression" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-call-delegate@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz#de82619898aa605d409c42be6ffb8d7204579692" - integrity sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A== - dependencies: - "@babel/helper-hoist-variables" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-compilation-targets@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz#03d7ecd454b7ebe19a254f76617e61770aed2c88" - integrity sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg== +"@babel/helper-compilation-targets@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" + integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== dependencies: - "@babel/compat-data" "^7.8.4" - browserslist "^4.8.5" + "@babel/compat-data" "^7.8.6" + browserslist "^4.9.1" invariant "^2.2.4" levenary "^1.1.1" semver "^5.5.0" -"@babel/helper-create-regexp-features-plugin@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz#c774268c95ec07ee92476a3862b75cc2839beb79" - integrity sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q== +"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" + integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-regex" "^7.8.3" - regexpu-core "^4.6.0" + regexpu-core "^4.7.0" "@babel/helper-define-map@^7.8.3": version "7.8.3" @@ -109,14 +102,14 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== +"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== dependencies: "@babel/helper-get-function-arity" "^7.8.3" "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/types" "^7.9.5" "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" @@ -146,16 +139,17 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-module-transforms@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz#d305e35d02bee720fbc2c3c3623aa0c316c01590" - integrity sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q== +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== dependencies: "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" "@babel/helper-simple-access" "^7.8.3" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" lodash "^4.17.13" "@babel/helper-optimise-call-expression@^7.8.3": @@ -165,7 +159,7 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== @@ -188,15 +182,15 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-replace-supers@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz#91192d25f6abbcd41da8a989d4492574fb1530bc" - integrity sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA== +"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== dependencies: "@babel/helper-member-expression-to-functions" "^7.8.3" "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" "@babel/helper-simple-access@^7.8.3": version "7.8.3" @@ -213,6 +207,11 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + "@babel/helper-wrap-function@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" @@ -223,28 +222,28 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helpers@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" "@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== dependencies: + "@babel/helper-validator-identifier" "^7.9.0" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" - integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== +"@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== "@babel/plugin-proposal-async-generator-functions@^7.8.3": version "7.8.3" @@ -279,13 +278,22 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-object-rest-spread@^7.8.3": +"@babel/plugin-proposal-numeric-separator@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" + integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz#3fd65911306d8746014ec0d0cf78f0e39a149116" + integrity sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg== dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.9.5" "@babel/plugin-proposal-optional-catch-binding@^7.8.3": version "7.8.3" @@ -295,20 +303,20 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543" - integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg== +"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" + integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-unicode-property-regex@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz#b646c3adea5f98800c9ab45105ac34d06cd4a47f" - integrity sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ== +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" + integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-create-regexp-features-plugin" "^7.8.8" "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-async-generators@^7.8.0": @@ -339,6 +347,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" @@ -398,17 +413,17 @@ "@babel/helper-plugin-utils" "^7.8.3" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz#46fd7a9d2bb9ea89ce88720477979fe0d71b21b8" - integrity sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w== +"@babel/plugin-transform-classes@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c" + integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg== dependencies: "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-define-map" "^7.8.3" - "@babel/helper-function-name" "^7.8.3" + "@babel/helper-function-name" "^7.9.5" "@babel/helper-optimise-call-expression" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" "@babel/helper-split-export-declaration" "^7.8.3" globals "^11.1.0" @@ -419,14 +434,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-destructuring@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz#20ddfbd9e4676906b1056ee60af88590cc7aaa0b" - integrity sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ== +"@babel/plugin-transform-destructuring@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz#72c97cf5f38604aea3abf3b935b0e17b1db76a50" + integrity sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-dotall-regex@^7.8.3": +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== @@ -449,10 +464,10 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-for-of@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz#6fe8eae5d6875086ee185dd0b098a8513783b47d" - integrity sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A== +"@babel/plugin-transform-for-of@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== dependencies: "@babel/helper-plugin-utils" "^7.8.3" @@ -478,41 +493,41 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-modules-amd@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz#65606d44616b50225e76f5578f33c568a0b876a5" - integrity sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ== +"@babel/plugin-transform-modules-amd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-commonjs@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz#df251706ec331bd058a34bdd72613915f82928a5" - integrity sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg== +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-simple-access" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-systemjs@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz#d8bbf222c1dbe3661f440f2f00c16e9bb7d0d420" - integrity sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg== +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== dependencies: "@babel/helper-hoist-variables" "^7.8.3" - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-umd@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz#592d578ce06c52f5b98b02f913d653ffe972661a" - integrity sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw== +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": @@ -537,12 +552,11 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-replace-supers" "^7.8.3" -"@babel/plugin-transform-parameters@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz#1d5155de0b65db0ccf9971165745d3bb990d77d3" - integrity sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA== +"@babel/plugin-transform-parameters@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz#173b265746f5e15b2afe527eeda65b73623a0795" + integrity sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA== dependencies: - "@babel/helper-call-delegate" "^7.8.3" "@babel/helper-get-function-arity" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" @@ -553,12 +567,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-regenerator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz#b31031e8059c07495bf23614c97f3d9698bc6ec8" - integrity sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA== +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" + integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== dependencies: - regenerator-transform "^0.14.0" + regenerator-transform "^0.14.2" "@babel/plugin-transform-reserved-words@^7.8.3": version "7.8.3" @@ -567,6 +581,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-transform-runtime@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169" + integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" @@ -613,26 +637,28 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/preset-env@^7.1.0": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.8.4.tgz#9dac6df5f423015d3d49b6e9e5fa3413e4a72c4e" - integrity sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w== + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.5.tgz#8ddc76039bc45b774b19e2fc548f6807d8a8919f" + integrity sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ== dependencies: - "@babel/compat-data" "^7.8.4" - "@babel/helper-compilation-targets" "^7.8.4" + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" "@babel/helper-module-imports" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-proposal-async-generator-functions" "^7.8.3" "@babel/plugin-proposal-dynamic-import" "^7.8.3" "@babel/plugin-proposal-json-strings" "^7.8.3" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-proposal-object-rest-spread" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.5" "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" - "@babel/plugin-proposal-optional-chaining" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" "@babel/plugin-syntax-async-generators" "^7.8.0" "@babel/plugin-syntax-dynamic-import" "^7.8.0" "@babel/plugin-syntax-json-strings" "^7.8.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" @@ -641,26 +667,26 @@ "@babel/plugin-transform-async-to-generator" "^7.8.3" "@babel/plugin-transform-block-scoped-functions" "^7.8.3" "@babel/plugin-transform-block-scoping" "^7.8.3" - "@babel/plugin-transform-classes" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.5" "@babel/plugin-transform-computed-properties" "^7.8.3" - "@babel/plugin-transform-destructuring" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.9.5" "@babel/plugin-transform-dotall-regex" "^7.8.3" "@babel/plugin-transform-duplicate-keys" "^7.8.3" "@babel/plugin-transform-exponentiation-operator" "^7.8.3" - "@babel/plugin-transform-for-of" "^7.8.4" + "@babel/plugin-transform-for-of" "^7.9.0" "@babel/plugin-transform-function-name" "^7.8.3" "@babel/plugin-transform-literals" "^7.8.3" "@babel/plugin-transform-member-expression-literals" "^7.8.3" - "@babel/plugin-transform-modules-amd" "^7.8.3" - "@babel/plugin-transform-modules-commonjs" "^7.8.3" - "@babel/plugin-transform-modules-systemjs" "^7.8.3" - "@babel/plugin-transform-modules-umd" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" "@babel/plugin-transform-new-target" "^7.8.3" "@babel/plugin-transform-object-super" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.8.4" + "@babel/plugin-transform-parameters" "^7.9.5" "@babel/plugin-transform-property-literals" "^7.8.3" - "@babel/plugin-transform-regenerator" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" "@babel/plugin-transform-reserved-words" "^7.8.3" "@babel/plugin-transform-shorthand-properties" "^7.8.3" "@babel/plugin-transform-spread" "^7.8.3" @@ -668,51 +694,70 @@ "@babel/plugin-transform-template-literals" "^7.8.3" "@babel/plugin-transform-typeof-symbol" "^7.8.4" "@babel/plugin-transform-unicode-regex" "^7.8.3" - "@babel/types" "^7.8.3" - browserslist "^4.8.5" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.5" + browserslist "^4.9.1" core-js-compat "^3.6.2" invariant "^2.2.2" levenary "^1.1.1" semver "^5.5.0" +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + "@babel/runtime-corejs3@^7.4.0": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.8.4.tgz#ccc4e042e2fae419c67fa709567e5d2179ed3940" - integrity sha512-+wpLqy5+fbQhvbllvlJEVRIpYj+COUWnnsm+I4jZlA8Lo7/MJmBhGTCHyk1/RWfOqBRJ2MbadddG6QltTKTlrg== + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz#26fe4aa77e9f1ecef9b776559bbb8e84d34284b7" + integrity sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA== dependencies: core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" + integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== + dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" - integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ== +"@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c" - integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg== +"@babel/traverse@^7.7.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" - "@babel/helper-function-name" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" - integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== +"@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== dependencies: - esutils "^2.0.2" + "@babel/helper-validator-identifier" "^7.9.5" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -722,9 +767,9 @@ integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== "@types/node@*": - version "12.12.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.8.tgz#dab418655af39ce2fa99286a0bed21ef8072ac9d" - integrity sha512-XLla8N+iyfjvsa0KKV+BP/iGSoTmwxsu5Ci5sM33z9TjohF72DEz95iNvD6pPmemvbQgxAv/909G73gUn8QR7w== + version "13.11.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" + integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -742,25 +787,25 @@ integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== "@types/uglify-js@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" - integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.5.tgz#2c70d5c68f6e002e3b2e4f849adc5f162546f633" + integrity sha512-L7EbSkhSaWBpkl+PZAEAqZTqtTeIsq7s/oX/q0LNnxxJoRVKQE0T81XDVyaxjiiKQwiV2vhVeYRqxdRNqGOGJw== dependencies: source-map "^0.6.1" "@types/webpack-sources@*", "@types/webpack-sources@^0.1.5": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.6.tgz#3d21dfc2ec0ad0c77758e79362426a9ba7d7cbcb" - integrity sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ== + version "0.1.7" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" + integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== dependencies: "@types/node" "*" "@types/source-list-map" "*" source-map "^0.6.1" "@types/webpack@^4.39.8": - version "4.41.6" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.6.tgz#c76afbdef59159d12e3e1332dc264b75574722a2" - integrity sha512-iWRpV5Ej+8uKrgxp6jXz3v7ZTjgtuMXY+rsxQjFNU0hYCnHkpA7vtiNffgxjuxX4feFHBbz0IF76OzX2OqDYPw== + version "4.41.10" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.10.tgz#2e1f6b3508a249854efe3dcc7690905ac5ee10be" + integrity sha512-vIy0qaq8AjOjZLuFPqpo7nAJzcoVXMdw3mvpNN07Uvdy0p1IpJeLNBe3obdRP7FX2jIusDE7z1pZa0A6qYUgnA== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -769,150 +814,149 @@ "@types/webpack-sources" "*" source-map "^0.6.0" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -930,16 +974,25 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -abstract-leveldown@^6.2.1, abstract-leveldown@~6.2.1: - version "6.2.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.2.tgz#677425beeb28204367c7639e264e93ea4b49971a" - integrity sha512-/a+Iwj0rn//CX0EJOasNyZJd2o8xur8Ce9C57Sznti/Ilt/cb6Qd8/k98A4ZOklXgTG+iAYYUs1OTG0s1eH+zQ== +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abstract-leveldown@^6.2.1, abstract-leveldown@~6.2.1, abstract-leveldown@~6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" + integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ== dependencies: + buffer "^5.5.0" + immediate "^3.2.3" level-concat-iterator "~2.0.0" level-supports "~1.0.0" xtend "~4.0.0" -abstract-leveldown@~6.0.0, abstract-leveldown@~6.0.1: +abstract-leveldown@~6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.0.3.tgz#b4b6159343c74b0c5197b2817854782d8f748c4a" integrity sha512-jzewKKpZbaYUa6HTThnrl+GrJhzjEAeuc7hTVpZdzg7kupXZFoqQDFwyOwLNbmJKJlmzw8yiipMPkDiuKkT06Q== @@ -948,44 +1001,29 @@ abstract-leveldown@~6.0.0, abstract-leveldown@~6.0.1: xtend "~4.0.0" acorn-jsx@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" - integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== acorn@^6.0.7, acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" - integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= - -ajv-keywords@^3.4.1: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0: - version "6.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" - integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: - version "6.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" - integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA== +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5, ajv@^6.9.1: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -1182,10 +1220,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: + object-assign "^4.1.1" util "0.10.3" assign-symbols@^1.0.0: @@ -1198,10 +1237,10 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async-foreach@^0.1.3: version "0.1.3" @@ -1220,7 +1259,7 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -1235,27 +1274,35 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + babel-eslint@^10.0.1: - version "10.0.3" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" - integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" eslint-visitor-keys "^1.0.0" resolve "^1.12.0" babel-loader@^8.0.2: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" pify "^4.0.1" + schema-utils "^2.6.5" babel-plugin-dynamic-import-node@^2.3.0: version "2.3.0" @@ -1270,9 +1317,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -1300,16 +1347,25 @@ big.js@^5.2.2: integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^1.0.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== -bl@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88" - integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A== +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: - readable-stream "^3.0.1" + file-uri-to-path "1.0.0" + +bl@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" + integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" block-stream@*: version "0.0.9" @@ -1341,7 +1397,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.0, braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -1421,14 +1477,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.8.3, browserslist@^4.8.5: - version "4.8.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.7.tgz#ec8301ff415e6a42c949d0e66b405eb539c532d0" - integrity sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA== +browserslist@^4.8.3, browserslist@^4.9.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" + integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== dependencies: - caniuse-lite "^1.0.30001027" - electron-to-chromium "^1.3.349" - node-releases "^1.1.49" + caniuse-lite "^1.0.30001038" + electron-to-chromium "^1.3.390" + node-releases "^1.1.53" + pkg-up "^2.0.0" buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: version "0.2.13" @@ -1451,18 +1508,18 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.1.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" - integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== +buffer@^5.1.0, buffer@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1492,9 +1549,9 @@ cacache@^10.0.4: y18n "^4.0.0" cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" chownr "^1.1.1" @@ -1574,10 +1631,10 @@ camelcase@^5.0.0, camelcase@^5.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001027: - version "1.0.30001027" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001027.tgz#283e2ef17d94889cc216a22c6f85303d78ca852d" - integrity sha512-7xvKeErvXZFtUItTHgNtLgS9RJpVnwBlWX8jSo/BO8VsF6deszemZSkJJJA1KOKrXuzZH4WALpAJdq5EyfgMLg== +caniuse-lite@^1.0.30001038: + version "1.0.30001039" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz#b3814a1c38ffeb23567f8323500c09526a577bbe" + integrity sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q== caseless@~0.12.0: version "0.12.0" @@ -1609,36 +1666,30 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.2.2" + fsevents "^1.2.7" -chownr@^1.0.1: +chownr@^1.0.1, chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== - chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -1766,9 +1817,9 @@ commondir@^1.0.1: integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== compress-commons@^2.1.1: version "2.1.1" @@ -1801,11 +1852,9 @@ confusing-browser-globals@^1.0.5: integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" @@ -2037,12 +2086,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" -debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2066,20 +2117,15 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deferred-leveldown@~5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.0.1.tgz#1642eb18b535dfb2b6ac4d39fb10a9cbcfd13b09" - integrity sha512-BXohsvTedWOLkj2n/TY+yqVlrCWa2Zs8LSxh3uCAgFOru7/pjxKyZAexGa1j83BaKloER4PqUyQ9rGPJLt9bqA== +deferred-leveldown@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.1.0.tgz#c21e40641a8e48530255a4ad31371cc7fe76b332" + integrity sha512-PvDY+BT2ONu2XVRgxHb77hYelLtMYxKSGuWuJJdVRXh9ntqx9GYTFJno/SKAz5xcd+yjQwyQeIZrUPjPvA52mg== dependencies: abstract-leveldown "~6.0.0" inherits "^2.0.3" @@ -2132,9 +2178,9 @@ delegates@^1.0.0: integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -2144,11 +2190,6 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2213,15 +2254,15 @@ ejs@^2.6.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -electron-to-chromium@^1.3.349: - version "1.3.349" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.349.tgz#663f26a69d348a462df47b4d7ab162a2f29bbcb7" - integrity sha512-uEb2zs6EJ6OZIqaMsCSliYVgzE/f7/s1fLWqtvRtHg/v5KBF2xds974fUnyatfxIDgkqzQVwFtam5KExqywx0Q== +electron-to-chromium@^1.3.390: + version "1.3.398" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz#4c01e29091bf39e578ac3f66c1f157d92fa5725d" + integrity sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w== elliptic@^6.0.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" - integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2241,6 +2282,11 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + encoding-down@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" @@ -2306,10 +2352,10 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" @@ -2406,17 +2452,25 @@ eslint-loader@^2.1.2: rimraf "^2.6.1" eslint-module-utils@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" - integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" + integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== dependencies: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-import@^2.16.0: - version "2.20.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" - integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== +eslint-plugin-es@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz#98cb1bc8ab0aa807977855e11ad9d1c9422d014b" + integrity sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-import@^2.20.2: + version "2.20.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" + integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== dependencies: array-includes "^3.0.3" array.prototype.flat "^1.2.1" @@ -2431,13 +2485,43 @@ eslint-plugin-import@^2.16.0: read-pkg-up "^2.0.0" resolve "^1.12.0" -eslint-plugin-prettier@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" - integrity sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA== +eslint-plugin-json@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-2.1.1.tgz#7b9c4da2121f6f48d44efceb9a99ac0d4d12b299" + integrity sha512-Ktsab8ij33V2KFLhh4alC1FYztdmbV32DeMZYYUCZm4kKLW1s4DrleKKgtbAHSJsmshCK5QGOZtfyc2r3jCRsg== + dependencies: + lodash "^4.17.15" + vscode-json-languageservice "^3.5.1" + +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-prettier@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca" + integrity sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ== dependencies: prettier-linter-helpers "^1.0.0" +eslint-plugin-promise@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" + integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== + +eslint-plugin-simple-import-sort@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-5.0.2.tgz#43b5c4ab5affa2dd8481ef40216c71723becd2e2" + integrity sha512-YPEGo7DbMANQ01d2OXlREcaHRszsW8LoUQ9mIjI7gXSdwpnWKfogtzL6FiBfDf1teCBx+AdcjcfDXSKpmhTWeA== + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -2453,6 +2537,13 @@ eslint-utils@^1.3.1: dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd" + integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA== + dependencies: + eslint-visitor-keys "^1.1.0" + eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" @@ -2515,11 +2606,11 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.1.0.tgz#c5c0b66f383e7656404f86b31334d72524eddb48" - integrity sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.0.tgz#a010a519c0288f2530b3404124bfb5f02e9797fe" + integrity sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q== dependencies: - estraverse "^4.0.0" + estraverse "^5.0.0" esrecurse@^4.1.0: version "4.2.1" @@ -2528,21 +2619,26 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.0.0: +estraverse@^4.1.0, estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estraverse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" + integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + events@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" @@ -2655,11 +2751,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - fast-deep-equal@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" @@ -2670,33 +2761,28 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== -fast-future@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" - integrity sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo= - fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fetch-cookie@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.7.0.tgz#a6fc137ad8363aa89125864c6451b86ecb7de802" - integrity sha512-Mm5pGlT3agW6t71xVM7vMZPIvI7T4FaTuFW4jari6dVzYHFDb3WZZsGpN22r/o3XMdkM0E7sPd1EGeyVbH2Tgg== +fetch-cookie@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.7.3.tgz#b8d023f421dd2b2f4a0eca9cd7318a967ed4eed8" + integrity sha512-rZPkLnI8x5V+zYAiz8QonAHsTb4BY+iFowFBI1RFn0zrO343AVp9X7/yUj/9wL6Ef/8fLls8b/vGtzUvmyAUGA== dependencies: es6-denodeify "^0.1.1" - tough-cookie "^2.3.1" + tough-cookie "^2.3.3" figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== figures@^2.0.0: version "2.0.0" @@ -2720,6 +2806,11 @@ file-loader@^1.1.11: loader-utils "^1.0.2" schema-utils "^0.4.5" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2748,7 +2839,7 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: +find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -2812,9 +2903,9 @@ flat-cache@^2.0.1: write "1.0.3" flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== flush-write-stream@^1.0.0: version "1.1.1" @@ -2824,6 +2915,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2863,13 +2961,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -2885,13 +2976,13 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" + bindings "^1.5.0" + nan "^2.12.1" fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" @@ -2996,7 +3087,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.4, glob@~7.1.1: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3008,18 +3099,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.4, glob@~7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-modules@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -3082,12 +3161,7 @@ globule@^1.0.0: lodash "~4.17.12" minimatch "~3.0.2" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - -graceful-fs@^4.1.15, graceful-fs@^4.2.0: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -3198,9 +3272,9 @@ homedir-polyfill@^1.0.1: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.8.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== http-signature@~1.2.0: version "1.2.0" @@ -3237,7 +3311,7 @@ icanhaz@0.10.3: resolved "https://registry.yarnpkg.com/icanhaz/-/icanhaz-0.10.3.tgz#b080e2cfb3035f7e289220ba05245f2883e4f4ba" integrity sha1-sIDiz7MDX34okiC6BSRfKIPk9Lo= -iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -3257,22 +3331,15 @@ icss-utils@^4.1.0: postcss "^7.0.14" ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - ignore@^3.3.5, ignore@^3.3.7: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -3283,12 +3350,17 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + immediate@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= -immediate@~3.2.3: +immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= @@ -3331,9 +3403,9 @@ imurmurhash@^0.1.4: integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + version "2.0.1" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== indent-string@^2.1.0: version "2.1.0" @@ -3360,22 +3432,22 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= -inherits@^2.0.4, inherits@~2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -3479,9 +3551,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-descriptor@^0.1.0: version "0.1.6" @@ -3524,11 +3596,9 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= - dependencies: - number-is-nan "^1.0.0" + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fullwidth-code-point@^1.0.0: version "1.0.0" @@ -3550,9 +3620,9 @@ is-glob@^3.1.0: is-extglob "^2.1.0" is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" @@ -3563,7 +3633,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -3599,7 +3669,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -3658,7 +3728,14 @@ jquery-flexdatalist@^2.2.4: dependencies: jquery ">=1.8" -jquery@>=1.8, jquery@^3.4.1: +jquery-searcher@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/jquery-searcher/-/jquery-searcher-0.3.0.tgz#1317f686ac80f271569fc9a0d9cc0e835b86faac" + integrity sha1-Exf2hqyA8nFWn8mg2cwOg1uG+qw= + dependencies: + jquery ">=1.4.3" + +jquery@>=1.4.3, jquery@>=1.8, jquery@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== @@ -3728,12 +3805,17 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: - minimist "^1.2.0" + minimist "^1.2.5" + +jsonc-parser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" + integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== jsprim@^1.2.2: version "1.4.1" @@ -3765,9 +3847,9 @@ kind-of@^5.0.0: integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== lazystream@^1.0.0: version "1.0.0" @@ -3816,21 +3898,20 @@ level-iterator-stream@~4.0.0: readable-stream "^3.4.0" xtend "^4.0.2" -level-js@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-js/-/level-js-4.0.1.tgz#3bad57d8bb46ebba7b13bc7442b56f4b45c8a2e0" - integrity sha512-m5JRIyHZn5VnCCFeRegJkn5bQd3MJK5qZX12zg3Oivc8+BUIS2yFS6ANMMeHX2ieGxucNvEn6/ZnyjmZQLLUWw== +level-js@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/level-js/-/level-js-5.0.2.tgz#5e280b8f93abd9ef3a305b13faf0b5397c969b55" + integrity sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg== dependencies: - abstract-leveldown "~6.0.1" - immediate "~3.2.3" + abstract-leveldown "~6.2.3" + buffer "^5.5.0" inherits "^2.0.3" ltgt "^2.1.2" - typedarray-to-buffer "~3.1.5" -level-packager@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.0.tgz#9c01c6c8e2380d3196d61e56bd79c2eff4a9d5c3" - integrity sha512-3pbJmDgGvp/lUQNULPoYQZtUbhMI8KoViYDw7Sa0kWl1mPeHWWJF7T/9upWI/NTMuEikkEE/cd6wBvmrW1+ZnQ== +level-packager@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" + integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== dependencies: encoding-down "^6.3.0" levelup "^4.3.2" @@ -3849,27 +3930,17 @@ level-write-stream@1.0.0: dependencies: end-stream "~0.1.0" -level@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/level/-/level-5.0.1.tgz#8528cc1ee37ac413270129a1eab938c610be3ccb" - integrity sha512-wcak5OQeA4rURGacqS62R/xNHjCYnJSQDBOlm4KNUGJVE9bWv2B04TclqReYejN+oD65PzD4FsqeWoI5wNC5Lg== +level@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-6.0.0.tgz#d216fb9b9c3940bcec15c5880d8da775ca086c5c" + integrity sha512-3oAi7gXLLNr7pHj8c4vbI6lHkXf35m8qb7zWMrNTrOax6CXBVggQAwL1xnC/1CszyYrW3BsLXsY5TMgTxtKfFA== dependencies: - level-js "^4.0.0" - level-packager "^5.0.0" - leveldown "^5.0.0" + level-js "^5.0.0" + level-packager "^5.1.0" + leveldown "^5.4.0" opencollective-postinstall "^2.0.0" -leveldown@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.0.2.tgz#c8edc2308c8abf893ffc81e66ab6536111cae92c" - integrity sha512-Ib6ygFYBleS8x2gh3C1AkVsdrUShqXpe6jSTnZ6sRycEXKhqVf+xOSkhgSnjidpPzyv0d95LJVFrYQ4NuXAqHA== - dependencies: - abstract-leveldown "~6.0.0" - fast-future "~1.0.2" - napi-macros "~1.8.1" - node-gyp-build "~3.8.0" - -leveldown@^5.0.0: +leveldown@5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.4.1.tgz#83a8fdd9bb52b1ed69be2ef59822b6cdfcdb51ec" integrity sha512-3lMPc7eU3yj5g+qF1qlALInzIYnkySIosR1AsUKFjL9D8fYbTLuENBAeDRZXIG4qeWOAyqRItOoLu2v2avWiMA== @@ -3878,12 +3949,21 @@ leveldown@^5.0.0: napi-macros "~2.0.0" node-gyp-build "~4.1.0" -levelup@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.0.2.tgz#bcb8d28d0a82ee97f1c6d00f20ea6d32c2803c5b" - integrity sha512-cx9PmLENwbGA3svWBEbeO2HazpOSOYSXH4VA+ahVpYyurvD+SDSfURl29VBY2qgyk+Vfy2dJd71SBRckj/EZVA== +leveldown@^5.4.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.6.0.tgz#16ba937bb2991c6094e13ac5a6898ee66d3eee98" + integrity sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ== dependencies: - deferred-leveldown "~5.0.0" + abstract-leveldown "~6.2.1" + napi-macros "~2.0.0" + node-gyp-build "~4.1.0" + +levelup@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.1.0.tgz#49ab5d3a341731cd102f91c6bc17a1acb1969a17" + integrity sha512-+Qhe2/jb5affN7BeFgWUUWVdYoGXO2nFS3QLEZKZynnQyP9xqA+7wgOz3fD8SST2UKpHQuZgjyJjTcB2nMl2dQ== + dependencies: + deferred-leveldown "~5.1.0" level-errors "~2.0.0" level-iterator-stream "~4.0.0" xtend "~4.0.0" @@ -3946,19 +4026,19 @@ load-json-file@^2.0.0: strip-bom "^3.0.0" loader-fs-cache@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" - integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== dependencies: find-cache-dir "^0.1.1" - mkdirp "0.5.1" + mkdirp "^0.5.1" loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@1.2.3, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: +loader-utils@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== @@ -3967,6 +4047,15 @@ loader-utils@1.2.3, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1. emojis-list "^2.0.0" json5 "^1.0.1" +loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3990,11 +4079,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -4075,11 +4159,6 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -4234,30 +4313,10 @@ minimatch@^3.0.4, minimatch@~3.0.2: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" +minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== mississippi@^2.0.0: version "2.0.0" @@ -4292,19 +4351,19 @@ mississippi@^3.0.0: through2 "^2.0.0" mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: - minimist "0.0.8" + minimist "^1.2.5" move-concurrently@^1.0.1: version "1.0.1" @@ -4319,9 +4378,9 @@ move-concurrently@^1.0.1: run-queue "^1.0.3" mri@^1.1.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" - integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== + version "1.1.5" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.5.tgz#ce21dba2c69f74a9b7cf8a1ec62307e089e223e0" + integrity sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg== ms@2.0.0: version "2.0.0" @@ -4348,15 +4407,15 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.13.2: +nan@^2.12.1, nan@^2.13.2: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -nan@^2.9.2: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== +nanoid@^2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" + integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== nanomatch@^1.2.9: version "1.2.13" @@ -4375,11 +4434,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -napi-macros@~1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.2.tgz#299265c1d8aa401351ad0675107d751228c03eda" - integrity sha512-Tr0DNY4RzTaBG2W2m3l7ZtFuJChTH6VZhXVhkGGjF/4cZTt+i8GcM9ozD+30Lmr4mDoZ5Xx34t2o4GJqYWDGcg== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" @@ -4390,21 +4444,7 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" - integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== - -neo-async@^2.6.1: +neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== @@ -4419,11 +4459,6 @@ node-fetch@2.4.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.4.1.tgz#b2e38f1117b8acbedbe0524f041fb3177188255d" integrity sha512-P9UbpFK87NyqBZzUuDBDz4f6Yiys8xm8j7ACDbi6usvFm6KItklQUKjeoqTrYS/S1k6I8oaOC2YLLDr/gg26Mw== -node-gyp-build@~3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.8.0.tgz#0f57efeb1971f404dfcbfab975c284de7c70f14a" - integrity sha512-bYbpIHyRqZ7sVWXxGpz8QIRug5JZc/hzZH4GbdT9HTZi6WmKCZ8GLvP8OZ9TTiIBvwPFKgtGrlWQSXDAvYdsPw== - node-gyp-build@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" @@ -4476,28 +4511,10 @@ node-gyp@^3.8.0: util "^0.11.0" vm-browserify "^1.0.1" -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-releases@^1.1.49: - version "1.1.49" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.49.tgz#67ba5a3fac2319262675ef864ed56798bb33b93e" - integrity sha512-xH8t0LS0disN0mtRCh+eByxFPie+msJUBL/lJDBuap53QGiYPa9joh83K4pCZgWJ+2L4b9h88vCVdXQ60NO2bg== - dependencies: - semver "^6.3.0" +node-releases@^1.1.53: + version "1.1.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" + integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== node-sass@^4.9.3: version "4.13.1" @@ -4529,14 +4546,6 @@ node-sass@^4.9.3: dependencies: abbrev "1" -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -4559,19 +4568,6 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== - -npm-packlist@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" - integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4579,7 +4575,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -4599,7 +4595,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -4734,7 +4730,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@0, osenv@^0.1.4: +osenv@0: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -4764,17 +4760,10 @@ p-limit@^1.0.0, p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== - dependencies: - p-try "^2.0.0" - -p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -4810,9 +4799,9 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27" - integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ== + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== papaparse@^4.1.0: version "4.6.3" @@ -4836,15 +4825,16 @@ parent-module@^1.0.0: callsites "^3.0.0" parse-asn1@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" parse-json@^2.2.0: version "2.2.0" @@ -5022,6 +5012,13 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + please-upgrade-node@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -5051,9 +5048,9 @@ postcss-modules-local-by-default@^2.0.6: postcss-value-parser "^3.3.1" postcss-modules-scope@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== dependencies: postcss "^7.0.6" postcss-selector-parser "^6.0.0" @@ -5081,37 +5078,38 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.26" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" - integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA== + version "7.0.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" + integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== dependencies: chalk "^2.4.2" source-map "^0.6.1" supports-color "^6.1.0" pouchdb@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.1.1.tgz#f5f8dcd1fc440fb76651cb26f6fc5d97a39cd6ce" - integrity sha512-8bXWclixNJZqokvxGHRsG19zehSJiaZaz4dVYlhXhhUctz7gMcNTElHjPBzBdZlKKvt9aFDndmXN1VVE53Co8g== + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.2.1.tgz#619e3d5c2463ddd94a4b1bf40d44408c46e9de79" + integrity sha512-AoDPdr6tFqj3xs7oiD2oioYj5MMu87c3UemRHZ/p++BwU+ZsKn5jpnL09OvWTLvMvaICGAOufiaUzmM1/KKoKQ== dependencies: + abort-controller "3.0.0" argsarray "0.0.1" buffer-from "1.1.0" clone-buffer "1.0.0" double-ended-queue "2.1.0-0" - fetch-cookie "0.7.0" + fetch-cookie "0.7.3" immediate "3.0.6" - inherits "2.0.3" - level "5.0.1" + inherits "2.0.4" + level "6.0.0" level-codec "9.0.1" level-write-stream "1.0.0" - leveldown "5.0.2" - levelup "4.0.2" + leveldown "5.4.1" + levelup "4.1.0" ltgt "2.2.1" node-fetch "2.4.1" readable-stream "1.0.33" spark-md5 "3.0.0" through2 "3.0.1" - uuid "3.2.1" + uuid "3.3.3" vuvuzela "1.0.3" prelude-ls@~1.1.2: @@ -5126,10 +5124,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^1.17.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +prettier@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" + integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== pretty-quick@^1.8.0: version "1.11.1" @@ -5143,15 +5141,15 @@ pretty-quick@^1.8.0: mri "^1.1.0" multimatch "^3.0.0" -private@^0.1.6: +private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@^0.11.10: version "0.11.10" @@ -5179,9 +5177,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.28: - version "1.4.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" - integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== public-encrypt@^4.0.0: version "4.0.3" @@ -5251,9 +5249,9 @@ querystring@0.2.0: integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" @@ -5265,16 +5263,6 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -5319,7 +5307,7 @@ read-pkg@^5.1.1: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -5342,29 +5330,7 @@ readable-stream@1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -"readable-stream@2 || 3", readable-stream@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.3, readable-stream@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.1, readable-stream@^3.1.1: +"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -5378,7 +5344,7 @@ readable-stream@~0.0.2: resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-0.0.4.tgz#f32d76e3fb863344a548d79923007173665b3b8d" integrity sha1-8y124/uGM0SlSNeZIwBxc2ZbO40= -readdirp@^2.0.0: +readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== @@ -5395,10 +5361,10 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" @@ -5407,17 +5373,18 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== +regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== dependencies: - private "^0.1.6" + "@babel/runtime" "^7.8.4" + private "^0.1.8" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -5432,27 +5399,32 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" - integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== +regexpp@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + unicode-match-property-value-ecmascript "^1.2.0" -regjsgen@^0.5.0: +regjsgen@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== -regjsparser@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.3.tgz#74192c5805d35e9f5ebe3c1fb5b40d40a8a38460" - integrity sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA== +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== dependencies: jsesc "~0.5.0" @@ -5461,6 +5433,11 @@ remove-trailing-separator@^1.0.1: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= +renderjson@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/renderjson/-/renderjson-1.4.0.tgz#d944644521ac5ef977ee524a6a05b76a2a945144" + integrity sha512-R0IZoxjWQP4XMJjLkPjNKSwjDyl20EiLohyu1Os7AvIvO4F4Vtar1N6IjJLPLjDN7OYOXTsqtIVJupQnQMvYQw== + repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -5556,7 +5533,14 @@ resolve@^1.10.0: dependencies: path-parse "^1.0.6" -resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.4.0: +resolve@^1.10.1: + version "1.16.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.16.0.tgz#063dc704fa3413e13ac1d0d1756a7cbfe95dd1a7" + integrity sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA== + dependencies: + path-parse "^1.0.6" + +resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== @@ -5576,14 +5560,14 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" -rimraf@2.6.3, rimraf@^2.6.1: +rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -5599,9 +5583,9 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: inherits "^2.0.1" run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== dependencies: is-promise "^2.1.0" @@ -5618,13 +5602,18 @@ run-queue@^1.0.0, run-queue@^1.0.3: aproba "^1.1.1" rxjs@^6.4.0: - version "6.5.4" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" - integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -5662,11 +5651,6 @@ sass-loader@^7.1.0: pify "^4.0.1" semver "^6.3.0" -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" @@ -5684,12 +5668,12 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.1: - version "2.6.4" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.4.tgz#a27efbf6e4e78689d91872ee3ccfa57d7bdd0f53" - integrity sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ== +schema-utils@^2.6.1, schema-utils@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== dependencies: - ajv "^6.10.2" + ajv "^6.12.0" ajv-keywords "^3.4.1" scss-tokenizer@^0.2.3: @@ -5720,7 +5704,7 @@ semver@^5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== -semver@^6.3.0: +semver@^6.1.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -5745,20 +5729,10 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5798,9 +5772,9 @@ shebang-regex@^1.0.0: integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== slash@^1.0.0: version "1.0.0" @@ -5857,11 +5831,11 @@ source-list-map@^2.0.0: integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" @@ -5902,6 +5876,11 @@ spark-md5@3.0.0: resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.0.tgz#3722227c54e2faf24b1dc6d933cc144e6f71bfef" integrity sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8= +spark-md5@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.1.tgz#83a0e255734f2ab4e5c466e5a2cfc9ba2aa2124d" + integrity sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig== + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -5985,9 +5964,9 @@ stdout-stream@^1.4.0: readable-stream "^2.0.1" stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" readable-stream "^2.0.2" @@ -6042,28 +6021,46 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string.prototype.trimend@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373" + integrity sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz#afe596a7ce9de905496919406c9734845f01a2f2" + integrity sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - safe-buffer "~5.1.0" + safe-buffer "~5.2.0" string_decoder@~0.10.x: version "0.10.31" @@ -6122,7 +6119,7 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -6172,11 +6169,11 @@ tapable@^1.0.0, tapable@^1.1.3: integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar-stream@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" - integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw== + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== dependencies: - bl "^3.0.0" + bl "^4.0.1" end-of-stream "^1.4.1" fs-constants "^1.0.0" inherits "^2.0.3" @@ -6191,19 +6188,6 @@ tar@^2.0.0: fstream "^1.0.12" inherits "2" -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - terser-webpack-plugin@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" @@ -6220,9 +6204,9 @@ terser-webpack-plugin@^1.4.3: worker-farm "^1.7.0" terser@^4.1.2: - version "4.6.3" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.3.tgz#e33aa42461ced5238d352d2df2a67f21921f8d87" - integrity sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ== + version "4.6.11" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.11.tgz#12ff99fdd62a26de2a82f508515407eb6ccd8a9f" + integrity sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -6254,9 +6238,9 @@ through@^2.3.6: integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== dependencies: setimmediate "^1.0.4" @@ -6302,7 +6286,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@^2.3.1, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -6323,9 +6307,9 @@ trim-newlines@^1.0.0: glob "^7.1.2" tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== tty-browserify@0.0.0: version "0.0.0" @@ -6356,13 +6340,6 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== -typedarray-to-buffer@~3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -6381,25 +6358,25 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" get-value "^2.0.6" is-extendable "^0.1.1" - set-value "^0.4.3" + set-value "^2.0.1" uniq@^1.0.1: version "1.0.1" @@ -6428,10 +6405,10 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -upath@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: version "4.2.2" @@ -6485,16 +6462,16 @@ util@^0.11.0: dependencies: inherits "2.0.3" -uuid@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - integrity sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA== - -uuid@^3.3.2: +uuid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" @@ -6530,17 +6507,48 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vscode-json-languageservice@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.5.2.tgz#4b898140a8e581359c10660845a4cae15dcbb4f9" + integrity sha512-9cUvBq00O08lpWVVOx6tQ1yLxCHss79nsUdEAVYGomRyMbnPBmc0AkYPcXI9WK1EM6HBo0R9Zo3NjFhcICpy4A== + dependencies: + jsonc-parser "^2.2.1" + vscode-languageserver-textdocument "^1.0.1" + vscode-languageserver-types "^3.15.1" + vscode-nls "^4.1.1" + vscode-uri "^2.1.1" + +vscode-languageserver-textdocument@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f" + integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA== + +vscode-languageserver-types@^3.15.1: + version "3.15.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de" + integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ== + +vscode-nls@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167" + integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw== + +vscode-uri@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90" + integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A== + vuvuzela@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b" integrity sha1-O+FF5YJxxzylUnndhR8SpoIRSws= watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + version "1.6.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" + integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== dependencies: - chokidar "^2.0.2" + chokidar "^2.1.8" graceful-fs "^4.1.2" neo-async "^2.5.0" @@ -6600,14 +6608,14 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-map "~0.6.1" webpack@^4.20.2: - version "4.41.6" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.6.tgz#12f2f804bf6542ef166755050d4afbc8f66ba7e1" - integrity sha512-yxXfV0Zv9WMGRD+QexkZzmGIh54bsvEs+9aRWxnN8erLWEOehAKUTeNBoUbA6HPEZPlRo7KDi2ZcNveoZgK9MA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + version "4.42.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.1.tgz#ae707baf091f5ca3ef9c38b884287cfe8f1983ef" + integrity sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" acorn "^6.2.1" ajv "^6.10.2" ajv-keywords "^3.4.1" @@ -6619,7 +6627,7 @@ webpack@^4.20.2: loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" @@ -6701,16 +6709,11 @@ write@1.0.3: mkdirp "^0.5.1" ws@^7.2.0: - version "7.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" - integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== - -xtend@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== -xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -6730,15 +6733,15 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yargs-parser@^13.1.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0"