commit 2787ebf163664df3a8f43f2790ab239effbcabd4 Author: Mattéo Delabre ✏ Date: Sun Apr 2 02:54:46 2017 +0200 Commit initial diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..2eaff7b --- /dev/null +++ b/.eslintrc @@ -0,0 +1,38 @@ +{ + "extends": ["eslint:recommended"], + + "rules": { + "no-console": 0, + + "no-shadow": 2, + "no-catch-shadow": 2, + "no-shadow-restricted-names": 2, + "radix": 2, + + "wrap-iife": 2, + "yoda": 2, + "semi": 2, + "indent": 2, + "camelcase": 2, + "brace-style": [2, "allman"], + "comma-spacing": 2, + "comma-style": 2, + "quotes": [2, "single", "avoid-escape"], + "no-spaced-func": 2, + "keyword-spacing": 2, + "space-before-blocks": 2, + "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], + "space-in-parens": 2, + "space-infix-ops": 2, + "space-unary-ops": 2, + "no-trailing-spaces": 0, + "no-underscore-dangle": 0 + }, + + "parser": "babel-eslint", + + "env": { + "es6": true, + "node": true + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..9501ff4 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# epenser-maze + +À l’occasion du 1er avril 2017, le vulgarisateur français [e-penser](https://www.youtube.com/user/epenser1) a posté sur YouTube un réseau de vidéos interconnectées à la manière d’un labyrinthe. À chaque vidéo, le vidéaste nous laisse le choix d’en visionner deux autres, et nous met au défi de toutes les regarder pour parvenir à trouver une vidéo mystérieuse. + +Ce dépôt contient le code utilisé pour générer [un graphe de dépendances de chaque vidéo vers celles liées](https://matteodelabre.github.io/epenser-maze), permettant d’accéder directement à la vidéo mystérieuse. + +## Technologies + +* [Javascript (ES6)](https://fr.wikipedia.org/wiki/JavaScript) : langage de programmation interprété. +* [Node.JS](https://fr.wikipedia.org/wiki/Node.js) : environnement d’exécution de JavaScript. +* [Graphviz](http://www.graphviz.org/) : outil pour visionner et générer des représentations des graphes. + +## Générer le graphe + +Pour générer le graphe par vous-mêmes, vous devez au préalable avoir installé Node.JS et Graphviz. Ensuite, lancez les commandes suivantes dans un terminal : + +``` +git clone https://github.com/matteodelabre/epenser-maze.git +cd epenser-maze +npm install +node ./src +dot maze.dot -Tsvg -o maze.svg +``` + +## Licence + +Publié sous la licence CC0. Dans la mesure permise par la loi, je renonce à tout droit d’auteur ou droit voisin sur cette logiciel. [Voir la licence complète.](http://creativecommons.org/publicdomain/zero/1.0/) diff --git a/index.html b/index.html new file mode 100644 index 0000000..f3b77db --- /dev/null +++ b/index.html @@ -0,0 +1,465 @@ + + + + + Exploration du labyrinthe du 1er avril d’e-penser + + + +

Exploration du labyrinthe du 1er avril d’e-penser

+ +

+ À l’occasion du 1er avril 2017, le vulgarisateur français e-penser a posté sur YouTube un réseau de vidéos interconnectées à la manière d’un labyrinthe. À chaque vidéo, le vidéaste nous laisse le choix d’en visionner deux autres, et nous met au défi de toutes les regarder pour parvenir à trouver une vidéo mystérieuse. +

+ +

+ Ce qui suit est le graphe issu de l’exploration automatisée du labyrinthe de vidéos. Chaque vidéo est cliquable. La première vidéo du graphe vous permettra de comprendre les règles établies par Bruce, la dernière est la « vidéo mystère ». +

+ +

+ + Plus d’infos sur l’exploration » + +

+ +
+ + + + epenser + + + EZGra6O8ClQ + + + 1 avril 2017 : présentation des règles + + + + + Ao990NQwn1Y + + + Vidéo sérieuse + + + + + EZGra6O8ClQ->Ao990NQwn1Y + + + + + OQloldjDS6w + + + TOP 14 DES FILMS AVEC UN TWIST DE FIN (SANS SPOIL) 🤐 + + + + + EZGra6O8ClQ->OQloldjDS6w + + + + + TabnloyIsz8 + + + Lien exemple, ne pas cliquer + + + + + EZGra6O8ClQ->TabnloyIsz8 + + + + + t2sBrJB0dCY + + + LE MENSONGE APOLLO XI 🌕 🌔 🌓 🌒 🌑 + + + + + Ao990NQwn1Y->t2sBrJB0dCY + + + + + EZjqL8kSkCE + + + Plus d'arguments sur la Terre plate + + + + + Ao990NQwn1Y->EZjqL8kSkCE + + + + + Hxho4NmIUi8 + + + TOP 6 DES SERIES MECONNUES 🤓 + + + + + OQloldjDS6w->Hxho4NmIUi8 + + + + + MgxGVSxIQbY + + + La liste de tous mes 📀 DVD 📀 + + + + + OQloldjDS6w->MgxGVSxIQbY + + + + + cUAPNwbZNzg + + + 1 avril 2017 : présentation des règles + + + + + TabnloyIsz8->cUAPNwbZNzg + + + + + t2sBrJB0dCY->OQloldjDS6w + + + + + gNO13ad_KpY + + + Une vidéo satisfaisante... 😌 + + + + + t2sBrJB0dCY->gNO13ad_KpY + + + + + EZjqL8kSkCE->OQloldjDS6w + + + + + EZjqL8kSkCE->t2sBrJB0dCY + + + + + Hxho4NmIUi8->MgxGVSxIQbY + + + + + Sw_iXCxB3Aw + + + TOP 4 DES FILMS LES PLUS SURÉVALUÉS 😤 + + + + + Hxho4NmIUi8->Sw_iXCxB3Aw + + + + + vX1CVTDopo0 + + + La liste de tous mes 📀 DVD 📀 + + + + + MgxGVSxIQbY->vX1CVTDopo0 + + + + + 54aErO8O6g0 + + + TOP 10 DES FILMS DE SCIENCE FICTION 👾 + + + + + MgxGVSxIQbY->54aErO8O6g0 + + + + + cUAPNwbZNzg->Ao990NQwn1Y + + + + + cUAPNwbZNzg->54aErO8O6g0 + + + + + U5swVaaiDI0 + + + Lien exemple, ne pas cliquer + + + + + cUAPNwbZNzg->U5swVaaiDI0 + + + + + Sw_iXCxB3Aw->54aErO8O6g0 + + + + + gGaqlwG1jOU + + + Unboxing n°2  ✂📦 + + + + + Sw_iXCxB3Aw->gGaqlwG1jOU + + + + + vX1CVTDopo0->MgxGVSxIQbY + + + + + vX1CVTDopo0->54aErO8O6g0 + + + + + 54aErO8O6g0->MgxGVSxIQbY + + + + + DIdfsbSHc5k + + + TOPCEPTION DES 5 FILMS DE MES 6 RÉALISATEURS PRÉFÉRÉS 🤒 + + + + + 54aErO8O6g0->DIdfsbSHc5k + + + + + U5swVaaiDI0->cUAPNwbZNzg + + + + + gGaqlwG1jOU->vX1CVTDopo0 + + + + + 3p8UjydB3uo + + + TOP 5 DES FILMS MÉCONNUS 😯 + + + + + gGaqlwG1jOU->3p8UjydB3uo + + + + + DIdfsbSHc5k->MgxGVSxIQbY + + + + + -kSgJdYLaUg + + + TOP 9 DES FILMS D'ARTS MARTIAUX 👊 + + + + + DIdfsbSHc5k->-kSgJdYLaUg + + + + + 3p8UjydB3uo->MgxGVSxIQbY + + + + + puHJLuBGsXU + + + TOP 5 DES COMEDIES MUSICALES 🎼 + + + + + 3p8UjydB3uo->puHJLuBGsXU + + + + + -kSgJdYLaUg->MgxGVSxIQbY + + + + + -kSgJdYLaUg->Sw_iXCxB3Aw + + + + + puHJLuBGsXU->MgxGVSxIQbY + + + + + MgemnP19JQA + + + TOP 10 DES PAGES WIKIPEDIA LES + VISITÉES 🌍 + + + + + puHJLuBGsXU->MgemnP19JQA + + + + + MgemnP19JQA->MgxGVSxIQbY + + + + + 9TEoWhqHgC8 + + + TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥 + + + + + MgemnP19JQA->9TEoWhqHgC8 + + + + + 9TEoWhqHgC8->DIdfsbSHc5k + + + + + lDbkj6uMH00 + + + Unboxing n°1  ✂📦 + + + + + 9TEoWhqHgC8->lDbkj6uMH00 + + + + + lDbkj6uMH00->gGaqlwG1jOU + + + + + AbfsEn_Ai2M + + + TOP 8 DES FILMS SUR LE VOYAGE DANS LE TEMPS 🕝🕒🕜🕖 + + + + + lDbkj6uMH00->AbfsEn_Ai2M + + + + + AbfsEn_Ai2M->lDbkj6uMH00 + + + + + 3OAdSASoYu0 + + + TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥 + + + + + AbfsEn_Ai2M->3OAdSASoYu0 + + + + + 3OAdSASoYu0->DIdfsbSHc5k + + + + + x6kjUMLpZaE + + + Unboxing n°1 ✂📦 + + + + + 3OAdSASoYu0->x6kjUMLpZaE + + + + + + + diff --git a/maze.dot b/maze.dot new file mode 100644 index 0000000..87f5db5 --- /dev/null +++ b/maze.dot @@ -0,0 +1,73 @@ +digraph epenser { + "EZGra6O8ClQ" [label="1 avril 2017 : présentation des règles", URL="https://youtu.be/EZGra6O8ClQ", fontcolor=blue] + "Ao990NQwn1Y" [label="Vidéo sérieuse", URL="https://youtu.be/Ao990NQwn1Y", fontcolor=blue] + "OQloldjDS6w" [label="TOP 14 DES FILMS AVEC UN TWIST DE FIN (SANS SPOIL) 🤐", URL="https://youtu.be/OQloldjDS6w", fontcolor=blue] + "TabnloyIsz8" [label="Lien exemple, ne pas cliquer", URL="https://youtu.be/TabnloyIsz8", fontcolor=blue] + "t2sBrJB0dCY" [label="LE MENSONGE APOLLO XI 🌕 🌔 🌓 🌒 🌑", URL="https://youtu.be/t2sBrJB0dCY", fontcolor=blue] + "EZjqL8kSkCE" [label="Plus d'arguments sur la Terre plate", URL="https://youtu.be/EZjqL8kSkCE", fontcolor=blue] + "Hxho4NmIUi8" [label="TOP 6 DES SERIES MECONNUES 🤓", URL="https://youtu.be/Hxho4NmIUi8", fontcolor=blue] + "MgxGVSxIQbY" [label="La liste de tous mes 📀 DVD 📀", URL="https://youtu.be/MgxGVSxIQbY", fontcolor=blue] + "cUAPNwbZNzg" [label="1 avril 2017 : présentation des règles", URL="https://youtu.be/cUAPNwbZNzg", fontcolor=blue] + "Sw_iXCxB3Aw" [label="TOP 4 DES FILMS LES PLUS SURÉVALUÉS 😤", URL="https://youtu.be/Sw_iXCxB3Aw", fontcolor=blue] + "vX1CVTDopo0" [label="La liste de tous mes 📀 DVD 📀", URL="https://youtu.be/vX1CVTDopo0", fontcolor=blue] + "54aErO8O6g0" [label="TOP 10 DES FILMS DE SCIENCE FICTION 👾", URL="https://youtu.be/54aErO8O6g0", fontcolor=blue] + "gNO13ad_KpY" [label="Une vidéo satisfaisante... 😌", URL="https://youtu.be/gNO13ad_KpY", fontcolor=blue] + "U5swVaaiDI0" [label="Lien exemple, ne pas cliquer", URL="https://youtu.be/U5swVaaiDI0", fontcolor=blue] + "gGaqlwG1jOU" [label="Unboxing n°2 ✂📦", URL="https://youtu.be/gGaqlwG1jOU", fontcolor=blue] + "DIdfsbSHc5k" [label="TOPCEPTION DES 5 FILMS DE MES 6 RÉALISATEURS PRÉFÉRÉS 🤒", URL="https://youtu.be/DIdfsbSHc5k", fontcolor=blue] + "3p8UjydB3uo" [label="TOP 5 DES FILMS MÉCONNUS 😯", URL="https://youtu.be/3p8UjydB3uo", fontcolor=blue] + "-kSgJdYLaUg" [label="TOP 9 DES FILMS D'ARTS MARTIAUX 👊", URL="https://youtu.be/-kSgJdYLaUg", fontcolor=blue] + "puHJLuBGsXU" [label="TOP 5 DES COMEDIES MUSICALES 🎼", URL="https://youtu.be/puHJLuBGsXU", fontcolor=blue] + "MgemnP19JQA" [label="TOP 10 DES PAGES WIKIPEDIA LES + VISITÉES 🌍", URL="https://youtu.be/MgemnP19JQA", fontcolor=blue] + "9TEoWhqHgC8" [label="TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥", URL="https://youtu.be/9TEoWhqHgC8", fontcolor=blue] + "lDbkj6uMH00" [label="Unboxing n°1 ✂📦", URL="https://youtu.be/lDbkj6uMH00", fontcolor=blue] + "AbfsEn_Ai2M" [label="TOP 8 DES FILMS SUR LE VOYAGE DANS LE TEMPS 🕝🕒🕜🕖", URL="https://youtu.be/AbfsEn_Ai2M", fontcolor=blue] + "3OAdSASoYu0" [label="TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥", URL="https://youtu.be/3OAdSASoYu0", fontcolor=blue] + "x6kjUMLpZaE" [label="Unboxing n°1 ✂📦", URL="https://youtu.be/x6kjUMLpZaE", fontcolor=blue] + "EZGra6O8ClQ" -> "Ao990NQwn1Y" + "EZGra6O8ClQ" -> "OQloldjDS6w" + "EZGra6O8ClQ" -> "TabnloyIsz8" + "Ao990NQwn1Y" -> "t2sBrJB0dCY" + "Ao990NQwn1Y" -> "EZjqL8kSkCE" + "OQloldjDS6w" -> "Hxho4NmIUi8" + "OQloldjDS6w" -> "MgxGVSxIQbY" + "TabnloyIsz8" -> "cUAPNwbZNzg" + "t2sBrJB0dCY" -> "OQloldjDS6w" + "t2sBrJB0dCY" -> "gNO13ad_KpY" + "EZjqL8kSkCE" -> "t2sBrJB0dCY" + "EZjqL8kSkCE" -> "OQloldjDS6w" + "Hxho4NmIUi8" -> "Sw_iXCxB3Aw" + "Hxho4NmIUi8" -> "MgxGVSxIQbY" + "MgxGVSxIQbY" -> "vX1CVTDopo0" + "MgxGVSxIQbY" -> "54aErO8O6g0" + "cUAPNwbZNzg" -> "Ao990NQwn1Y" + "cUAPNwbZNzg" -> "54aErO8O6g0" + "cUAPNwbZNzg" -> "U5swVaaiDI0" + "Sw_iXCxB3Aw" -> "54aErO8O6g0" + "Sw_iXCxB3Aw" -> "gGaqlwG1jOU" + "vX1CVTDopo0" -> "MgxGVSxIQbY" + "vX1CVTDopo0" -> "54aErO8O6g0" + "54aErO8O6g0" -> "DIdfsbSHc5k" + "54aErO8O6g0" -> "MgxGVSxIQbY" + "U5swVaaiDI0" -> "cUAPNwbZNzg" + "gGaqlwG1jOU" -> "vX1CVTDopo0" + "gGaqlwG1jOU" -> "3p8UjydB3uo" + "DIdfsbSHc5k" -> "-kSgJdYLaUg" + "DIdfsbSHc5k" -> "MgxGVSxIQbY" + "3p8UjydB3uo" -> "puHJLuBGsXU" + "3p8UjydB3uo" -> "MgxGVSxIQbY" + "-kSgJdYLaUg" -> "Sw_iXCxB3Aw" + "-kSgJdYLaUg" -> "MgxGVSxIQbY" + "puHJLuBGsXU" -> "MgemnP19JQA" + "puHJLuBGsXU" -> "MgxGVSxIQbY" + "MgemnP19JQA" -> "MgxGVSxIQbY" + "MgemnP19JQA" -> "9TEoWhqHgC8" + "9TEoWhqHgC8" -> "DIdfsbSHc5k" + "9TEoWhqHgC8" -> "lDbkj6uMH00" + "lDbkj6uMH00" -> "gGaqlwG1jOU" + "lDbkj6uMH00" -> "AbfsEn_Ai2M" + "AbfsEn_Ai2M" -> "lDbkj6uMH00" + "AbfsEn_Ai2M" -> "3OAdSASoYu0" + "3OAdSASoYu0" -> "x6kjUMLpZaE" + "3OAdSASoYu0" -> "DIdfsbSHc5k" +} \ No newline at end of file diff --git a/maze.svg b/maze.svg new file mode 100644 index 0000000..be5a7e7 --- /dev/null +++ b/maze.svg @@ -0,0 +1,443 @@ + + + + + + +epenser + + +EZGra6O8ClQ + + +1 avril 2017 : présentation des règles + + + + +Ao990NQwn1Y + + +Vidéo sérieuse + + + + +EZGra6O8ClQ->Ao990NQwn1Y + + + + +OQloldjDS6w + + +TOP 14 DES FILMS AVEC UN TWIST DE FIN (SANS SPOIL) 🤐 + + + + +EZGra6O8ClQ->OQloldjDS6w + + + + +TabnloyIsz8 + + +Lien exemple, ne pas cliquer + + + + +EZGra6O8ClQ->TabnloyIsz8 + + + + +t2sBrJB0dCY + + +LE MENSONGE APOLLO XI 🌕 🌔 🌓 🌒 🌑 + + + + +Ao990NQwn1Y->t2sBrJB0dCY + + + + +EZjqL8kSkCE + + +Plus d'arguments sur la Terre plate + + + + +Ao990NQwn1Y->EZjqL8kSkCE + + + + +Hxho4NmIUi8 + + +TOP 6 DES SERIES MECONNUES 🤓 + + + + +OQloldjDS6w->Hxho4NmIUi8 + + + + +MgxGVSxIQbY + + +La liste de tous mes 📀 DVD 📀 + + + + +OQloldjDS6w->MgxGVSxIQbY + + + + +cUAPNwbZNzg + + +1 avril 2017 : présentation des règles + + + + +TabnloyIsz8->cUAPNwbZNzg + + + + +t2sBrJB0dCY->OQloldjDS6w + + + + +gNO13ad_KpY + + +Une vidéo satisfaisante... 😌 + + + + +t2sBrJB0dCY->gNO13ad_KpY + + + + +EZjqL8kSkCE->OQloldjDS6w + + + + +EZjqL8kSkCE->t2sBrJB0dCY + + + + +Hxho4NmIUi8->MgxGVSxIQbY + + + + +Sw_iXCxB3Aw + + +TOP 4 DES FILMS LES PLUS SURÉVALUÉS 😤 + + + + +Hxho4NmIUi8->Sw_iXCxB3Aw + + + + +vX1CVTDopo0 + + +La liste de tous mes 📀 DVD 📀 + + + + +MgxGVSxIQbY->vX1CVTDopo0 + + + + +54aErO8O6g0 + + +TOP 10 DES FILMS DE SCIENCE FICTION 👾 + + + + +MgxGVSxIQbY->54aErO8O6g0 + + + + +cUAPNwbZNzg->Ao990NQwn1Y + + + + +cUAPNwbZNzg->54aErO8O6g0 + + + + +U5swVaaiDI0 + + +Lien exemple, ne pas cliquer + + + + +cUAPNwbZNzg->U5swVaaiDI0 + + + + +Sw_iXCxB3Aw->54aErO8O6g0 + + + + +gGaqlwG1jOU + + +Unboxing n°2  ✂📦 + + + + +Sw_iXCxB3Aw->gGaqlwG1jOU + + + + +vX1CVTDopo0->MgxGVSxIQbY + + + + +vX1CVTDopo0->54aErO8O6g0 + + + + +54aErO8O6g0->MgxGVSxIQbY + + + + +DIdfsbSHc5k + + +TOPCEPTION DES 5 FILMS DE MES 6 RÉALISATEURS PRÉFÉRÉS 🤒 + + + + +54aErO8O6g0->DIdfsbSHc5k + + + + +U5swVaaiDI0->cUAPNwbZNzg + + + + +gGaqlwG1jOU->vX1CVTDopo0 + + + + +3p8UjydB3uo + + +TOP 5 DES FILMS MÉCONNUS 😯 + + + + +gGaqlwG1jOU->3p8UjydB3uo + + + + +DIdfsbSHc5k->MgxGVSxIQbY + + + + +-kSgJdYLaUg + + +TOP 9 DES FILMS D'ARTS MARTIAUX 👊 + + + + +DIdfsbSHc5k->-kSgJdYLaUg + + + + +3p8UjydB3uo->MgxGVSxIQbY + + + + +puHJLuBGsXU + + +TOP 5 DES COMEDIES MUSICALES 🎼 + + + + +3p8UjydB3uo->puHJLuBGsXU + + + + +-kSgJdYLaUg->MgxGVSxIQbY + + + + +-kSgJdYLaUg->Sw_iXCxB3Aw + + + + +puHJLuBGsXU->MgxGVSxIQbY + + + + +MgemnP19JQA + + +TOP 10 DES PAGES WIKIPEDIA LES + VISITÉES 🌍 + + + + +puHJLuBGsXU->MgemnP19JQA + + + + +MgemnP19JQA->MgxGVSxIQbY + + + + +9TEoWhqHgC8 + + +TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥 + + + + +MgemnP19JQA->9TEoWhqHgC8 + + + + +9TEoWhqHgC8->DIdfsbSHc5k + + + + +lDbkj6uMH00 + + +Unboxing n°1  ✂📦 + + + + +9TEoWhqHgC8->lDbkj6uMH00 + + + + +lDbkj6uMH00->gGaqlwG1jOU + + + + +AbfsEn_Ai2M + + +TOP 8 DES FILMS SUR LE VOYAGE DANS LE TEMPS 🕝🕒🕜🕖 + + + + +lDbkj6uMH00->AbfsEn_Ai2M + + + + +AbfsEn_Ai2M->lDbkj6uMH00 + + + + +3OAdSASoYu0 + + +TOP 10 DES BONS GROS FILMS D'ACTIONS 👉⚔🔫🎥 + + + + +AbfsEn_Ai2M->3OAdSASoYu0 + + + + +3OAdSASoYu0->DIdfsbSHc5k + + + + +x6kjUMLpZaE + + +Unboxing n°1 ✂📦 + + + + +3OAdSASoYu0->x6kjUMLpZaE + + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..ade8f04 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "epenser-maze", + "version": "0.1.0", + "main": "src/index.js", + "license": "CC0", + "dependencies": { + "babel-eslint": "^7.2.1", + "cheerio": "^0.22.0", + "eslint": "^3.19.0", + "graph-data-structure": "^0.8.0", + "request": "^2.81.0" + } +} diff --git a/src/api.js b/src/api.js new file mode 100644 index 0000000..eb6dbac --- /dev/null +++ b/src/api.js @@ -0,0 +1,109 @@ +'use strict'; + +const util = require('util'); +const request = require('request'); +const cheerio = require('cheerio'); + +const YOUTUBE_BASE = 'https://www.youtube.com/%s'; +const VIDEO_ID_REGEX = /watch\?v=([^&]*)/i; +const END_SCREEN_BASE = util.format(YOUTUBE_BASE, 'get_endscreen?v=%s'); +const CARD_BASE = util.format(YOUTUBE_BASE, 'annotations_invideo?video_id=%s'); + +/** + * Récupère une liste des vidéos liées à la fin d’une autre vidéo. + * + * @param videoId Identifiant de la vidéo source. + * @return Liste des vidéos liées. Chaque vidéo est un objet contenant + * son identifiant (videoId) et son titre (title). + */ +const getEndScreenVideos = videoId => +{ + const url = util.format(END_SCREEN_BASE, videoId); + + return new Promise((resolve, reject) => + { + request(url, (err, res, body) => + { + if (err) + { + reject(err); + return; + } + + // Suppression des caractères initiaux inutiles si applicable + if (body.substr(0, 3) === ')]}') + { + body = body.substr(3); + } + + // Interprétation du JSON + const data = JSON.parse(body); + + // Aucun écran de fin + if ( + typeof data !== 'object' || data === null || + data.elements === undefined + ) + { + resolve([]); + return; + } + + // Filtrage des données pour extraire le titre et l’ID des vidéos + resolve(data.elements.map(elt => ({ + videoId: elt.endscreenElementRenderer.endpoint + .watchEndpoint.videoId, + title: elt.endscreenElementRenderer.title.runs[0].text, + }))); + }); + }); +}; + +exports.getEndScreenVideos = getEndScreenVideos; + +/** + * Récupère une liste des vidéos liées en tant que carte d’une autre vidéo. + * + * @param videoId Identifiant de la vidéo source. + * @return Liste des vidéos liées. Chaque vidéo est un objet contenant + * son identifiant (videoId) et son titre (title). + */ +const getCardVideos = videoId => +{ + const url = util.format(CARD_BASE, videoId); + + return new Promise((resolve, reject) => + { + request(url, (err, res, body) => + { + if (err) + { + reject(err); + return; + } + + // Interprétation du XML externe et recherche des annotations + // de type carte + const nav = cheerio.load(body); + const cards = nav('annotation[type="card"][style="video"]'); + const list = []; + + cards.each((i, el) => + { + // Interprétation du JSON de chaque carte, extraction + // du titre et de l’identifiant de la vidéo + const data = JSON.parse(nav(el).children('data').text()); + const videoIdResults = VIDEO_ID_REGEX.exec(data.url); + + list.push({ + title: data.title, + videoId: videoIdResults ? videoIdResults[1] : null + }); + }); + + resolve(list); + }); + }); +}; + +exports.getCardVideos = getCardVideos; diff --git a/src/graph.js b/src/graph.js new file mode 100644 index 0000000..5ef738b --- /dev/null +++ b/src/graph.js @@ -0,0 +1,53 @@ +'use strict'; + +const util = require('util'); + +const GRAPH_NODE = ' "%s" [label="%s"]'; +const GRAPH_NODE_URL = ' "%s" [label="%s", URL="%s", fontcolor=blue]'; +const GRAPH_LINK = ' "%s" -> "%s"'; + +/** + * Convertit un graphe en format DOT. + * + * @param graph Graphe à convertir. + * @param [title=identity] Fonction donnant le titre de chaque nœud du graphe. + * @param [url=none] Fonction donnant l’URL de chaque nœud du graphe, ou la + * chaîne vide si un nœud n’a pas d’URL. + * @return Représentation DOT du graphe. + */ +const graphToDOT = (graph, title = id => id, url = () => '') => +{ + const ser = graph.serialize(); + + // Conversion des nœuds de vidéo + const nodes = ser.nodes.map(({id}) => + { + const nodeTitle = title(id); + const nodeUrl = url(id); + + if (url === '') + { + return util.format(GRAPH_NODE, id, nodeTitle); + } + else + { + return util.format(GRAPH_NODE_URL, id, nodeTitle, nodeUrl); + } + } + ).join('\n'); + + // Conversion des liens de vidéo + const links = ser.links.map(({source, target}) => + util.format(GRAPH_LINK, source, target) + ).join('\n'); + + return ( + 'digraph epenser {\n' + + nodes + + '\n' + + links + + '\n}' + ); +}; + +exports.graphToDOT = graphToDOT; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..0d9fe91 --- /dev/null +++ b/src/index.js @@ -0,0 +1,82 @@ +'use strict'; + +const Graph = require('graph-data-structure'); +const fs = require('fs'); +const path = require('path'); +const util = require('util'); + +const {getEndScreenVideos, getCardVideos} = require('./api'); +const {graphToDOT} = require('./graph'); + +const YOUTUBE_WATCH = 'https://youtu.be/%s'; + +// Graphe des vidéos. Chaque nœud est une vidéo, et est liée à toutes +// les vidéos vers lesquelles elle a un lien (par carte ou écran de fin) +const videosGraph = Graph(); + +// Stocke les métadonnées de chaque vidéo +const videosMeta = Object.create(null); + +// Se souvient des vidéos déja visitées +const visitedVideos = Object.create(null); + +/** + * Explore récursivement les liens d’une vidéo pour remplir le graphe + * des vidéos. + * + * @param videoId Identifiant de la vidéo source. + */ +const exploreVideo = videoId => +{ + // S’assure de ne pas visiter deux fois la même vidéo + if (visitedVideos[videoId] === true) + { + return Promise.resolve(); + } + + visitedVideos[videoId] = true; + + return Promise.all([ + getEndScreenVideos(videoId), + getCardVideos(videoId) + ]).then(results => + { + const videos = [].concat(...results); + const ids = videos.map(video => video.videoId); + // const remaining = ids.filter(id => videos[id] === undefined); + + // Ajout des vidéos liées dans les métadonnées + videos.forEach(video => videosMeta[video.videoId] = video); + + // Ajout des liens entre la vidéo et ses vidéos liées + ids.forEach(id => videosGraph.addEdge(videoId, id)); + + // Récursion sur les vidéos non-explorées + return Promise.all(ids.map(id => exploreVideo(id))); + }); +}; + +// Métadonnées de la vidéo source +const rootVideoId = 'EZGra6O8ClQ'; +videosMeta[rootVideoId] = { + title: '1 avril 2017 : présentation des règles', + videoId: rootVideoId, + links: [] +}; + +console.log('Démarrage de l’exploration !'); + +exploreVideo(rootVideoId).then(() => +{ + const dest = path.join(__dirname, '../maze.dot'); + console.log('Terminé. Résultat dans ' + dest); + + fs.writeFileSync( + dest, + graphToDOT( + videosGraph, + id => videosMeta[id].title, + id => util.format(YOUTUBE_WATCH, id) + ) + ); +}).catch(console.error); diff --git a/style.css b/style.css new file mode 100644 index 0000000..7820769 --- /dev/null +++ b/style.css @@ -0,0 +1,18 @@ +html +{ + margin: 0; + padding: 0; +} + +body +{ + padding: 4em 6em; + font-family: sans-serif; +} + +hr +{ + border: 0; + border-bottom: 1px solid black; + margin-bottom: 2em; +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..11ceb26 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1295 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-eslint@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.1.tgz#079422eb73ba811e3ca0865ce87af29327f8c52f" + dependencies: + babel-code-frame "^6.22.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.16.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-traverse@^6.23.1: + version "6.23.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.15.0, babylon@^6.16.1: + version "6.16.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +cheerio@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +circular-json@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug@^2.1.1, debug@^2.2.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" + dependencies: + ms "0.7.2" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +dom-serializer@0, dom-serializer@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + +domelementtype@1, domelementtype@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domhandler@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + dependencies: + domelementtype "1" + +domutils@1.5.1, domutils@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.15" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2" + dependencies: + acorn "^5.0.1" + acorn-jsx "^3.0.0" + +esprima@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + dependencies: + estraverse "~4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0, globals@^9.14.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +graph-data-structure@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/graph-data-structure/-/graph-data-structure-0.8.0.tgz#52ca8be48359ad688ae420a3252937c4e27204ce" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +htmlparser2@^3.9.1: + version "3.9.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" + dependencies: + domelementtype "^1.3.0" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^2.0.2" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +ignore@^3.2.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-my-json-valid@^2.10.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +js-yaml@^3.5.1: + version "3.8.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" + dependencies: + argparse "^1.0.7" + esprima "^3.1.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" + dependencies: + assert-plus "1.0.0" + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + +lodash.merge@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + +lodash.some@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + +lodash@^4.0.0, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +mime-db@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" + +mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.15" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" + dependencies: + mime-db "~1.27.0" + +minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +nth-check@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" + dependencies: + boolbase "~1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +readable-stream@^2.0.2, readable-stream@^2.2.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regenerator-runtime@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve@^1.1.6: + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +rimraf@^2.2.8: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + +shelljs@^0.7.5: + version "0.7.7" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"