├── .gitignore ├── .jscsrc ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE.md ├── README.md ├── dist ├── html │ ├── home.html │ ├── options.html │ ├── settings_modal.html │ └── toast_new_version.html ├── icons │ ├── arrow-right.svg │ ├── close.svg │ ├── content-duplicate.svg │ ├── content-save.svg │ ├── credit-card.svg │ ├── delete.svg │ ├── dots-horizontal.svg │ ├── dots-vertical.svg │ ├── eye-off.svg │ ├── github-circle.svg │ ├── google-chrome.svg │ ├── magnify.svg │ ├── pin-off.svg │ ├── pin.svg │ ├── refresh.svg │ ├── reload.svg │ └── settings.svg ├── img │ ├── default.png │ ├── icon_128.png │ ├── icon_16.png │ ├── icon_32.png │ ├── icon_48.png │ ├── icon_64.png │ └── tab_modifier_32.png ├── js │ ├── background.js │ ├── libs │ │ └── angular-google-analytics.min.js │ └── options.js └── manifest.json ├── gulpfile.js ├── package.json ├── screenshots └── home.png ├── src ├── html │ ├── home.html │ ├── options.html │ ├── settings_modal.html │ └── toast_new_version.html └── js │ ├── background.js │ └── options │ ├── app.js │ ├── home.controller.js │ └── main.controller.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules/ 3 | coverage/ 4 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowQuotedKeysInObjects": true, 3 | "requireCapitalizedConstructors": true, 4 | "requireDotNotation": true, 5 | "requireMatchingFunctionName": true, 6 | "requireSemicolons": true, 7 | "requireSpaceBetweenArguments": true, 8 | "requireSpacesInForStatement": true, 9 | "requireCurlyBraces": [ 10 | "if", 11 | "else", 12 | "for", 13 | "while", 14 | "do", 15 | "try", 16 | "catch" 17 | ], 18 | "requireSpaceBeforeKeywords": [ 19 | "else", 20 | "while", 21 | "catch" 22 | ], 23 | "requireSpaceAfterKeywords": [ 24 | "if", 25 | "else", 26 | "for", 27 | "while", 28 | "do", 29 | "switch", 30 | "return", 31 | "try", 32 | "catch" 33 | ], 34 | "requireSpaceBeforeBlockStatements": true, 35 | "requireParenthesesAroundIIFE": true, 36 | "requireSpacesInConditionalExpression": { 37 | "afterTest": true, 38 | "beforeConsequent": true, 39 | "afterConsequent": true, 40 | "beforeAlternate": true 41 | }, 42 | "requireSpacesInFunctionExpression": { 43 | "beforeOpeningRoundBrace": true, 44 | "beforeOpeningCurlyBrace": true 45 | }, 46 | "requireSpacesInAnonymousFunctionExpression": { 47 | "beforeOpeningRoundBrace": true, 48 | "beforeOpeningCurlyBrace": true 49 | }, 50 | "requireSpacesInNamedFunctionExpression": { 51 | "beforeOpeningRoundBrace": true, 52 | "beforeOpeningCurlyBrace": true 53 | }, 54 | "requireSpacesInFunctionDeclaration": { 55 | "beforeOpeningRoundBrace": true, 56 | "beforeOpeningCurlyBrace": true 57 | }, 58 | "requireSpacesInFunction": { 59 | "beforeOpeningRoundBrace": true, 60 | "beforeOpeningCurlyBrace": true 61 | }, 62 | "requireMultipleVarDecl": true, 63 | "requireBlocksOnNewline": true, 64 | "disallowEmptyBlocks": true, 65 | "disallowSpacesInsideArrayBrackets": "all", 66 | "disallowSpacesInsideParentheses": true, 67 | "disallowSpacesInsideParenthesizedExpression": true, 68 | "requireSpacesInsideObjectBrackets": "all", 69 | "disallowSpaceAfterObjectKeys": true, 70 | "requireSpaceBeforeObjectValues": true, 71 | "requireCommaBeforeLineBreak": true, 72 | "requireOperatorBeforeLineBreak": [ 73 | "?", 74 | "=", 75 | "+", 76 | "-", 77 | "/", 78 | "*", 79 | "==", 80 | "===", 81 | "!=", 82 | "!==", 83 | ">", 84 | ">=", 85 | "<", 86 | "<=" 87 | ], 88 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 89 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 90 | "disallowImplicitTypeConversion": ["numeric", "boolean", "binary", "string"], 91 | "disallowKeywords": ["with"], 92 | "disallowMultipleLineStrings": true, 93 | "disallowMultipleLineBreaks": true, 94 | "validateQuoteMarks": "'", 95 | "validateIndentation": 4, 96 | "disallowMixedSpacesAndTabs": true, 97 | "disallowTrailingComma": true, 98 | "disallowKeywordsOnNewLine": ["else"], 99 | "requireLineFeedAtFileEnd": true, 100 | "maximumLineLength": { 101 | "value": 600, 102 | "allowComments": true, 103 | "allowUrlComments": true, 104 | "allowRegex": true 105 | }, 106 | "requireCapitalizedConstructors": true, 107 | "safeContextKeyword": ["that", "self"], 108 | "disallowYodaConditions": true, 109 | "requireSpaceAfterLineComment": false, 110 | "disallowNewlineBeforeBlockStatements": true 111 | } 112 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | 4 | node_js: 5 | - "5" 6 | 7 | script: 8 | - gulp build 9 | 10 | notifications: 11 | email: false 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at sylvain.valienne+github@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Syl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # icon Open Tabs 2 | 3 | Show open tabs. 4 | 5 | [![Build Status](http://img.shields.io/travis/sylouuu/chrome-open-tabs.svg?style=flat)](https://travis-ci.org/sylouuu/chrome-open-tabs) 6 | [![devDependency Status](http://img.shields.io/david/dev/sylouuu/chrome-open-tabs.svg?style=flat)](https://david-dm.org/sylouuu/chrome-open-tabs#info=devDependencies) 7 | 8 | ## Features 9 | 10 | * Go to tab 11 | * Close tab 12 | * Reload tab 13 | * Duplicate tab 14 | * Pin/unpin tab 15 | * Hide tab 16 | 17 | The open tabs are updated in real time. 18 | 19 | ## Why? 20 | 21 | I wanted to find an extension that shows opened tabs in an elegant way but didn't find it. Hope you will like Open Tabs. 22 | 23 | ## Installation 24 | 25 | Install from the **[Chrome Web Store](https://chrome.google.com/webstore/detail/open-tabs/cepfpldhbcfaklnnldhoaahgliijehap)**. 26 | 27 | Also available for **[Opera Browser](https://addons.opera.com/fr/extensions/details/open-tabs/)**. 28 | 29 | ## Usage 30 | 31 | * Click on the icon icon to open. 32 | * Try & enjoy! 33 | 34 | ## Screenshot 35 | 36 | help 37 | 38 | ## Changelog 39 | 40 | See [releases](https://github.com/sylouuu/chrome-open-tabs/releases) section. 41 | 42 | ## Development 43 | 44 | In case you want to contribute or just want to play with the code, follow the guide. 45 | 46 | ### Setup 47 | 48 | Download and install [NodeJS](http://nodejs.org/download/) to get [npm](https://www.npmjs.org/). 49 | 50 | Install `gulp` and `yarn` globally: 51 | 52 | ```bash 53 | npm install -g gulp yarn 54 | ``` 55 | 56 | Clone the project and install dependencies with `yarn`. 57 | 58 | Type `gulp` to watch your changes inside `src/` folder or type `gulp build` after each change. 59 | 60 | ### Load local extension in Chrome 61 | 62 | Go to `chrome://extensions/` and enable the "Developer mode". 63 | 64 | Click on "Load unpacked extension..." and select the project `dist/` folder. 65 | 66 | ## License 67 | 68 | See [license](LICENSE.md) file. 69 | -------------------------------------------------------------------------------- /dist/html/home.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 | 29 |
30 | 31 | 163 | -------------------------------------------------------------------------------- /dist/html/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Open Tabs 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 |

Open Tabs

54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Refresh list 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Chrome Web Store 82 | 83 | 84 | 85 | 86 | 87 | GitHub 88 | 89 | 90 | 91 | 92 | 93 | Donate 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | tab-modifier-icon 102 | Tab Modifier 103 | 104 | 105 | 106 | 107 | 108 | 109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /dist/html/settings_modal.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |

Settings

6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | 16 |
17 |

Show open tabs count

18 |

Disable if you don't care about this count.

19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 |

Enable "New version" toast

27 |

In case you worry about extension changes.

28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 | 36 | 37 | 38 | 39 |  Save 40 | 41 | 42 |
43 |
44 | -------------------------------------------------------------------------------- /dist/html/toast_new_version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Open changelog 5 | 6 | 7 | Close 8 | 9 | 10 | -------------------------------------------------------------------------------- /dist/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/content-duplicate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/content-save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/credit-card.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/dots-horizontal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/dots-vertical.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/eye-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/github-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/google-chrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/magnify.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/pin-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/pin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/reload.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/icons/settings.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/img/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/default.png -------------------------------------------------------------------------------- /dist/img/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/icon_128.png -------------------------------------------------------------------------------- /dist/img/icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/icon_16.png -------------------------------------------------------------------------------- /dist/img/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/icon_32.png -------------------------------------------------------------------------------- /dist/img/icon_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/icon_48.png -------------------------------------------------------------------------------- /dist/img/icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/icon_64.png -------------------------------------------------------------------------------- /dist/img/tab_modifier_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/dist/img/tab_modifier_32.png -------------------------------------------------------------------------------- /dist/js/background.js: -------------------------------------------------------------------------------- 1 | var options_url = chrome.extension.getURL('html/options.html'), openOptionsPage, getOpenTabsCount, getStorage, updateBrowserActionBadge, handleBrowserActionBadgeEvents; 2 | 3 | // -------------------------------------------------------------------------------------------------------- 4 | // Functions 5 | 6 | openOptionsPage = function (hash) { 7 | chrome.tabs.query({ url: options_url }, function (tabs) { 8 | if (tabs.length > 0) { 9 | chrome.tabs.update(tabs[0].id, { active: true, highlighted: true }, function (current_tab) { 10 | chrome.windows.update(current_tab.windowId, { focused: true }); 11 | }); 12 | } else { 13 | chrome.tabs.create({ url: (hash !== undefined) ? options_url + '#' + hash : options_url }); 14 | } 15 | }); 16 | }; 17 | 18 | getOpenTabsCount = function (callback) { 19 | var count = 0; 20 | 21 | chrome.tabs.query({ url: options_url }, function (tabs) { 22 | count -= tabs.length; 23 | 24 | chrome.tabs.query({}, function (tabs) { 25 | count += tabs.length; 26 | 27 | callback(count); 28 | }); 29 | }); 30 | }; 31 | 32 | getStorage = function (callback) { 33 | chrome.storage.local.get('open_tabs', function (items) { 34 | callback(items.open_tabs); 35 | }); 36 | }; 37 | 38 | chrome.browserAction.setBadgeBackgroundColor({ color: '#1E88E5' }); 39 | 40 | updateBrowserActionBadge = function (open_tabs) { 41 | if (open_tabs === undefined || open_tabs.settings.show_browser_action_count === true) { 42 | getOpenTabsCount(function (count) { 43 | chrome.browserAction.setBadgeText({ text: count.toString() }); 44 | }); 45 | } else { 46 | chrome.browserAction.setBadgeText({ text: '' }); 47 | } 48 | }; 49 | 50 | handleBrowserActionBadgeEvents = function () { 51 | var tab_listener = function () { 52 | getStorage(function (open_tabs) { 53 | return updateBrowserActionBadge(open_tabs); 54 | }); 55 | }; 56 | 57 | getStorage(function (open_tabs) { 58 | if (open_tabs === undefined || open_tabs.settings.show_browser_action_count === true) { 59 | chrome.tabs.onCreated.addListener(tab_listener); 60 | chrome.tabs.onRemoved.addListener(tab_listener); 61 | } else { 62 | chrome.tabs.onCreated.removeListener(tab_listener); 63 | chrome.tabs.onRemoved.removeListener(tab_listener); 64 | } 65 | 66 | updateBrowserActionBadge(open_tabs); 67 | }); 68 | }; 69 | 70 | // -------------------------------------------------------------------------------------------------------- 71 | // Events 72 | 73 | chrome.browserAction.onClicked.addListener(function () { 74 | openOptionsPage(); 75 | }); 76 | 77 | handleBrowserActionBadgeEvents(); 78 | 79 | chrome.runtime.onInstalled.addListener(function (details) { 80 | switch (details.reason) { 81 | case 'install': 82 | openOptionsPage('install'); 83 | break; 84 | case 'update': 85 | getStorage(function (open_tabs) { 86 | if (open_tabs === undefined || open_tabs.settings === undefined) { 87 | return; 88 | } 89 | 90 | if (open_tabs.settings !== undefined && open_tabs.settings.enable_new_version_notification === true && details.previousVersion !== chrome.runtime.getManifest().version) { 91 | openOptionsPage('update/' + chrome.runtime.getManifest().version); 92 | } 93 | }); 94 | break; 95 | } 96 | }); 97 | -------------------------------------------------------------------------------- /dist/js/libs/angular-google-analytics.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Angular Google Analytics - Easy tracking for your AngularJS application 3 | * @version v1.1.7 - 2016-03-25 4 | * @link http://github.com/revolunet/angular-google-analytics 5 | * @author Julien Bouquillon (https://github.com/revolunet) 6 | * @contributors Julien Bouquillon (https://github.com/revolunet),Justin Saunders (https://github.com/justinsa),Chris Esplin (https://github.com/deltaepsilon),Adam Misiorny (https://github.com/adam187) 7 | * @license MIT License, http://www.opensource.org/licenses/MIT 8 | */ 9 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):"object"==typeof module&&module.exports?module.exports=b(require("angular")):b(a.angular)}(this,function(a,b){"use strict";return a.module("angular-google-analytics",[]).provider("Analytics",function(){var c,d,e,f,g,h=!0,i="auto",j=!1,k=!1,l="USD",m=!1,n=!1,o=!1,p=!1,q=!1,r=!1,s=!1,t=!1,u=!1,v=!1,w=!1,x="$routeChangeSuccess",y=!1,z=!1,A=!1,B="",C=!0,D=!1;this.log=[],this.offlineQueue=[],this.setAccount=function(d){return c=a.isUndefined(d)||d===!1?b:a.isArray(d)?d:a.isObject(d)?[d]:[{tracker:d,trackEvent:!0}],this},this.trackPages=function(a){return C=!!a,this},this.trackPrefix=function(a){return B=a,this},this.setDomainName=function(a){return e=a,this},this.useDisplayFeatures=function(a){return o=!!a,this},this.useAnalytics=function(a){return h=!!a,this},this.useEnhancedLinkAttribution=function(a){return s=!!a,this},this.useCrossDomainLinker=function(a){return k=!!a,this},this.setCrossLinkDomains=function(a){return d=a,this},this.setPageEvent=function(a){return x=a,this},this.setCookieConfig=function(a){return i=a,this},this.useECommerce=function(a,b){return q=!!a,r=!!b,this},this.setCurrency=function(a){return l=a,this},this.setRemoveRegExp=function(a){return a instanceof RegExp&&(g=a),this},this.setExperimentId=function(a){return f=a,this},this.ignoreFirstPageLoad=function(a){return t=!!a,this},this.trackUrlParams=function(a){return D=!!a,this},this.disableAnalytics=function(a){return p=!!a,this},this.setHybridMobileSupport=function(a){return v=!!a,this},this.startOffline=function(a){return w=!!a,w===!0&&this.delayScriptTag(!0),this},this.delayScriptTag=function(a){return n=!!a,this},this.logAllCalls=function(a){return u=!!a,this},this.enterTestMode=function(){return z=!0,this},this.enterDebugMode=function(a){return m=!0,A=!!a,this},this.readFromRoute=function(a){return y=!!a,this},this.$get=["$document","$location","$log","$rootScope","$window","$injector",function(E,F,G,H,I,J){var K=this,L=function(b,c){return a.isObject(c)&&a.isDefined(c[b])},M=function(a,b,c){return L(a,b)&&b[a]===c},N=function(b,c){return a.isString(c)?c+"."+b:L("name",c)?c.name+"."+b:b},O={};y&&(J.has("$route")?O=J.get("$route"):G.warn("$route service is not available. Make sure you have included ng-route in your application dependencies."));var P=function(){if(y&&O.current&&"pageTrack"in O.current)return O.current.pageTrack;var a=D?F.url():F.path();return g?a.replace(g,""):a},Q=function(){var b={utm_source:"campaignSource",utm_medium:"campaignMedium",utm_term:"campaignTerm",utm_content:"campaignContent",utm_campaign:"campaignName"},c={};return a.forEach(F.search(),function(d,e){var f=b[e];a.isDefined(f)&&(c[f]=d)}),c},R=function(a,b,c,d,e,f,g,h,i){var j={};return a&&(j.id=a),b&&(j.affiliation=b),c&&(j.revenue=c),d&&(j.tax=d),e&&(j.shipping=e),f&&(j.coupon=f),g&&(j.list=g),h&&(j.step=h),i&&(j.option=i),j},S=function(a){!h&&I._gaq&&"function"==typeof a&&a()},T=function(){var a=Array.prototype.slice.call(arguments);return w===!0?void K.offlineQueue.push([T,a]):(I._gaq||(I._gaq=[]),u===!0&&K._log.apply(K,a),void I._gaq.push(a))},U=function(a){h&&I.ga&&"function"==typeof a&&a()},V=function(){var a=Array.prototype.slice.call(arguments);return w===!0?void K.offlineQueue.push([V,a]):"function"!=typeof I.ga?void K._log("warn","ga function not set on window"):(u===!0&&K._log.apply(K,a),void I.ga.apply(null,a))},W=function(a){var b=Array.prototype.slice.call(arguments,1),d=b[0],e=[];return"function"==typeof a?c.forEach(function(b){a(b)&&e.push(b)}):e=c,0===e.length?void V.apply(K,b):void e.forEach(function(a){L("select",a)&&"function"==typeof a.select&&!a.select(b)||(b[0]=N(d,a),V.apply(K,b))})};return this._log=function(){var a=Array.prototype.slice.call(arguments);if(a.length>0){if(a.length>1)switch(a[0]){case"debug":case"error":case"info":case"log":case"warn":G[a[0]](a.slice(1))}K.log.push(a)}},this._createScriptTag=function(){if(!c||c.length<1)return void K._log("warn","No account id set to create script tag");if(c.length>1&&(K._log("warn","Multiple trackers are not supported with ga.js. Using first tracker only"),c=c.slice(0,1)),j===!0)return void K._log("warn","ga.js or analytics.js script tag already created");p===!0&&(K._log("info","Analytics disabled: "+c[0].tracker),I["ga-disable-"+c[0].tracker]=!0),T("_setAccount",c[0].tracker),e&&T("_setDomainName",e),s&&T("_require","inpage_linkid","//www.google-analytics.com/plugins/ga/inpage_linkid.js"),C&&!t&&(g?T("_trackPageview",P()):T("_trackPageview"));var a,b=E[0];return a=o===!0?("https:"===b.location.protocol?"https://":"http://")+"stats.g.doubleclick.net/dc.js":("https:"===b.location.protocol?"https://ssl":"http://www")+".google-analytics.com/ga.js",z!==!0?!function(){var c=b.createElement("script");c.type="text/javascript",c.async=!0,c.src=a;var d=b.getElementsByTagName("script")[0];d.parentNode.insertBefore(c,d)}():K._log("inject",a),j=!0,!0},this._createAnalyticsScriptTag=function(){if(!c)return void K._log("warn","No account id set to create analytics script tag");if(j===!0)return void K._log("warn","ga.js or analytics.js script tag already created");p===!0&&c.forEach(function(a){K._log("info","Analytics disabled: "+a.tracker),I["ga-disable-"+a.tracker]=!0});var b=E[0],e=v===!0?"https:":"",g=e+"//www.google-analytics.com/"+(m?"analytics_debug.js":"analytics.js");if(z!==!0?!function(a,b,c,d,e,f,g){a.GoogleAnalyticsObject=e,a[e]=a[e]||function(){(a[e].q=a[e].q||[]).push(arguments)},a[e].l=1*new Date,f=b.createElement(c),g=b.getElementsByTagName(c)[0],f.async=1,f.src=d,g.parentNode.insertBefore(f,g)}(window,b,"script",g,"ga"):("function"!=typeof I.ga&&(I.ga=function(){}),K._log("inject",g)),A&&(I.ga_debug={trace:!0}),c.forEach(function(b){b.crossDomainLinker=L("crossDomainLinker",b)?b.crossDomainLinker:k,b.crossLinkDomains=L("crossLinkDomains",b)?b.crossLinkDomains:d,b.displayFeatures=L("displayFeatures",b)?b.displayFeatures:o,b.enhancedLinkAttribution=L("enhancedLinkAttribution",b)?b.enhancedLinkAttribution:s,b.set=L("set",b)?b.set:{},b.trackEcommerce=L("trackEcommerce",b)?b.trackEcommerce:q,b.trackEvent=L("trackEvent",b)?b.trackEvent:!1;var c={};L("fields",b)?c=b.fields:L("cookieConfig",b)?a.isString(b.cookieConfig)?c.cookieDomain=b.cookieConfig:c=b.cookieConfig:a.isString(i)?c.cookieDomain=i:i&&(c=i),b.crossDomainLinker===!0&&(c.allowLinker=!0),L("name",b)&&(c.name=b.name),b.fields=c,V("create",b.tracker,b.fields),v===!0&&V(N("set",b),"checkProtocolTask",null);for(var e in b.set)b.set.hasOwnProperty(e)&&V(N("set",b),e,b.set[e]);b.crossDomainLinker===!0&&(V(N("require",b),"linker"),a.isDefined(b.crossLinkDomains)&&V(N("linker:autoLink",b),b.crossLinkDomains)),b.displayFeatures&&V(N("require",b),"displayfeatures"),b.trackEcommerce&&(r?(V(N("require",b),"ec"),V(N("set",b),"&cu",l)):V(N("require",b),"ecommerce")),b.enhancedLinkAttribution&&V(N("require",b),"linkid"),C&&!t&&V(N("send",b),"pageview",B+P())}),f){var h=b.createElement("script"),n=b.getElementsByTagName("script")[0];h.src=e+"//www.google-analytics.com/cx/api.js?experiment="+f,n.parentNode.insertBefore(h,n)}return j=!0,!0},this._ecommerceEnabled=function(a,b){var c=q&&!r;return a===!0&&c===!1&&(q&&r?K._log("warn",b+" is not available when Enhanced Ecommerce is enabled with analytics.js"):K._log("warn","Ecommerce must be enabled to use "+b+" with analytics.js")),c},this._enhancedEcommerceEnabled=function(a,b){var c=q&&r;return a===!0&&c===!1&&K._log("warn","Enhanced Ecommerce must be enabled to use "+b+" with analytics.js"),c},this._trackPage=function(c,d,e){c=c?c:P(),d=d?d:E[0].title,S(function(){T("_set","title",d),T("_trackPageview",B+c)}),U(function(){var f={page:B+c,title:d};a.extend(f,Q()),a.isObject(e)&&a.extend(f,e),W(b,"send","pageview",f)})},this._trackEvent=function(b,c,d,e,f,g){S(function(){T("_trackEvent",b,c,d,e,!!f)}),U(function(){var h={},i=function(a){return M("trackEvent",a,!0)};a.isDefined(f)&&(h.nonInteraction=!!f),a.isObject(g)&&a.extend(h,g),a.isDefined(h.page)||(h.page=P()),W(i,"send","event",b,c,d,e,h)})},this._addTrans=function(a,b,c,d,e,f,g,h,i){S(function(){T("_addTrans",a,b,c,d,e,f,g,h)}),U(function(){if(K._ecommerceEnabled(!0,"addTrans")){var f=function(a){return M("trackEcommerce",a,!0)};W(f,"ecommerce:addTransaction",{id:a,affiliation:b,revenue:c,tax:d,shipping:e,currency:i||"USD"})}})},this._addItem=function(a,b,c,d,e,f){S(function(){T("_addItem",a,b,c,d,e,f)}),U(function(){if(K._ecommerceEnabled(!0,"addItem")){var g=function(a){return M("trackEcommerce",a,!0)};W(g,"ecommerce:addItem",{id:a,name:c,sku:b,category:d,price:e,quantity:f})}})},this._trackTrans=function(){S(function(){T("_trackTrans")}),U(function(){if(K._ecommerceEnabled(!0,"trackTrans")){var a=function(a){return M("trackEcommerce",a,!0)};W(a,"ecommerce:send")}})},this._clearTrans=function(){U(function(){if(K._ecommerceEnabled(!0,"clearTrans")){var a=function(a){return M("trackEcommerce",a,!0)};W(a,"ecommerce:clear")}})},this._addProduct=function(b,c,d,e,f,g,h,i,j,k){S(function(){T("_addProduct",b,c,d,e,f,g,h,i,j)}),U(function(){if(K._enhancedEcommerceEnabled(!0,"addProduct")){var l=function(a){return M("trackEcommerce",a,!0)},m={id:b,name:c,category:d,brand:e,variant:f,price:g,quantity:h,coupon:i,position:j};a.isObject(k)&&a.extend(m,k),W(l,"ec:addProduct",m)}})},this._addImpression=function(a,b,c,d,e,f,g,h){S(function(){T("_addImpression",a,b,c,d,e,f,g,h)}),U(function(){if(K._enhancedEcommerceEnabled(!0,"addImpression")){var i=function(a){return M("trackEcommerce",a,!0)};W(i,"ec:addImpression",{id:a,name:b,category:e,brand:d,variant:f,list:c,position:g,price:h})}})},this._addPromo=function(a,b,c,d){S(function(){T("_addPromo",a,b,c,d)}),U(function(){if(K._enhancedEcommerceEnabled(!0,"addPromo")){var e=function(a){return M("trackEcommerce",a,!0)};W(e,"ec:addPromo",{id:a,name:b,creative:c,position:d})}})},this._setAction=function(a,b){S(function(){T("_setAction",a,b)}),U(function(){if(K._enhancedEcommerceEnabled(!0,"setAction")){var c=function(a){return M("trackEcommerce",a,!0)};W(c,"ec:setAction",a,b)}})},this._trackTransaction=function(a,b,c,d,e,f,g,h,i){this._setAction("purchase",R(a,b,c,d,e,f,g,h,i))},this._trackRefund=function(a){this._setAction("refund",R(a))},this._trackCheckOut=function(a,b){this._setAction("checkout",R(null,null,null,null,null,null,null,a,b))},this._trackDetail=function(){this._setAction("detail"),this._pageView()},this._trackCart=function(a,b){-1!==["add","remove"].indexOf(a)&&(this._setAction(a,{list:b}),this._trackEvent("UX","click",a+("add"===a?" to cart":" from cart")))},this._promoClick=function(a){this._setAction("promo_click"),this._trackEvent("Internal Promotions","click",a)},this._productClick=function(a){this._setAction("click",R(null,null,null,null,null,null,a,null,null)),this._trackEvent("UX","click",a)},this._pageView=function(a){U(function(){V(N("send",a),"pageview")})},this._send=function(){var a=Array.prototype.slice.call(arguments);a.unshift("send"),U(function(){V.apply(K,a)})},this._set=function(a,b,c){U(function(){V(N("set",c),a,b)})},this._trackTimings=function(a,c,d,e){U(function(){W(b,"send","timing",a,c,d,e)})},this._trackException=function(a,c){U(function(){W(b,"send","exception",{exDescription:a,exFatal:!!c})})},n||(h?this._createAnalyticsScriptTag():this._createScriptTag()),C&&H.$on(x,function(){(!y||O.current&&O.current.templateUrl&&!O.current.doNotTrack)&&K._trackPage()}),{log:K.log,offlineQueue:K.offlineQueue,configuration:{accounts:c,universalAnalytics:h,crossDomainLinker:k,crossLinkDomains:d,currency:l,debugMode:m,delayScriptTag:n,disableAnalytics:p,displayFeatures:o,domainName:e,ecommerce:K._ecommerceEnabled(),enhancedEcommerce:K._enhancedEcommerceEnabled(),enhancedLinkAttribution:s,experimentId:f,hybridMobileSupport:v,ignoreFirstPageLoad:t,logAllCalls:u,pageEvent:x,readFromRoute:y,removeRegExp:g,testMode:z,traceDebuggingMode:A,trackPrefix:B,trackRoutes:C,trackUrlParams:D},getUrl:P,setCookieConfig:K._setCookieConfig,getCookieConfig:function(){return i},createAnalyticsScriptTag:function(a){return a&&(i=a),K._createAnalyticsScriptTag()},createScriptTag:function(){return K._createScriptTag()},offline:function(a){if(a===!0&&w===!1&&(w=!0),a===!1&&w===!0)for(w=!1;K.offlineQueue.length>0;){var b=K.offlineQueue.shift();b[0].apply(K,b[1])}return w},trackPage:function(a,b,c){K._trackPage.apply(K,arguments)},trackEvent:function(a,b,c,d,e,f){K._trackEvent.apply(K,arguments)},addTrans:function(a,b,c,d,e,f,g,h,i){K._addTrans.apply(K,arguments)},addItem:function(a,b,c,d,e,f){K._addItem.apply(K,arguments)},trackTrans:function(){K._trackTrans.apply(K,arguments)},clearTrans:function(){K._clearTrans.apply(K,arguments)},addProduct:function(a,b,c,d,e,f,g,h,i,j){K._addProduct.apply(K,arguments)},addPromo:function(a,b,c,d){K._addPromo.apply(K,arguments)},addImpression:function(a,b,c,d,e,f,g,h){K._addImpression.apply(K,arguments)},productClick:function(a){K._productClick.apply(K,arguments)},promoClick:function(a){K._promoClick.apply(K,arguments)},trackDetail:function(){K._trackDetail.apply(K,arguments)},trackCart:function(a,b){K._trackCart.apply(K,arguments)},trackCheckout:function(a,b){K._trackCheckOut.apply(K,arguments)},trackTimings:function(a,b,c,d){K._trackTimings.apply(K,arguments)},trackTransaction:function(a,b,c,d,e,f,g,h,i){K._trackTransaction.apply(K,arguments)},trackException:function(a,b){K._trackException.apply(K,arguments)},setAction:function(a,b){K._setAction.apply(K,arguments)},pageView:function(){K._pageView.apply(K,arguments)},send:function(a){K._send.apply(K,arguments)},set:function(a,b,c){K._set.apply(K,arguments)}}}]}).directive("gaTrackEvent",["Analytics","$parse",function(a,b){return{restrict:"A",link:function(c,d,e){var f=b(e.gaTrackEvent);d.bind("click",function(){e.gaTrackEventIf&&!c.$eval(e.gaTrackEventIf)||f.length>1&&a.trackEvent.apply(a,f(c))})}}}]),a.module("angular-google-analytics")}); 10 | -------------------------------------------------------------------------------- /dist/js/options.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('OpenTabs', ['ngRoute', 'ngAnimate', 'ngAria', 'ngMaterial', 'angular-google-analytics']); 2 | 3 | app.config(['$routeProvider', '$compileProvider', '$mdIconProvider', '$mdThemingProvider', 'AnalyticsProvider', function ($routeProvider, $compileProvider, $mdIconProvider, $mdThemingProvider, AnalyticsProvider) { 4 | 5 | // Allow "chrome-extension" protocol 6 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|chrome-extension|blob:chrome-extension|file|blob):/); 7 | $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|chrome-extension|file|blob):|data:image\//); 8 | 9 | // Load icons list by name 10 | $mdIconProvider 11 | .icon('arrow-right', '/icons/arrow-right.svg') 12 | .icon('close', '/icons/close.svg') 13 | .icon('content-duplicate', '/icons/content-duplicate.svg') 14 | .icon('credit-card', '/icons/credit-card.svg') 15 | .icon('delete', '/icons/delete.svg') 16 | .icon('dots-horizontal', '/icons/dots-horizontal.svg') 17 | .icon('dots-vertical', '/icons/dots-vertical.svg') 18 | .icon('eye-off', '/icons/eye-off.svg') 19 | .icon('github-circle', '/icons/github-circle.svg') 20 | .icon('google-chrome', '/icons/google-chrome.svg') 21 | .icon('magnify', '/icons/magnify.svg') 22 | .icon('pin', '/icons/pin.svg') 23 | .icon('pin-off', '/icons/pin-off.svg') 24 | .icon('refresh', '/icons/refresh.svg') 25 | .icon('reload', '/icons/reload.svg') 26 | .icon('save', '/icons/content-save.svg') 27 | .icon('settings', '/icons/settings.svg'); 28 | 29 | $mdThemingProvider 30 | .theme('default') 31 | .primaryPalette('blue', { 32 | default: '600' 33 | }) 34 | .accentPalette('yellow', { 35 | default: '700' 36 | }) 37 | .warnPalette('red', { 38 | default: 'A700' 39 | }); 40 | 41 | // Analytics config 42 | AnalyticsProvider.setAccount('UA-27524593-8'); 43 | AnalyticsProvider.setHybridMobileSupport(true); 44 | AnalyticsProvider.setDomainName('none'); 45 | 46 | var routes = { 47 | '/:event?/:version?': { 48 | templateUrl: '/html/home.html', 49 | controller: 'HomeController' 50 | } 51 | }; 52 | 53 | for (var path in routes) { 54 | if (routes.hasOwnProperty(path)) { 55 | $routeProvider.when(path, routes[path]); 56 | } 57 | } 58 | 59 | }]); 60 | 61 | app.run(['Analytics', function (Analytics) { 62 | 63 | }]); 64 | 65 | app.filter('searchFilter', function () { 66 | return function (items, query) { 67 | if (query === null || query === '') { 68 | return items; 69 | } 70 | 71 | query = query.toLowerCase(); 72 | 73 | var filtered = []; 74 | 75 | angular.forEach(items, function (item) { 76 | if (item.title.toLowerCase().indexOf(query) !== -1 || item.url.toLowerCase().indexOf(query) !== -1) { 77 | filtered.push(item); 78 | } 79 | }); 80 | 81 | return filtered; 82 | }; 83 | }); 84 | 85 | app.controller('HomeController', ['$scope', '$routeParams', '$location', '$mdDialog', '$mdToast', 'Analytics', function ($scope, $routeParams, $location, $mdDialog, $mdToast, Analytics) { 86 | 87 | $scope.syncHiddenTabs = function () { 88 | $scope.open_tabs.hidden_tabs = $scope.tabs.hidden.data; 89 | 90 | chrome.storage.local.set({ open_tabs: $scope.open_tabs }); 91 | }; 92 | 93 | // --------------------------------------------------------------------------------- 94 | // Checkboxes handling 95 | 96 | $scope.isIndeterminate = function (array) { 97 | return (array.selected.length > 0 && array.selected.length !== array.data.length); 98 | }; 99 | 100 | $scope.isChecked = function (array) { 101 | return array.selected.length === array.data.length; 102 | }; 103 | 104 | $scope.toggleAll = function (array) { 105 | if (array.selected.length === array.data.length) { 106 | array.selected = []; 107 | } else { 108 | array.selected = []; 109 | 110 | angular.forEach(array.data, function (tab) { 111 | array.selected.push(tab.id); 112 | }); 113 | } 114 | }; 115 | 116 | $scope.toggle = function (array, tab_id) { 117 | var i = array.selected.indexOf(tab_id); 118 | 119 | if (i > -1) { 120 | array.selected.splice(i, 1); 121 | } else { 122 | array.selected.push(tab_id); 123 | } 124 | }; 125 | 126 | // --------------------------------------------------------------------------------- 127 | // Actions on checked tabs 128 | 129 | $scope.closeAllTabs = function (array) { 130 | chrome.tabs.remove(array.selected); 131 | 132 | array.selected = []; 133 | }; 134 | 135 | $scope.reloadAllTabs = function (array) { 136 | angular.forEach(array.selected, function (id) { 137 | $scope.reloadTab(id); 138 | }); 139 | 140 | array.selected = []; 141 | }; 142 | 143 | $scope.pinOrUnpinAllTabs = function (array, pinned) { 144 | angular.forEach(array.selected, function (id) { 145 | $scope.pinOrUnpinTab(id, pinned); 146 | }); 147 | 148 | array.selected = []; 149 | }; 150 | 151 | $scope.hideAllTabs = function (array) { 152 | angular.forEach(array.selected, function (id) { 153 | chrome.tabs.get(id, function (tab) { 154 | $scope.hideTab(tab); 155 | }); 156 | }); 157 | 158 | array.selected = []; 159 | }; 160 | 161 | $scope.removeAllHiddenTabs = function (array) { 162 | // Loop in reverse because of splice 163 | for (var i = array.data.length - 1; i >= 0; i--) { 164 | if (array.selected.indexOf(array.data[i].id) !== -1) { 165 | array.data.splice(array.data.indexOf(array.data[i]), 1); 166 | } 167 | } 168 | 169 | array.selected = []; 170 | 171 | $scope.syncHiddenTabs(); 172 | }; 173 | 174 | // --------------------------------------------------------------------------------- 175 | // Actions on individual tab 176 | 177 | $scope.goToTab = function (tab) { 178 | chrome.tabs.update(tab.id, { active: true, highlighted: true }, function (current_tab) { 179 | chrome.windows.update(current_tab.windowId, { focused: true }); 180 | }); 181 | }; 182 | 183 | $scope.removeTab = function (tab) { 184 | chrome.tabs.remove(tab.id); 185 | }; 186 | 187 | $scope.reloadTab = function (id) { 188 | chrome.tabs.reload(id); 189 | }; 190 | 191 | $scope.duplicateTab = function (tab) { 192 | chrome.tabs.create({ url: tab.url, active: false, pinned: tab.pinned, index: tab.index + 1 }); 193 | }; 194 | 195 | $scope.pinOrUnpinTab = function (id, pinned) { 196 | chrome.tabs.update(id, { pinned: pinned }); 197 | }; 198 | 199 | $scope.hideTab = function (tab) { 200 | $scope.tabs.hidden.data.push(tab); 201 | $scope.removeTab(tab); 202 | $scope.syncHiddenTabs(); 203 | }; 204 | 205 | $scope.removeHiddenTab = function (tab) { 206 | $scope.tabs.hidden.data.splice($scope.tabs.hidden.data.indexOf(tab), 1); 207 | $scope.syncHiddenTabs(); 208 | }; 209 | 210 | $scope.openHiddenTab = function (tab) { 211 | chrome.tabs.create({ url: tab.url, active: true }); 212 | 213 | $scope.removeHiddenTab(tab); 214 | }; 215 | 216 | // -------------------------------------------------------------------------------------------------------- 217 | // Events 218 | 219 | // New install 220 | if ($routeParams.event === 'install') { 221 | var alert = $mdDialog 222 | .alert() 223 | .clickOutsideToClose(true) 224 | .title('Greetings') 225 | .textContent('Hello, thank you for installing Open Tabs!') 226 | .ariaLabel('Greetings') 227 | .targetEvent() 228 | .ok('Ok'); 229 | 230 | $mdDialog.show(alert).then(function () { 231 | Analytics.trackEvent('greetings-dialog', 'close'); 232 | 233 | $location.path('/'); 234 | }, function () { 235 | Analytics.trackEvent('greetings-dialog', 'show-form'); 236 | 237 | $location.path('/'); 238 | }); 239 | } 240 | 241 | // New version 242 | if ($routeParams.event === 'update' && $routeParams.version !== undefined) { 243 | $mdToast.show({ 244 | hideDelay: 0, 245 | position: 'top right', 246 | controller: 'ToastNewVersionController', 247 | templateUrl: '../html/toast_new_version.html', 248 | locals: { 249 | version: $routeParams.version 250 | } 251 | }); 252 | } 253 | 254 | }]); 255 | 256 | app.controller('ToastNewVersionController', ['$scope', '$location', '$mdToast', 'version', function ($scope, $location, $mdToast, version) { 257 | $scope.version = version; 258 | 259 | $scope.closeToast = function () { 260 | $mdToast.hide().then(function () { 261 | $location.path('/'); 262 | }); 263 | }; 264 | 265 | $scope.openGitHubReleases = function () { 266 | chrome.tabs.create({ url: 'https://github.com/sylouuu/chrome-open-tabs/releases' }); 267 | 268 | $scope.closeToast(); 269 | }; 270 | }]); 271 | 272 | app.controller('MainController', ['$scope', '$mdDialog', '$mdMedia', 'Analytics', function ($scope, $mdDialog, $mdMedia, Analytics) { 273 | 274 | $scope.open_tabs = { 275 | settings: { 276 | enable_new_version_notification: false, 277 | show_browser_action_count: true 278 | }, 279 | hidden_tabs: [] 280 | }; 281 | $scope.search = { query: null }; 282 | $scope.tabs = { 283 | pinned: { code: 'PINNED_TABS', title: 'Pinned tabs', data: [], selected: [] }, 284 | standard: { code: 'STANDARD_TABS', title: 'Standard tabs', data: [], selected: [] }, 285 | hidden: { code: 'HIDDEN_TABS', title: 'Hidden tabs', data: [], selected: [] } 286 | }; 287 | 288 | chrome.storage.local.get('open_tabs', function (items) { 289 | if (items.open_tabs !== undefined) { 290 | $scope.open_tabs = items.open_tabs; 291 | 292 | $scope.tabs.hidden.data = (items.open_tabs.hidden_tabs === undefined) ? [] : items.open_tabs.hidden_tabs; 293 | } 294 | 295 | $scope.$apply(); 296 | }); 297 | 298 | $scope.saveSettings = function (open_tabs) { 299 | chrome.storage.local.set({ open_tabs: open_tabs }); 300 | 301 | chrome.extension.getBackgroundPage().handleBrowserActionBadgeEvents(); 302 | }; 303 | 304 | $scope.loadTabs = function () { 305 | chrome.tabs.query({}, function (tabs) { 306 | $scope.tabs.pinned.data = []; 307 | $scope.tabs.standard.data = []; 308 | 309 | for (var i = 0; i < tabs.length; i++) { 310 | // Exclude options page 311 | if (tabs[i].url !== chrome.extension.getURL('html/options.html')) { 312 | if (tabs[i].pinned === true) { 313 | $scope.tabs.pinned.data.push(tabs[i]); 314 | } else { 315 | $scope.tabs.standard.data.push(tabs[i]); 316 | } 317 | } 318 | } 319 | 320 | $scope.$apply(); 321 | }); 322 | }; 323 | 324 | $scope.loadTabs(); 325 | 326 | $scope.showSettings = function (evt) { 327 | $mdDialog.show({ 328 | controller: 'SettingsModalController', 329 | templateUrl: '../html/settings_modal.html', 330 | targetEvent: evt, 331 | clickOutsideToClose: false, 332 | fullscreen: $mdMedia('xs'), 333 | resolve: { 334 | open_tabs: function () { 335 | return $scope.open_tabs; 336 | } 337 | } 338 | }).then(function (data) { 339 | $scope.saveSettings(data); 340 | 341 | Analytics.trackEvent('settings', 'save'); 342 | }); 343 | }; 344 | 345 | // --------------------------------------------------------------------------------- 346 | // Listeners 347 | 348 | chrome.tabs.onCreated.addListener(function () { 349 | $scope.loadTabs(); 350 | }); 351 | 352 | chrome.tabs.onUpdated.addListener(function () { 353 | $scope.loadTabs(); 354 | }); 355 | 356 | chrome.tabs.onRemoved.addListener(function () { 357 | $scope.loadTabs(); 358 | }); 359 | 360 | chrome.tabs.onReplaced.addListener(function () { 361 | $scope.loadTabs(); 362 | }); 363 | 364 | chrome.tabs.onMoved.addListener(function () { 365 | $scope.loadTabs(); 366 | }); 367 | 368 | chrome.tabs.onDetached.addListener(function () { 369 | $scope.loadTabs(); 370 | }); 371 | 372 | chrome.tabs.onAttached.addListener(function () { 373 | $scope.loadTabs(); 374 | }); 375 | 376 | chrome.tabs.onActivated.addListener(function () { 377 | $scope.loadTabs(); 378 | }); 379 | 380 | }]); 381 | 382 | app.controller('SettingsModalController', ['$scope', '$mdDialog', 'open_tabs', function ($scope, $mdDialog, open_tabs) { 383 | 384 | $scope.open_tabs = open_tabs; 385 | 386 | $scope.closeForm = function () { 387 | $mdDialog.cancel(); 388 | }; 389 | 390 | $scope.save = function (data) { 391 | $mdDialog.hide(data); 392 | }; 393 | 394 | }]); 395 | -------------------------------------------------------------------------------- /dist/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Open Tabs", 4 | "version": "0.3.2", 5 | "description": "Show open tabs", 6 | "homepage_url": "https://github.com/sylouuu/chrome-open-tabs", 7 | 8 | "icons": { 9 | "16": "img/icon_16.png", 10 | "32": "img/icon_32.png", 11 | "48": "img/icon_48.png", 12 | "64": "img/icon_64.png", 13 | "128": "img/icon_128.png" 14 | }, 15 | 16 | "browser_action": { 17 | "default_icon": "img/icon_48.png" 18 | }, 19 | 20 | "content_security_policy": "script-src 'self' https://ajax.googleapis.com https://www.google-analytics.com; object-src 'self'", 21 | 22 | "options_page": "html/options.html", 23 | 24 | "background": { 25 | "scripts": ["js/background.js"], 26 | "persistent": false 27 | }, 28 | 29 | "web_accessible_resources": [ 30 | "img/*.png" 31 | ], 32 | 33 | "permissions": [ 34 | "tabs", 35 | "storage" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | 'use strict'; 4 | 5 | // Gulp dependencies 6 | var gulp = require('gulp'), 7 | jshint = require('gulp-jshint'), 8 | concat = require('gulp-concat'), 9 | jscs = require('gulp-jscs'); 10 | 11 | // Linter 12 | // ------------------------------------------------------------------------------------------------------ 13 | 14 | gulp.task('lint', function () { 15 | return gulp 16 | .src('src/js/**/*.js') 17 | .pipe(jscs()) 18 | .pipe(jscs.reporter()) 19 | .pipe(jscs.reporter('fail')) 20 | .pipe(jshint()) 21 | .pipe(jshint.reporter('default')); 22 | }); 23 | 24 | // Core 25 | // ------------------------------------------------------------------------------------------------------ 26 | 27 | gulp.task('build_core', ['build_background_script']); 28 | 29 | gulp.task('build_background_script', function () { 30 | return gulp 31 | .src(['src/js/background.js']) 32 | .pipe(gulp.dest('dist/js')); 33 | }); 34 | 35 | // Core 36 | // ------------------------------------------------------------------------------------------------------ 37 | 38 | gulp.task('build_options', ['build_options_script', 'build_options_html']); 39 | 40 | gulp.task('build_options_script', function () { 41 | return gulp 42 | .src(['src/js/options/**/*.js']) 43 | .pipe(concat('options.js')) 44 | .pipe(gulp.dest('dist/js')); 45 | }); 46 | 47 | gulp.task('build_options_html', function () { 48 | return gulp 49 | .src(['src/html/**/*.html']) 50 | .pipe(gulp.dest('dist/html')); 51 | }); 52 | 53 | gulp.task('build', [ 54 | 'build_core', 55 | 'build_options', 56 | 'lint' 57 | ]); 58 | 59 | gulp.task('watch', function() { 60 | gulp.watch('src/**/*', ['build_core', 'build_options']); 61 | }); 62 | 63 | // Default tasks (called when running `gulp` from cli) 64 | gulp.task('default', [ 65 | 'build_core', 66 | 'build_options', 67 | 'watch' 68 | ]); 69 | 70 | }()); 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chrome-open-tabs", 3 | "version": "0.3.2", 4 | "description": "Show open tabs", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/sylouuu/chrome-open-tabs.git" 8 | }, 9 | "author": "sylouuu", 10 | "license": "MIT", 11 | "bugs": { 12 | "url": "https://github.com/sylouuu/chrome-open-tabs/issues" 13 | }, 14 | "devDependencies": { 15 | "gulp": "~3.9.0", 16 | "gulp-concat": "~2.6.0", 17 | "gulp-jscs": "~4.0.0", 18 | "gulp-jshint": "~2.0.0", 19 | "jshint": "^2.9.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /screenshots/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylouuu/chrome-open-tabs/2fc18726475c28854723b5968a2ad0946cecb3e2/screenshots/home.png -------------------------------------------------------------------------------- /src/html/home.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 | 29 |
30 | 31 | 163 | -------------------------------------------------------------------------------- /src/html/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Open Tabs 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 |

Open Tabs

54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Refresh list 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Chrome Web Store 82 | 83 | 84 | 85 | 86 | 87 | GitHub 88 | 89 | 90 | 91 | 92 | 93 | Donate 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | tab-modifier-icon 102 | Tab Modifier 103 | 104 | 105 | 106 | 107 | 108 | 109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/html/settings_modal.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |

Settings

6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | 16 |
17 |

Show open tabs count

18 |

Disable if you don't care about this count.

19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 |

Enable "New version" toast

27 |

In case you worry about extension changes.

28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 | 36 | 37 | 38 | 39 |  Save 40 | 41 | 42 |
43 |
44 | -------------------------------------------------------------------------------- /src/html/toast_new_version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Open changelog 5 | 6 | 7 | Close 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/js/background.js: -------------------------------------------------------------------------------- 1 | var options_url = chrome.extension.getURL('html/options.html'), openOptionsPage, getOpenTabsCount, getStorage, updateBrowserActionBadge, handleBrowserActionBadgeEvents; 2 | 3 | // -------------------------------------------------------------------------------------------------------- 4 | // Functions 5 | 6 | openOptionsPage = function (hash) { 7 | chrome.tabs.query({ url: options_url }, function (tabs) { 8 | if (tabs.length > 0) { 9 | chrome.tabs.update(tabs[0].id, { active: true, highlighted: true }, function (current_tab) { 10 | chrome.windows.update(current_tab.windowId, { focused: true }); 11 | }); 12 | } else { 13 | chrome.tabs.create({ url: (hash !== undefined) ? options_url + '#' + hash : options_url }); 14 | } 15 | }); 16 | }; 17 | 18 | getOpenTabsCount = function (callback) { 19 | var count = 0; 20 | 21 | chrome.tabs.query({ url: options_url }, function (tabs) { 22 | count -= tabs.length; 23 | 24 | chrome.tabs.query({}, function (tabs) { 25 | count += tabs.length; 26 | 27 | callback(count); 28 | }); 29 | }); 30 | }; 31 | 32 | getStorage = function (callback) { 33 | chrome.storage.local.get('open_tabs', function (items) { 34 | callback(items.open_tabs); 35 | }); 36 | }; 37 | 38 | chrome.browserAction.setBadgeBackgroundColor({ color: '#1E88E5' }); 39 | 40 | updateBrowserActionBadge = function (open_tabs) { 41 | if (open_tabs === undefined || open_tabs.settings.show_browser_action_count === true) { 42 | getOpenTabsCount(function (count) { 43 | chrome.browserAction.setBadgeText({ text: count.toString() }); 44 | }); 45 | } else { 46 | chrome.browserAction.setBadgeText({ text: '' }); 47 | } 48 | }; 49 | 50 | handleBrowserActionBadgeEvents = function () { 51 | var tab_listener = function () { 52 | getStorage(function (open_tabs) { 53 | return updateBrowserActionBadge(open_tabs); 54 | }); 55 | }; 56 | 57 | getStorage(function (open_tabs) { 58 | if (open_tabs === undefined || open_tabs.settings.show_browser_action_count === true) { 59 | chrome.tabs.onCreated.addListener(tab_listener); 60 | chrome.tabs.onRemoved.addListener(tab_listener); 61 | } else { 62 | chrome.tabs.onCreated.removeListener(tab_listener); 63 | chrome.tabs.onRemoved.removeListener(tab_listener); 64 | } 65 | 66 | updateBrowserActionBadge(open_tabs); 67 | }); 68 | }; 69 | 70 | // -------------------------------------------------------------------------------------------------------- 71 | // Events 72 | 73 | chrome.browserAction.onClicked.addListener(function () { 74 | openOptionsPage(); 75 | }); 76 | 77 | handleBrowserActionBadgeEvents(); 78 | 79 | chrome.runtime.onInstalled.addListener(function (details) { 80 | switch (details.reason) { 81 | case 'install': 82 | openOptionsPage('install'); 83 | break; 84 | case 'update': 85 | getStorage(function (open_tabs) { 86 | if (open_tabs === undefined || open_tabs.settings === undefined) { 87 | return; 88 | } 89 | 90 | if (open_tabs.settings !== undefined && open_tabs.settings.enable_new_version_notification === true && details.previousVersion !== chrome.runtime.getManifest().version) { 91 | openOptionsPage('update/' + chrome.runtime.getManifest().version); 92 | } 93 | }); 94 | break; 95 | } 96 | }); 97 | -------------------------------------------------------------------------------- /src/js/options/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('OpenTabs', ['ngRoute', 'ngAnimate', 'ngAria', 'ngMaterial', 'angular-google-analytics']); 2 | 3 | app.config(['$routeProvider', '$compileProvider', '$mdIconProvider', '$mdThemingProvider', 'AnalyticsProvider', function ($routeProvider, $compileProvider, $mdIconProvider, $mdThemingProvider, AnalyticsProvider) { 4 | 5 | // Allow "chrome-extension" protocol 6 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|chrome-extension|blob:chrome-extension|file|blob):/); 7 | $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|chrome-extension|file|blob):|data:image\//); 8 | 9 | // Load icons list by name 10 | $mdIconProvider 11 | .icon('arrow-right', '/icons/arrow-right.svg') 12 | .icon('close', '/icons/close.svg') 13 | .icon('content-duplicate', '/icons/content-duplicate.svg') 14 | .icon('credit-card', '/icons/credit-card.svg') 15 | .icon('delete', '/icons/delete.svg') 16 | .icon('dots-horizontal', '/icons/dots-horizontal.svg') 17 | .icon('dots-vertical', '/icons/dots-vertical.svg') 18 | .icon('eye-off', '/icons/eye-off.svg') 19 | .icon('github-circle', '/icons/github-circle.svg') 20 | .icon('google-chrome', '/icons/google-chrome.svg') 21 | .icon('magnify', '/icons/magnify.svg') 22 | .icon('pin', '/icons/pin.svg') 23 | .icon('pin-off', '/icons/pin-off.svg') 24 | .icon('refresh', '/icons/refresh.svg') 25 | .icon('reload', '/icons/reload.svg') 26 | .icon('save', '/icons/content-save.svg') 27 | .icon('settings', '/icons/settings.svg'); 28 | 29 | $mdThemingProvider 30 | .theme('default') 31 | .primaryPalette('blue', { 32 | default: '600' 33 | }) 34 | .accentPalette('yellow', { 35 | default: '700' 36 | }) 37 | .warnPalette('red', { 38 | default: 'A700' 39 | }); 40 | 41 | // Analytics config 42 | AnalyticsProvider.setAccount('UA-27524593-8'); 43 | AnalyticsProvider.setHybridMobileSupport(true); 44 | AnalyticsProvider.setDomainName('none'); 45 | 46 | var routes = { 47 | '/:event?/:version?': { 48 | templateUrl: '/html/home.html', 49 | controller: 'HomeController' 50 | } 51 | }; 52 | 53 | for (var path in routes) { 54 | if (routes.hasOwnProperty(path)) { 55 | $routeProvider.when(path, routes[path]); 56 | } 57 | } 58 | 59 | }]); 60 | 61 | app.run(['Analytics', function (Analytics) { 62 | 63 | }]); 64 | 65 | app.filter('searchFilter', function () { 66 | return function (items, query) { 67 | if (query === null || query === '') { 68 | return items; 69 | } 70 | 71 | query = query.toLowerCase(); 72 | 73 | var filtered = []; 74 | 75 | angular.forEach(items, function (item) { 76 | if (item.title.toLowerCase().indexOf(query) !== -1 || item.url.toLowerCase().indexOf(query) !== -1) { 77 | filtered.push(item); 78 | } 79 | }); 80 | 81 | return filtered; 82 | }; 83 | }); 84 | -------------------------------------------------------------------------------- /src/js/options/home.controller.js: -------------------------------------------------------------------------------- 1 | app.controller('HomeController', ['$scope', '$routeParams', '$location', '$mdDialog', '$mdToast', 'Analytics', function ($scope, $routeParams, $location, $mdDialog, $mdToast, Analytics) { 2 | 3 | $scope.syncHiddenTabs = function () { 4 | $scope.open_tabs.hidden_tabs = $scope.tabs.hidden.data; 5 | 6 | chrome.storage.local.set({ open_tabs: $scope.open_tabs }); 7 | }; 8 | 9 | // --------------------------------------------------------------------------------- 10 | // Checkboxes handling 11 | 12 | $scope.isIndeterminate = function (array) { 13 | return (array.selected.length > 0 && array.selected.length !== array.data.length); 14 | }; 15 | 16 | $scope.isChecked = function (array) { 17 | return array.selected.length === array.data.length; 18 | }; 19 | 20 | $scope.toggleAll = function (array) { 21 | if (array.selected.length === array.data.length) { 22 | array.selected = []; 23 | } else { 24 | array.selected = []; 25 | 26 | angular.forEach(array.data, function (tab) { 27 | array.selected.push(tab.id); 28 | }); 29 | } 30 | }; 31 | 32 | $scope.toggle = function (array, tab_id) { 33 | var i = array.selected.indexOf(tab_id); 34 | 35 | if (i > -1) { 36 | array.selected.splice(i, 1); 37 | } else { 38 | array.selected.push(tab_id); 39 | } 40 | }; 41 | 42 | // --------------------------------------------------------------------------------- 43 | // Actions on checked tabs 44 | 45 | $scope.closeAllTabs = function (array) { 46 | chrome.tabs.remove(array.selected); 47 | 48 | array.selected = []; 49 | }; 50 | 51 | $scope.reloadAllTabs = function (array) { 52 | angular.forEach(array.selected, function (id) { 53 | $scope.reloadTab(id); 54 | }); 55 | 56 | array.selected = []; 57 | }; 58 | 59 | $scope.pinOrUnpinAllTabs = function (array, pinned) { 60 | angular.forEach(array.selected, function (id) { 61 | $scope.pinOrUnpinTab(id, pinned); 62 | }); 63 | 64 | array.selected = []; 65 | }; 66 | 67 | $scope.hideAllTabs = function (array) { 68 | angular.forEach(array.selected, function (id) { 69 | chrome.tabs.get(id, function (tab) { 70 | $scope.hideTab(tab); 71 | }); 72 | }); 73 | 74 | array.selected = []; 75 | }; 76 | 77 | $scope.removeAllHiddenTabs = function (array) { 78 | // Loop in reverse because of splice 79 | for (var i = array.data.length - 1; i >= 0; i--) { 80 | if (array.selected.indexOf(array.data[i].id) !== -1) { 81 | array.data.splice(array.data.indexOf(array.data[i]), 1); 82 | } 83 | } 84 | 85 | array.selected = []; 86 | 87 | $scope.syncHiddenTabs(); 88 | }; 89 | 90 | // --------------------------------------------------------------------------------- 91 | // Actions on individual tab 92 | 93 | $scope.goToTab = function (tab) { 94 | chrome.tabs.update(tab.id, { active: true, highlighted: true }, function (current_tab) { 95 | chrome.windows.update(current_tab.windowId, { focused: true }); 96 | }); 97 | }; 98 | 99 | $scope.removeTab = function (tab) { 100 | chrome.tabs.remove(tab.id); 101 | }; 102 | 103 | $scope.reloadTab = function (id) { 104 | chrome.tabs.reload(id); 105 | }; 106 | 107 | $scope.duplicateTab = function (tab) { 108 | chrome.tabs.create({ url: tab.url, active: false, pinned: tab.pinned, index: tab.index + 1 }); 109 | }; 110 | 111 | $scope.pinOrUnpinTab = function (id, pinned) { 112 | chrome.tabs.update(id, { pinned: pinned }); 113 | }; 114 | 115 | $scope.hideTab = function (tab) { 116 | $scope.tabs.hidden.data.push(tab); 117 | $scope.removeTab(tab); 118 | $scope.syncHiddenTabs(); 119 | }; 120 | 121 | $scope.removeHiddenTab = function (tab) { 122 | $scope.tabs.hidden.data.splice($scope.tabs.hidden.data.indexOf(tab), 1); 123 | $scope.syncHiddenTabs(); 124 | }; 125 | 126 | $scope.openHiddenTab = function (tab) { 127 | chrome.tabs.create({ url: tab.url, active: true }); 128 | 129 | $scope.removeHiddenTab(tab); 130 | }; 131 | 132 | // -------------------------------------------------------------------------------------------------------- 133 | // Events 134 | 135 | // New install 136 | if ($routeParams.event === 'install') { 137 | var alert = $mdDialog 138 | .alert() 139 | .clickOutsideToClose(true) 140 | .title('Greetings') 141 | .textContent('Hello, thank you for installing Open Tabs!') 142 | .ariaLabel('Greetings') 143 | .targetEvent() 144 | .ok('Ok'); 145 | 146 | $mdDialog.show(alert).then(function () { 147 | Analytics.trackEvent('greetings-dialog', 'close'); 148 | 149 | $location.path('/'); 150 | }, function () { 151 | Analytics.trackEvent('greetings-dialog', 'show-form'); 152 | 153 | $location.path('/'); 154 | }); 155 | } 156 | 157 | // New version 158 | if ($routeParams.event === 'update' && $routeParams.version !== undefined) { 159 | $mdToast.show({ 160 | hideDelay: 0, 161 | position: 'top right', 162 | controller: 'ToastNewVersionController', 163 | templateUrl: '../html/toast_new_version.html', 164 | locals: { 165 | version: $routeParams.version 166 | } 167 | }); 168 | } 169 | 170 | }]); 171 | 172 | app.controller('ToastNewVersionController', ['$scope', '$location', '$mdToast', 'version', function ($scope, $location, $mdToast, version) { 173 | $scope.version = version; 174 | 175 | $scope.closeToast = function () { 176 | $mdToast.hide().then(function () { 177 | $location.path('/'); 178 | }); 179 | }; 180 | 181 | $scope.openGitHubReleases = function () { 182 | chrome.tabs.create({ url: 'https://github.com/sylouuu/chrome-open-tabs/releases' }); 183 | 184 | $scope.closeToast(); 185 | }; 186 | }]); 187 | -------------------------------------------------------------------------------- /src/js/options/main.controller.js: -------------------------------------------------------------------------------- 1 | app.controller('MainController', ['$scope', '$mdDialog', '$mdMedia', 'Analytics', function ($scope, $mdDialog, $mdMedia, Analytics) { 2 | 3 | $scope.open_tabs = { 4 | settings: { 5 | enable_new_version_notification: false, 6 | show_browser_action_count: true 7 | }, 8 | hidden_tabs: [] 9 | }; 10 | $scope.search = { query: null }; 11 | $scope.tabs = { 12 | pinned: { code: 'PINNED_TABS', title: 'Pinned tabs', data: [], selected: [] }, 13 | standard: { code: 'STANDARD_TABS', title: 'Standard tabs', data: [], selected: [] }, 14 | hidden: { code: 'HIDDEN_TABS', title: 'Hidden tabs', data: [], selected: [] } 15 | }; 16 | 17 | chrome.storage.local.get('open_tabs', function (items) { 18 | if (items.open_tabs !== undefined) { 19 | $scope.open_tabs = items.open_tabs; 20 | 21 | $scope.tabs.hidden.data = (items.open_tabs.hidden_tabs === undefined) ? [] : items.open_tabs.hidden_tabs; 22 | } 23 | 24 | $scope.$apply(); 25 | }); 26 | 27 | $scope.saveSettings = function (open_tabs) { 28 | chrome.storage.local.set({ open_tabs: open_tabs }); 29 | 30 | chrome.extension.getBackgroundPage().handleBrowserActionBadgeEvents(); 31 | }; 32 | 33 | $scope.loadTabs = function () { 34 | chrome.tabs.query({}, function (tabs) { 35 | $scope.tabs.pinned.data = []; 36 | $scope.tabs.standard.data = []; 37 | 38 | for (var i = 0; i < tabs.length; i++) { 39 | // Exclude options page 40 | if (tabs[i].url !== chrome.extension.getURL('html/options.html')) { 41 | if (tabs[i].pinned === true) { 42 | $scope.tabs.pinned.data.push(tabs[i]); 43 | } else { 44 | $scope.tabs.standard.data.push(tabs[i]); 45 | } 46 | } 47 | } 48 | 49 | $scope.$apply(); 50 | }); 51 | }; 52 | 53 | $scope.loadTabs(); 54 | 55 | $scope.showSettings = function (evt) { 56 | $mdDialog.show({ 57 | controller: 'SettingsModalController', 58 | templateUrl: '../html/settings_modal.html', 59 | targetEvent: evt, 60 | clickOutsideToClose: false, 61 | fullscreen: $mdMedia('xs'), 62 | resolve: { 63 | open_tabs: function () { 64 | return $scope.open_tabs; 65 | } 66 | } 67 | }).then(function (data) { 68 | $scope.saveSettings(data); 69 | 70 | Analytics.trackEvent('settings', 'save'); 71 | }); 72 | }; 73 | 74 | // --------------------------------------------------------------------------------- 75 | // Listeners 76 | 77 | chrome.tabs.onCreated.addListener(function () { 78 | $scope.loadTabs(); 79 | }); 80 | 81 | chrome.tabs.onUpdated.addListener(function () { 82 | $scope.loadTabs(); 83 | }); 84 | 85 | chrome.tabs.onRemoved.addListener(function () { 86 | $scope.loadTabs(); 87 | }); 88 | 89 | chrome.tabs.onReplaced.addListener(function () { 90 | $scope.loadTabs(); 91 | }); 92 | 93 | chrome.tabs.onMoved.addListener(function () { 94 | $scope.loadTabs(); 95 | }); 96 | 97 | chrome.tabs.onDetached.addListener(function () { 98 | $scope.loadTabs(); 99 | }); 100 | 101 | chrome.tabs.onAttached.addListener(function () { 102 | $scope.loadTabs(); 103 | }); 104 | 105 | chrome.tabs.onActivated.addListener(function () { 106 | $scope.loadTabs(); 107 | }); 108 | 109 | }]); 110 | 111 | app.controller('SettingsModalController', ['$scope', '$mdDialog', 'open_tabs', function ($scope, $mdDialog, open_tabs) { 112 | 113 | $scope.open_tabs = open_tabs; 114 | 115 | $scope.closeForm = function () { 116 | $mdDialog.cancel(); 117 | }; 118 | 119 | $scope.save = function (data) { 120 | $mdDialog.hide(data); 121 | }; 122 | 123 | }]); 124 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "JSV@>= 4.0.x": 6 | version "4.0.2" 7 | resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" 8 | 9 | ansi-regex@^2.0.0: 10 | version "2.1.1" 11 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 12 | 13 | ansi-styles@^2.2.1: 14 | version "2.2.1" 15 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 16 | 17 | ansi-styles@~1.0.0: 18 | version "1.0.0" 19 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" 20 | 21 | archy@^1.0.0: 22 | version "1.0.0" 23 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" 24 | 25 | argparse@^1.0.2: 26 | version "1.0.9" 27 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 28 | dependencies: 29 | sprintf-js "~1.0.2" 30 | 31 | arr-diff@^2.0.0: 32 | version "2.0.0" 33 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 34 | dependencies: 35 | arr-flatten "^1.0.1" 36 | 37 | arr-flatten@^1.0.1: 38 | version "1.0.3" 39 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" 40 | 41 | array-differ@^1.0.0: 42 | version "1.0.0" 43 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" 44 | 45 | array-uniq@^1.0.2: 46 | version "1.0.3" 47 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 48 | 49 | array-unique@^0.2.1: 50 | version "0.2.1" 51 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 52 | 53 | async@0.2.x, async@~0.2.9: 54 | version "0.2.10" 55 | resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" 56 | 57 | babel-runtime@^6.9.2: 58 | version "6.23.0" 59 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" 60 | dependencies: 61 | core-js "^2.4.0" 62 | regenerator-runtime "^0.10.0" 63 | 64 | babylon@^6.8.1: 65 | version "6.17.3" 66 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.3.tgz#1327d709950b558f204e5352587fd0290f8d8e48" 67 | 68 | balanced-match@^0.4.1: 69 | version "0.4.2" 70 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 71 | 72 | beeper@^1.0.0: 73 | version "1.1.1" 74 | resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" 75 | 76 | brace-expansion@^1.0.0, brace-expansion@^1.1.7: 77 | version "1.1.7" 78 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" 79 | dependencies: 80 | balanced-match "^0.4.1" 81 | concat-map "0.0.1" 82 | 83 | braces@^1.8.2: 84 | version "1.8.5" 85 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 86 | dependencies: 87 | expand-range "^1.8.1" 88 | preserve "^0.2.0" 89 | repeat-element "^1.1.2" 90 | 91 | chalk@^1.0.0, chalk@^1.1.1, chalk@~1.1.0: 92 | version "1.1.3" 93 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 94 | dependencies: 95 | ansi-styles "^2.2.1" 96 | escape-string-regexp "^1.0.2" 97 | has-ansi "^2.0.0" 98 | strip-ansi "^3.0.0" 99 | supports-color "^2.0.0" 100 | 101 | chalk@~0.4.0: 102 | version "0.4.0" 103 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" 104 | dependencies: 105 | ansi-styles "~1.0.0" 106 | has-color "~0.1.0" 107 | strip-ansi "~0.1.0" 108 | 109 | cli-table@~0.3.1: 110 | version "0.3.1" 111 | resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" 112 | dependencies: 113 | colors "1.0.3" 114 | 115 | cli@~1.0.0: 116 | version "1.0.1" 117 | resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14" 118 | dependencies: 119 | exit "0.1.2" 120 | glob "^7.1.1" 121 | 122 | clone-buffer@^1.0.0: 123 | version "1.0.0" 124 | resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" 125 | 126 | clone-stats@^0.0.1: 127 | version "0.0.1" 128 | resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" 129 | 130 | clone-stats@^1.0.0: 131 | version "1.0.0" 132 | resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" 133 | 134 | clone@^0.2.0: 135 | version "0.2.0" 136 | resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" 137 | 138 | clone@^1.0.0, clone@^1.0.2: 139 | version "1.0.2" 140 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" 141 | 142 | cloneable-readable@^1.0.0: 143 | version "1.0.0" 144 | resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" 145 | dependencies: 146 | inherits "^2.0.1" 147 | process-nextick-args "^1.0.6" 148 | through2 "^2.0.1" 149 | 150 | colors@0.6.x: 151 | version "0.6.2" 152 | resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" 153 | 154 | colors@1.0.3: 155 | version "1.0.3" 156 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" 157 | 158 | commander@~2.9.0: 159 | version "2.9.0" 160 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 161 | dependencies: 162 | graceful-readlink ">= 1.0.0" 163 | 164 | comment-parser@^0.3.1: 165 | version "0.3.1" 166 | resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.3.1.tgz#fd657aac8c1492d308c9a6100fc9b49d2435aba1" 167 | dependencies: 168 | readable-stream "^2.0.4" 169 | 170 | concat-map@0.0.1: 171 | version "0.0.1" 172 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 173 | 174 | concat-with-sourcemaps@^1.0.0: 175 | version "1.0.4" 176 | resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz#f55b3be2aeb47601b10a2d5259ccfb70fd2f1dd6" 177 | dependencies: 178 | source-map "^0.5.1" 179 | 180 | console-browserify@1.1.x: 181 | version "1.1.0" 182 | resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" 183 | dependencies: 184 | date-now "^0.1.4" 185 | 186 | core-js@^2.4.0: 187 | version "2.4.1" 188 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" 189 | 190 | core-util-is@~1.0.0: 191 | version "1.0.2" 192 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 193 | 194 | cst@^0.4.3: 195 | version "0.4.9" 196 | resolved "https://registry.yarnpkg.com/cst/-/cst-0.4.9.tgz#51af14213bf5f8e8e715966ac645e1e2a56c6834" 197 | dependencies: 198 | babel-runtime "^6.9.2" 199 | babylon "^6.8.1" 200 | source-map-support "^0.4.0" 201 | 202 | cycle@1.0.x: 203 | version "1.0.3" 204 | resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" 205 | 206 | date-now@^0.1.4: 207 | version "0.1.4" 208 | resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" 209 | 210 | dateformat@^2.0.0: 211 | version "2.0.0" 212 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" 213 | 214 | deep-equal@*: 215 | version "1.0.1" 216 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 217 | 218 | defaults@^1.0.0: 219 | version "1.0.3" 220 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" 221 | dependencies: 222 | clone "^1.0.2" 223 | 224 | deprecated@^0.0.1: 225 | version "0.0.1" 226 | resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" 227 | 228 | detect-file@^0.1.0: 229 | version "0.1.0" 230 | resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" 231 | dependencies: 232 | fs-exists-sync "^0.1.0" 233 | 234 | dom-serializer@0: 235 | version "0.1.0" 236 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" 237 | dependencies: 238 | domelementtype "~1.1.1" 239 | entities "~1.1.1" 240 | 241 | domelementtype@1: 242 | version "1.3.0" 243 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" 244 | 245 | domelementtype@~1.1.1: 246 | version "1.1.3" 247 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" 248 | 249 | domhandler@2.3: 250 | version "2.3.0" 251 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" 252 | dependencies: 253 | domelementtype "1" 254 | 255 | domutils@1.5: 256 | version "1.5.1" 257 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" 258 | dependencies: 259 | dom-serializer "0" 260 | domelementtype "1" 261 | 262 | duplexer2@0.0.2: 263 | version "0.0.2" 264 | resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" 265 | dependencies: 266 | readable-stream "~1.1.9" 267 | 268 | end-of-stream@~0.1.5: 269 | version "0.1.5" 270 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" 271 | dependencies: 272 | once "~1.3.0" 273 | 274 | entities@1.0: 275 | version "1.0.0" 276 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" 277 | 278 | entities@~1.1.1: 279 | version "1.1.1" 280 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" 281 | 282 | escape-string-regexp@^1.0.2: 283 | version "1.0.5" 284 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 285 | 286 | esprima@^2.6.0: 287 | version "2.7.3" 288 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" 289 | 290 | estraverse@^4.1.0: 291 | version "4.2.0" 292 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" 293 | 294 | exit@0.1.2, exit@0.1.x, exit@~0.1.2: 295 | version "0.1.2" 296 | resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" 297 | 298 | expand-brackets@^0.1.4: 299 | version "0.1.5" 300 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 301 | dependencies: 302 | is-posix-bracket "^0.1.0" 303 | 304 | expand-range@^1.8.1: 305 | version "1.8.2" 306 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 307 | dependencies: 308 | fill-range "^2.1.0" 309 | 310 | expand-tilde@^1.2.1, expand-tilde@^1.2.2: 311 | version "1.2.2" 312 | resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" 313 | dependencies: 314 | os-homedir "^1.0.1" 315 | 316 | extend@^3.0.0: 317 | version "3.0.1" 318 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 319 | 320 | extglob@^0.3.1: 321 | version "0.3.2" 322 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 323 | dependencies: 324 | is-extglob "^1.0.0" 325 | 326 | eyes@0.1.x: 327 | version "0.1.8" 328 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 329 | 330 | fancy-log@^1.1.0: 331 | version "1.3.0" 332 | resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" 333 | dependencies: 334 | chalk "^1.1.1" 335 | time-stamp "^1.0.0" 336 | 337 | filename-regex@^2.0.0: 338 | version "2.0.1" 339 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 340 | 341 | fill-range@^2.1.0: 342 | version "2.2.3" 343 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 344 | dependencies: 345 | is-number "^2.1.0" 346 | isobject "^2.0.0" 347 | randomatic "^1.1.3" 348 | repeat-element "^1.1.2" 349 | repeat-string "^1.5.2" 350 | 351 | find-index@^0.1.1: 352 | version "0.1.1" 353 | resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" 354 | 355 | findup-sync@^0.4.2: 356 | version "0.4.3" 357 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" 358 | dependencies: 359 | detect-file "^0.1.0" 360 | is-glob "^2.0.1" 361 | micromatch "^2.3.7" 362 | resolve-dir "^0.1.0" 363 | 364 | fined@^1.0.1: 365 | version "1.0.2" 366 | resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" 367 | dependencies: 368 | expand-tilde "^1.2.1" 369 | lodash.assignwith "^4.0.7" 370 | lodash.isempty "^4.2.1" 371 | lodash.isplainobject "^4.0.4" 372 | lodash.isstring "^4.0.1" 373 | lodash.pick "^4.2.1" 374 | parse-filepath "^1.0.1" 375 | 376 | first-chunk-stream@^1.0.0: 377 | version "1.0.0" 378 | resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" 379 | 380 | flagged-respawn@^0.3.2: 381 | version "0.3.2" 382 | resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" 383 | 384 | for-in@^1.0.1: 385 | version "1.0.2" 386 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 387 | 388 | for-own@^0.1.4: 389 | version "0.1.5" 390 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 391 | dependencies: 392 | for-in "^1.0.1" 393 | 394 | fs-exists-sync@^0.1.0: 395 | version "0.1.0" 396 | resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" 397 | 398 | fs.realpath@^1.0.0: 399 | version "1.0.0" 400 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 401 | 402 | gaze@^0.5.1: 403 | version "0.5.2" 404 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" 405 | dependencies: 406 | globule "~0.1.0" 407 | 408 | glob-base@^0.3.0: 409 | version "0.3.0" 410 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 411 | dependencies: 412 | glob-parent "^2.0.0" 413 | is-glob "^2.0.0" 414 | 415 | glob-parent@^2.0.0: 416 | version "2.0.0" 417 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 418 | dependencies: 419 | is-glob "^2.0.0" 420 | 421 | glob-stream@^3.1.5: 422 | version "3.1.18" 423 | resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" 424 | dependencies: 425 | glob "^4.3.1" 426 | glob2base "^0.0.12" 427 | minimatch "^2.0.1" 428 | ordered-read-streams "^0.1.0" 429 | through2 "^0.6.1" 430 | unique-stream "^1.0.0" 431 | 432 | glob-watcher@^0.0.6: 433 | version "0.0.6" 434 | resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" 435 | dependencies: 436 | gaze "^0.5.1" 437 | 438 | glob2base@^0.0.12: 439 | version "0.0.12" 440 | resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" 441 | dependencies: 442 | find-index "^0.1.1" 443 | 444 | glob@^4.3.1: 445 | version "4.5.3" 446 | resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" 447 | dependencies: 448 | inflight "^1.0.4" 449 | inherits "2" 450 | minimatch "^2.0.1" 451 | once "^1.3.0" 452 | 453 | glob@^5.0.1: 454 | version "5.0.15" 455 | resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" 456 | dependencies: 457 | inflight "^1.0.4" 458 | inherits "2" 459 | minimatch "2 || 3" 460 | once "^1.3.0" 461 | path-is-absolute "^1.0.0" 462 | 463 | glob@^7.0.5, glob@^7.1.1: 464 | version "7.1.2" 465 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 466 | dependencies: 467 | fs.realpath "^1.0.0" 468 | inflight "^1.0.4" 469 | inherits "2" 470 | minimatch "^3.0.4" 471 | once "^1.3.0" 472 | path-is-absolute "^1.0.0" 473 | 474 | glob@~3.1.21: 475 | version "3.1.21" 476 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" 477 | dependencies: 478 | graceful-fs "~1.2.0" 479 | inherits "1" 480 | minimatch "~0.2.11" 481 | 482 | global-modules@^0.2.3: 483 | version "0.2.3" 484 | resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" 485 | dependencies: 486 | global-prefix "^0.1.4" 487 | is-windows "^0.2.0" 488 | 489 | global-prefix@^0.1.4: 490 | version "0.1.5" 491 | resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" 492 | dependencies: 493 | homedir-polyfill "^1.0.0" 494 | ini "^1.3.4" 495 | is-windows "^0.2.0" 496 | which "^1.2.12" 497 | 498 | globule@~0.1.0: 499 | version "0.1.0" 500 | resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" 501 | dependencies: 502 | glob "~3.1.21" 503 | lodash "~1.0.1" 504 | minimatch "~0.2.11" 505 | 506 | glogg@^1.0.0: 507 | version "1.0.0" 508 | resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" 509 | dependencies: 510 | sparkles "^1.0.0" 511 | 512 | graceful-fs@^3.0.0: 513 | version "3.0.11" 514 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" 515 | dependencies: 516 | natives "^1.1.0" 517 | 518 | graceful-fs@~1.2.0: 519 | version "1.2.3" 520 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" 521 | 522 | "graceful-readlink@>= 1.0.0": 523 | version "1.0.1" 524 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 525 | 526 | gulp-concat@~2.6.0: 527 | version "2.6.1" 528 | resolved "https://registry.yarnpkg.com/gulp-concat/-/gulp-concat-2.6.1.tgz#633d16c95d88504628ad02665663cee5a4793353" 529 | dependencies: 530 | concat-with-sourcemaps "^1.0.0" 531 | through2 "^2.0.0" 532 | vinyl "^2.0.0" 533 | 534 | gulp-jscs@~4.0.0: 535 | version "4.0.0" 536 | resolved "https://registry.yarnpkg.com/gulp-jscs/-/gulp-jscs-4.0.0.tgz#4db2d63f9207ce4a54b5b26790e318e346b76a85" 537 | dependencies: 538 | gulp-util "^3.0.4" 539 | jscs "^3.0.4" 540 | through2 "^2.0.0" 541 | tildify "^1.0.0" 542 | 543 | gulp-jshint@~2.0.0: 544 | version "2.0.4" 545 | resolved "https://registry.yarnpkg.com/gulp-jshint/-/gulp-jshint-2.0.4.tgz#f382b18564b1072def0c9aaf753c146dadb4f0e8" 546 | dependencies: 547 | gulp-util "^3.0.0" 548 | lodash "^4.12.0" 549 | minimatch "^3.0.3" 550 | rcloader "^0.2.2" 551 | through2 "^2.0.0" 552 | 553 | gulp-util@^3.0.0, gulp-util@^3.0.4: 554 | version "3.0.8" 555 | resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" 556 | dependencies: 557 | array-differ "^1.0.0" 558 | array-uniq "^1.0.2" 559 | beeper "^1.0.0" 560 | chalk "^1.0.0" 561 | dateformat "^2.0.0" 562 | fancy-log "^1.1.0" 563 | gulplog "^1.0.0" 564 | has-gulplog "^0.1.0" 565 | lodash._reescape "^3.0.0" 566 | lodash._reevaluate "^3.0.0" 567 | lodash._reinterpolate "^3.0.0" 568 | lodash.template "^3.0.0" 569 | minimist "^1.1.0" 570 | multipipe "^0.1.2" 571 | object-assign "^3.0.0" 572 | replace-ext "0.0.1" 573 | through2 "^2.0.0" 574 | vinyl "^0.5.0" 575 | 576 | gulp@~3.9.0: 577 | version "3.9.1" 578 | resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" 579 | dependencies: 580 | archy "^1.0.0" 581 | chalk "^1.0.0" 582 | deprecated "^0.0.1" 583 | gulp-util "^3.0.0" 584 | interpret "^1.0.0" 585 | liftoff "^2.1.0" 586 | minimist "^1.1.0" 587 | orchestrator "^0.3.0" 588 | pretty-hrtime "^1.0.0" 589 | semver "^4.1.0" 590 | tildify "^1.0.0" 591 | v8flags "^2.0.2" 592 | vinyl-fs "^0.3.0" 593 | 594 | gulplog@^1.0.0: 595 | version "1.0.0" 596 | resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" 597 | dependencies: 598 | glogg "^1.0.0" 599 | 600 | has-ansi@^2.0.0: 601 | version "2.0.0" 602 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 603 | dependencies: 604 | ansi-regex "^2.0.0" 605 | 606 | has-color@~0.1.0: 607 | version "0.1.7" 608 | resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" 609 | 610 | has-gulplog@^0.1.0: 611 | version "0.1.0" 612 | resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" 613 | dependencies: 614 | sparkles "^1.0.0" 615 | 616 | homedir-polyfill@^1.0.0: 617 | version "1.0.1" 618 | resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" 619 | dependencies: 620 | parse-passwd "^1.0.0" 621 | 622 | htmlparser2@3.8.3, htmlparser2@3.8.x: 623 | version "3.8.3" 624 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" 625 | dependencies: 626 | domelementtype "1" 627 | domhandler "2.3" 628 | domutils "1.5" 629 | entities "1.0" 630 | readable-stream "1.1" 631 | 632 | i@0.3.x: 633 | version "0.3.5" 634 | resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5" 635 | 636 | inflight@^1.0.4: 637 | version "1.0.6" 638 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 639 | dependencies: 640 | once "^1.3.0" 641 | wrappy "1" 642 | 643 | inherit@^2.2.2: 644 | version "2.2.6" 645 | resolved "https://registry.yarnpkg.com/inherit/-/inherit-2.2.6.tgz#f1614b06c8544e8128e4229c86347db73ad9788d" 646 | 647 | inherits@1: 648 | version "1.0.2" 649 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" 650 | 651 | inherits@2, inherits@^2.0.1, inherits@~2.0.1: 652 | version "2.0.3" 653 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 654 | 655 | ini@^1.3.4: 656 | version "1.3.4" 657 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" 658 | 659 | interpret@^1.0.0: 660 | version "1.0.3" 661 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" 662 | 663 | is-absolute@^0.2.3: 664 | version "0.2.6" 665 | resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" 666 | dependencies: 667 | is-relative "^0.2.1" 668 | is-windows "^0.2.0" 669 | 670 | is-buffer@^1.1.5: 671 | version "1.1.5" 672 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 673 | 674 | is-dotfile@^1.0.0: 675 | version "1.0.3" 676 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 677 | 678 | is-equal-shallow@^0.1.3: 679 | version "0.1.3" 680 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 681 | dependencies: 682 | is-primitive "^2.0.0" 683 | 684 | is-extendable@^0.1.1: 685 | version "0.1.1" 686 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 687 | 688 | is-extglob@^1.0.0: 689 | version "1.0.0" 690 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 691 | 692 | is-glob@^2.0.0, is-glob@^2.0.1: 693 | version "2.0.1" 694 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 695 | dependencies: 696 | is-extglob "^1.0.0" 697 | 698 | is-number@^2.1.0: 699 | version "2.1.0" 700 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 701 | dependencies: 702 | kind-of "^3.0.2" 703 | 704 | is-number@^3.0.0: 705 | version "3.0.0" 706 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" 707 | dependencies: 708 | kind-of "^3.0.2" 709 | 710 | is-posix-bracket@^0.1.0: 711 | version "0.1.1" 712 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 713 | 714 | is-primitive@^2.0.0: 715 | version "2.0.0" 716 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 717 | 718 | is-relative@^0.2.1: 719 | version "0.2.1" 720 | resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" 721 | dependencies: 722 | is-unc-path "^0.1.1" 723 | 724 | is-stream@^1.1.0: 725 | version "1.1.0" 726 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 727 | 728 | is-unc-path@^0.1.1: 729 | version "0.1.2" 730 | resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" 731 | dependencies: 732 | unc-path-regex "^0.1.0" 733 | 734 | is-utf8@^0.2.0: 735 | version "0.2.1" 736 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 737 | 738 | is-windows@^0.2.0: 739 | version "0.2.0" 740 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" 741 | 742 | isarray@0.0.1: 743 | version "0.0.1" 744 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 745 | 746 | isarray@1.0.0, isarray@~1.0.0: 747 | version "1.0.0" 748 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 749 | 750 | isexe@^2.0.0: 751 | version "2.0.0" 752 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 753 | 754 | isobject@^2.0.0: 755 | version "2.1.0" 756 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 757 | dependencies: 758 | isarray "1.0.0" 759 | 760 | isstream@0.1.x: 761 | version "0.1.2" 762 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 763 | 764 | js-yaml@~3.4.0: 765 | version "3.4.6" 766 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.4.6.tgz#6be1b23f6249f53d293370fd4d1aaa63ce1b4eb0" 767 | dependencies: 768 | argparse "^1.0.2" 769 | esprima "^2.6.0" 770 | inherit "^2.2.2" 771 | 772 | jscs-jsdoc@^2.0.0: 773 | version "2.0.0" 774 | resolved "https://registry.yarnpkg.com/jscs-jsdoc/-/jscs-jsdoc-2.0.0.tgz#f53ebce029aa3125bd88290ba50d64d4510a4871" 775 | dependencies: 776 | comment-parser "^0.3.1" 777 | jsdoctypeparser "~1.2.0" 778 | 779 | jscs-preset-wikimedia@~1.0.0: 780 | version "1.0.0" 781 | resolved "https://registry.yarnpkg.com/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.0.tgz#fff563342038fc2e8826b7bb7309c3ae3406fc7e" 782 | 783 | jscs@^3.0.4: 784 | version "3.0.7" 785 | resolved "https://registry.yarnpkg.com/jscs/-/jscs-3.0.7.tgz#7141b4dff5b86e32d0e99d764b836767c30d201a" 786 | dependencies: 787 | chalk "~1.1.0" 788 | cli-table "~0.3.1" 789 | commander "~2.9.0" 790 | cst "^0.4.3" 791 | estraverse "^4.1.0" 792 | exit "~0.1.2" 793 | glob "^5.0.1" 794 | htmlparser2 "3.8.3" 795 | js-yaml "~3.4.0" 796 | jscs-jsdoc "^2.0.0" 797 | jscs-preset-wikimedia "~1.0.0" 798 | jsonlint "~1.6.2" 799 | lodash "~3.10.0" 800 | minimatch "~3.0.0" 801 | natural-compare "~1.2.2" 802 | pathval "~0.1.1" 803 | prompt "~0.2.14" 804 | reserved-words "^0.1.1" 805 | resolve "^1.1.6" 806 | strip-bom "^2.0.0" 807 | strip-json-comments "~1.0.2" 808 | to-double-quotes "^2.0.0" 809 | to-single-quotes "^2.0.0" 810 | vow "~0.4.8" 811 | vow-fs "~0.3.4" 812 | xmlbuilder "^3.1.0" 813 | 814 | jsdoctypeparser@~1.2.0: 815 | version "1.2.0" 816 | resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz#e7dedc153a11849ffc5141144ae86a7ef0c25392" 817 | dependencies: 818 | lodash "^3.7.0" 819 | 820 | jshint@^2.9.2: 821 | version "2.9.4" 822 | resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.4.tgz#5e3ba97848d5290273db514aee47fe24cf592934" 823 | dependencies: 824 | cli "~1.0.0" 825 | console-browserify "1.1.x" 826 | exit "0.1.x" 827 | htmlparser2 "3.8.x" 828 | lodash "3.7.x" 829 | minimatch "~3.0.2" 830 | shelljs "0.3.x" 831 | strip-json-comments "1.0.x" 832 | 833 | jsonlint@~1.6.2: 834 | version "1.6.2" 835 | resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.2.tgz#5737045085f55eb455c68b1ff4ebc01bd50e8830" 836 | dependencies: 837 | JSV ">= 4.0.x" 838 | nomnom ">= 1.5.x" 839 | 840 | kind-of@^3.0.2: 841 | version "3.2.2" 842 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 843 | dependencies: 844 | is-buffer "^1.1.5" 845 | 846 | kind-of@^4.0.0: 847 | version "4.0.0" 848 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" 849 | dependencies: 850 | is-buffer "^1.1.5" 851 | 852 | liftoff@^2.1.0: 853 | version "2.3.0" 854 | resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" 855 | dependencies: 856 | extend "^3.0.0" 857 | findup-sync "^0.4.2" 858 | fined "^1.0.1" 859 | flagged-respawn "^0.3.2" 860 | lodash.isplainobject "^4.0.4" 861 | lodash.isstring "^4.0.1" 862 | lodash.mapvalues "^4.4.0" 863 | rechoir "^0.6.2" 864 | resolve "^1.1.7" 865 | 866 | lodash._basecopy@^3.0.0: 867 | version "3.0.1" 868 | resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" 869 | 870 | lodash._basetostring@^3.0.0: 871 | version "3.0.1" 872 | resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" 873 | 874 | lodash._basevalues@^3.0.0: 875 | version "3.0.0" 876 | resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" 877 | 878 | lodash._getnative@^3.0.0: 879 | version "3.9.1" 880 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" 881 | 882 | lodash._isiterateecall@^3.0.0: 883 | version "3.0.9" 884 | resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" 885 | 886 | lodash._reescape@^3.0.0: 887 | version "3.0.0" 888 | resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" 889 | 890 | lodash._reevaluate@^3.0.0: 891 | version "3.0.0" 892 | resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" 893 | 894 | lodash._reinterpolate@^3.0.0: 895 | version "3.0.0" 896 | resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" 897 | 898 | lodash._root@^3.0.0: 899 | version "3.0.1" 900 | resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" 901 | 902 | lodash.assign@^4.2.0: 903 | version "4.2.0" 904 | resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" 905 | 906 | lodash.assignwith@^4.0.7: 907 | version "4.2.0" 908 | resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" 909 | 910 | lodash.clonedeep@^4.3.2: 911 | version "4.5.0" 912 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 913 | 914 | lodash.escape@^3.0.0: 915 | version "3.2.0" 916 | resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" 917 | dependencies: 918 | lodash._root "^3.0.0" 919 | 920 | lodash.isarguments@^3.0.0: 921 | version "3.1.0" 922 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" 923 | 924 | lodash.isarray@^3.0.0: 925 | version "3.0.4" 926 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" 927 | 928 | lodash.isempty@^4.2.1: 929 | version "4.4.0" 930 | resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" 931 | 932 | lodash.isobject@^3.0.2: 933 | version "3.0.2" 934 | resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" 935 | 936 | lodash.isplainobject@^4.0.4: 937 | version "4.0.6" 938 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 939 | 940 | lodash.isstring@^4.0.1: 941 | version "4.0.1" 942 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 943 | 944 | lodash.keys@^3.0.0: 945 | version "3.1.2" 946 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" 947 | dependencies: 948 | lodash._getnative "^3.0.0" 949 | lodash.isarguments "^3.0.0" 950 | lodash.isarray "^3.0.0" 951 | 952 | lodash.mapvalues@^4.4.0: 953 | version "4.6.0" 954 | resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" 955 | 956 | lodash.merge@^4.6.0: 957 | version "4.6.0" 958 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" 959 | 960 | lodash.pick@^4.2.1: 961 | version "4.4.0" 962 | resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" 963 | 964 | lodash.restparam@^3.0.0: 965 | version "3.6.1" 966 | resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" 967 | 968 | lodash.template@^3.0.0: 969 | version "3.6.2" 970 | resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" 971 | dependencies: 972 | lodash._basecopy "^3.0.0" 973 | lodash._basetostring "^3.0.0" 974 | lodash._basevalues "^3.0.0" 975 | lodash._isiterateecall "^3.0.0" 976 | lodash._reinterpolate "^3.0.0" 977 | lodash.escape "^3.0.0" 978 | lodash.keys "^3.0.0" 979 | lodash.restparam "^3.0.0" 980 | lodash.templatesettings "^3.0.0" 981 | 982 | lodash.templatesettings@^3.0.0: 983 | version "3.1.1" 984 | resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" 985 | dependencies: 986 | lodash._reinterpolate "^3.0.0" 987 | lodash.escape "^3.0.0" 988 | 989 | lodash@3.7.x: 990 | version "3.7.0" 991 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.7.0.tgz#3678bd8ab995057c07ade836ed2ef087da811d45" 992 | 993 | lodash@^3.5.0, lodash@^3.7.0, lodash@~3.10.0: 994 | version "3.10.1" 995 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" 996 | 997 | lodash@^4.12.0: 998 | version "4.17.4" 999 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 1000 | 1001 | lodash@~1.0.1: 1002 | version "1.0.2" 1003 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" 1004 | 1005 | lru-cache@2: 1006 | version "2.7.3" 1007 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" 1008 | 1009 | map-cache@^0.2.0: 1010 | version "0.2.2" 1011 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" 1012 | 1013 | micromatch@^2.3.7: 1014 | version "2.3.11" 1015 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 1016 | dependencies: 1017 | arr-diff "^2.0.0" 1018 | array-unique "^0.2.1" 1019 | braces "^1.8.2" 1020 | expand-brackets "^0.1.4" 1021 | extglob "^0.3.1" 1022 | filename-regex "^2.0.0" 1023 | is-extglob "^1.0.0" 1024 | is-glob "^2.0.1" 1025 | kind-of "^3.0.2" 1026 | normalize-path "^2.0.1" 1027 | object.omit "^2.0.0" 1028 | parse-glob "^3.0.4" 1029 | regex-cache "^0.4.2" 1030 | 1031 | "minimatch@2 || 3", minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.0, minimatch@~3.0.2: 1032 | version "3.0.4" 1033 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1034 | dependencies: 1035 | brace-expansion "^1.1.7" 1036 | 1037 | minimatch@^2.0.1: 1038 | version "2.0.10" 1039 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" 1040 | dependencies: 1041 | brace-expansion "^1.0.0" 1042 | 1043 | minimatch@~0.2.11: 1044 | version "0.2.14" 1045 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" 1046 | dependencies: 1047 | lru-cache "2" 1048 | sigmund "~1.0.0" 1049 | 1050 | minimist@0.0.8: 1051 | version "0.0.8" 1052 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1053 | 1054 | minimist@^1.1.0: 1055 | version "1.2.0" 1056 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 1057 | 1058 | mkdirp@0.x.x, mkdirp@^0.5.0: 1059 | version "0.5.1" 1060 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1061 | dependencies: 1062 | minimist "0.0.8" 1063 | 1064 | multipipe@^0.1.2: 1065 | version "0.1.2" 1066 | resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" 1067 | dependencies: 1068 | duplexer2 "0.0.2" 1069 | 1070 | mute-stream@~0.0.4: 1071 | version "0.0.7" 1072 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" 1073 | 1074 | natives@^1.1.0: 1075 | version "1.1.0" 1076 | resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" 1077 | 1078 | natural-compare@~1.2.2: 1079 | version "1.2.2" 1080 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.2.2.tgz#1f96d60e3141cac1b6d05653ce0daeac763af6aa" 1081 | 1082 | ncp@0.4.x: 1083 | version "0.4.2" 1084 | resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574" 1085 | 1086 | "nomnom@>= 1.5.x": 1087 | version "1.8.1" 1088 | resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" 1089 | dependencies: 1090 | chalk "~0.4.0" 1091 | underscore "~1.6.0" 1092 | 1093 | normalize-path@^2.0.1: 1094 | version "2.1.1" 1095 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 1096 | dependencies: 1097 | remove-trailing-separator "^1.0.1" 1098 | 1099 | object-assign@^3.0.0: 1100 | version "3.0.0" 1101 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" 1102 | 1103 | object.omit@^2.0.0: 1104 | version "2.0.1" 1105 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 1106 | dependencies: 1107 | for-own "^0.1.4" 1108 | is-extendable "^0.1.1" 1109 | 1110 | once@^1.3.0: 1111 | version "1.4.0" 1112 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1113 | dependencies: 1114 | wrappy "1" 1115 | 1116 | once@~1.3.0: 1117 | version "1.3.3" 1118 | resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" 1119 | dependencies: 1120 | wrappy "1" 1121 | 1122 | orchestrator@^0.3.0: 1123 | version "0.3.8" 1124 | resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" 1125 | dependencies: 1126 | end-of-stream "~0.1.5" 1127 | sequencify "~0.0.7" 1128 | stream-consume "~0.1.0" 1129 | 1130 | ordered-read-streams@^0.1.0: 1131 | version "0.1.0" 1132 | resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" 1133 | 1134 | os-homedir@^1.0.0, os-homedir@^1.0.1: 1135 | version "1.0.2" 1136 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1137 | 1138 | parse-filepath@^1.0.1: 1139 | version "1.0.1" 1140 | resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" 1141 | dependencies: 1142 | is-absolute "^0.2.3" 1143 | map-cache "^0.2.0" 1144 | path-root "^0.1.1" 1145 | 1146 | parse-glob@^3.0.4: 1147 | version "3.0.4" 1148 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 1149 | dependencies: 1150 | glob-base "^0.3.0" 1151 | is-dotfile "^1.0.0" 1152 | is-extglob "^1.0.0" 1153 | is-glob "^2.0.0" 1154 | 1155 | parse-passwd@^1.0.0: 1156 | version "1.0.0" 1157 | resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" 1158 | 1159 | path-is-absolute@^1.0.0: 1160 | version "1.0.1" 1161 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1162 | 1163 | path-parse@^1.0.5: 1164 | version "1.0.5" 1165 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 1166 | 1167 | path-root-regex@^0.1.0: 1168 | version "0.1.2" 1169 | resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" 1170 | 1171 | path-root@^0.1.1: 1172 | version "0.1.1" 1173 | resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" 1174 | dependencies: 1175 | path-root-regex "^0.1.0" 1176 | 1177 | pathval@~0.1.1: 1178 | version "0.1.1" 1179 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-0.1.1.tgz#08f911cdca9cce5942880da7817bc0b723b66d82" 1180 | 1181 | pkginfo@0.3.x: 1182 | version "0.3.1" 1183 | resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" 1184 | 1185 | pkginfo@0.x.x: 1186 | version "0.4.0" 1187 | resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" 1188 | 1189 | preserve@^0.2.0: 1190 | version "0.2.0" 1191 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 1192 | 1193 | pretty-hrtime@^1.0.0: 1194 | version "1.0.3" 1195 | resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" 1196 | 1197 | process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: 1198 | version "1.0.7" 1199 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 1200 | 1201 | prompt@~0.2.14: 1202 | version "0.2.14" 1203 | resolved "https://registry.yarnpkg.com/prompt/-/prompt-0.2.14.tgz#57754f64f543fd7b0845707c818ece618f05ffdc" 1204 | dependencies: 1205 | pkginfo "0.x.x" 1206 | read "1.0.x" 1207 | revalidator "0.1.x" 1208 | utile "0.2.x" 1209 | winston "0.8.x" 1210 | 1211 | randomatic@^1.1.3: 1212 | version "1.1.7" 1213 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" 1214 | dependencies: 1215 | is-number "^3.0.0" 1216 | kind-of "^4.0.0" 1217 | 1218 | rcfinder@^0.1.6: 1219 | version "0.1.9" 1220 | resolved "https://registry.yarnpkg.com/rcfinder/-/rcfinder-0.1.9.tgz#f3e80f387ddf9ae80ae30a4100329642eae81115" 1221 | dependencies: 1222 | lodash.clonedeep "^4.3.2" 1223 | 1224 | rcloader@^0.2.2: 1225 | version "0.2.2" 1226 | resolved "https://registry.yarnpkg.com/rcloader/-/rcloader-0.2.2.tgz#58d2298b462d0b9bfd2133d2a1ec74fbd705c717" 1227 | dependencies: 1228 | lodash.assign "^4.2.0" 1229 | lodash.isobject "^3.0.2" 1230 | lodash.merge "^4.6.0" 1231 | rcfinder "^0.1.6" 1232 | 1233 | read@1.0.x: 1234 | version "1.0.7" 1235 | resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" 1236 | dependencies: 1237 | mute-stream "~0.0.4" 1238 | 1239 | readable-stream@1.1, readable-stream@~1.1.9: 1240 | version "1.1.13" 1241 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" 1242 | dependencies: 1243 | core-util-is "~1.0.0" 1244 | inherits "~2.0.1" 1245 | isarray "0.0.1" 1246 | string_decoder "~0.10.x" 1247 | 1248 | "readable-stream@>=1.0.33-1 <1.1.0-0": 1249 | version "1.0.34" 1250 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" 1251 | dependencies: 1252 | core-util-is "~1.0.0" 1253 | inherits "~2.0.1" 1254 | isarray "0.0.1" 1255 | string_decoder "~0.10.x" 1256 | 1257 | readable-stream@^2.0.4, readable-stream@^2.1.5: 1258 | version "2.2.11" 1259 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" 1260 | dependencies: 1261 | core-util-is "~1.0.0" 1262 | inherits "~2.0.1" 1263 | isarray "~1.0.0" 1264 | process-nextick-args "~1.0.6" 1265 | safe-buffer "~5.0.1" 1266 | string_decoder "~1.0.0" 1267 | util-deprecate "~1.0.1" 1268 | 1269 | rechoir@^0.6.2: 1270 | version "0.6.2" 1271 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 1272 | dependencies: 1273 | resolve "^1.1.6" 1274 | 1275 | regenerator-runtime@^0.10.0: 1276 | version "0.10.5" 1277 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" 1278 | 1279 | regex-cache@^0.4.2: 1280 | version "0.4.3" 1281 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" 1282 | dependencies: 1283 | is-equal-shallow "^0.1.3" 1284 | is-primitive "^2.0.0" 1285 | 1286 | remove-trailing-separator@^1.0.1: 1287 | version "1.0.2" 1288 | resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" 1289 | 1290 | repeat-element@^1.1.2: 1291 | version "1.1.2" 1292 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 1293 | 1294 | repeat-string@^1.5.2: 1295 | version "1.6.1" 1296 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 1297 | 1298 | replace-ext@0.0.1: 1299 | version "0.0.1" 1300 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" 1301 | 1302 | replace-ext@^1.0.0: 1303 | version "1.0.0" 1304 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" 1305 | 1306 | reserved-words@^0.1.1: 1307 | version "0.1.1" 1308 | resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.1.tgz#6f7c15e5e5614c50da961630da46addc87c0cef2" 1309 | 1310 | resolve-dir@^0.1.0: 1311 | version "0.1.1" 1312 | resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" 1313 | dependencies: 1314 | expand-tilde "^1.2.2" 1315 | global-modules "^0.2.3" 1316 | 1317 | resolve@^1.1.6, resolve@^1.1.7: 1318 | version "1.3.3" 1319 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" 1320 | dependencies: 1321 | path-parse "^1.0.5" 1322 | 1323 | revalidator@0.1.x: 1324 | version "0.1.8" 1325 | resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" 1326 | 1327 | rimraf@2.x.x: 1328 | version "2.6.1" 1329 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" 1330 | dependencies: 1331 | glob "^7.0.5" 1332 | 1333 | safe-buffer@~5.0.1: 1334 | version "5.0.1" 1335 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" 1336 | 1337 | semver@^4.1.0: 1338 | version "4.3.6" 1339 | resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" 1340 | 1341 | sequencify@~0.0.7: 1342 | version "0.0.7" 1343 | resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" 1344 | 1345 | shelljs@0.3.x: 1346 | version "0.3.0" 1347 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" 1348 | 1349 | sigmund@~1.0.0: 1350 | version "1.0.1" 1351 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" 1352 | 1353 | source-map-support@^0.4.0: 1354 | version "0.4.15" 1355 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" 1356 | dependencies: 1357 | source-map "^0.5.6" 1358 | 1359 | source-map@^0.5.1, source-map@^0.5.6: 1360 | version "0.5.6" 1361 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" 1362 | 1363 | sparkles@^1.0.0: 1364 | version "1.0.0" 1365 | resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" 1366 | 1367 | sprintf-js@~1.0.2: 1368 | version "1.0.3" 1369 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1370 | 1371 | stack-trace@0.0.x: 1372 | version "0.0.10" 1373 | resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" 1374 | 1375 | stream-consume@~0.1.0: 1376 | version "0.1.0" 1377 | resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" 1378 | 1379 | string_decoder@~0.10.x: 1380 | version "0.10.31" 1381 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1382 | 1383 | string_decoder@~1.0.0: 1384 | version "1.0.2" 1385 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" 1386 | dependencies: 1387 | safe-buffer "~5.0.1" 1388 | 1389 | strip-ansi@^3.0.0: 1390 | version "3.0.1" 1391 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1392 | dependencies: 1393 | ansi-regex "^2.0.0" 1394 | 1395 | strip-ansi@~0.1.0: 1396 | version "0.1.1" 1397 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" 1398 | 1399 | strip-bom@^1.0.0: 1400 | version "1.0.0" 1401 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" 1402 | dependencies: 1403 | first-chunk-stream "^1.0.0" 1404 | is-utf8 "^0.2.0" 1405 | 1406 | strip-bom@^2.0.0: 1407 | version "2.0.0" 1408 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" 1409 | dependencies: 1410 | is-utf8 "^0.2.0" 1411 | 1412 | strip-json-comments@1.0.x, strip-json-comments@~1.0.2: 1413 | version "1.0.4" 1414 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" 1415 | 1416 | supports-color@^2.0.0: 1417 | version "2.0.0" 1418 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1419 | 1420 | through2@^0.6.1: 1421 | version "0.6.5" 1422 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" 1423 | dependencies: 1424 | readable-stream ">=1.0.33-1 <1.1.0-0" 1425 | xtend ">=4.0.0 <4.1.0-0" 1426 | 1427 | through2@^2.0.0, through2@^2.0.1: 1428 | version "2.0.3" 1429 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" 1430 | dependencies: 1431 | readable-stream "^2.1.5" 1432 | xtend "~4.0.1" 1433 | 1434 | tildify@^1.0.0: 1435 | version "1.2.0" 1436 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" 1437 | dependencies: 1438 | os-homedir "^1.0.0" 1439 | 1440 | time-stamp@^1.0.0: 1441 | version "1.1.0" 1442 | resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" 1443 | 1444 | to-double-quotes@^2.0.0: 1445 | version "2.0.0" 1446 | resolved "https://registry.yarnpkg.com/to-double-quotes/-/to-double-quotes-2.0.0.tgz#aaf231d6fa948949f819301bbab4484d8588e4a7" 1447 | 1448 | to-single-quotes@^2.0.0: 1449 | version "2.0.1" 1450 | resolved "https://registry.yarnpkg.com/to-single-quotes/-/to-single-quotes-2.0.1.tgz#7cc29151f0f5f2c41946f119f5932fe554170125" 1451 | 1452 | unc-path-regex@^0.1.0: 1453 | version "0.1.2" 1454 | resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" 1455 | 1456 | underscore@~1.6.0: 1457 | version "1.6.0" 1458 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" 1459 | 1460 | unique-stream@^1.0.0: 1461 | version "1.0.0" 1462 | resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" 1463 | 1464 | user-home@^1.1.1: 1465 | version "1.1.1" 1466 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" 1467 | 1468 | util-deprecate@~1.0.1: 1469 | version "1.0.2" 1470 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1471 | 1472 | utile@0.2.x: 1473 | version "0.2.1" 1474 | resolved "https://registry.yarnpkg.com/utile/-/utile-0.2.1.tgz#930c88e99098d6220834c356cbd9a770522d90d7" 1475 | dependencies: 1476 | async "~0.2.9" 1477 | deep-equal "*" 1478 | i "0.3.x" 1479 | mkdirp "0.x.x" 1480 | ncp "0.4.x" 1481 | rimraf "2.x.x" 1482 | 1483 | uuid@^2.0.2: 1484 | version "2.0.3" 1485 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" 1486 | 1487 | v8flags@^2.0.2: 1488 | version "2.1.1" 1489 | resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" 1490 | dependencies: 1491 | user-home "^1.1.1" 1492 | 1493 | vinyl-fs@^0.3.0: 1494 | version "0.3.14" 1495 | resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" 1496 | dependencies: 1497 | defaults "^1.0.0" 1498 | glob-stream "^3.1.5" 1499 | glob-watcher "^0.0.6" 1500 | graceful-fs "^3.0.0" 1501 | mkdirp "^0.5.0" 1502 | strip-bom "^1.0.0" 1503 | through2 "^0.6.1" 1504 | vinyl "^0.4.0" 1505 | 1506 | vinyl@^0.4.0: 1507 | version "0.4.6" 1508 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" 1509 | dependencies: 1510 | clone "^0.2.0" 1511 | clone-stats "^0.0.1" 1512 | 1513 | vinyl@^0.5.0: 1514 | version "0.5.3" 1515 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" 1516 | dependencies: 1517 | clone "^1.0.0" 1518 | clone-stats "^0.0.1" 1519 | replace-ext "0.0.1" 1520 | 1521 | vinyl@^2.0.0: 1522 | version "2.0.2" 1523 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" 1524 | dependencies: 1525 | clone "^1.0.0" 1526 | clone-buffer "^1.0.0" 1527 | clone-stats "^1.0.0" 1528 | cloneable-readable "^1.0.0" 1529 | is-stream "^1.1.0" 1530 | remove-trailing-separator "^1.0.1" 1531 | replace-ext "^1.0.0" 1532 | 1533 | vow-fs@~0.3.4: 1534 | version "0.3.6" 1535 | resolved "https://registry.yarnpkg.com/vow-fs/-/vow-fs-0.3.6.tgz#2d4c59be22e2bf2618ddf597ab4baa923be7200d" 1536 | dependencies: 1537 | glob "^7.0.5" 1538 | uuid "^2.0.2" 1539 | vow "^0.4.7" 1540 | vow-queue "^0.4.1" 1541 | 1542 | vow-queue@^0.4.1: 1543 | version "0.4.2" 1544 | resolved "https://registry.yarnpkg.com/vow-queue/-/vow-queue-0.4.2.tgz#e7fe17160e15c7c4184d1b666a9bc64e18e30184" 1545 | dependencies: 1546 | vow "~0.4.0" 1547 | 1548 | vow@^0.4.7, vow@~0.4.0, vow@~0.4.8: 1549 | version "0.4.16" 1550 | resolved "https://registry.yarnpkg.com/vow/-/vow-0.4.16.tgz#bb9d54d938d5f80520d658a740e7a895e30feeeb" 1551 | 1552 | which@^1.2.12: 1553 | version "1.2.14" 1554 | resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" 1555 | dependencies: 1556 | isexe "^2.0.0" 1557 | 1558 | winston@0.8.x: 1559 | version "0.8.3" 1560 | resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0" 1561 | dependencies: 1562 | async "0.2.x" 1563 | colors "0.6.x" 1564 | cycle "1.0.x" 1565 | eyes "0.1.x" 1566 | isstream "0.1.x" 1567 | pkginfo "0.3.x" 1568 | stack-trace "0.0.x" 1569 | 1570 | wrappy@1: 1571 | version "1.0.2" 1572 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1573 | 1574 | xmlbuilder@^3.1.0: 1575 | version "3.1.0" 1576 | resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-3.1.0.tgz#2c86888f2d4eade850fa38ca7f7223f7209516e1" 1577 | dependencies: 1578 | lodash "^3.5.0" 1579 | 1580 | "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1: 1581 | version "4.0.1" 1582 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 1583 | --------------------------------------------------------------------------------